aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index acd32e3f1b68..26175bffbaa0 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);
@@ -863,7 +877,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
863 __tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr); 877 __tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr);
864 878
865 fl6.flowi6_proto = IPPROTO_TCP; 879 fl6.flowi6_proto = IPPROTO_TCP;
866 fl6.flowi6_oif = inet6_iif(skb); 880 if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
881 fl6.flowi6_oif = inet6_iif(skb);
867 fl6.fl6_dport = t1->dest; 882 fl6.fl6_dport = t1->dest;
868 fl6.fl6_sport = t1->source; 883 fl6.fl6_sport = t1->source;
869 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); 884 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
@@ -988,7 +1003,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
988 &ipv6_hdr(skb)->saddr, 1003 &ipv6_hdr(skb)->saddr,
989 &ipv6_hdr(skb)->daddr, inet6_iif(skb)); 1004 &ipv6_hdr(skb)->daddr, inet6_iif(skb));
990 if (req) 1005 if (req)
991 return tcp_check_req(sk, skb, req, prev); 1006 return tcp_check_req(sk, skb, req, prev, false);
992 1007
993 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, 1008 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo,
994 &ipv6_hdr(skb)->saddr, th->source, 1009 &ipv6_hdr(skb)->saddr, th->source,
@@ -1169,7 +1184,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1169 } 1184 }
1170have_isn: 1185have_isn:
1171 tcp_rsk(req)->snt_isn = isn; 1186 tcp_rsk(req)->snt_isn = isn;
1172 tcp_rsk(req)->snt_synack = tcp_time_stamp;
1173 1187
1174 if (security_inet_conn_request(sk, skb, req)) 1188 if (security_inet_conn_request(sk, skb, req))
1175 goto drop_and_release; 1189 goto drop_and_release;
@@ -1180,6 +1194,8 @@ have_isn:
1180 want_cookie) 1194 want_cookie)
1181 goto drop_and_free; 1195 goto drop_and_free;
1182 1196
1197 tcp_rsk(req)->snt_synack = tcp_time_stamp;
1198 tcp_rsk(req)->listener = NULL;
1183 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 1199 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
1184 return 0; 1200 return 0;
1185 1201
@@ -1347,9 +1363,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; 1363 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
1348 1364
1349 tcp_initialize_rcv_mss(newsk); 1365 tcp_initialize_rcv_mss(newsk);
1350 if (tcp_rsk(req)->snt_synack) 1366 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; 1367 newtp->total_retrans = req->retrans;
1354 1368
1355 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; 1369 newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
@@ -1829,7 +1843,7 @@ static void tcp_v6_destroy_sock(struct sock *sk)
1829#ifdef CONFIG_PROC_FS 1843#ifdef CONFIG_PROC_FS
1830/* Proc filesystem TCPv6 sock list dumping. */ 1844/* Proc filesystem TCPv6 sock list dumping. */
1831static void get_openreq6(struct seq_file *seq, 1845static void get_openreq6(struct seq_file *seq,
1832 const struct sock *sk, struct request_sock *req, int i, int uid) 1846 const struct sock *sk, struct request_sock *req, int i, kuid_t uid)
1833{ 1847{
1834 int ttd = req->expires - jiffies; 1848 int ttd = req->expires - jiffies;
1835 const struct in6_addr *src = &inet6_rsk(req)->loc_addr; 1849 const struct in6_addr *src = &inet6_rsk(req)->loc_addr;
@@ -1853,7 +1867,7 @@ static void get_openreq6(struct seq_file *seq,
1853 1, /* timers active (only the expire timer) */ 1867 1, /* timers active (only the expire timer) */
1854 jiffies_to_clock_t(ttd), 1868 jiffies_to_clock_t(ttd),
1855 req->retrans, 1869 req->retrans,
1856 uid, 1870 from_kuid_munged(seq_user_ns(seq), uid),
1857 0, /* non standard timer */ 1871 0, /* non standard timer */
1858 0, /* open_requests have no inode */ 1872 0, /* open_requests have no inode */
1859 0, req); 1873 0, req);
@@ -1901,9 +1915,9 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1901 tp->write_seq-tp->snd_una, 1915 tp->write_seq-tp->snd_una,
1902 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq), 1916 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
1903 timer_active, 1917 timer_active,
1904 jiffies_to_clock_t(timer_expires - jiffies), 1918 jiffies_delta_to_clock_t(timer_expires - jiffies),
1905 icsk->icsk_retransmits, 1919 icsk->icsk_retransmits,
1906 sock_i_uid(sp), 1920 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1907 icsk->icsk_probes_out, 1921 icsk->icsk_probes_out,
1908 sock_i_ino(sp), 1922 sock_i_ino(sp),
1909 atomic_read(&sp->sk_refcnt), sp, 1923 atomic_read(&sp->sk_refcnt), sp,
@@ -1921,10 +1935,7 @@ static void get_timewait6_sock(struct seq_file *seq,
1921 const struct in6_addr *dest, *src; 1935 const struct in6_addr *dest, *src;
1922 __u16 destp, srcp; 1936 __u16 destp, srcp;
1923 const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw); 1937 const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw);
1924 int ttd = tw->tw_ttd - jiffies; 1938 long delta = tw->tw_ttd - jiffies;
1925
1926 if (ttd < 0)
1927 ttd = 0;
1928 1939
1929 dest = &tw6->tw_v6_daddr; 1940 dest = &tw6->tw_v6_daddr;
1930 src = &tw6->tw_v6_rcv_saddr; 1941 src = &tw6->tw_v6_rcv_saddr;
@@ -1940,7 +1951,7 @@ static void get_timewait6_sock(struct seq_file *seq,
1940 dest->s6_addr32[0], dest->s6_addr32[1], 1951 dest->s6_addr32[0], dest->s6_addr32[1],
1941 dest->s6_addr32[2], dest->s6_addr32[3], destp, 1952 dest->s6_addr32[2], dest->s6_addr32[3], destp,
1942 tw->tw_substate, 0, 0, 1953 tw->tw_substate, 0, 0,
1943 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0, 1954 3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
1944 atomic_read(&tw->tw_refcnt), tw); 1955 atomic_read(&tw->tw_refcnt), tw);
1945} 1956}
1946 1957