diff options
author | Davide Caratti <dcaratti@redhat.com> | 2023-05-23 10:54:36 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-08-02 19:39:48 (GMT) |
commit | 05bd6366387cd7824a8036de95008dc5359aa193 (patch) | |
tree | efb0b8a44213c89fbce92069c48f28e9fb190c34 | |
parent | 77a8a0053a102a9d8258702a895ccb4b98d41a5e (diff) | |
download | libnl-05bd6366387cd7824a8036de95008dc5359aa193.zip libnl-05bd6366387cd7824a8036de95008dc5359aa193.tar.gz libnl-05bd6366387cd7824a8036de95008dc5359aa193.tar.bz2 |
add support for TC action statistics
https://github.com/thom311/libnl/issues/343
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
https://github.com/thom311/libnl/pull/346
-rw-r--r-- | lib/route/act.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/route/act.c b/lib/route/act.c index 33f0d3e..d1504df 100644 --- a/lib/route/act.c +++ b/lib/route/act.c @@ -386,6 +386,13 @@ void rtnl_act_put_all(struct rtnl_act **head) *head = NULL; } +static struct nla_policy tc_act_stats_policy[TCA_STATS_MAX+1] = { + [TCA_STATS_BASIC] = { .minlen = sizeof(struct gnet_stats_basic) }, + [TCA_STATS_QUEUE] = { .minlen = sizeof(struct gnet_stats_queue) }, + [TCA_STATS_RATE_EST] = { .minlen = sizeof(struct gnet_stats_rate_est) }, + [TCA_STATS_RATE_EST64] = { .minlen = sizeof(struct gnet_stats_rate_est64) }, +}; + int rtnl_act_parse(struct rtnl_act **head, struct nlattr *tb) { struct rtnl_act *act; @@ -434,6 +441,45 @@ int rtnl_act_parse(struct rtnl_act **head, struct nlattr *tb) tc->ce_mask |= TCA_ATTR_OPTS; } + if (tb2[TCA_ACT_STATS]) { + struct nlattr *tb3[TCA_STATS_MAX + 1]; + + err = nla_parse_nested(tb3, TCA_STATS_MAX, tb2[TCA_ACT_STATS], + tc_act_stats_policy); + if (err < 0) + return err; + + if (tb3[TCA_STATS_BASIC]) { + struct gnet_stats_basic bs; + + memcpy(&bs, nla_data(tb3[TCA_STATS_BASIC]), + sizeof(bs)); + tc->tc_stats[RTNL_TC_BYTES] = bs.bytes; + tc->tc_stats[RTNL_TC_PACKETS] = bs.packets; + } + if (tb3[TCA_STATS_RATE_EST64]) { + struct gnet_stats_rate_est64 re; + + memcpy(&re, nla_data(tb3[TCA_STATS_RATE_EST64]), + sizeof(re)); + tc->tc_stats[RTNL_TC_RATE_BPS] = re.bps; + tc->tc_stats[RTNL_TC_RATE_PPS] = re.pps; + } else if (tb3[TCA_STATS_RATE_EST]) { + struct gnet_stats_rate_est *re; + + re = nla_data(tb3[TCA_STATS_RATE_EST]); + tc->tc_stats[RTNL_TC_RATE_BPS] = re->bps; + tc->tc_stats[RTNL_TC_RATE_PPS] = re->pps; + } + if (tb3[TCA_STATS_QUEUE]) { + struct gnet_stats_queue *q; + + q = nla_data(tb3[TCA_STATS_QUEUE]); + tc->tc_stats[RTNL_TC_DROPS] = q->drops; + tc->tc_stats[RTNL_TC_OVERLIMITS] = q->overlimits; + } + } + ops = rtnl_tc_get_ops(tc); if (ops && ops->to_msg_parser) { void *data = rtnl_tc_data(tc); |