Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 194323
b: refs/heads/master
c: e802af9
h: refs/heads/master
i:
  194321: 8ef6832
  194319: 77b81de
v: v3
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Apr 22, 2010
1 parent 3b5fb03 commit 8b656c2
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9ccb8975940c4ee51161152e37058e3d9e06c62f
refs/heads/master: e802af9cabb011f09b9c19a82faef3dd315f27eb
3 changes: 3 additions & 0 deletions trunk/include/linux/in6.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ struct in6_flowlabel_req {
#define IPV6_PREFER_SRC_CGA 0x0008
#define IPV6_PREFER_SRC_NONCGA 0x0800

/* RFC5082: Generalized Ttl Security Mechanism */
#define IPV6_MINHOPCOUNT 73

/*
* Multicast Routing:
* see include/linux/mroute6.h.
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ struct ipv6_pinfo {
* 010: prefer public address
* 100: prefer care-of address
*/
__u8 min_hopcount;
__u8 tclass;

__u32 dst_cookie;
Expand Down
12 changes: 12 additions & 0 deletions trunk/net/ipv6/ipv6_sockglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,

break;
}
case IPV6_MINHOPCOUNT:
if (optlen < sizeof(int))
goto e_inval;
if (val < 0 || val > 255)
goto e_inval;
np->min_hopcount = val;
retv = 0;
break;
}

release_sock(sk);
Expand Down Expand Up @@ -1116,6 +1124,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
val |= IPV6_PREFER_SRC_HOME;
break;

case IPV6_MINHOPCOUNT:
val = np->min_hopcount;
break;

default:
return -ENOPROTOOPT;
}
Expand Down
14 changes: 13 additions & 1 deletion trunk/net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,11 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
if (sk->sk_state == TCP_CLOSE)
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);
seq = ntohl(th->seq);
if (sk->sk_state != TCP_LISTEN &&
Expand Down Expand Up @@ -1678,6 +1683,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
static int tcp_v6_rcv(struct sk_buff *skb)
{
struct tcphdr *th;
struct ipv6hdr *hdr;
struct sock *sk;
int ret;
struct net *net = dev_net(skb->dev);
Expand All @@ -1704,12 +1710,13 @@ static int tcp_v6_rcv(struct sk_buff *skb)
goto bad_packet;

th = tcp_hdr(skb);
hdr = ipv6_hdr(skb);
TCP_SKB_CB(skb)->seq = ntohl(th->seq);
TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
skb->len - th->doff*4);
TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
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;

sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
Expand All @@ -1720,6 +1727,11 @@ static int tcp_v6_rcv(struct sk_buff *skb)
if (sk->sk_state == TCP_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))
goto discard_and_relse;

Expand Down

0 comments on commit 8b656c2

Please sign in to comment.