From c102b35fbe88ea0cffb15de2ebf8d9d9484839a1 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czarnota Date: Thu, 4 Feb 2021 16:51:11 +0100 Subject: tbf: add pburst and burst parameters --- include/netlink-private/types.h | 4 ++ include/netlink/route/qdisc/tbf.h | 6 +++ lib/route/qdisc/tbf.c | 86 ++++++++++++++++++++++++++++--- libnl-route-3.sym | 4 ++ 4 files changed, 92 insertions(+), 8 deletions(-) --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -768,6 +768,10 @@ struct rtnl_tbf uint32_t qt_peakrate_bucket; uint32_t qt_peakrate_txtime; uint32_t qt_mask; + uint64_t qt_rate64; + uint64_t qt_prate64; + uint32_t qt_burst; + uint32_t qt_pburst; }; struct rtnl_sfq --- a/include/netlink/route/qdisc/tbf.h +++ b/include/netlink/route/qdisc/tbf.h @@ -24,6 +24,12 @@ extern void rtnl_qdisc_tbf_set_limit(str extern int rtnl_qdisc_tbf_set_limit_by_latency(struct rtnl_qdisc *, int); extern int rtnl_qdisc_tbf_get_limit(struct rtnl_qdisc *); +extern void rtnl_qdisc_tbf_set_burst(struct rtnl_qdisc *, int); +extern int rtnl_qdisc_tbf_get_burst(struct rtnl_qdisc *); + +extern void rtnl_qdisc_tbf_set_peakburst(struct rtnl_qdisc *, int); +extern int rtnl_qdisc_tbf_get_peakburst(struct rtnl_qdisc *); + extern void rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *, int, int, int); extern int rtnl_qdisc_tbf_get_rate(struct rtnl_qdisc *); extern int rtnl_qdisc_tbf_get_rate_bucket(struct rtnl_qdisc *); --- a/lib/route/qdisc/tbf.c +++ b/lib/route/qdisc/tbf.c @@ -30,10 +30,18 @@ #define TBF_ATTR_LIMIT 0x01 #define TBF_ATTR_RATE 0x02 #define TBF_ATTR_PEAKRATE 0x10 +#define TBF_ATTR_RATE64 0x20 +#define TBF_ATTR_PRATE64 0x40 +#define TBF_ATTR_BURST 0x80 +#define TBF_ATTR_PBURST 0x100 /** @endcond */ static struct nla_policy tbf_policy[TCA_TBF_MAX+1] = { - [TCA_TBF_PARMS] = { .minlen = sizeof(struct tc_tbf_qopt) }, + [TCA_TBF_PARMS] = { .minlen = sizeof(struct tc_tbf_qopt) }, + [TCA_TBF_RATE64] = { .type = NLA_U64 }, + [TCA_TBF_PRATE64] = { .type = NLA_U64 }, + [TCA_TBF_BURST] = { .type = NLA_U32 }, + [TCA_TBF_PBURST] = { .type = NLA_U32 }, }; static int tbf_msg_parser(struct rtnl_tc *tc, void *data) @@ -70,6 +78,16 @@ static int tbf_msg_parser(struct rtnl_tc tbf->qt_mask = (TBF_ATTR_LIMIT | TBF_ATTR_RATE | TBF_ATTR_PEAKRATE); } + if (tb[TCA_TBF_PBURST]) { + tbf->qt_pburst = nla_get_u32(tb[TCA_TBF_BURST]); + tbf->qt_mask |= TBF_ATTR_BURST; + } + + if (tb[TCA_TBF_PBURST]) { + tbf->qt_pburst = nla_get_u32(tb[TCA_TBF_PBURST]); + tbf->qt_mask |= TBF_ATTR_PBURST; + } + return 0; } @@ -155,6 +173,12 @@ static int tbf_msg_fill(struct rtnl_tc * NLA_PUT(msg, TCA_TBF_PARMS, sizeof(opts), &opts); NLA_PUT(msg, TCA_TBF_RTAB, sizeof(rtab), rtab); + if (tbf->qt_mask & TBF_ATTR_PBURST) + NLA_PUT_U32(msg, TCA_TBF_PBURST, tbf->qt_pburst); + + if (tbf->qt_mask & TBF_ATTR_BURST) + NLA_PUT_U32(msg, TCA_TBF_BURST, tbf->qt_burst); + if (tbf->qt_mask & TBF_ATTR_PEAKRATE) NLA_PUT(msg, TCA_TBF_PTAB, sizeof(ptab), ptab); @@ -259,12 +283,6 @@ int rtnl_qdisc_tbf_get_limit(struct rtnl return -NLE_NOATTR; } -static inline int calc_cell_log(int cell, int bucket) -{ - cell = rtnl_tc_calc_cell_log(cell); - return cell; -} - /** * Set rate of TBF qdisc. * @arg qdisc TBF qdisc to be modified. @@ -365,7 +383,10 @@ int rtnl_qdisc_tbf_set_peakrate(struct r if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) BUG(); - cell_log = calc_cell_log(cell, bucket); + if (!cell) + cell_log = UINT8_MAX; + else + cell_log = rtnl_tc_calc_cell_log(cell); if (cell_log < 0) return cell_log; @@ -433,6 +454,55 @@ int rtnl_qdisc_tbf_get_peakrate_cell(str return -1; } +void rtnl_qdisc_tbf_set_burst(struct rtnl_qdisc *qdisc, int burst) +{ + struct rtnl_tbf *tbf; + + if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) + BUG(); + + tbf->qt_mask |= TBF_ATTR_BURST; + tbf->qt_burst = burst; +} + +int rtnl_qdisc_tbf_get_burst(struct rtnl_qdisc *qdisc) +{ + struct rtnl_tbf *tbf; + + if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) + BUG(); + + if (tbf->qt_mask & TBF_ATTR_BURST) + return tbf->qt_burst; + else + return -1; +} + +void rtnl_qdisc_tbf_set_peakburst(struct rtnl_qdisc *qdisc, int peakburst) +{ + struct rtnl_tbf *tbf; + + if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) + BUG(); + + tbf->qt_mask |= TBF_ATTR_PBURST; + tbf->qt_pburst = peakburst; +} + +int rtnl_qdisc_tbf_get_peakburst(struct rtnl_qdisc *qdisc) +{ + struct rtnl_tbf *tbf; + + if (!(tbf = rtnl_tc_data(TC_CAST(qdisc)))) + BUG(); + + if (tbf->qt_mask & TBF_ATTR_PBURST) + return tbf->qt_pburst; + else + return -1; +} + + /** @} */ static struct rtnl_tc_ops tbf_tc_ops = { --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -750,6 +750,10 @@ global: rtnl_qdisc_tbf_set_limit_by_latency; rtnl_qdisc_tbf_set_peakrate; rtnl_qdisc_tbf_set_rate; + rtnl_qdisc_tbf_set_burst; + rtnl_qdisc_tbf_set_peakburst; + rtnl_qdisc_tbf_get_burst; + rtnl_qdisc_tbf_get_peakburst; rtnl_qdisc_update; rtnl_realms2str; rtnl_red_get_limit;