aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 16:38:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 16:38:27 -0400
commitaecdc33e111b2c447b622e287c6003726daa1426 (patch)
tree3e7657eae4b785e1a1fb5dfb225dbae0b2f0cfc6 /net/ipv6/tcp_ipv6.c
parenta20acf99f75e49271381d65db097c9763060a1e8 (diff)
parenta3a6cab5ea10cca64d036851fe0d932448f2fe4f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller: 1) GRE now works over ipv6, from Dmitry Kozlov. 2) Make SCTP more network namespace aware, from Eric Biederman. 3) TEAM driver now works with non-ethernet devices, from Jiri Pirko. 4) Make openvswitch network namespace aware, from Pravin B Shelar. 5) IPV6 NAT implementation, from Patrick McHardy. 6) Server side support for TCP Fast Open, from Jerry Chu and others. 7) Packet BPF filter supports MOD and XOR, from Eric Dumazet and Daniel Borkmann. 8) Increate the loopback default MTU to 64K, from Eric Dumazet. 9) Use a per-task rather than per-socket page fragment allocator for outgoing networking traffic. This benefits processes that have very many mostly idle sockets, which is quite common. From Eric Dumazet. 10) Use up to 32K for page fragment allocations, with fallbacks to smaller sizes when higher order page allocations fail. Benefits are a) less segments for driver to process b) less calls to page allocator c) less waste of space. From Eric Dumazet. 11) Allow GRO to be used on GRE tunnels, from Eric Dumazet. 12) VXLAN device driver, one way to handle VLAN issues such as the limitation of 4096 VLAN IDs yet still have some level of isolation. From Stephen Hemminger. 13) As usual there is a large boatload of driver changes, with the scale perhaps tilted towards the wireless side this time around. Fix up various fairly trivial conflicts, mostly caused by the user namespace changes. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1012 commits) hyperv: Add buffer for extended info after the RNDIS response message. hyperv: Report actual status in receive completion packet hyperv: Remove extra allocated space for recv_pkt_list elements hyperv: Fix page buffer handling in rndis_filter_send_request() hyperv: Fix the missing return value in rndis_filter_set_packet_filter() hyperv: Fix the max_xfer_size in RNDIS initialization vxlan: put UDP socket in correct namespace vxlan: Depend on CONFIG_INET sfc: Fix the reported priorities of different filter types sfc: Remove EFX_FILTER_FLAG_RX_OVERRIDE_IP sfc: Fix loopback self-test with separate_tx_channels=1 sfc: Fix MCDI structure field lookup sfc: Add parentheses around use of bitfield macro arguments sfc: Fix null function pointer in efx_sriov_channel_type vxlan: virtual extensible lan igmp: export symbol ip_mc_leave_group netlink: add attributes to fdb interface tg3: unconditionally select HWMON support when tg3 is enabled. Revert "net: ti cpsw ethernet: allow reading phy interface mode from DT" gre: fix sparse warning ...
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 342ec62cdbde..49c890386ce9 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -476,7 +476,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
476 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) 476 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
477 goto done; 477 goto done;
478 478
479 skb = tcp_make_synack(sk, dst, req, rvp); 479 skb = tcp_make_synack(sk, dst, req, rvp, NULL);
480 480
481 if (skb) { 481 if (skb) {
482 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); 482 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
@@ -763,6 +763,8 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
763 struct sk_buff *skb) 763 struct sk_buff *skb)
764{ 764{
765 const struct ipv6hdr *iph = skb_gro_network_header(skb); 765 const struct ipv6hdr *iph = skb_gro_network_header(skb);
766 __wsum wsum;
767 __sum16 sum;
766 768
767 switch (skb->ip_summed) { 769 switch (skb->ip_summed) {
768 case CHECKSUM_COMPLETE: 770 case CHECKSUM_COMPLETE:
@@ -771,11 +773,23 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
771 skb->ip_summed = CHECKSUM_UNNECESSARY; 773 skb->ip_summed = CHECKSUM_UNNECESSARY;
772 break; 774 break;
773 } 775 }
774 776flush:
775 /* fall through */
776 case CHECKSUM_NONE:
777 NAPI_GRO_CB(skb)->flush = 1; 777 NAPI_GRO_CB(skb)->flush = 1;
778 return NULL; 778 return NULL;
779
780 case CHECKSUM_NONE:
781 wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
782 skb_gro_len(skb),
783 IPPROTO_TCP, 0));
784 sum = csum_fold(skb_checksum(skb,
785 skb_gro_offset(skb),
786 skb_gro_len(skb),
787 wsum));
788 if (sum)
789 goto flush;
790
791 skb->ip_summed = CHECKSUM_UNNECESSARY;
792 break;
779 } 793 }
780 794
781 return tcp_gro_receive(head, skb); 795 return tcp_gro_receive(head, skb);
@@ -988,7 +1002,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
988 &ipv6_hdr(skb)->saddr, 1002 &ipv6_hdr(skb)->saddr,
989 &ipv6_hdr(skb)->daddr, inet6_iif(skb)); 1003 &ipv6_hdr(skb)->daddr, inet6_iif(skb));
990 if (req) 1004 if (req)
991 return tcp_check_req(sk, skb, req, prev); 1005 return tcp_check_req(sk, skb, req, prev, false);
992 1006
993 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, 1007 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo,
994 &ipv6_hdr(skb)->saddr, th->source, 1008 &ipv6_hdr(skb)->saddr, th->source,
@@ -1169,7 +1183,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1169 } 1183 }
1170have_isn: 1184have_isn:
1171 tcp_rsk(req)->snt_isn = isn; 1185 tcp_rsk(req)->snt_isn = isn;
1172 tcp_rsk(req)->snt_synack = tcp_time_stamp;
1173 1186
1174 if (security_inet_conn_request(sk, skb, req)) 1187 if (security_inet_conn_request(sk, skb, req))
1175 goto drop_and_release; 1188 goto drop_and_release;
@@ -1180,6 +1193,8 @@ have_isn:
1180 want_cookie) 1193 want_cookie)
1181 goto drop_and_free; 1194 goto drop_and_free;
1182 1195
1196 tcp_rsk(req)->snt_synack = tcp_time_stamp;
1197 tcp_rsk(req)->listener = NULL;
1183 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 1198 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
1184 return 0; 1199 return 0;
1185 1200
@@ -1347,9 +1362,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1347 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; 1362 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
1348 1363
1349 tcp_initialize_rcv_mss(newsk); 1364 tcp_initialize_rcv_mss(newsk);
1350 if (tcp_rsk(req)->snt_synack) 1365 tcp_synack_rtt_meas(newsk, req);
1351 tcp_valid_rtt_meas(newsk,
1352 tcp_time_stamp - tcp_rsk(req)->snt_synack);
1353 newtp->total_retrans = req->retrans; 1366 newtp->total_retrans = req->retrans;
1354 1367
1355 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; 1368 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
@@ -1901,7 +1914,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1901 tp->write_seq-tp->snd_una, 1914 tp->write_seq-tp->snd_una,
1902 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq), 1915 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
1903 timer_active, 1916 timer_active,
1904 jiffies_to_clock_t(timer_expires - jiffies), 1917 jiffies_delta_to_clock_t(timer_expires - jiffies),
1905 icsk->icsk_retransmits, 1918 icsk->icsk_retransmits,
1906 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), 1919 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1907 icsk->icsk_probes_out, 1920 icsk->icsk_probes_out,
@@ -1921,10 +1934,7 @@ static void get_timewait6_sock(struct seq_file *seq,
1921 const struct in6_addr *dest, *src; 1934 const struct in6_addr *dest, *src;
1922 __u16 destp, srcp; 1935 __u16 destp, srcp;
1923 const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw); 1936 const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw);
1924 int ttd = tw->tw_ttd - jiffies; 1937 long delta = tw->tw_ttd - jiffies;
1925
1926 if (ttd < 0)
1927 ttd = 0;
1928 1938
1929 dest = &tw6->tw_v6_daddr; 1939 dest = &tw6->tw_v6_daddr;
1930 src = &tw6->tw_v6_rcv_saddr; 1940 src = &tw6->tw_v6_rcv_saddr;
@@ -1940,7 +1950,7 @@ static void get_timewait6_sock(struct seq_file *seq,
1940 dest->s6_addr32[0], dest->s6_addr32[1], 1950 dest->s6_addr32[0], dest->s6_addr32[1],
1941 dest->s6_addr32[2], dest->s6_addr32[3], destp, 1951 dest->s6_addr32[2], dest->s6_addr32[3], destp,
1942 tw->tw_substate, 0, 0, 1952 tw->tw_substate, 0, 0,
1943 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0, 1953 3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
1944 atomic_read(&tw->tw_refcnt), tw); 1954 atomic_read(&tw->tw_refcnt), tw);
1945} 1955}
1946 1956