00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <netlink-local.h>
00033 #include <netlink-tc.h>
00034 #include <netlink/netlink.h>
00035 #include <netlink/route/tc-api.h>
00036 #include <netlink/route/qdisc.h>
00037 #include <netlink/route/qdisc/fifo.h>
00038 #include <netlink/utils.h>
00039
00040
00041 #define SCH_FIFO_ATTR_LIMIT 1
00042
00043
00044 static int fifo_msg_parser(struct rtnl_tc *tc, void *data)
00045 {
00046 struct rtnl_fifo *fifo = data;
00047 struct tc_fifo_qopt *opt;
00048
00049 if (tc->tc_opts->d_size < sizeof(struct tc_fifo_qopt))
00050 return -NLE_INVAL;
00051
00052 opt = (struct tc_fifo_qopt *) tc->tc_opts->d_data;
00053 fifo->qf_limit = opt->limit;
00054 fifo->qf_mask = SCH_FIFO_ATTR_LIMIT;
00055
00056 return 0;
00057 }
00058
00059 static void pfifo_dump_line(struct rtnl_tc *tc, void *data,
00060 struct nl_dump_params *p)
00061 {
00062 struct rtnl_fifo *fifo = data;
00063
00064 if (fifo)
00065 nl_dump(p, " limit %u packets", fifo->qf_limit);
00066 }
00067
00068 static void bfifo_dump_line(struct rtnl_tc *tc, void *data,
00069 struct nl_dump_params *p)
00070 {
00071 struct rtnl_fifo *fifo = data;
00072 char *unit;
00073 double r;
00074
00075 if (!fifo)
00076 return;
00077
00078 r = nl_cancel_down_bytes(fifo->qf_limit, &unit);
00079 nl_dump(p, " limit %.1f%s", r, unit);
00080 }
00081
00082 static int fifo_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
00083 {
00084 struct rtnl_fifo *fifo = data;
00085 struct tc_fifo_qopt opts = {0};
00086
00087 if (!fifo || !(fifo->qf_mask & SCH_FIFO_ATTR_LIMIT))
00088 return -NLE_INVAL;
00089
00090 opts.limit = fifo->qf_limit;
00091
00092 return nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD);
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 int rtnl_qdisc_fifo_set_limit(struct rtnl_qdisc *qdisc, int limit)
00107 {
00108 struct rtnl_fifo *fifo;
00109
00110 if (!(fifo = rtnl_tc_data(TC_CAST(qdisc))))
00111 return -NLE_NOMEM;
00112
00113 fifo->qf_limit = limit;
00114 fifo->qf_mask |= SCH_FIFO_ATTR_LIMIT;
00115
00116 return 0;
00117 }
00118
00119
00120
00121
00122
00123
00124 int rtnl_qdisc_fifo_get_limit(struct rtnl_qdisc *qdisc)
00125 {
00126 struct rtnl_fifo *fifo;
00127
00128 if (!(fifo = rtnl_tc_data(TC_CAST(qdisc))))
00129 return -NLE_NOMEM;
00130
00131 if (fifo->qf_mask & SCH_FIFO_ATTR_LIMIT)
00132 return fifo->qf_limit;
00133 else
00134 return -NLE_NOATTR;
00135 }
00136
00137
00138
00139 static struct rtnl_tc_ops pfifo_ops = {
00140 .to_kind = "pfifo",
00141 .to_type = RTNL_TC_TYPE_QDISC,
00142 .to_size = sizeof(struct rtnl_fifo),
00143 .to_msg_parser = fifo_msg_parser,
00144 .to_dump[NL_DUMP_LINE] = pfifo_dump_line,
00145 .to_msg_fill = fifo_msg_fill,
00146 };
00147
00148 static struct rtnl_tc_ops bfifo_ops = {
00149 .to_kind = "bfifo",
00150 .to_type = RTNL_TC_TYPE_QDISC,
00151 .to_size = sizeof(struct rtnl_fifo),
00152 .to_msg_parser = fifo_msg_parser,
00153 .to_dump[NL_DUMP_LINE] = bfifo_dump_line,
00154 .to_msg_fill = fifo_msg_fill,
00155 };
00156
00157 static void __init fifo_init(void)
00158 {
00159 rtnl_tc_register(&pfifo_ops);
00160 rtnl_tc_register(&bfifo_ops);
00161 }
00162
00163 static void __exit fifo_exit(void)
00164 {
00165 rtnl_tc_unregister(&pfifo_ops);
00166 rtnl_tc_unregister(&bfifo_ops);
00167 }
00168
00169