00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <netlink/cli/utils.h>
00013 #include <netlink/cli/tc.h>
00014 #include <netlink/route/qdisc/htb.h>
00015
00016 static void print_qdisc_usage(void)
00017 {
00018 printf(
00019 "Usage: nl-qdisc-add [...] htb [OPTIONS]...\n"
00020 "\n"
00021 "OPTIONS\n"
00022 " --help Show this help text.\n"
00023 " --r2q=DIV Rate to quantum divisor (default: 10)\n"
00024 " --default=ID Default class for unclassified traffic.\n"
00025 "\n"
00026 "EXAMPLE"
00027 " # Create htb root qdisc 1: and direct unclassified traffic to class 1:10\n"
00028 " nl-qdisc-add --dev=eth1 --parent=root --handle=1: htb --default=10\n");
00029 }
00030
00031 static void htb_parse_qdisc_argv(struct rtnl_tc *tc, int argc, char **argv)
00032 {
00033 struct rtnl_qdisc *qdisc = (struct rtnl_qdisc *) tc;
00034
00035 for (;;) {
00036 int c, optidx = 0;
00037 enum {
00038 ARG_R2Q = 257,
00039 ARG_DEFAULT = 258,
00040 };
00041 static struct option long_opts[] = {
00042 { "help", 0, 0, 'h' },
00043 { "r2q", 1, 0, ARG_R2Q },
00044 { "default", 1, 0, ARG_DEFAULT },
00045 { 0, 0, 0, 0 }
00046 };
00047
00048 c = getopt_long(argc, argv, "hv", long_opts, &optidx);
00049 if (c == -1)
00050 break;
00051
00052 switch (c) {
00053 case 'h':
00054 print_qdisc_usage();
00055 return;
00056
00057 case ARG_R2Q:
00058 rtnl_htb_set_rate2quantum(qdisc, nl_cli_parse_u32(optarg));
00059 break;
00060
00061 case ARG_DEFAULT:
00062 rtnl_htb_set_defcls(qdisc, nl_cli_parse_u32(optarg));
00063 break;
00064 }
00065 }
00066 }
00067
00068 static void print_class_usage(void)
00069 {
00070 printf(
00071 "Usage: nl-class-add [...] htb [OPTIONS]...\n"
00072 "\n"
00073 "OPTIONS\n"
00074 " --help Show this help text.\n"
00075 " --rate=RATE Rate limit.\n"
00076 " --ceil=RATE Rate limit while borrowing (default: equal to --rate).\n"
00077 " --prio=PRIO Priority, lower is served first (default: 0).\n"
00078 " --quantum=SIZE Amount of bytes to serve at once (default: rate/r2q).\n"
00079 " --burst=SIZE Max charge size of rate burst buffer (default: auto).\n"
00080 " --cburst=SIZE Max charge size of ceil rate burst buffer (default: auto)\n"
00081 "\n"
00082 "EXAMPLE"
00083 " # Attach class 1:1 to htb qdisc 1: and rate limit it to 20mbit\n"
00084 " nl-class-add --dev=eth1 --parent=1: --classid=1:1 htb --rate=20mbit\n");
00085 }
00086
00087 static void htb_parse_class_argv(struct rtnl_tc *tc, int argc, char **argv)
00088 {
00089 struct rtnl_class *class = (struct rtnl_class *) tc;
00090 long rate;
00091
00092 for (;;) {
00093 int c, optidx = 0;
00094 enum {
00095 ARG_RATE = 257,
00096 ARG_QUANTUM = 258,
00097 ARG_CEIL,
00098 ARG_PRIO,
00099 ARG_BURST,
00100 ARG_CBURST,
00101 };
00102 static struct option long_opts[] = {
00103 { "help", 0, 0, 'h' },
00104 { "rate", 1, 0, ARG_RATE },
00105 { "quantum", 1, 0, ARG_QUANTUM },
00106 { "ceil", 1, 0, ARG_CEIL },
00107 { "prio", 1, 0, ARG_PRIO },
00108 { "burst", 1, 0, ARG_BURST },
00109 { "cburst", 1, 0, ARG_CBURST },
00110 { 0, 0, 0, 0 }
00111 };
00112
00113 c = getopt_long(argc, argv, "h", long_opts, &optidx);
00114 if (c == -1)
00115 break;
00116
00117 switch (c) {
00118 case 'h':
00119 print_class_usage();
00120 return;
00121
00122 case ARG_RATE:
00123 rate = nl_size2int(optarg);
00124 if (rate < 0) {
00125 nl_cli_fatal(rate, "Unable to parse htb rate "
00126 "\"%s\": Invalid format.", optarg);
00127 }
00128
00129 rtnl_htb_set_rate(class, rate);
00130 break;
00131
00132 case ARG_CEIL:
00133 rate = nl_size2int(optarg);
00134 if (rate < 0) {
00135 nl_cli_fatal(rate, "Unable to parse htb ceil rate "
00136 "\"%s\": Invalid format.", optarg);
00137 }
00138
00139 rtnl_htb_set_ceil(class, rate);
00140 break;
00141
00142 case ARG_PRIO:
00143 rtnl_htb_set_prio(class, nl_cli_parse_u32(optarg));
00144 break;
00145
00146 case ARG_QUANTUM:
00147 rate = nl_size2int(optarg);
00148 if (rate < 0) {
00149 nl_cli_fatal(rate, "Unable to parse quantum "
00150 "\"%s\": Invalid format.", optarg);
00151 }
00152
00153 rtnl_htb_set_quantum(class, rate);
00154 break;
00155
00156 case ARG_BURST:
00157 rate = nl_size2int(optarg);
00158 if (rate < 0) {
00159 nl_cli_fatal(rate, "Unable to parse burst "
00160 "\"%s\": Invalid format.", optarg);
00161 }
00162
00163 rtnl_htb_set_rbuffer(class, rate);
00164 break;
00165
00166 case ARG_CBURST:
00167 rate = nl_size2int(optarg);
00168 if (rate < 0) {
00169 nl_cli_fatal(rate, "Unable to parse cburst "
00170 "\"%s\": Invalid format.", optarg);
00171 }
00172
00173 rtnl_htb_set_cbuffer(class, rate);
00174 break;
00175 }
00176 }
00177 }
00178
00179 static struct nl_cli_tc_module htb_qdisc_module =
00180 {
00181 .tm_name = "htb",
00182 .tm_type = RTNL_TC_TYPE_QDISC,
00183 .tm_parse_argv = htb_parse_qdisc_argv,
00184 };
00185
00186 static struct nl_cli_tc_module htb_class_module =
00187 {
00188 .tm_name = "htb",
00189 .tm_type = RTNL_TC_TYPE_CLASS,
00190 .tm_parse_argv = htb_parse_class_argv,
00191 };
00192
00193 static void __init htb_init(void)
00194 {
00195 nl_cli_tc_register(&htb_qdisc_module);
00196 nl_cli_tc_register(&htb_class_module);
00197 }
00198
00199 static void __exit htb_exit(void)
00200 {
00201 nl_cli_tc_unregister(&htb_class_module);
00202 nl_cli_tc_unregister(&htb_qdisc_module);
00203 }