aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Buslov <vladbu@mellanox.com>2019-02-11 03:55:43 -0500
committerDavid S. Miller <davem@davemloft.net>2019-02-12 13:41:33 -0500
commitec6743a10996d38e0438e5f45f2347ff2f42df0a (patch)
treed75c1ea33f894ba7ec79f4046cacdfb59759731e
parent726d061286ceeeabda54ba6f080d0cb8f187a9d7 (diff)
net: sched: track rtnl lock status when validating extensions
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>
-rw-r--r--include/net/pkt_cls.h2
-rw-r--r--net/sched/cls_api.c9
-rw-r--r--net/sched/cls_basic.c2
-rw-r--r--net/sched/cls_bpf.c3
-rw-r--r--net/sched/cls_cgroup.c2
-rw-r--r--net/sched/cls_flow.c2
-rw-r--r--net/sched/cls_flower.c3
-rw-r--r--net/sched/cls_fw.c2
-rw-r--r--net/sched/cls_matchall.c3
-rw-r--r--net/sched/cls_route.c2
-rw-r--r--net/sched/cls_rsvp.h3
-rw-r--r--net/sched/cls_tcindex.c2
-rw-r--r--net/sched/cls_u32.c2
13 files changed, 21 insertions, 16 deletions
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index e5dafa5ee1b2..0e3b61016931 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -416,7 +416,7 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
416 416
417int tcf_exts_validate(struct net *net, struct tcf_proto *tp, 417int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
418 struct nlattr **tb, struct nlattr *rate_tlv, 418 struct nlattr **tb, struct nlattr *rate_tlv,
419 struct tcf_exts *exts, bool ovr, 419 struct tcf_exts *exts, bool ovr, bool rtnl_held,
420 struct netlink_ext_ack *extack); 420 struct netlink_ext_ack *extack);
421void tcf_exts_destroy(struct tcf_exts *exts); 421void tcf_exts_destroy(struct tcf_exts *exts);
422void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src); 422void 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 3038a82f6591..a3e715d34efb 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -2841,7 +2841,7 @@ EXPORT_SYMBOL(tcf_exts_destroy);
2841 2841
2842int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, 2842int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
2843 struct nlattr *rate_tlv, struct tcf_exts *exts, bool ovr, 2843 struct nlattr *rate_tlv, struct tcf_exts *exts, bool ovr,
2844 struct netlink_ext_ack *extack) 2844 bool rtnl_held, struct netlink_ext_ack *extack)
2845{ 2845{
2846#ifdef CONFIG_NET_CLS_ACT 2846#ifdef CONFIG_NET_CLS_ACT
2847 { 2847 {
@@ -2851,7 +2851,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
2851 if (exts->police && tb[exts->police]) { 2851 if (exts->police && tb[exts->police]) {
2852 act = tcf_action_init_1(net, tp, tb[exts->police], 2852 act = tcf_action_init_1(net, tp, tb[exts->police],
2853 rate_tlv, "police", ovr, 2853 rate_tlv, "police", ovr,
2854 TCA_ACT_BIND, true, extack); 2854 TCA_ACT_BIND, rtnl_held,
2855 extack);
2855 if (IS_ERR(act)) 2856 if (IS_ERR(act))
2856 return PTR_ERR(act); 2857 return PTR_ERR(act);
2857 2858
@@ -2863,8 +2864,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
2863 2864
2864 err = tcf_action_init(net, tp, tb[exts->action], 2865 err = tcf_action_init(net, tp, tb[exts->action],
2865 rate_tlv, NULL, ovr, TCA_ACT_BIND, 2866 rate_tlv, NULL, ovr, TCA_ACT_BIND,
2866 exts->actions, &attr_size, true, 2867 exts->actions, &attr_size,
2867 extack); 2868 rtnl_held, extack);
2868 if (err < 0) 2869 if (err < 0)
2869 return err; 2870 return err;
2870 exts->nr_actions = err; 2871 exts->nr_actions = err;
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 4a57fec6f306..eaf9c02fe792 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -153,7 +153,7 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
153{ 153{
154 int err; 154 int err;
155 155
156 err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, extack); 156 err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, true, extack);
157 if (err < 0) 157 if (err < 0)
158 return err; 158 return err;
159 159
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index a95cb240a606..656b3423ad35 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,
417 if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) 417 if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf))
418 return -EINVAL; 418 return -EINVAL;
419 419
420 ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, ovr, extack); 420 ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, ovr, true,
421 extack);
421 if (ret < 0) 422 if (ret < 0)
422 return ret; 423 return ret;
423 424
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,
110 goto errout; 110 goto errout;
111 111
112 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &new->exts, ovr, 112 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &new->exts, ovr,
113 extack); 113 true, extack);
114 if (err < 0) 114 if (err < 0)
115 goto errout; 115 goto errout;
116 116
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,
445 goto err2; 445 goto err2;
446 446
447 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &fnew->exts, ovr, 447 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &fnew->exts, ovr,
448 extack); 448 true, extack);
449 if (err < 0) 449 if (err < 0)
450 goto err2; 450 goto err2;
451 451
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 6a341287a527..5e3f74ab68ca 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -1272,7 +1272,8 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
1272{ 1272{
1273 int err; 1273 int err;
1274 1274
1275 err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, extack); 1275 err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, true,
1276 extack);
1276 if (err < 0) 1277 if (err < 0)
1277 return err; 1278 return err;
1278 1279
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,
217 int err; 217 int err;
218 218
219 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &f->exts, ovr, 219 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &f->exts, ovr,
220 extack); 220 true, extack);
221 if (err < 0) 221 if (err < 0)
222 return err; 222 return err;
223 223
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index a1b803fd372e..8848a147c4bf 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -145,7 +145,8 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp,
145{ 145{
146 int err; 146 int err;
147 147
148 err = tcf_exts_validate(net, tp, tb, est, &head->exts, ovr, extack); 148 err = tcf_exts_validate(net, tp, tb, est, &head->exts, ovr, true,
149 extack);
149 if (err < 0) 150 if (err < 0)
150 return err; 151 return err;
151 152
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,
393 struct route4_bucket *b; 393 struct route4_bucket *b;
394 int err; 394 int err;
395 395
396 err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, extack); 396 err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr, true, extack);
397 if (err < 0) 397 if (err < 0)
398 return err; 398 return err;
399 399
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,
502 err = tcf_exts_init(&e, TCA_RSVP_ACT, TCA_RSVP_POLICE); 502 err = tcf_exts_init(&e, TCA_RSVP_ACT, TCA_RSVP_POLICE);
503 if (err < 0) 503 if (err < 0)
504 return err; 504 return err;
505 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr, extack); 505 err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr, true,
506 extack);
506 if (err < 0) 507 if (err < 0)
507 goto errout2; 508 goto errout2;
508 509
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,
314 err = tcf_exts_init(&e, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE); 314 err = tcf_exts_init(&e, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
315 if (err < 0) 315 if (err < 0)
316 return err; 316 return err;
317 err = tcf_exts_validate(net, tp, tb, est, &e, ovr, extack); 317 err = tcf_exts_validate(net, tp, tb, est, &e, ovr, true, extack);
318 if (err < 0) 318 if (err < 0)
319 goto errout; 319 goto errout;
320 320
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index dcea21004604..e891f30d42e9 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,
726{ 726{
727 int err; 727 int err;
728 728
729 err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr, extack); 729 err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr, true, extack);
730 if (err < 0) 730 if (err < 0)
731 return err; 731 return err;
732 732