diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ad3e65bdd368..67bc95fb5d9e 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -683,7 +683,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
683 | arg.bound_dev_if = sk->sk_bound_dev_if; | 683 | arg.bound_dev_if = sk->sk_bound_dev_if; |
684 | 684 | ||
685 | arg.tos = ip_hdr(skb)->tos; | 685 | arg.tos = ip_hdr(skb)->tos; |
686 | ip_send_unicast_reply(net, skb, &TCP_SKB_CB(skb)->header.h4.opt, | 686 | ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), |
687 | skb, &TCP_SKB_CB(skb)->header.h4.opt, | ||
687 | ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, | 688 | ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, |
688 | &arg, arg.iov[0].iov_len); | 689 | &arg, arg.iov[0].iov_len); |
689 | 690 | ||
@@ -767,7 +768,8 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, | |||
767 | if (oif) | 768 | if (oif) |
768 | arg.bound_dev_if = oif; | 769 | arg.bound_dev_if = oif; |
769 | arg.tos = tos; | 770 | arg.tos = tos; |
770 | ip_send_unicast_reply(net, skb, &TCP_SKB_CB(skb)->header.h4.opt, | 771 | ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), |
772 | skb, &TCP_SKB_CB(skb)->header.h4.opt, | ||
771 | ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, | 773 | ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, |
772 | &arg, arg.iov[0].iov_len); | 774 | &arg, arg.iov[0].iov_len); |
773 | 775 | ||
@@ -2430,14 +2432,39 @@ struct proto tcp_prot = { | |||
2430 | }; | 2432 | }; |
2431 | EXPORT_SYMBOL(tcp_prot); | 2433 | EXPORT_SYMBOL(tcp_prot); |
2432 | 2434 | ||
2435 | static void __net_exit tcp_sk_exit(struct net *net) | ||
2436 | { | ||
2437 | int cpu; | ||
2438 | |||
2439 | for_each_possible_cpu(cpu) | ||
2440 | inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv4.tcp_sk, cpu)); | ||
2441 | free_percpu(net->ipv4.tcp_sk); | ||
2442 | } | ||
2443 | |||
2433 | static int __net_init tcp_sk_init(struct net *net) | 2444 | static int __net_init tcp_sk_init(struct net *net) |
2434 | { | 2445 | { |
2446 | int res, cpu; | ||
2447 | |||
2448 | net->ipv4.tcp_sk = alloc_percpu(struct sock *); | ||
2449 | if (!net->ipv4.tcp_sk) | ||
2450 | return -ENOMEM; | ||
2451 | |||
2452 | for_each_possible_cpu(cpu) { | ||
2453 | struct sock *sk; | ||
2454 | |||
2455 | res = inet_ctl_sock_create(&sk, PF_INET, SOCK_RAW, | ||
2456 | IPPROTO_TCP, net); | ||
2457 | if (res) | ||
2458 | goto fail; | ||
2459 | *per_cpu_ptr(net->ipv4.tcp_sk, cpu) = sk; | ||
2460 | } | ||
2435 | net->ipv4.sysctl_tcp_ecn = 2; | 2461 | net->ipv4.sysctl_tcp_ecn = 2; |
2436 | return 0; | 2462 | return 0; |
2437 | } | ||
2438 | 2463 | ||
2439 | static void __net_exit tcp_sk_exit(struct net *net) | 2464 | fail: |
2440 | { | 2465 | tcp_sk_exit(net); |
2466 | |||
2467 | return res; | ||
2441 | } | 2468 | } |
2442 | 2469 | ||
2443 | static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list) | 2470 | static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list) |