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 (at) suug.ch> 10 */ 11 12 #include <netlink/cli/utils.h> 13 #include <netlink/cli/tc.h> 14 #include <netlink/route/qdisc/htb.h> 15 16 static 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 31 static 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 68 static 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 87 static 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 179 static 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 186 static 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 193 static void __init htb_init(void) 194 { 195 nl_cli_tc_register(&htb_qdisc_module); 196 nl_cli_tc_register(&htb_class_module); 197 } 198 199 static void __exit htb_exit(void) 200 { 201 nl_cli_tc_unregister(&htb_class_module); 202 nl_cli_tc_unregister(&htb_qdisc_module); 203 } 204