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.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index bd5ef7b6e48e..6603511e3673 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -353,6 +353,11 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
353 if (sk->sk_state == TCP_CLOSE) 353 if (sk->sk_state == TCP_CLOSE)
354 goto out; 354 goto out;
355 355
356 if (ipv6_hdr(skb)->hop_limit < inet6_sk(sk)->min_hopcount) {
357 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
358 goto out;
359 }
360
356 tp = tcp_sk(sk); 361 tp = tcp_sk(sk);
357 seq = ntohl(th->seq); 362 seq = ntohl(th->seq);
358 if (sk->sk_state != TCP_LISTEN && 363 if (sk->sk_state != TCP_LISTEN &&
@@ -1018,7 +1023,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
1018 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); 1023 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
1019 1024
1020 t1 = (struct tcphdr *) skb_push(buff, tot_len); 1025 t1 = (struct tcphdr *) skb_push(buff, tot_len);
1021 skb_reset_transport_header(skb); 1026 skb_reset_transport_header(buff);
1022 1027
1023 /* Swap the send and the receive. */ 1028 /* Swap the send and the receive. */
1024 memset(t1, 0, sizeof(*t1)); 1029 memset(t1, 0, sizeof(*t1));
@@ -1050,12 +1055,13 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
1050 } 1055 }
1051#endif 1056#endif
1052 1057
1053 buff->csum = csum_partial(t1, tot_len, 0);
1054
1055 memset(&fl, 0, sizeof(fl)); 1058 memset(&fl, 0, sizeof(fl));
1056 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); 1059 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
1057 ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); 1060 ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
1058 1061
1062 buff->ip_summed = CHECKSUM_PARTIAL;
1063 buff->csum = 0;
1064
1059 __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst); 1065 __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst);
1060 1066
1061 fl.proto = IPPROTO_TCP; 1067 fl.proto = IPPROTO_TCP;
@@ -1234,12 +1240,12 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1234 goto drop_and_free; 1240 goto drop_and_free;
1235 1241
1236 /* Secret recipe starts with IP addresses */ 1242 /* Secret recipe starts with IP addresses */
1237 d = &ipv6_hdr(skb)->daddr.s6_addr32[0]; 1243 d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0];
1238 *mess++ ^= *d++; 1244 *mess++ ^= *d++;
1239 *mess++ ^= *d++; 1245 *mess++ ^= *d++;
1240 *mess++ ^= *d++; 1246 *mess++ ^= *d++;
1241 *mess++ ^= *d++; 1247 *mess++ ^= *d++;
1242 d = &ipv6_hdr(skb)->saddr.s6_addr32[0]; 1248 d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0];
1243 *mess++ ^= *d++; 1249 *mess++ ^= *d++;
1244 *mess++ ^= *d++; 1250 *mess++ ^= *d++;
1245 *mess++ ^= *d++; 1251 *mess++ ^= *d++;
@@ -1677,6 +1683,7 @@ ipv6_pktoptions:
1677static int tcp_v6_rcv(struct sk_buff *skb) 1683static int tcp_v6_rcv(struct sk_buff *skb)
1678{ 1684{
1679 struct tcphdr *th; 1685 struct tcphdr *th;
1686 struct ipv6hdr *hdr;
1680 struct sock *sk; 1687 struct sock *sk;
1681 int ret; 1688 int ret;
1682 struct net *net = dev_net(skb->dev); 1689 struct net *net = dev_net(skb->dev);
@@ -1703,12 +1710,13 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1703 goto bad_packet; 1710 goto bad_packet;
1704 1711
1705 th = tcp_hdr(skb); 1712 th = tcp_hdr(skb);
1713 hdr = ipv6_hdr(skb);
1706 TCP_SKB_CB(skb)->seq = ntohl(th->seq); 1714 TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1707 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + 1715 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1708 skb->len - th->doff*4); 1716 skb->len - th->doff*4);
1709 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); 1717 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1710 TCP_SKB_CB(skb)->when = 0; 1718 TCP_SKB_CB(skb)->when = 0;
1711 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); 1719 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(hdr);
1712 TCP_SKB_CB(skb)->sacked = 0; 1720 TCP_SKB_CB(skb)->sacked = 0;
1713 1721
1714 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); 1722 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
@@ -1719,6 +1727,11 @@ process:
1719 if (sk->sk_state == TCP_TIME_WAIT) 1727 if (sk->sk_state == TCP_TIME_WAIT)
1720 goto do_time_wait; 1728 goto do_time_wait;
1721 1729
1730 if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) {
1731 NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
1732 goto discard_and_relse;
1733 }
1734
1722 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 1735 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1723 goto discard_and_relse; 1736 goto discard_and_relse;
1724 1737