diff options
author | Eric Dumazet <edumazet@google.com> | 2016-06-18 21:52:04 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-18 22:11:39 -0700 |
commit | 2d7a3b276be2d032a6c1a48ced87a474327ee3d3 (patch) | |
tree | 7ec3681b46b8aa456e987f7b0248dd94abafddb6 /net | |
parent | 5fbba8ac9358f1e796c8aedcccc3487364643723 (diff) | |
download | linux-stable-2d7a3b276be2d032a6c1a48ced87a474327ee3d3.tar.gz linux-stable-2d7a3b276be2d032a6c1a48ced87a474327ee3d3.tar.bz2 linux-stable-2d7a3b276be2d032a6c1a48ced87a474327ee3d3.zip |
ipv6: translate ICMP_TIME_EXCEEDED to ICMPV6_TIME_EXCEED
For better traceroute/mtr support for SIT and GRE tunnels,
we translate IPV4 ICMP ICMP_TIME_EXCEEDED to ICMPV6_TIME_EXCEED
We also have to translate the IPv4 source IP address of ICMP
message to IPv6 v4mapped.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/icmp.c | 12 | ||||
-rw-r--r-- | net/ipv6/sit.c | 6 |
2 files changed, 12 insertions, 6 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 07bc63c23712..867aebc34248 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -564,8 +564,9 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos) * Either an IPv4 header for SIT encap * an IPv4 header + GRE header for GRE encap */ -int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs) +int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type) { + struct in6_addr temp_saddr; struct rt6_info *rt; struct sk_buff *skb2; @@ -586,8 +587,13 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs) if (rt && rt->dst.dev) skb2->dev = rt->dst.dev; - icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); - + ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr); + if (type == ICMP_TIME_EXCEEDED) + icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, + 0, &temp_saddr); + else + icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, + 0, &temp_saddr); if (rt) ip6_rt_put(rt); diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 78e84d6793ee..d7a36114eb50 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -535,11 +535,11 @@ static int ipip6_err(struct sk_buff *skb, u32 info) goto out; } - if (t->parms.iph.daddr == 0) + err = 0; + if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type)) goto out; - err = 0; - if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4)) + if (t->parms.iph.daddr == 0) goto out; if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) |