diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 93825dd3a7c0..9b6460055df5 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -423,6 +423,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
423 | } | 423 | } |
424 | 424 | ||
425 | inet_csk_reqsk_queue_drop(sk, req, prev); | 425 | inet_csk_reqsk_queue_drop(sk, req, prev); |
426 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
426 | goto out; | 427 | goto out; |
427 | 428 | ||
428 | case TCP_SYN_SENT: | 429 | case TCP_SYN_SENT: |
@@ -712,7 +713,8 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { | |||
712 | #endif | 713 | #endif |
713 | 714 | ||
714 | static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | 715 | static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, |
715 | u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass) | 716 | u32 tsval, u32 tsecr, |
717 | struct tcp_md5sig_key *key, int rst, u8 tclass) | ||
716 | { | 718 | { |
717 | const struct tcphdr *th = tcp_hdr(skb); | 719 | const struct tcphdr *th = tcp_hdr(skb); |
718 | struct tcphdr *t1; | 720 | struct tcphdr *t1; |
@@ -724,7 +726,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
724 | struct dst_entry *dst; | 726 | struct dst_entry *dst; |
725 | __be32 *topt; | 727 | __be32 *topt; |
726 | 728 | ||
727 | if (ts) | 729 | if (tsecr) |
728 | tot_len += TCPOLEN_TSTAMP_ALIGNED; | 730 | tot_len += TCPOLEN_TSTAMP_ALIGNED; |
729 | #ifdef CONFIG_TCP_MD5SIG | 731 | #ifdef CONFIG_TCP_MD5SIG |
730 | if (key) | 732 | if (key) |
@@ -754,11 +756,11 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
754 | 756 | ||
755 | topt = (__be32 *)(t1 + 1); | 757 | topt = (__be32 *)(t1 + 1); |
756 | 758 | ||
757 | if (ts) { | 759 | if (tsecr) { |
758 | *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | 760 | *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | |
759 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | 761 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); |
760 | *topt++ = htonl(tcp_time_stamp); | 762 | *topt++ = htonl(tsval); |
761 | *topt++ = htonl(ts); | 763 | *topt++ = htonl(tsecr); |
762 | } | 764 | } |
763 | 765 | ||
764 | #ifdef CONFIG_TCP_MD5SIG | 766 | #ifdef CONFIG_TCP_MD5SIG |
@@ -834,7 +836,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) | |||
834 | * no RST generated if md5 hash doesn't match. | 836 | * no RST generated if md5 hash doesn't match. |
835 | */ | 837 | */ |
836 | sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev), | 838 | sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev), |
837 | &tcp_hashinfo, &ipv6h->daddr, | 839 | &tcp_hashinfo, &ipv6h->saddr, |
840 | th->source, &ipv6h->daddr, | ||
838 | ntohs(th->source), inet6_iif(skb)); | 841 | ntohs(th->source), inet6_iif(skb)); |
839 | if (!sk1) | 842 | if (!sk1) |
840 | return; | 843 | return; |
@@ -858,7 +861,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) | |||
858 | ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len - | 861 | ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len - |
859 | (th->doff << 2); | 862 | (th->doff << 2); |
860 | 863 | ||
861 | tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1, 0); | 864 | tcp_v6_send_response(skb, seq, ack_seq, 0, 0, 0, key, 1, 0); |
862 | 865 | ||
863 | #ifdef CONFIG_TCP_MD5SIG | 866 | #ifdef CONFIG_TCP_MD5SIG |
864 | release_sk1: | 867 | release_sk1: |
@@ -869,10 +872,11 @@ release_sk1: | |||
869 | #endif | 872 | #endif |
870 | } | 873 | } |
871 | 874 | ||
872 | static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts, | 875 | static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, |
876 | u32 win, u32 tsval, u32 tsecr, | ||
873 | struct tcp_md5sig_key *key, u8 tclass) | 877 | struct tcp_md5sig_key *key, u8 tclass) |
874 | { | 878 | { |
875 | tcp_v6_send_response(skb, seq, ack, win, ts, key, 0, tclass); | 879 | tcp_v6_send_response(skb, seq, ack, win, tsval, tsecr, key, 0, tclass); |
876 | } | 880 | } |
877 | 881 | ||
878 | static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) | 882 | static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) |
@@ -882,6 +886,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) | |||
882 | 886 | ||
883 | tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, | 887 | tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, |
884 | tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, | 888 | tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, |
889 | tcp_time_stamp + tcptw->tw_ts_offset, | ||
885 | tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw), | 890 | tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw), |
886 | tw->tw_tclass); | 891 | tw->tw_tclass); |
887 | 892 | ||
@@ -891,7 +896,8 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) | |||
891 | static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, | 896 | static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, |
892 | struct request_sock *req) | 897 | struct request_sock *req) |
893 | { | 898 | { |
894 | tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, | 899 | tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, |
900 | req->rcv_wnd, tcp_time_stamp, req->ts_recent, | ||
895 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 0); | 901 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 0); |
896 | } | 902 | } |
897 | 903 | ||
@@ -958,8 +964,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
958 | goto drop; | 964 | goto drop; |
959 | } | 965 | } |
960 | 966 | ||
961 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) | 967 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) { |
968 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); | ||
962 | goto drop; | 969 | goto drop; |
970 | } | ||
963 | 971 | ||
964 | req = inet6_reqsk_alloc(&tcp6_request_sock_ops); | 972 | req = inet6_reqsk_alloc(&tcp6_request_sock_ops); |
965 | if (req == NULL) | 973 | if (req == NULL) |
@@ -1027,7 +1035,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1027 | treq->rmt_addr = ipv6_hdr(skb)->saddr; | 1035 | treq->rmt_addr = ipv6_hdr(skb)->saddr; |
1028 | treq->loc_addr = ipv6_hdr(skb)->daddr; | 1036 | treq->loc_addr = ipv6_hdr(skb)->daddr; |
1029 | if (!want_cookie || tmp_opt.tstamp_ok) | 1037 | if (!want_cookie || tmp_opt.tstamp_ok) |
1030 | TCP_ECN_create_request(req, skb); | 1038 | TCP_ECN_create_request(req, skb, sock_net(sk)); |
1031 | 1039 | ||
1032 | treq->iif = sk->sk_bound_dev_if; | 1040 | treq->iif = sk->sk_bound_dev_if; |
1033 | 1041 | ||
@@ -1108,6 +1116,7 @@ drop_and_release: | |||
1108 | drop_and_free: | 1116 | drop_and_free: |
1109 | reqsk_free(req); | 1117 | reqsk_free(req); |
1110 | drop: | 1118 | drop: |
1119 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
1111 | return 0; /* don't send reset */ | 1120 | return 0; /* don't send reset */ |
1112 | } | 1121 | } |
1113 | 1122 | ||
@@ -1163,7 +1172,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1163 | newnp->opt = NULL; | 1172 | newnp->opt = NULL; |
1164 | newnp->mcast_oif = inet6_iif(skb); | 1173 | newnp->mcast_oif = inet6_iif(skb); |
1165 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; | 1174 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
1166 | newnp->rcv_tclass = ipv6_tclass(ipv6_hdr(skb)); | 1175 | newnp->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb)); |
1167 | 1176 | ||
1168 | /* | 1177 | /* |
1169 | * No need to charge this sock to the relevant IPv6 refcnt debug socks count | 1178 | * No need to charge this sock to the relevant IPv6 refcnt debug socks count |
@@ -1243,7 +1252,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1243 | newnp->opt = NULL; | 1252 | newnp->opt = NULL; |
1244 | newnp->mcast_oif = inet6_iif(skb); | 1253 | newnp->mcast_oif = inet6_iif(skb); |
1245 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; | 1254 | newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
1246 | newnp->rcv_tclass = ipv6_tclass(ipv6_hdr(skb)); | 1255 | newnp->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb)); |
1247 | 1256 | ||
1248 | /* Clone native IPv6 options from listening socket (if any) | 1257 | /* Clone native IPv6 options from listening socket (if any) |
1249 | 1258 | ||
@@ -1456,7 +1465,7 @@ ipv6_pktoptions: | |||
1456 | if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) | 1465 | if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) |
1457 | np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; | 1466 | np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; |
1458 | if (np->rxopt.bits.rxtclass) | 1467 | if (np->rxopt.bits.rxtclass) |
1459 | np->rcv_tclass = ipv6_tclass(ipv6_hdr(skb)); | 1468 | np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb)); |
1460 | if (ipv6_opt_accepted(sk, opt_skb)) { | 1469 | if (ipv6_opt_accepted(sk, opt_skb)) { |
1461 | skb_set_owner_r(opt_skb, sk); | 1470 | skb_set_owner_r(opt_skb, sk); |
1462 | opt_skb = xchg(&np->pktoptions, opt_skb); | 1471 | opt_skb = xchg(&np->pktoptions, opt_skb); |
@@ -1598,6 +1607,7 @@ do_time_wait: | |||
1598 | struct sock *sk2; | 1607 | struct sock *sk2; |
1599 | 1608 | ||
1600 | sk2 = inet6_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, | 1609 | sk2 = inet6_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, |
1610 | &ipv6_hdr(skb)->saddr, th->source, | ||
1601 | &ipv6_hdr(skb)->daddr, | 1611 | &ipv6_hdr(skb)->daddr, |
1602 | ntohs(th->dest), inet6_iif(skb)); | 1612 | ntohs(th->dest), inet6_iif(skb)); |
1603 | if (sk2 != NULL) { | 1613 | if (sk2 != NULL) { |