aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d8841a2f1569..a4d523709ab3 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -73,7 +73,6 @@
73#include <net/timewait_sock.h> 73#include <net/timewait_sock.h>
74#include <net/xfrm.h> 74#include <net/xfrm.h>
75#include <net/secure_seq.h> 75#include <net/secure_seq.h>
76#include <net/tcp_memcontrol.h>
77#include <net/busy_poll.h> 76#include <net/busy_poll.h>
78 77
79#include <linux/inet.h> 78#include <linux/inet.h>
@@ -587,7 +586,7 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
587 } rep; 586 } rep;
588 struct ip_reply_arg arg; 587 struct ip_reply_arg arg;
589#ifdef CONFIG_TCP_MD5SIG 588#ifdef CONFIG_TCP_MD5SIG
590 struct tcp_md5sig_key *key; 589 struct tcp_md5sig_key *key = NULL;
591 const __u8 *hash_location = NULL; 590 const __u8 *hash_location = NULL;
592 unsigned char newhash[16]; 591 unsigned char newhash[16];
593 int genhash; 592 int genhash;
@@ -627,7 +626,10 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
627 net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev); 626 net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev);
628#ifdef CONFIG_TCP_MD5SIG 627#ifdef CONFIG_TCP_MD5SIG
629 hash_location = tcp_parse_md5sig_option(th); 628 hash_location = tcp_parse_md5sig_option(th);
630 if (!sk && hash_location) { 629 if (sk && sk_fullsock(sk)) {
630 key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)
631 &ip_hdr(skb)->saddr, AF_INET);
632 } else if (hash_location) {
631 /* 633 /*
632 * active side is lost. Try to find listening socket through 634 * active side is lost. Try to find listening socket through
633 * source port, and then find md5 key through listening socket. 635 * source port, and then find md5 key through listening socket.
@@ -651,10 +653,6 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
651 genhash = tcp_v4_md5_hash_skb(newhash, key, NULL, skb); 653 genhash = tcp_v4_md5_hash_skb(newhash, key, NULL, skb);
652 if (genhash || memcmp(hash_location, newhash, 16) != 0) 654 if (genhash || memcmp(hash_location, newhash, 16) != 0)
653 goto release_sk1; 655 goto release_sk1;
654 } else {
655 key = sk ? tcp_md5_do_lookup(sk, (union tcp_md5_addr *)
656 &ip_hdr(skb)->saddr,
657 AF_INET) : NULL;
658 } 656 }
659 657
660 if (key) { 658 if (key) {
@@ -675,7 +673,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
675 ip_hdr(skb)->saddr, /* XXX */ 673 ip_hdr(skb)->saddr, /* XXX */
676 arg.iov[0].iov_len, IPPROTO_TCP, 0); 674 arg.iov[0].iov_len, IPPROTO_TCP, 0);
677 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 675 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
678 arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0; 676 arg.flags = (sk && inet_sk_transparent(sk)) ? IP_REPLY_ARG_NOSRCCHECK : 0;
677
679 /* When socket is gone, all binding information is lost. 678 /* When socket is gone, all binding information is lost.
680 * routing might fail in this case. No choice here, if we choose to force 679 * routing might fail in this case. No choice here, if we choose to force
681 * input interface, we will misroute in case of asymmetric route. 680 * input interface, we will misroute in case of asymmetric route.
@@ -683,6 +682,9 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
683 if (sk) 682 if (sk)
684 arg.bound_dev_if = sk->sk_bound_dev_if; 683 arg.bound_dev_if = sk->sk_bound_dev_if;
685 684
685 BUILD_BUG_ON(offsetof(struct sock, sk_bound_dev_if) !=
686 offsetof(struct inet_timewait_sock, tw_bound_dev_if));
687
686 arg.tos = ip_hdr(skb)->tos; 688 arg.tos = ip_hdr(skb)->tos;
687 ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), 689 ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk),
688 skb, &TCP_SKB_CB(skb)->header.h4.opt, 690 skb, &TCP_SKB_CB(skb)->header.h4.opt,
@@ -705,7 +707,8 @@ release_sk1:
705 outside socket context is ugly, certainly. What can I do? 707 outside socket context is ugly, certainly. What can I do?
706 */ 708 */
707 709
708static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, 710static void tcp_v4_send_ack(struct net *net,
711 struct sk_buff *skb, u32 seq, u32 ack,
709 u32 win, u32 tsval, u32 tsecr, int oif, 712 u32 win, u32 tsval, u32 tsecr, int oif,
710 struct tcp_md5sig_key *key, 713 struct tcp_md5sig_key *key,
711 int reply_flags, u8 tos) 714 int reply_flags, u8 tos)
@@ -720,7 +723,6 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
720 ]; 723 ];
721 } rep; 724 } rep;
722 struct ip_reply_arg arg; 725 struct ip_reply_arg arg;
723 struct net *net = dev_net(skb_dst(skb)->dev);
724 726
725 memset(&rep.th, 0, sizeof(struct tcphdr)); 727 memset(&rep.th, 0, sizeof(struct tcphdr));
726 memset(&arg, 0, sizeof(arg)); 728 memset(&arg, 0, sizeof(arg));
@@ -782,7 +784,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
782 struct inet_timewait_sock *tw = inet_twsk(sk); 784 struct inet_timewait_sock *tw = inet_twsk(sk);
783 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 785 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
784 786
785 tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 787 tcp_v4_send_ack(sock_net(sk), skb,
788 tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
786 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 789 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
787 tcp_time_stamp + tcptw->tw_ts_offset, 790 tcp_time_stamp + tcptw->tw_ts_offset,
788 tcptw->tw_ts_recent, 791 tcptw->tw_ts_recent,
@@ -801,8 +804,10 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
801 /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV 804 /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
802 * sk->sk_state == TCP_SYN_RECV -> for Fast Open. 805 * sk->sk_state == TCP_SYN_RECV -> for Fast Open.
803 */ 806 */
804 tcp_v4_send_ack(skb, (sk->sk_state == TCP_LISTEN) ? 807 u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 :
805 tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, 808 tcp_sk(sk)->snd_nxt;
809
810 tcp_v4_send_ack(sock_net(sk), skb, seq,
806 tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd, 811 tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd,
807 tcp_time_stamp, 812 tcp_time_stamp,
808 req->ts_recent, 813 req->ts_recent,
@@ -1276,6 +1281,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
1276 ireq = inet_rsk(req); 1281 ireq = inet_rsk(req);
1277 sk_daddr_set(newsk, ireq->ir_rmt_addr); 1282 sk_daddr_set(newsk, ireq->ir_rmt_addr);
1278 sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); 1283 sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
1284 newsk->sk_bound_dev_if = ireq->ir_iif;
1279 newinet->inet_saddr = ireq->ir_loc_addr; 1285 newinet->inet_saddr = ireq->ir_loc_addr;
1280 inet_opt = ireq->opt; 1286 inet_opt = ireq->opt;
1281 rcu_assign_pointer(newinet->inet_opt, inet_opt); 1287 rcu_assign_pointer(newinet->inet_opt, inet_opt);
@@ -1705,7 +1711,9 @@ do_time_wait:
1705 tcp_v4_timewait_ack(sk, skb); 1711 tcp_v4_timewait_ack(sk, skb);
1706 break; 1712 break;
1707 case TCP_TW_RST: 1713 case TCP_TW_RST:
1708 goto no_tcp_socket; 1714 tcp_v4_send_reset(sk, skb);
1715 inet_twsk_deschedule_put(inet_twsk(sk));
1716 goto discard_it;
1709 case TCP_TW_SUCCESS:; 1717 case TCP_TW_SUCCESS:;
1710 } 1718 }
1711 goto discard_it; 1719 goto discard_it;
@@ -1812,7 +1820,9 @@ void tcp_v4_destroy_sock(struct sock *sk)
1812 tcp_saved_syn_free(tp); 1820 tcp_saved_syn_free(tp);
1813 1821
1814 sk_sockets_allocated_dec(sk); 1822 sk_sockets_allocated_dec(sk);
1815 sock_release_memcg(sk); 1823
1824 if (mem_cgroup_sockets_enabled && sk->sk_memcg)
1825 sock_release_memcg(sk);
1816} 1826}
1817EXPORT_SYMBOL(tcp_v4_destroy_sock); 1827EXPORT_SYMBOL(tcp_v4_destroy_sock);
1818 1828
@@ -2336,11 +2346,7 @@ struct proto tcp_prot = {
2336 .compat_setsockopt = compat_tcp_setsockopt, 2346 .compat_setsockopt = compat_tcp_setsockopt,
2337 .compat_getsockopt = compat_tcp_getsockopt, 2347 .compat_getsockopt = compat_tcp_getsockopt,
2338#endif 2348#endif
2339#ifdef CONFIG_MEMCG_KMEM 2349 .diag_destroy = tcp_abort,
2340 .init_cgroup = tcp_init_cgroup,
2341 .destroy_cgroup = tcp_destroy_cgroup,
2342 .proto_cgroup = tcp_proto_cgroup,
2343#endif
2344}; 2350};
2345EXPORT_SYMBOL(tcp_prot); 2351EXPORT_SYMBOL(tcp_prot);
2346 2352
@@ -2378,6 +2384,10 @@ static int __net_init tcp_sk_init(struct net *net)
2378 net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; 2384 net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD;
2379 net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL; 2385 net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL;
2380 2386
2387 net->ipv4.sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME;
2388 net->ipv4.sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES;
2389 net->ipv4.sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL;
2390
2381 return 0; 2391 return 0;
2382fail: 2392fail:
2383 tcp_sk_exit(net); 2393 tcp_sk_exit(net);