net: sched: implement terse dump support in act
authorVlad Buslov <vladbu@mellanox.com>
Fri, 15 May 2020 11:40:12 +0000 (14:40 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 May 2020 17:23:11 +0000 (10:23 -0700)
Extend tcf_action_dump() with boolean argument 'terse' that is used to
request terse-mode action dump. In terse mode only essential data needed to
identify particular action (action kind, cookie, etc.) and its stats is put
to resulting skb and everything else is omitted. Implement
tcf_exts_terse_dump() helper in cls API that is intended to be used to
request terse dump of all exts (actions) attached to the filter.

Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/act_api.h
include/net/pkt_cls.h
net/sched/act_api.c
net/sched/cls_api.c

index c24d7643548ee927b4741f963a20e00925e755d9..1b4bfc4437be1fe8b661b237a44026177737e431 100644 (file)
@@ -193,7 +193,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
                                    bool rtnl_held,
                                    struct netlink_ext_ack *extack);
 int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind,
-                   int ref);
+                   int ref, bool terse);
 int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
 int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
 
index 04aa0649f3b09bb093cfee126f9cd51378006e4a..ed65619cbc47ae597ae4a500b28127d47fd834d3 100644 (file)
@@ -325,6 +325,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
 void tcf_exts_destroy(struct tcf_exts *exts);
 void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
 int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
+int tcf_exts_terse_dump(struct sk_buff *skb, struct tcf_exts *exts);
 int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
 
 /**
index fbbec2e562f5872be91bb6567f3a8a0a2f60192a..8ac7eb0a8309619e67dfcfbd7bd254e33230c59a 100644 (file)
@@ -766,12 +766,10 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
        return a->ops->dump(skb, a, bind, ref);
 }
 
-int
-tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+static int
+tcf_action_dump_terse(struct sk_buff *skb, struct tc_action *a)
 {
-       int err = -EINVAL;
        unsigned char *b = skb_tail_pointer(skb);
-       struct nlattr *nest;
        struct tc_cookie *cookie;
 
        if (nla_put_string(skb, TCA_KIND, a->ops->kind))
@@ -789,6 +787,23 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
        }
        rcu_read_unlock();
 
+       return 0;
+
+nla_put_failure:
+       nlmsg_trim(skb, b);
+       return -1;
+}
+
+int
+tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+{
+       int err = -EINVAL;
+       unsigned char *b = skb_tail_pointer(skb);
+       struct nlattr *nest;
+
+       if (tcf_action_dump_terse(skb, a))
+               goto nla_put_failure;
+
        if (a->hw_stats != TCA_ACT_HW_STATS_ANY &&
            nla_put_bitfield32(skb, TCA_ACT_HW_STATS,
                               a->hw_stats, TCA_ACT_HW_STATS_ANY))
@@ -820,7 +835,7 @@ nla_put_failure:
 EXPORT_SYMBOL(tcf_action_dump_1);
 
 int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[],
-                   int bind, int ref)
+                   int bind, int ref, bool terse)
 {
        struct tc_action *a;
        int err = -EINVAL, i;
@@ -831,7 +846,8 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[],
                nest = nla_nest_start_noflag(skb, i + 1);
                if (nest == NULL)
                        goto nla_put_failure;
-               err = tcf_action_dump_1(skb, a, bind, ref);
+               err = terse ? tcf_action_dump_terse(skb, a) :
+                       tcf_action_dump_1(skb, a, bind, ref);
                if (err < 0)
                        goto errout;
                nla_nest_end(skb, nest);
@@ -1133,7 +1149,7 @@ static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],
        if (!nest)
                goto out_nlmsg_trim;
 
-       if (tcf_action_dump(skb, actions, bind, ref) < 0)
+       if (tcf_action_dump(skb, actions, bind, ref, false) < 0)
                goto out_nlmsg_trim;
 
        nla_nest_end(skb, nest);
index cb2c10e0fee5dbe755af80b373aa2940df5e203f..752d608f44427ef20022e23ce682472c2ab5ca19 100644 (file)
@@ -3179,7 +3179,8 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts)
                        if (nest == NULL)
                                goto nla_put_failure;
 
-                       if (tcf_action_dump(skb, exts->actions, 0, 0) < 0)
+                       if (tcf_action_dump(skb, exts->actions, 0, 0, false)
+                           < 0)
                                goto nla_put_failure;
                        nla_nest_end(skb, nest);
                } else if (exts->police) {
@@ -3203,6 +3204,31 @@ nla_put_failure:
 }
 EXPORT_SYMBOL(tcf_exts_dump);
 
+int tcf_exts_terse_dump(struct sk_buff *skb, struct tcf_exts *exts)
+{
+#ifdef CONFIG_NET_CLS_ACT
+       struct nlattr *nest;
+
+       if (!exts->action || !tcf_exts_has_actions(exts))
+               return 0;
+
+       nest = nla_nest_start_noflag(skb, exts->action);
+       if (!nest)
+               goto nla_put_failure;
+
+       if (tcf_action_dump(skb, exts->actions, 0, 0, true) < 0)
+               goto nla_put_failure;
+       nla_nest_end(skb, nest);
+       return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
+       return -1;
+#else
+       return 0;
+#endif
+}
+EXPORT_SYMBOL(tcf_exts_terse_dump);
 
 int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts)
 {