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.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 25ecc6e2478b..c83938b8fcb1 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -52,7 +52,6 @@
52 * a single port at the same time. 52 * a single port at the same time.
53 */ 53 */
54 54
55#include <linux/config.h>
56 55
57#include <linux/types.h> 56#include <linux/types.h>
58#include <linux/fcntl.h> 57#include <linux/fcntl.h>
@@ -79,8 +78,8 @@
79#include <linux/proc_fs.h> 78#include <linux/proc_fs.h>
80#include <linux/seq_file.h> 79#include <linux/seq_file.h>
81 80
82int sysctl_tcp_tw_reuse; 81int sysctl_tcp_tw_reuse __read_mostly;
83int sysctl_tcp_low_latency; 82int sysctl_tcp_low_latency __read_mostly;
84 83
85/* Check TCP sequence numbers in ICMP packets. */ 84/* Check TCP sequence numbers in ICMP packets. */
86#define ICMP_MIN_LENGTH 8 85#define ICMP_MIN_LENGTH 8
@@ -91,7 +90,7 @@ static struct socket *tcp_socket;
91void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb); 90void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
92 91
93struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { 92struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
94 .lhash_lock = RW_LOCK_UNLOCKED, 93 .lhash_lock = __RW_LOCK_UNLOCKED(tcp_hashinfo.lhash_lock),
95 .lhash_users = ATOMIC_INIT(0), 94 .lhash_users = ATOMIC_INIT(0),
96 .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait), 95 .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait),
97}; 96};
@@ -160,7 +159,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
160 struct tcp_sock *tp = tcp_sk(sk); 159 struct tcp_sock *tp = tcp_sk(sk);
161 struct sockaddr_in *usin = (struct sockaddr_in *)uaddr; 160 struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
162 struct rtable *rt; 161 struct rtable *rt;
163 u32 daddr, nexthop; 162 __be32 daddr, nexthop;
164 int tmp; 163 int tmp;
165 int err; 164 int err;
166 165
@@ -242,6 +241,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
242 goto failure; 241 goto failure;
243 242
244 /* OK, now commit destination to socket. */ 243 /* OK, now commit destination to socket. */
244 sk->sk_gso_type = SKB_GSO_TCPV4;
245 sk_setup_caps(sk, &rt->u.dst); 245 sk_setup_caps(sk, &rt->u.dst);
246 246
247 if (!tp->write_seq) 247 if (!tp->write_seq)
@@ -438,7 +438,6 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
438 It can f.e. if SYNs crossed. 438 It can f.e. if SYNs crossed.
439 */ 439 */
440 if (!sock_owned_by_user(sk)) { 440 if (!sock_owned_by_user(sk)) {
441 TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
442 sk->sk_err = err; 441 sk->sk_err = err;
443 442
444 sk->sk_error_report(sk); 443 sk->sk_error_report(sk);
@@ -485,7 +484,7 @@ void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
485 struct inet_sock *inet = inet_sk(sk); 484 struct inet_sock *inet = inet_sk(sk);
486 struct tcphdr *th = skb->h.th; 485 struct tcphdr *th = skb->h.th;
487 486
488 if (skb->ip_summed == CHECKSUM_HW) { 487 if (skb->ip_summed == CHECKSUM_PARTIAL) {
489 th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0); 488 th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0);
490 skb->csum = offsetof(struct tcphdr, check); 489 skb->csum = offsetof(struct tcphdr, check);
491 } else { 490 } else {
@@ -496,6 +495,24 @@ void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
496 } 495 }
497} 496}
498 497
498int tcp_v4_gso_send_check(struct sk_buff *skb)
499{
500 struct iphdr *iph;
501 struct tcphdr *th;
502
503 if (!pskb_may_pull(skb, sizeof(*th)))
504 return -EINVAL;
505
506 iph = skb->nh.iph;
507 th = skb->h.th;
508
509 th->check = 0;
510 th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0);
511 skb->csum = offsetof(struct tcphdr, check);
512 skb->ip_summed = CHECKSUM_PARTIAL;
513 return 0;
514}
515
499/* 516/*
500 * This routine will send an RST to the other tcp. 517 * This routine will send an RST to the other tcp.
501 * 518 *
@@ -717,8 +734,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
717 struct inet_request_sock *ireq; 734 struct inet_request_sock *ireq;
718 struct tcp_options_received tmp_opt; 735 struct tcp_options_received tmp_opt;
719 struct request_sock *req; 736 struct request_sock *req;
720 __u32 saddr = skb->nh.iph->saddr; 737 __be32 saddr = skb->nh.iph->saddr;
721 __u32 daddr = skb->nh.iph->daddr; 738 __be32 daddr = skb->nh.iph->daddr;
722 __u32 isn = TCP_SKB_CB(skb)->when; 739 __u32 isn = TCP_SKB_CB(skb)->when;
723 struct dst_entry *dst = NULL; 740 struct dst_entry *dst = NULL;
724#ifdef CONFIG_SYN_COOKIES 741#ifdef CONFIG_SYN_COOKIES
@@ -781,6 +798,9 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
781 798
782 tcp_openreq_init(req, &tmp_opt, skb); 799 tcp_openreq_init(req, &tmp_opt, skb);
783 800
801 if (security_inet_conn_request(sk, skb, req))
802 goto drop_and_free;
803
784 ireq = inet_rsk(req); 804 ireq = inet_rsk(req);
785 ireq->loc_addr = daddr; 805 ireq->loc_addr = daddr;
786 ireq->rmt_addr = saddr; 806 ireq->rmt_addr = saddr;
@@ -856,7 +876,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
856drop_and_free: 876drop_and_free:
857 reqsk_free(req); 877 reqsk_free(req);
858drop: 878drop:
859 TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
860 return 0; 879 return 0;
861} 880}
862 881
@@ -884,6 +903,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
884 if (!newsk) 903 if (!newsk)
885 goto exit; 904 goto exit;
886 905
906 newsk->sk_gso_type = SKB_GSO_TCPV4;
887 sk_setup_caps(newsk, dst); 907 sk_setup_caps(newsk, dst);
888 908
889 newtp = tcp_sk(newsk); 909 newtp = tcp_sk(newsk);
@@ -931,9 +951,9 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
931 if (req) 951 if (req)
932 return tcp_check_req(sk, skb, req, prev); 952 return tcp_check_req(sk, skb, req, prev);
933 953
934 nsk = __inet_lookup_established(&tcp_hashinfo, skb->nh.iph->saddr, 954 nsk = inet_lookup_established(&tcp_hashinfo, skb->nh.iph->saddr,
935 th->source, skb->nh.iph->daddr, 955 th->source, skb->nh.iph->daddr,
936 ntohs(th->dest), inet_iif(skb)); 956 th->dest, inet_iif(skb));
937 957
938 if (nsk) { 958 if (nsk) {
939 if (nsk->sk_state != TCP_TIME_WAIT) { 959 if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -953,7 +973,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
953 973
954static int tcp_v4_checksum_init(struct sk_buff *skb) 974static int tcp_v4_checksum_init(struct sk_buff *skb)
955{ 975{
956 if (skb->ip_summed == CHECKSUM_HW) { 976 if (skb->ip_summed == CHECKSUM_COMPLETE) {
957 if (!tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr, 977 if (!tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr,
958 skb->nh.iph->daddr, skb->csum)) { 978 skb->nh.iph->daddr, skb->csum)) {
959 skb->ip_summed = CHECKSUM_UNNECESSARY; 979 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1070,7 +1090,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
1070 TCP_SKB_CB(skb)->sacked = 0; 1090 TCP_SKB_CB(skb)->sacked = 0;
1071 1091
1072 sk = __inet_lookup(&tcp_hashinfo, skb->nh.iph->saddr, th->source, 1092 sk = __inet_lookup(&tcp_hashinfo, skb->nh.iph->saddr, th->source,
1073 skb->nh.iph->daddr, ntohs(th->dest), 1093 skb->nh.iph->daddr, th->dest,
1074 inet_iif(skb)); 1094 inet_iif(skb));
1075 1095
1076 if (!sk) 1096 if (!sk)
@@ -1084,12 +1104,12 @@ process:
1084 goto discard_and_relse; 1104 goto discard_and_relse;
1085 nf_reset(skb); 1105 nf_reset(skb);
1086 1106
1087 if (sk_filter(sk, skb, 0)) 1107 if (sk_filter(sk, skb))
1088 goto discard_and_relse; 1108 goto discard_and_relse;
1089 1109
1090 skb->dev = NULL; 1110 skb->dev = NULL;
1091 1111
1092 bh_lock_sock(sk); 1112 bh_lock_sock_nested(sk);
1093 ret = 0; 1113 ret = 0;
1094 if (!sock_owned_by_user(sk)) { 1114 if (!sock_owned_by_user(sk)) {
1095#ifdef CONFIG_NET_DMA 1115#ifdef CONFIG_NET_DMA
@@ -1148,7 +1168,7 @@ do_time_wait:
1148 case TCP_TW_SYN: { 1168 case TCP_TW_SYN: {
1149 struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo, 1169 struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
1150 skb->nh.iph->daddr, 1170 skb->nh.iph->daddr,
1151 ntohs(th->dest), 1171 th->dest,
1152 inet_iif(skb)); 1172 inet_iif(skb));
1153 if (sk2) { 1173 if (sk2) {
1154 inet_twsk_deschedule((struct inet_timewait_sock *)sk, 1174 inet_twsk_deschedule((struct inet_timewait_sock *)sk,
@@ -1621,10 +1641,9 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
1621 if (unlikely(afinfo == NULL)) 1641 if (unlikely(afinfo == NULL))
1622 return -EINVAL; 1642 return -EINVAL;
1623 1643
1624 s = kmalloc(sizeof(*s), GFP_KERNEL); 1644 s = kzalloc(sizeof(*s), GFP_KERNEL);
1625 if (!s) 1645 if (!s)
1626 return -ENOMEM; 1646 return -ENOMEM;
1627 memset(s, 0, sizeof(*s));
1628 s->family = afinfo->family; 1647 s->family = afinfo->family;
1629 s->seq_ops.start = tcp_seq_start; 1648 s->seq_ops.start = tcp_seq_start;
1630 s->seq_ops.next = tcp_seq_next; 1649 s->seq_ops.next = tcp_seq_next;
@@ -1726,7 +1745,8 @@ static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i)
1726 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " 1745 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
1727 "%08X %5d %8d %lu %d %p %u %u %u %u %d", 1746 "%08X %5d %8d %lu %d %p %u %u %u %u %d",
1728 i, src, srcp, dest, destp, sp->sk_state, 1747 i, src, srcp, dest, destp, sp->sk_state,
1729 tp->write_seq - tp->snd_una, tp->rcv_nxt - tp->copied_seq, 1748 tp->write_seq - tp->snd_una,
1749 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
1730 timer_active, 1750 timer_active,
1731 jiffies_to_clock_t(timer_expires - jiffies), 1751 jiffies_to_clock_t(timer_expires - jiffies),
1732 icsk->icsk_retransmits, 1752 icsk->icsk_retransmits,
@@ -1743,7 +1763,7 @@ static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i)
1743 1763
1744static void get_timewait4_sock(struct inet_timewait_sock *tw, char *tmpbuf, int i) 1764static void get_timewait4_sock(struct inet_timewait_sock *tw, char *tmpbuf, int i)
1745{ 1765{
1746 unsigned int dest, src; 1766 __be32 dest, src;
1747 __u16 destp, srcp; 1767 __u16 destp, srcp;
1748 int ttd = tw->tw_ttd - jiffies; 1768 int ttd = tw->tw_ttd - jiffies;
1749 1769