diff options
author | Amir Vadai <amirva@mellanox.com> | 2016-05-13 12:55:37 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-16 13:43:50 -0400 |
commit | 10cbc6843446165ee250e1ee80dc19ee325f1e6d (patch) | |
tree | 9a281054241598e1a44a6dfd3826e7d1e2657f98 | |
parent | 9fea47d93bcc98946a6eca0f019ced337564a344 (diff) | |
download | linux-10cbc6843446165ee250e1ee80dc19ee325f1e6d.tar.bz2 |
net/sched: cls_flower: Hardware offloaded filters statistics support
Introduce a new command in ndo_setup_tc() for hardware offloaded
filters, to call the NIC driver, and make it update the statistics.
This will be done before dumping the filter and its statistics.
Signed-off-by: Amir Vadai <amirva@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/pkt_cls.h | 1 | ||||
-rw-r--r-- | net/sched/cls_flower.c | 21 |
2 files changed, 22 insertions, 0 deletions
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 8b4893878cf4..0f7efa88f210 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -426,6 +426,7 @@ static inline bool tc_flags_valid(u32 flags) enum tc_fl_command { TC_CLSFLOWER_REPLACE, TC_CLSFLOWER_DESTROY, + TC_CLSFLOWER_STATS, }; struct tc_cls_flower_offload { diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 2181ffc76638..730aacafc22d 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -210,6 +210,25 @@ static void fl_hw_replace_filter(struct tcf_proto *tp, dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, &tc); } +static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f) +{ + struct net_device *dev = tp->q->dev_queue->dev; + struct tc_cls_flower_offload offload = {0}; + struct tc_to_netdev tc; + + if (!tc_should_offload(dev, 0)) + return; + + offload.command = TC_CLSFLOWER_STATS; + offload.cookie = (unsigned long)f; + offload.exts = &f->exts; + + tc.type = TC_SETUP_CLSFLOWER; + tc.cls_flower = &offload; + + dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, &tc); +} + static bool fl_destroy(struct tcf_proto *tp, bool force) { struct cls_fl_head *head = rtnl_dereference(tp->root); @@ -662,6 +681,8 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, goto nla_put_failure; } + fl_hw_update_stats(tp, f); + if (fl_dump_key_val(skb, key->eth.dst, TCA_FLOWER_KEY_ETH_DST, mask->eth.dst, TCA_FLOWER_KEY_ETH_DST_MASK, sizeof(key->eth.dst)) || |