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 <vla...@mellanox.com>
Acked-by: Jiri Pirko <j...@mellanox.com>
---
 include/net/pkt_cls.h    | 2 +-
 net/sched/cls_api.c      | 9 +++++----
 net/sched/cls_basic.c    | 2 +-
 net/sched/cls_bpf.c      | 3 ++-
 net/sched/cls_cgroup.c   | 2 +-
 net/sched/cls_flow.c     | 2 +-
 net/sched/cls_flower.c   | 3 ++-
 net/sched/cls_fw.c       | 2 +-
 net/sched/cls_matchall.c | 3 ++-
 net/sched/cls_route.c    | 2 +-
 net/sched/cls_rsvp.h     | 3 ++-
 net/sched/cls_tcindex.c  | 2 +-
 net/sched/cls_u32.c      | 2 +-
 13 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 411ac4334942..5c3cd5b96ab3 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -415,7 +415,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);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index bbcac772cc21..bc8d1d1600a4 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -2871,7 +2871,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
        {
@@ -2881,7 +2881,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);
 
@@ -2893,8 +2894,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;
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 6a5dce8baf19..90e44888f85d 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -148,7 +148,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;
 
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index fa6fe2fe0f32..9c0ac7c23ad7 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -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;
 
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 3bc01bdde165..663ee1c6d606 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -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;
 
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 2bb043cd436b..39a6407d4832 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -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;
 
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 85e9f8e1da10..c4e28e5c8582 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -1261,7 +1261,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;
 
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 29eeeaf3ea44..c8173ebb69f2 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -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;
 
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index 856fa79d4ffd..5621c38a303a 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -142,7 +142,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;
 
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 0404aa5fa7cb..44b26038c4c4 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -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;
 
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index e9ccf7daea7d..9dd9530e6a52 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -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;
 
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 9ccc93f257db..b7dc667b6ec0 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -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;
 
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 4c54bc440798..6305b6758b98 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -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;
 
-- 
2.7.5

Reply via email to