diff options
| -rw-r--r-- | include/net/act_api.h | 6 | ||||
| -rw-r--r-- | net/sched/act_api.c | 4 | ||||
| -rw-r--r-- | net/sched/act_bpf.c | 2 | ||||
| -rw-r--r-- | net/sched/act_connmark.c | 2 | ||||
| -rw-r--r-- | net/sched/act_csum.c | 2 | ||||
| -rw-r--r-- | net/sched/act_gact.c | 2 | ||||
| -rw-r--r-- | net/sched/act_ife.c | 2 | ||||
| -rw-r--r-- | net/sched/act_ipt.c | 4 | ||||
| -rw-r--r-- | net/sched/act_mirred.c | 2 | ||||
| -rw-r--r-- | net/sched/act_nat.c | 2 | ||||
| -rw-r--r-- | net/sched/act_pedit.c | 2 | ||||
| -rw-r--r-- | net/sched/act_police.c | 2 | ||||
| -rw-r--r-- | net/sched/act_sample.c | 2 | ||||
| -rw-r--r-- | net/sched/act_simple.c | 2 | ||||
| -rw-r--r-- | net/sched/act_skbedit.c | 2 | ||||
| -rw-r--r-- | net/sched/act_skbmod.c | 2 | ||||
| -rw-r--r-- | net/sched/act_tunnel_key.c | 2 | ||||
| -rw-r--r-- | net/sched/act_vlan.c | 2 |
18 files changed, 26 insertions, 18 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h index b944e0eb93be..c68551255032 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | struct tcf_idrinfo { | 13 | struct tcf_idrinfo { |
| 14 | spinlock_t lock; | 14 | spinlock_t lock; |
| 15 | struct idr action_idr; | 15 | struct idr action_idr; |
| 16 | struct net *net; | ||
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 18 | struct tc_action_ops; | 19 | struct tc_action_ops; |
| @@ -104,7 +105,7 @@ struct tc_action_net { | |||
| 104 | 105 | ||
| 105 | static inline | 106 | static inline |
| 106 | int tc_action_net_init(struct tc_action_net *tn, | 107 | int tc_action_net_init(struct tc_action_net *tn, |
| 107 | const struct tc_action_ops *ops) | 108 | const struct tc_action_ops *ops, struct net *net) |
| 108 | { | 109 | { |
| 109 | int err = 0; | 110 | int err = 0; |
| 110 | 111 | ||
| @@ -112,6 +113,7 @@ int tc_action_net_init(struct tc_action_net *tn, | |||
| 112 | if (!tn->idrinfo) | 113 | if (!tn->idrinfo) |
| 113 | return -ENOMEM; | 114 | return -ENOMEM; |
| 114 | tn->ops = ops; | 115 | tn->ops = ops; |
| 116 | tn->idrinfo->net = net; | ||
| 115 | spin_lock_init(&tn->idrinfo->lock); | 117 | spin_lock_init(&tn->idrinfo->lock); |
| 116 | idr_init(&tn->idrinfo->action_idr); | 118 | idr_init(&tn->idrinfo->action_idr); |
| 117 | return err; | 119 | return err; |
| @@ -122,7 +124,9 @@ void tcf_idrinfo_destroy(const struct tc_action_ops *ops, | |||
| 122 | 124 | ||
| 123 | static inline void tc_action_net_exit(struct tc_action_net *tn) | 125 | static inline void tc_action_net_exit(struct tc_action_net *tn) |
| 124 | { | 126 | { |
| 127 | rtnl_lock(); | ||
| 125 | tcf_idrinfo_destroy(tn->ops, tn->idrinfo); | 128 | tcf_idrinfo_destroy(tn->ops, tn->idrinfo); |
| 129 | rtnl_unlock(); | ||
| 126 | kfree(tn->idrinfo); | 130 | kfree(tn->idrinfo); |
| 127 | } | 131 | } |
| 128 | 132 | ||
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index da6fa82c98a8..ca2ff0b3123f 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
| @@ -78,6 +78,7 @@ static void tcf_idr_remove(struct tcf_idrinfo *idrinfo, struct tc_action *p) | |||
| 78 | spin_lock_bh(&idrinfo->lock); | 78 | spin_lock_bh(&idrinfo->lock); |
| 79 | idr_remove_ext(&idrinfo->action_idr, p->tcfa_index); | 79 | idr_remove_ext(&idrinfo->action_idr, p->tcfa_index); |
| 80 | spin_unlock_bh(&idrinfo->lock); | 80 | spin_unlock_bh(&idrinfo->lock); |
| 81 | put_net(idrinfo->net); | ||
| 81 | gen_kill_estimator(&p->tcfa_rate_est); | 82 | gen_kill_estimator(&p->tcfa_rate_est); |
| 82 | free_tcf(p); | 83 | free_tcf(p); |
| 83 | } | 84 | } |
| @@ -86,6 +87,8 @@ int __tcf_idr_release(struct tc_action *p, bool bind, bool strict) | |||
| 86 | { | 87 | { |
| 87 | int ret = 0; | 88 | int ret = 0; |
| 88 | 89 | ||
| 90 | ASSERT_RTNL(); | ||
| 91 | |||
| 89 | if (p) { | 92 | if (p) { |
| 90 | if (bind) | 93 | if (bind) |
| 91 | p->tcfa_bindcnt--; | 94 | p->tcfa_bindcnt--; |
| @@ -334,6 +337,7 @@ err3: | |||
| 334 | p->idrinfo = idrinfo; | 337 | p->idrinfo = idrinfo; |
| 335 | p->ops = ops; | 338 | p->ops = ops; |
| 336 | INIT_LIST_HEAD(&p->list); | 339 | INIT_LIST_HEAD(&p->list); |
| 340 | get_net(idrinfo->net); | ||
| 337 | *a = p; | 341 | *a = p; |
| 338 | return 0; | 342 | return 0; |
| 339 | } | 343 | } |
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c index c0c707eb2c96..9bce8cc84cbb 100644 --- a/net/sched/act_bpf.c +++ b/net/sched/act_bpf.c | |||
| @@ -398,7 +398,7 @@ static __net_init int bpf_init_net(struct net *net) | |||
| 398 | { | 398 | { |
| 399 | struct tc_action_net *tn = net_generic(net, bpf_net_id); | 399 | struct tc_action_net *tn = net_generic(net, bpf_net_id); |
| 400 | 400 | ||
| 401 | return tc_action_net_init(tn, &act_bpf_ops); | 401 | return tc_action_net_init(tn, &act_bpf_ops, net); |
| 402 | } | 402 | } |
| 403 | 403 | ||
| 404 | static void __net_exit bpf_exit_net(struct net *net) | 404 | static void __net_exit bpf_exit_net(struct net *net) |
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c index 10b7a8855a6c..34e52d01a5dd 100644 --- a/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c | |||
| @@ -206,7 +206,7 @@ static __net_init int connmark_init_net(struct net *net) | |||
| 206 | { | 206 | { |
| 207 | struct tc_action_net *tn = net_generic(net, connmark_net_id); | 207 | struct tc_action_net *tn = net_generic(net, connmark_net_id); |
| 208 | 208 | ||
| 209 | return tc_action_net_init(tn, &act_connmark_ops); | 209 | return tc_action_net_init(tn, &act_connmark_ops, net); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | static void __net_exit connmark_exit_net(struct net *net) | 212 | static void __net_exit connmark_exit_net(struct net *net) |
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 1c40caadcff9..35171df2ebef 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
| @@ -626,7 +626,7 @@ static __net_init int csum_init_net(struct net *net) | |||
| 626 | { | 626 | { |
| 627 | struct tc_action_net *tn = net_generic(net, csum_net_id); | 627 | struct tc_action_net *tn = net_generic(net, csum_net_id); |
| 628 | 628 | ||
| 629 | return tc_action_net_init(tn, &act_csum_ops); | 629 | return tc_action_net_init(tn, &act_csum_ops, net); |
| 630 | } | 630 | } |
| 631 | 631 | ||
| 632 | static void __net_exit csum_exit_net(struct net *net) | 632 | static void __net_exit csum_exit_net(struct net *net) |
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index e29a48ef7fc3..ef7f7f39d26d 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
| @@ -232,7 +232,7 @@ static __net_init int gact_init_net(struct net *net) | |||
| 232 | { | 232 | { |
| 233 | struct tc_action_net *tn = net_generic(net, gact_net_id); | 233 | struct tc_action_net *tn = net_generic(net, gact_net_id); |
| 234 | 234 | ||
| 235 | return tc_action_net_init(tn, &act_gact_ops); | 235 | return tc_action_net_init(tn, &act_gact_ops, net); |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | static void __net_exit gact_exit_net(struct net *net) | 238 | static void __net_exit gact_exit_net(struct net *net) |
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index 8ccd35825b6b..f65e4b5058e0 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c | |||
| @@ -818,7 +818,7 @@ static __net_init int ife_init_net(struct net *net) | |||
| 818 | { | 818 | { |
| 819 | struct tc_action_net *tn = net_generic(net, ife_net_id); | 819 | struct tc_action_net *tn = net_generic(net, ife_net_id); |
| 820 | 820 | ||
| 821 | return tc_action_net_init(tn, &act_ife_ops); | 821 | return tc_action_net_init(tn, &act_ife_ops, net); |
| 822 | } | 822 | } |
| 823 | 823 | ||
| 824 | static void __net_exit ife_exit_net(struct net *net) | 824 | static void __net_exit ife_exit_net(struct net *net) |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index d9e399a7e3d5..dbdf3b2470d5 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
| @@ -334,7 +334,7 @@ static __net_init int ipt_init_net(struct net *net) | |||
| 334 | { | 334 | { |
| 335 | struct tc_action_net *tn = net_generic(net, ipt_net_id); | 335 | struct tc_action_net *tn = net_generic(net, ipt_net_id); |
| 336 | 336 | ||
| 337 | return tc_action_net_init(tn, &act_ipt_ops); | 337 | return tc_action_net_init(tn, &act_ipt_ops, net); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | static void __net_exit ipt_exit_net(struct net *net) | 340 | static void __net_exit ipt_exit_net(struct net *net) |
| @@ -384,7 +384,7 @@ static __net_init int xt_init_net(struct net *net) | |||
| 384 | { | 384 | { |
| 385 | struct tc_action_net *tn = net_generic(net, xt_net_id); | 385 | struct tc_action_net *tn = net_generic(net, xt_net_id); |
| 386 | 386 | ||
| 387 | return tc_action_net_init(tn, &act_xt_ops); | 387 | return tc_action_net_init(tn, &act_xt_ops, net); |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | static void __net_exit xt_exit_net(struct net *net) | 390 | static void __net_exit xt_exit_net(struct net *net) |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 416627c66f08..84759cfd5a33 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
| @@ -343,7 +343,7 @@ static __net_init int mirred_init_net(struct net *net) | |||
| 343 | { | 343 | { |
| 344 | struct tc_action_net *tn = net_generic(net, mirred_net_id); | 344 | struct tc_action_net *tn = net_generic(net, mirred_net_id); |
| 345 | 345 | ||
| 346 | return tc_action_net_init(tn, &act_mirred_ops); | 346 | return tc_action_net_init(tn, &act_mirred_ops, net); |
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | static void __net_exit mirred_exit_net(struct net *net) | 349 | static void __net_exit mirred_exit_net(struct net *net) |
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index c365d01b99c8..7eeaaf9217b6 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
| @@ -307,7 +307,7 @@ static __net_init int nat_init_net(struct net *net) | |||
| 307 | { | 307 | { |
| 308 | struct tc_action_net *tn = net_generic(net, nat_net_id); | 308 | struct tc_action_net *tn = net_generic(net, nat_net_id); |
| 309 | 309 | ||
| 310 | return tc_action_net_init(tn, &act_nat_ops); | 310 | return tc_action_net_init(tn, &act_nat_ops, net); |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | static void __net_exit nat_exit_net(struct net *net) | 313 | static void __net_exit nat_exit_net(struct net *net) |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 491fe5deb09e..b3d82c334a5f 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
| @@ -450,7 +450,7 @@ static __net_init int pedit_init_net(struct net *net) | |||
| 450 | { | 450 | { |
| 451 | struct tc_action_net *tn = net_generic(net, pedit_net_id); | 451 | struct tc_action_net *tn = net_generic(net, pedit_net_id); |
| 452 | 452 | ||
| 453 | return tc_action_net_init(tn, &act_pedit_ops); | 453 | return tc_action_net_init(tn, &act_pedit_ops, net); |
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | static void __net_exit pedit_exit_net(struct net *net) | 456 | static void __net_exit pedit_exit_net(struct net *net) |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 3bb2ebf9e9ae..9ec42b26e4b9 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
| @@ -331,7 +331,7 @@ static __net_init int police_init_net(struct net *net) | |||
| 331 | { | 331 | { |
| 332 | struct tc_action_net *tn = net_generic(net, police_net_id); | 332 | struct tc_action_net *tn = net_generic(net, police_net_id); |
| 333 | 333 | ||
| 334 | return tc_action_net_init(tn, &act_police_ops); | 334 | return tc_action_net_init(tn, &act_police_ops, net); |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | static void __net_exit police_exit_net(struct net *net) | 337 | static void __net_exit police_exit_net(struct net *net) |
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index 8b5abcd2f32f..e69a1e3a39bf 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c | |||
| @@ -240,7 +240,7 @@ static __net_init int sample_init_net(struct net *net) | |||
| 240 | { | 240 | { |
| 241 | struct tc_action_net *tn = net_generic(net, sample_net_id); | 241 | struct tc_action_net *tn = net_generic(net, sample_net_id); |
| 242 | 242 | ||
| 243 | return tc_action_net_init(tn, &act_sample_ops); | 243 | return tc_action_net_init(tn, &act_sample_ops, net); |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | static void __net_exit sample_exit_net(struct net *net) | 246 | static void __net_exit sample_exit_net(struct net *net) |
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index e7b57e5071a3..a8d0ea95f894 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
| @@ -201,7 +201,7 @@ static __net_init int simp_init_net(struct net *net) | |||
| 201 | { | 201 | { |
| 202 | struct tc_action_net *tn = net_generic(net, simp_net_id); | 202 | struct tc_action_net *tn = net_generic(net, simp_net_id); |
| 203 | 203 | ||
| 204 | return tc_action_net_init(tn, &act_simp_ops); | 204 | return tc_action_net_init(tn, &act_simp_ops, net); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | static void __net_exit simp_exit_net(struct net *net) | 207 | static void __net_exit simp_exit_net(struct net *net) |
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 59949d61f20d..fbac62472e09 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
| @@ -238,7 +238,7 @@ static __net_init int skbedit_init_net(struct net *net) | |||
| 238 | { | 238 | { |
| 239 | struct tc_action_net *tn = net_generic(net, skbedit_net_id); | 239 | struct tc_action_net *tn = net_generic(net, skbedit_net_id); |
| 240 | 240 | ||
| 241 | return tc_action_net_init(tn, &act_skbedit_ops); | 241 | return tc_action_net_init(tn, &act_skbedit_ops, net); |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | static void __net_exit skbedit_exit_net(struct net *net) | 244 | static void __net_exit skbedit_exit_net(struct net *net) |
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index b642ad3d39dd..8e12d8897d2f 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c | |||
| @@ -263,7 +263,7 @@ static __net_init int skbmod_init_net(struct net *net) | |||
| 263 | { | 263 | { |
| 264 | struct tc_action_net *tn = net_generic(net, skbmod_net_id); | 264 | struct tc_action_net *tn = net_generic(net, skbmod_net_id); |
| 265 | 265 | ||
| 266 | return tc_action_net_init(tn, &act_skbmod_ops); | 266 | return tc_action_net_init(tn, &act_skbmod_ops, net); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | static void __net_exit skbmod_exit_net(struct net *net) | 269 | static void __net_exit skbmod_exit_net(struct net *net) |
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index 30c96274c638..c33faa373cf2 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c | |||
| @@ -322,7 +322,7 @@ static __net_init int tunnel_key_init_net(struct net *net) | |||
| 322 | { | 322 | { |
| 323 | struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); | 323 | struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); |
| 324 | 324 | ||
| 325 | return tc_action_net_init(tn, &act_tunnel_key_ops); | 325 | return tc_action_net_init(tn, &act_tunnel_key_ops, net); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | static void __net_exit tunnel_key_exit_net(struct net *net) | 328 | static void __net_exit tunnel_key_exit_net(struct net *net) |
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index 16eb067a8d8f..115fc33cc6d8 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c | |||
| @@ -269,7 +269,7 @@ static __net_init int vlan_init_net(struct net *net) | |||
| 269 | { | 269 | { |
| 270 | struct tc_action_net *tn = net_generic(net, vlan_net_id); | 270 | struct tc_action_net *tn = net_generic(net, vlan_net_id); |
| 271 | 271 | ||
| 272 | return tc_action_net_init(tn, &act_vlan_ops); | 272 | return tc_action_net_init(tn, &act_vlan_ops, net); |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | static void __net_exit vlan_exit_net(struct net *net) | 275 | static void __net_exit vlan_exit_net(struct net *net) |
