diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 49 |
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 | 776 | flush: | |
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 | } |
1170 | have_isn: | 1185 | have_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. */ |
1831 | static void get_openreq6(struct seq_file *seq, | 1845 | static 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 | ||