diff options
author | David S. Miller <davem@davemloft.net> | 2015-04-06 21:52:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-04-06 22:34:15 -0400 |
commit | c85d6975ef923cffdd56de3e0e6aba0977282cff (patch) | |
tree | cb497deea01827951809c9c7c0f1c22780c146be /net | |
parent | 60302ff631f0f3eac0ec592e128b776f0676b397 (diff) | |
parent | f22e6e847115abc3a0e2ad7bb18d243d42275af1 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/mellanox/mlx4/cmd.c
net/core/fib_rules.c
net/ipv4/fib_frontend.c
The fib_rules.c and fib_frontend.c conflicts were locking adjustments
in 'net' overlapping addition and removal of code in 'net-next'.
The mlx4 conflict was a bug fix in 'net' happening in the same
place a constant was being replaced with a more suitable macro.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 4 | ||||
-rw-r--r-- | net/core/fib_rules.c | 2 | ||||
-rw-r--r-- | net/core/net_namespace.c | 28 | ||||
-rw-r--r-- | net/core/sock.c | 19 | ||||
-rw-r--r-- | net/decnet/dn_rules.c | 2 | ||||
-rw-r--r-- | net/dsa/dsa.c | 23 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 2 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 5 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 7 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 4 | ||||
-rw-r--r-- | net/l2tp/l2tp_core.c | 1 |
13 files changed, 60 insertions, 42 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 26622d614f81..3b3965288f52 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2870,7 +2870,9 @@ static void skb_update_prio(struct sk_buff *skb) | |||
2870 | #define skb_update_prio(skb) | 2870 | #define skb_update_prio(skb) |
2871 | #endif | 2871 | #endif |
2872 | 2872 | ||
2873 | static DEFINE_PER_CPU(int, xmit_recursion); | 2873 | DEFINE_PER_CPU(int, xmit_recursion); |
2874 | EXPORT_SYMBOL(xmit_recursion); | ||
2875 | |||
2874 | #define RECURSION_LIMIT 10 | 2876 | #define RECURSION_LIMIT 10 |
2875 | 2877 | ||
2876 | /** | 2878 | /** |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 68ea6950cad1..9a12668f7d62 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -165,9 +165,9 @@ void fib_rules_unregister(struct fib_rules_ops *ops) | |||
165 | 165 | ||
166 | spin_lock(&net->rules_mod_lock); | 166 | spin_lock(&net->rules_mod_lock); |
167 | list_del_rcu(&ops->list); | 167 | list_del_rcu(&ops->list); |
168 | fib_rules_cleanup_ops(ops); | ||
169 | spin_unlock(&net->rules_mod_lock); | 168 | spin_unlock(&net->rules_mod_lock); |
170 | 169 | ||
170 | fib_rules_cleanup_ops(ops); | ||
171 | kfree_rcu(ops, rcu); | 171 | kfree_rcu(ops, rcu); |
172 | } | 172 | } |
173 | EXPORT_SYMBOL_GPL(fib_rules_unregister); | 173 | EXPORT_SYMBOL_GPL(fib_rules_unregister); |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index ce6396a75b8b..e7345d9031df 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -198,8 +198,10 @@ static int __peernet2id(struct net *net, struct net *peer, bool alloc) | |||
198 | */ | 198 | */ |
199 | int peernet2id(struct net *net, struct net *peer) | 199 | int peernet2id(struct net *net, struct net *peer) |
200 | { | 200 | { |
201 | int id = __peernet2id(net, peer, true); | 201 | bool alloc = atomic_read(&peer->count) == 0 ? false : true; |
202 | int id; | ||
202 | 203 | ||
204 | id = __peernet2id(net, peer, alloc); | ||
203 | return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED; | 205 | return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED; |
204 | } | 206 | } |
205 | EXPORT_SYMBOL(peernet2id); | 207 | EXPORT_SYMBOL(peernet2id); |
@@ -338,7 +340,7 @@ static LIST_HEAD(cleanup_list); /* Must hold cleanup_list_lock to touch */ | |||
338 | static void cleanup_net(struct work_struct *work) | 340 | static void cleanup_net(struct work_struct *work) |
339 | { | 341 | { |
340 | const struct pernet_operations *ops; | 342 | const struct pernet_operations *ops; |
341 | struct net *net, *tmp, *peer; | 343 | struct net *net, *tmp; |
342 | struct list_head net_kill_list; | 344 | struct list_head net_kill_list; |
343 | LIST_HEAD(net_exit_list); | 345 | LIST_HEAD(net_exit_list); |
344 | 346 | ||
@@ -354,6 +356,14 @@ static void cleanup_net(struct work_struct *work) | |||
354 | list_for_each_entry(net, &net_kill_list, cleanup_list) { | 356 | list_for_each_entry(net, &net_kill_list, cleanup_list) { |
355 | list_del_rcu(&net->list); | 357 | list_del_rcu(&net->list); |
356 | list_add_tail(&net->exit_list, &net_exit_list); | 358 | list_add_tail(&net->exit_list, &net_exit_list); |
359 | for_each_net(tmp) { | ||
360 | int id = __peernet2id(tmp, net, false); | ||
361 | |||
362 | if (id >= 0) | ||
363 | idr_remove(&tmp->netns_ids, id); | ||
364 | } | ||
365 | idr_destroy(&net->netns_ids); | ||
366 | |||
357 | } | 367 | } |
358 | rtnl_unlock(); | 368 | rtnl_unlock(); |
359 | 369 | ||
@@ -379,26 +389,12 @@ static void cleanup_net(struct work_struct *work) | |||
379 | */ | 389 | */ |
380 | rcu_barrier(); | 390 | rcu_barrier(); |
381 | 391 | ||
382 | rtnl_lock(); | ||
383 | /* Finally it is safe to free my network namespace structure */ | 392 | /* Finally it is safe to free my network namespace structure */ |
384 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { | 393 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { |
385 | /* Unreference net from all peers (no need to loop over | ||
386 | * net_exit_list because idr_destroy() will be called for each | ||
387 | * element of this list. | ||
388 | */ | ||
389 | for_each_net(peer) { | ||
390 | int id = __peernet2id(peer, net, false); | ||
391 | |||
392 | if (id >= 0) | ||
393 | idr_remove(&peer->netns_ids, id); | ||
394 | } | ||
395 | idr_destroy(&net->netns_ids); | ||
396 | |||
397 | list_del_init(&net->exit_list); | 394 | list_del_init(&net->exit_list); |
398 | put_user_ns(net->user_ns); | 395 | put_user_ns(net->user_ns); |
399 | net_drop_ns(net); | 396 | net_drop_ns(net); |
400 | } | 397 | } |
401 | rtnl_unlock(); | ||
402 | } | 398 | } |
403 | static DECLARE_WORK(net_cleanup_work, cleanup_net); | 399 | static DECLARE_WORK(net_cleanup_work, cleanup_net); |
404 | 400 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 119ae464b44a..654e38a99759 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -653,6 +653,25 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool) | |||
653 | sock_reset_flag(sk, bit); | 653 | sock_reset_flag(sk, bit); |
654 | } | 654 | } |
655 | 655 | ||
656 | bool sk_mc_loop(struct sock *sk) | ||
657 | { | ||
658 | if (dev_recursion_level()) | ||
659 | return false; | ||
660 | if (!sk) | ||
661 | return true; | ||
662 | switch (sk->sk_family) { | ||
663 | case AF_INET: | ||
664 | return inet_sk(sk)->mc_loop; | ||
665 | #if IS_ENABLED(CONFIG_IPV6) | ||
666 | case AF_INET6: | ||
667 | return inet6_sk(sk)->mc_loop; | ||
668 | #endif | ||
669 | } | ||
670 | WARN_ON(1); | ||
671 | return true; | ||
672 | } | ||
673 | EXPORT_SYMBOL(sk_mc_loop); | ||
674 | |||
656 | /* | 675 | /* |
657 | * This is meant for all protocols to use and covers goings on | 676 | * This is meant for all protocols to use and covers goings on |
658 | * at the socket level. Everything here is generic. | 677 | * at the socket level. Everything here is generic. |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index faf7cc3483fe..9d66a0f72f90 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -248,7 +248,9 @@ void __init dn_fib_rules_init(void) | |||
248 | 248 | ||
249 | void __exit dn_fib_rules_cleanup(void) | 249 | void __exit dn_fib_rules_cleanup(void) |
250 | { | 250 | { |
251 | rtnl_lock(); | ||
251 | fib_rules_unregister(dn_fib_rules_ops); | 252 | fib_rules_unregister(dn_fib_rules_ops); |
253 | rtnl_unlock(); | ||
252 | rcu_barrier(); | 254 | rcu_barrier(); |
253 | } | 255 | } |
254 | 256 | ||
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 899772108ee3..5eaadabe23a1 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
@@ -513,12 +513,10 @@ static struct net_device *dev_to_net_device(struct device *dev) | |||
513 | #ifdef CONFIG_OF | 513 | #ifdef CONFIG_OF |
514 | static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, | 514 | static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, |
515 | struct dsa_chip_data *cd, | 515 | struct dsa_chip_data *cd, |
516 | int chip_index, | 516 | int chip_index, int port_index, |
517 | struct device_node *link) | 517 | struct device_node *link) |
518 | { | 518 | { |
519 | int ret; | ||
520 | const __be32 *reg; | 519 | const __be32 *reg; |
521 | int link_port_addr; | ||
522 | int link_sw_addr; | 520 | int link_sw_addr; |
523 | struct device_node *parent_sw; | 521 | struct device_node *parent_sw; |
524 | int len; | 522 | int len; |
@@ -531,6 +529,10 @@ static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, | |||
531 | if (!reg || (len != sizeof(*reg) * 2)) | 529 | if (!reg || (len != sizeof(*reg) * 2)) |
532 | return -EINVAL; | 530 | return -EINVAL; |
533 | 531 | ||
532 | /* | ||
533 | * Get the destination switch number from the second field of its 'reg' | ||
534 | * property, i.e. for "reg = <0x19 1>" sw_addr is '1'. | ||
535 | */ | ||
534 | link_sw_addr = be32_to_cpup(reg + 1); | 536 | link_sw_addr = be32_to_cpup(reg + 1); |
535 | 537 | ||
536 | if (link_sw_addr >= pd->nr_chips) | 538 | if (link_sw_addr >= pd->nr_chips) |
@@ -547,20 +549,9 @@ static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, | |||
547 | memset(cd->rtable, -1, pd->nr_chips * sizeof(s8)); | 549 | memset(cd->rtable, -1, pd->nr_chips * sizeof(s8)); |
548 | } | 550 | } |
549 | 551 | ||
550 | reg = of_get_property(link, "reg", NULL); | 552 | cd->rtable[link_sw_addr] = port_index; |
551 | if (!reg) { | ||
552 | ret = -EINVAL; | ||
553 | goto out; | ||
554 | } | ||
555 | |||
556 | link_port_addr = be32_to_cpup(reg); | ||
557 | |||
558 | cd->rtable[link_sw_addr] = link_port_addr; | ||
559 | 553 | ||
560 | return 0; | 554 | return 0; |
561 | out: | ||
562 | kfree(cd->rtable); | ||
563 | return ret; | ||
564 | } | 555 | } |
565 | 556 | ||
566 | static void dsa_of_free_platform_data(struct dsa_platform_data *pd) | 557 | static void dsa_of_free_platform_data(struct dsa_platform_data *pd) |
@@ -670,7 +661,7 @@ static int dsa_of_probe(struct device *dev) | |||
670 | if (!strcmp(port_name, "dsa") && link && | 661 | if (!strcmp(port_name, "dsa") && link && |
671 | pd->nr_chips > 1) { | 662 | pd->nr_chips > 1) { |
672 | ret = dsa_of_setup_routing_table(pd, cd, | 663 | ret = dsa_of_setup_routing_table(pd, cd, |
673 | chip_index, link); | 664 | chip_index, port_index, link); |
674 | if (ret) | 665 | if (ret) |
675 | goto out_free_chip; | 666 | goto out_free_chip; |
676 | } | 667 | } |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 2166d2bf1562..872494e6e6eb 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -1175,13 +1175,11 @@ static void ip_fib_net_exit(struct net *net) | |||
1175 | unsigned int i; | 1175 | unsigned int i; |
1176 | 1176 | ||
1177 | rtnl_lock(); | 1177 | rtnl_lock(); |
1178 | |||
1179 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1178 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
1180 | RCU_INIT_POINTER(net->ipv4.fib_local, NULL); | 1179 | RCU_INIT_POINTER(net->ipv4.fib_local, NULL); |
1181 | RCU_INIT_POINTER(net->ipv4.fib_main, NULL); | 1180 | RCU_INIT_POINTER(net->ipv4.fib_main, NULL); |
1182 | RCU_INIT_POINTER(net->ipv4.fib_default, NULL); | 1181 | RCU_INIT_POINTER(net->ipv4.fib_default, NULL); |
1183 | #endif | 1182 | #endif |
1184 | |||
1185 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) { | 1183 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) { |
1186 | struct hlist_head *head = &net->ipv4.fib_table_hash[i]; | 1184 | struct hlist_head *head = &net->ipv4.fib_table_hash[i]; |
1187 | struct hlist_node *tmp; | 1185 | struct hlist_node *tmp; |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index c204b728bbc1..5f17d0e78071 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -276,11 +276,13 @@ static void __net_exit ipmr_rules_exit(struct net *net) | |||
276 | { | 276 | { |
277 | struct mr_table *mrt, *next; | 277 | struct mr_table *mrt, *next; |
278 | 278 | ||
279 | rtnl_lock(); | ||
279 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { | 280 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { |
280 | list_del(&mrt->list); | 281 | list_del(&mrt->list); |
281 | ipmr_free_table(mrt); | 282 | ipmr_free_table(mrt); |
282 | } | 283 | } |
283 | fib_rules_unregister(net->ipv4.mr_rules_ops); | 284 | fib_rules_unregister(net->ipv4.mr_rules_ops); |
285 | rtnl_unlock(); | ||
284 | } | 286 | } |
285 | #else | 287 | #else |
286 | #define ipmr_for_each_table(mrt, net) \ | 288 | #define ipmr_for_each_table(mrt, net) \ |
@@ -306,7 +308,10 @@ static int __net_init ipmr_rules_init(struct net *net) | |||
306 | 308 | ||
307 | static void __net_exit ipmr_rules_exit(struct net *net) | 309 | static void __net_exit ipmr_rules_exit(struct net *net) |
308 | { | 310 | { |
311 | rtnl_lock(); | ||
309 | ipmr_free_table(net->ipv4.mrt); | 312 | ipmr_free_table(net->ipv4.mrt); |
313 | net->ipv4.mrt = NULL; | ||
314 | rtnl_unlock(); | ||
310 | } | 315 | } |
311 | #endif | 316 | #endif |
312 | 317 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index df7e7fa12733..c1ce304ba8d2 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3105,10 +3105,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3105 | if (!first_ackt.v64) | 3105 | if (!first_ackt.v64) |
3106 | first_ackt = last_ackt; | 3106 | first_ackt = last_ackt; |
3107 | 3107 | ||
3108 | if (!(sacked & TCPCB_SACKED_ACKED)) | 3108 | if (!(sacked & TCPCB_SACKED_ACKED)) { |
3109 | reord = min(pkts_acked, reord); | 3109 | reord = min(pkts_acked, reord); |
3110 | if (!after(scb->end_seq, tp->high_seq)) | 3110 | if (!after(scb->end_seq, tp->high_seq)) |
3111 | flag |= FLAG_ORIG_SACK_ACKED; | 3111 | flag |= FLAG_ORIG_SACK_ACKED; |
3112 | } | ||
3112 | } | 3113 | } |
3113 | 3114 | ||
3114 | if (sacked & TCPCB_SACKED_ACKED) | 3115 | if (sacked & TCPCB_SACKED_ACKED) |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 61fb184b818d..2367a16eae58 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -315,7 +315,9 @@ out_fib6_rules_ops: | |||
315 | 315 | ||
316 | static void __net_exit fib6_rules_net_exit(struct net *net) | 316 | static void __net_exit fib6_rules_net_exit(struct net *net) |
317 | { | 317 | { |
318 | rtnl_lock(); | ||
318 | fib_rules_unregister(net->ipv6.fib6_rules_ops); | 319 | fib_rules_unregister(net->ipv6.fib6_rules_ops); |
320 | rtnl_unlock(); | ||
319 | } | 321 | } |
320 | 322 | ||
321 | static struct pernet_operations fib6_rules_net_ops = { | 323 | static struct pernet_operations fib6_rules_net_ops = { |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 84c58da10f5c..654f245aa930 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -542,7 +542,8 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
542 | { | 542 | { |
543 | struct sk_buff *frag; | 543 | struct sk_buff *frag; |
544 | struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); | 544 | struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); |
545 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; | 545 | struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ? |
546 | inet6_sk(skb->sk) : NULL; | ||
546 | struct ipv6hdr *tmp_hdr; | 547 | struct ipv6hdr *tmp_hdr; |
547 | struct frag_hdr *fh; | 548 | struct frag_hdr *fh; |
548 | unsigned int mtu, hlen, left, len; | 549 | unsigned int mtu, hlen, left, len; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 26456037bdfc..8493a22e74eb 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -265,8 +265,8 @@ static void __net_exit ip6mr_rules_exit(struct net *net) | |||
265 | list_del(&mrt->list); | 265 | list_del(&mrt->list); |
266 | ip6mr_free_table(mrt); | 266 | ip6mr_free_table(mrt); |
267 | } | 267 | } |
268 | rtnl_unlock(); | ||
269 | fib_rules_unregister(net->ipv6.mr6_rules_ops); | 268 | fib_rules_unregister(net->ipv6.mr6_rules_ops); |
269 | rtnl_unlock(); | ||
270 | } | 270 | } |
271 | #else | 271 | #else |
272 | #define ip6mr_for_each_table(mrt, net) \ | 272 | #define ip6mr_for_each_table(mrt, net) \ |
@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id) | |||
334 | 334 | ||
335 | static void ip6mr_free_table(struct mr6_table *mrt) | 335 | static void ip6mr_free_table(struct mr6_table *mrt) |
336 | { | 336 | { |
337 | del_timer(&mrt->ipmr_expire_timer); | 337 | del_timer_sync(&mrt->ipmr_expire_timer); |
338 | mroute_clean_tables(mrt); | 338 | mroute_clean_tables(mrt); |
339 | kfree(mrt); | 339 | kfree(mrt); |
340 | } | 340 | } |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 895348e44c7d..a29a504492af 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1871,6 +1871,7 @@ static int __init l2tp_init(void) | |||
1871 | l2tp_wq = alloc_workqueue("l2tp", WQ_UNBOUND, 0); | 1871 | l2tp_wq = alloc_workqueue("l2tp", WQ_UNBOUND, 0); |
1872 | if (!l2tp_wq) { | 1872 | if (!l2tp_wq) { |
1873 | pr_err("alloc_workqueue failed\n"); | 1873 | pr_err("alloc_workqueue failed\n"); |
1874 | unregister_pernet_device(&l2tp_net_ops); | ||
1874 | rc = -ENOMEM; | 1875 | rc = -ENOMEM; |
1875 | goto out; | 1876 | goto out; |
1876 | } | 1877 | } |