net/sched: cls_flower: Hardware offloaded filters statistics support
authorAmir Vadai <amirva@mellanox.com>
Fri, 13 May 2016 12:55:37 +0000 (12:55 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 16 May 2016 17:43:50 +0000 (13:43 -0400)
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>
include/net/pkt_cls.h
net/sched/cls_flower.c

index 8b4893878cf4614ea346d24a720856edbfbc3fbd..0f7efa88f210360928b36a80022c9bd53d778b40 100644 (file)
@@ -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 {
index 2181ffc76638035a93c077e7395d93892e82570e..730aacafc22d8638ccebce757cc5b6f8968bd39f 100644 (file)
@@ -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)) ||