net: sched: track rtnl lock status when validating extensions
authorVlad Buslov <vladbu@mellanox.com>
Mon, 11 Feb 2019 08:55:43 +0000 (10:55 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 12 Feb 2019 18:41:33 +0000 (13:41 -0500)
Actions API is already updated to not rely on rtnl lock for
synchronization. However, it need to be provided with rtnl status when
called from classifiers API in order to be able to correctly release the
lock when loading kernel module.

Extend extension validation function with 'rtnl_held' flag which is passed
to actions API. Add new 'rtnl_held' parameter to tcf_exts_validate() in cls
API. No classifier is currently updated to support unlocked execution, so
pass hardcoded 'true' flag parameter value.

Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
13 files changed:
include/net/pkt_cls.h
net/sched/cls_api.c
net/sched/cls_basic.c
net/sched/cls_bpf.c
net/sched/cls_cgroup.c
net/sched/cls_flow.c
net/sched/cls_flower.c
net/sched/cls_fw.c
net/sched/cls_matchall.c
net/sched/cls_route.c
net/sched/cls_rsvp.h
net/sched/cls_tcindex.c
net/sched/cls_u32.c

index e5dafa5ee1b2a07f5cdb2d04b7b5cf6b4ba2d402..0e3b6101693144c95f5e70f31cd12cd44c313c5a 100644 (file)
@@ -416,7 +416,7 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
 
 int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
                      struct nlattr **tb, struct nlattr *rate_tlv,
-                     struct tcf_exts *exts, bool ovr,
+                     struct tcf_exts *exts, bool ovr, bool rtnl_held,
                      struct netlink_ext_ack *extack);
 void tcf_exts_destroy(struct tcf_exts *exts);
 void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
index 3038a82f6591f10446a9accf51fa3535f678fef9..a3e715d34efbc71df85d2cc7bebf7f0f30ee10fb 100644 (file)
@@ -2841,7 +2841,7 @@ EXPORT_SYMBOL(tcf_exts_destroy);
 
 int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
                      struct nlattr *rate_tlv, struct tcf_exts *exts, bool ovr,
-                     struct netlink_ext_ack *extack)
+                     bool rtnl_held, struct netlink_ext_ack *extack)
 {
 #ifdef CONFIG_NET_CLS_ACT
        {
@@ -2851,7 +2851,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
                if (exts->police && tb[exts->police]) {
                        act = tcf_action_init_1(net, tp, tb[exts->police],
                                                rate_tlv, "police", ovr,
-                                               TCA_ACT_BIND, true, extack);
+                                               TCA_ACT_BIND, rtnl_held,
+                                               extack);
                        if (IS_ERR(act))
                                return PTR_ERR(act);
 
@@ -2863,8 +2864,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
 
                        err = tcf_action_init(net, tp, tb[exts->action],
                                              rate_tlv, NULL, ovr, TCA_ACT_BIND,
-                                             exts->actions, &attr_size, true,
-                                             extack);
+                                             exts->actions, &attr_size,
+                                             rtnl_held, extack);
                        if (err < 0)
                                return err;
                        exts->nr_actions = err;
index 4a57fec6f306812b798e7868f3ff9e2c0d2b7f6e..eaf9c02fe792e54c0ade135abbd924f4488cf856 100644 (file)
@@ -153,7 +153,7 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 {
        int err;
 
-       err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, extack);
+       err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, true, extack);
        if (err < 0)
                return err;
 
index a95cb240a6067d07709419f454de105cc6e5ab94..656b3423ad3587bba2864832771be6ac81b987ae 100644 (file)
@@ -417,7 +417,8 @@ static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp,
        if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf))
                return -EINVAL;
 
-       ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, ovr, extack);
+       ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, ovr, true,
+                               extack);
        if (ret < 0)
                return ret;
 
index 3bc01bdde1659bdac6eba560bf8410e8bc3adfff..663ee1c6d6065113480daab7332c89f1a7f12046 100644 (file)
@@ -110,7 +110,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
                goto errout;
 
        err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &new->exts, ovr,
-                               extack);
+                               true, extack);
        if (err < 0)
                goto errout;
 
index 2bb043cd436b3a5135a0f6f80ecd083a348be639..39a6407d48328cceadd5243e21f95c9d102f3b9e 100644 (file)
@@ -445,7 +445,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
                goto err2;
 
        err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &fnew->exts, ovr,
-                               extack);
+                               true, extack);
        if (err < 0)
                goto err2;
 
index 6a341287a52764a60fd0628284e158bbbb5c2b03..5e3f74ab68ca28eb73accd54a8218fa9c64b07c2 100644 (file)
@@ -1272,7 +1272,8 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
 {
        int err;
 
-       err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, extack);
+       err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, true,
+                               extack);
        if (err < 0)
                return err;
 
index 29eeeaf3ea4401ea43496f4a9da8916fa744a2ef..c8173ebb69f28e645570e9070ce6be7c8c78852b 100644 (file)
@@ -217,7 +217,7 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp,
        int err;
 
        err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &f->exts, ovr,
-                               extack);
+                               true, extack);
        if (err < 0)
                return err;
 
index a1b803fd372eb7ba3bf13a64c0c6b5684b9350ea..8848a147c4bf18e3d2d3d67db85cee20927ddb38 100644 (file)
@@ -145,7 +145,8 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp,
 {
        int err;
 
-       err = tcf_exts_validate(net, tp, tb, est, &head->exts, ovr, extack);
+       err = tcf_exts_validate(net, tp, tb, est, &head->exts, ovr, true,
+                               extack);
        if (err < 0)
                return err;
 
index 0404aa5fa7cbb91a008b75a5ce3ff2f1b563d00e..44b26038c4c41df52d7f28200c63b98bba7ba838 100644 (file)
@@ -393,7 +393,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
        struct route4_bucket *b;
        int err;
 
-       err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, extack);
+       err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, true, extack);
        if (err < 0)
                return err;
 
index e9ccf7daea7d84eeefe5e872b3497a6f0edc7ea9..9dd9530e6a526b3e8d2817b079d73e8f1ad9fc1e 100644 (file)
@@ -502,7 +502,8 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
        err = tcf_exts_init(&e, TCA_RSVP_ACT, TCA_RSVP_POLICE);
        if (err < 0)
                return err;
-       err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr, extack);
+       err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr, true,
+                               extack);
        if (err < 0)
                goto errout2;
 
index 9ccc93f257db0966f5ea5206819cfdb7605c1e2a..b7dc667b6ec0567e51a6228af9fb6ecb42a11651 100644 (file)
@@ -314,7 +314,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
        err = tcf_exts_init(&e, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
        if (err < 0)
                return err;
-       err = tcf_exts_validate(net, tp, tb, est, &e, ovr, extack);
+       err = tcf_exts_validate(net, tp, tb, est, &e, ovr, true, extack);
        if (err < 0)
                goto errout;
 
index dcea210046041a4769bc513da07c8aeacc645b18..e891f30d42e9ec01b434da0179ace8b5068197a0 100644 (file)
@@ -726,7 +726,7 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
 {
        int err;
 
-       err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr, extack);
+       err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr, true, extack);
        if (err < 0)
                return err;