htb.c

00001 /*
00002  * src/lib/htb.c        HTB module for CLI lib
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2010-2011 Thomas Graf <tgraf@suug.ch>
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 }