|
@@ -353,6 +353,11 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
|
if (sk->sk_state == TCP_CLOSE)
|
|
if (sk->sk_state == TCP_CLOSE)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
|
|
+ if (ipv6_hdr(skb)->hop_limit < inet6_sk(sk)->min_hopcount) {
|
|
|
|
+ NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
tp = tcp_sk(sk);
|
|
tp = tcp_sk(sk);
|
|
seq = ntohl(th->seq);
|
|
seq = ntohl(th->seq);
|
|
if (sk->sk_state != TCP_LISTEN &&
|
|
if (sk->sk_state != TCP_LISTEN &&
|
|
@@ -1678,6 +1683,7 @@ ipv6_pktoptions:
|
|
static int tcp_v6_rcv(struct sk_buff *skb)
|
|
static int tcp_v6_rcv(struct sk_buff *skb)
|
|
{
|
|
{
|
|
struct tcphdr *th;
|
|
struct tcphdr *th;
|
|
|
|
+ struct ipv6hdr *hdr;
|
|
struct sock *sk;
|
|
struct sock *sk;
|
|
int ret;
|
|
int ret;
|
|
struct net *net = dev_net(skb->dev);
|
|
struct net *net = dev_net(skb->dev);
|
|
@@ -1704,12 +1710,13 @@ static int tcp_v6_rcv(struct sk_buff *skb)
|
|
goto bad_packet;
|
|
goto bad_packet;
|
|
|
|
|
|
th = tcp_hdr(skb);
|
|
th = tcp_hdr(skb);
|
|
|
|
+ hdr = ipv6_hdr(skb);
|
|
TCP_SKB_CB(skb)->seq = ntohl(th->seq);
|
|
TCP_SKB_CB(skb)->seq = ntohl(th->seq);
|
|
TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
|
|
TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
|
|
skb->len - th->doff*4);
|
|
skb->len - th->doff*4);
|
|
TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
|
|
TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
|
|
TCP_SKB_CB(skb)->when = 0;
|
|
TCP_SKB_CB(skb)->when = 0;
|
|
- TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
|
|
|
|
|
|
+ TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(hdr);
|
|
TCP_SKB_CB(skb)->sacked = 0;
|
|
TCP_SKB_CB(skb)->sacked = 0;
|
|
|
|
|
|
sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
|
|
sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
|
|
@@ -1720,6 +1727,11 @@ process:
|
|
if (sk->sk_state == TCP_TIME_WAIT)
|
|
if (sk->sk_state == TCP_TIME_WAIT)
|
|
goto do_time_wait;
|
|
goto do_time_wait;
|
|
|
|
|
|
|
|
+ if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) {
|
|
|
|
+ NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
|
|
|
|
+ goto discard_and_relse;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
|
|
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
|
|
goto discard_and_relse;
|
|
goto discard_and_relse;
|
|
|
|
|