1/* 2 * src/lib/htb.c HTB module for CLI lib 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation version 2.1 7 * of the License. 8 * 9 * Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch> 10 */ 11 12#include <netlink/cli/utils.h> 13#include <netlink/cli/tc.h> 14#include <netlink/route/qdisc/htb.h> 15 16static void print_qdisc_usage(void) 17{ 18 printf( 19"Usage: nl-qdisc-add [...] htb [OPTIONS]...\n" 20"\n" 21"OPTIONS\n" 22" --help Show this help text.\n" 23" --r2q=DIV Rate to quantum divisor (default: 10)\n" 24" --default=ID Default class for unclassified traffic.\n" 25"\n" 26"EXAMPLE" 27" # Create htb root qdisc 1: and direct unclassified traffic to class 1:10\n" 28" nl-qdisc-add --dev=eth1 --parent=root --handle=1: htb --default=10\n"); 29} 30 31static void htb_parse_qdisc_argv(struct rtnl_tc *tc, int argc, char **argv) 32{ 33 struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc; 34 35 for (;;) { 36 int c, optidx = 0; 37 enum { 38 ARG_R2Q = 257, 39 ARG_DEFAULT = 258, 40 }; 41 static struct option long_opts[] = { 42 { "help", 0, 0, 'h' }, 43 { "r2q", 1, 0, ARG_R2Q }, 44 { "default", 1, 0, ARG_DEFAULT }, 45 { 0, 0, 0, 0 } 46 }; 47 48 c = getopt_long(argc, argv, "hv", long_opts, &optidx); 49 if (c == -1) 50 break; 51 52 switch (c) { 53 case 'h': 54 print_qdisc_usage(); 55 return; 56 57 case ARG_R2Q: 58 rtnl_htb_set_rate2quantum(qdisc, nl_cli_parse_u32(optarg)); 59 break; 60 61 case ARG_DEFAULT: 62 rtnl_htb_set_defcls(qdisc, nl_cli_parse_u32(optarg)); 63 break; 64 } 65 } 66} 67 68static void print_class_usage(void) 69{ 70 printf( 71"Usage: nl-class-add [...] htb [OPTIONS]...\n" 72"\n" 73"OPTIONS\n" 74" --help Show this help text.\n" 75" --rate=RATE Rate limit.\n" 76" --ceil=RATE Rate limit while borrowing (default: equal to --rate).\n" 77" --prio=PRIO Priority, lower is served first (default: 0).\n" 78" --quantum=SIZE Amount of bytes to serve at once (default: rate/r2q).\n" 79" --burst=SIZE Max charge size of rate burst buffer (default: auto).\n" 80" --cburst=SIZE Max charge size of ceil rate burst buffer (default: auto)\n" 81"\n" 82"EXAMPLE" 83" # Attach class 1:1 to htb qdisc 1: and rate limit it to 20mbit\n" 84" nl-class-add --dev=eth1 --parent=1: --classid=1:1 htb --rate=20mbit\n"); 85} 86 87static void htb_parse_class_argv(struct rtnl_tc *tc, int argc, char **argv) 88{ 89 struct rtnl_class *class = (struct rtnl_class *) tc; 90 long rate; 91 92 for (;;) { 93 int c, optidx = 0; 94 enum { 95 ARG_RATE = 257, 96 ARG_QUANTUM = 258, 97 ARG_CEIL, 98 ARG_PRIO, 99 ARG_BURST, 100 ARG_CBURST, 101 }; 102 static struct option long_opts[] = { 103 { "help", 0, 0, 'h' }, 104 { "rate", 1, 0, ARG_RATE }, 105 { "quantum", 1, 0, ARG_QUANTUM }, 106 { "ceil", 1, 0, ARG_CEIL }, 107 { "prio", 1, 0, ARG_PRIO }, 108 { "burst", 1, 0, ARG_BURST }, 109 { "cburst", 1, 0, ARG_CBURST }, 110 { 0, 0, 0, 0 } 111 }; 112 113 c = getopt_long(argc, argv, "h", long_opts, &optidx); 114 if (c == -1) 115 break; 116 117 switch (c) { 118 case 'h': 119 print_class_usage(); 120 return; 121 122 case ARG_RATE: 123 rate = nl_size2int(optarg); 124 if (rate < 0) { 125 nl_cli_fatal(rate, "Unable to parse htb rate " 126 "\"%s\": Invalid format.", optarg); 127 } 128 129 rtnl_htb_set_rate(class, rate); 130 break; 131 132 case ARG_CEIL: 133 rate = nl_size2int(optarg); 134 if (rate < 0) { 135 nl_cli_fatal(rate, "Unable to parse htb ceil rate " 136 "\"%s\": Invalid format.", optarg); 137 } 138 139 rtnl_htb_set_ceil(class, rate); 140 break; 141 142 case ARG_PRIO: 143 rtnl_htb_set_prio(class, nl_cli_parse_u32(optarg)); 144 break; 145 146 case ARG_QUANTUM: 147 rate = nl_size2int(optarg); 148 if (rate < 0) { 149 nl_cli_fatal(rate, "Unable to parse quantum " 150 "\"%s\": Invalid format.", optarg); 151 } 152 153 rtnl_htb_set_quantum(class, rate); 154 break; 155 156 case ARG_BURST: 157 rate = nl_size2int(optarg); 158 if (rate < 0) { 159 nl_cli_fatal(rate, "Unable to parse burst " 160 "\"%s\": Invalid format.", optarg); 161 } 162 163 rtnl_htb_set_rbuffer(class, rate); 164 break; 165 166 case ARG_CBURST: 167 rate = nl_size2int(optarg); 168 if (rate < 0) { 169 nl_cli_fatal(rate, "Unable to parse cburst " 170 "\"%s\": Invalid format.", optarg); 171 } 172 173 rtnl_htb_set_cbuffer(class, rate); 174 break; 175 } 176 } 177} 178 179static struct nl_cli_tc_module htb_qdisc_module = 180{ 181 .tm_name = "htb", 182 .tm_type = RTNL_TC_TYPE_QDISC, 183 .tm_parse_argv = htb_parse_qdisc_argv, 184}; 185 186static struct nl_cli_tc_module htb_class_module = 187{ 188 .tm_name = "htb", 189 .tm_type = RTNL_TC_TYPE_CLASS, 190 .tm_parse_argv = htb_parse_class_argv, 191}; 192 193static void __init htb_init(void) 194{ 195 nl_cli_tc_register(&htb_qdisc_module); 196 nl_cli_tc_register(&htb_class_module); 197} 198 199static void __exit htb_exit(void) 200{ 201 nl_cli_tc_unregister(&htb_class_module); 202 nl_cli_tc_unregister(&htb_qdisc_module); 203} 204