libnl  3.2.3
/build/buildd/libnl3-3.2.3/lib/route/qdisc/red.c
00001 /*
00002  * lib/route/qdisc/red.c                RED Qdisc
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) 2003-2011 Thomas Graf <tgraf@suug.ch>
00010  */
00011 
00012 /**
00013  * @ingroup qdisc
00014  * @defgroup qdisc_red Random Early Detection (RED)
00015  * @brief
00016  * @{
00017  */
00018 
00019 #include <netlink-local.h>
00020 #include <netlink-tc.h>
00021 #include <netlink/netlink.h>
00022 #include <netlink/utils.h>
00023 #include <netlink/route/tc-api.h>
00024 #include <netlink/route/qdisc.h>
00025 #include <netlink/route/qdisc/red.h>
00026 
00027 /** @cond SKIP */
00028 #define RED_ATTR_LIMIT          0x01
00029 #define RED_ATTR_QTH_MIN        0x02
00030 #define RED_ATTR_QTH_MAX        0x04
00031 #define RED_ATTR_FLAGS          0x08
00032 #define RED_ATTR_WLOG           0x10
00033 #define RED_ATTR_PLOG           0x20
00034 #define RED_ATTR_SCELL_LOG      0x40
00035 /** @endcond */
00036 
00037 static struct nla_policy red_policy[TCA_RED_MAX+1] = {
00038         [TCA_RED_PARMS]         = { .minlen = sizeof(struct tc_red_qopt) },
00039 };
00040 
00041 static int red_msg_parser(struct rtnl_tc *tc, void *data)
00042 {
00043         struct nlattr *tb[TCA_RED_MAX+1];
00044         struct rtnl_red *red = data;
00045         struct tc_red_qopt *opts;
00046         int err;
00047 
00048         if (!(tc->ce_mask & TCA_ATTR_OPTS))
00049                 return 0;
00050 
00051         err = tca_parse(tb, TCA_RED_MAX, tc, red_policy);
00052         if (err < 0)
00053                 return err;
00054 
00055         if (!tb[TCA_RED_PARMS])
00056                 return -NLE_MISSING_ATTR;
00057 
00058         opts = nla_data(tb[TCA_RED_PARMS]);
00059 
00060         red->qr_limit = opts->limit;
00061         red->qr_qth_min = opts->qth_min;
00062         red->qr_qth_max = opts->qth_max;
00063         red->qr_flags = opts->flags;
00064         red->qr_wlog = opts->Wlog;
00065         red->qr_plog = opts->Plog;
00066         red->qr_scell_log = opts->Scell_log;
00067 
00068         red->qr_mask = (RED_ATTR_LIMIT | RED_ATTR_QTH_MIN | RED_ATTR_QTH_MAX |
00069                         RED_ATTR_FLAGS | RED_ATTR_WLOG | RED_ATTR_PLOG |
00070                         RED_ATTR_SCELL_LOG);
00071 
00072         return 0;
00073 }
00074 
00075 static void red_dump_line(struct rtnl_tc *tc, void *data,
00076                           struct nl_dump_params *p)
00077 {
00078         struct rtnl_red *red = data;
00079 
00080         if (red) {
00081                 /* XXX: limit, min, max, flags */
00082         }
00083 }
00084 
00085 static void red_dump_details(struct rtnl_tc *tc, void *data,
00086                              struct nl_dump_params *p)
00087 {
00088         struct rtnl_red *red = data;
00089 
00090         if (red) {
00091                 /* XXX: wlog, plog, scell_log */
00092         }
00093 }
00094 
00095 static void red_dump_stats(struct rtnl_tc *tc, void *data,
00096                            struct nl_dump_params *p)
00097 {
00098         struct rtnl_red *red = data;
00099 
00100         if (red) {
00101                 /* XXX: xstats */
00102         }
00103 }
00104 
00105 static int red_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
00106 {
00107         struct rtnl_red *red = data;
00108 
00109         if (!red)
00110                 BUG();
00111 
00112 #if 0
00113         memset(&opts, 0, sizeof(opts));
00114         opts.quantum = sfq->qs_quantum;
00115         opts.perturb_period = sfq->qs_perturb;
00116         opts.limit = sfq->qs_limit;
00117 
00118         if (nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD) < 0)
00119                 goto errout;
00120 #endif
00121 
00122         return -NLE_OPNOTSUPP;
00123 }
00124 
00125 /**
00126  * @name Attribute Access
00127  * @{
00128  */
00129 
00130 /**
00131  * Set limit of RED qdisc.
00132  * @arg qdisc           RED qdisc to be modified.
00133  * @arg limit           New limit in number of packets.
00134  * @return 0 on success or a negative error code.
00135  */
00136 void rtnl_red_set_limit(struct rtnl_qdisc *qdisc, int limit)
00137 {
00138         struct rtnl_red *red;
00139 
00140         if (!(red = rtnl_tc_data(TC_CAST(qdisc))))
00141                 BUG();
00142 
00143         red->qr_limit = limit;
00144         red->qr_mask |= RED_ATTR_LIMIT;
00145 }
00146 
00147 /**
00148  * Get limit of RED qdisc.
00149  * @arg qdisc           RED qdisc.
00150  * @return Limit or a negative error code.
00151  */
00152 int rtnl_red_get_limit(struct rtnl_qdisc *qdisc)
00153 {
00154         struct rtnl_red *red;
00155 
00156         if (!(red = rtnl_tc_data(TC_CAST(qdisc))))
00157                 BUG();
00158 
00159         if (red->qr_mask & RED_ATTR_LIMIT)
00160                 return red->qr_limit;
00161         else
00162                 return -NLE_NOATTR;
00163 }
00164 
00165 /** @} */
00166 
00167 static struct rtnl_tc_ops red_ops = {
00168         .to_kind                = "red",
00169         .to_type                = RTNL_TC_TYPE_QDISC,
00170         .to_size                = sizeof(struct rtnl_red),
00171         .to_msg_parser          = red_msg_parser,
00172         .to_dump = {
00173             [NL_DUMP_LINE]      = red_dump_line,
00174             [NL_DUMP_DETAILS]   = red_dump_details,
00175             [NL_DUMP_STATS]     = red_dump_stats,
00176         },
00177         .to_msg_fill            = red_msg_fill,
00178 };
00179 
00180 static void __init red_init(void)
00181 {
00182         rtnl_tc_register(&red_ops);
00183 }
00184 
00185 static void __exit red_exit(void)
00186 {
00187         rtnl_tc_unregister(&red_ops);
00188 }
00189 
00190 /** @} */