mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-14 13:39:10 +00:00
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>
This commit is contained in:
parent
5fbba8ac93
commit
2d7a3b276b
@ -18,7 +18,7 @@ typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
|
|||||||
const struct in6_addr *force_saddr);
|
const struct in6_addr *force_saddr);
|
||||||
extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
|
extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
|
||||||
extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
|
extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
|
||||||
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);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -564,8 +564,9 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
|
|||||||
* Either an IPv4 header for SIT encap
|
* Either an IPv4 header for SIT encap
|
||||||
* an IPv4 header + GRE header for GRE 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 rt6_info *rt;
|
||||||
struct sk_buff *skb2;
|
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)
|
if (rt && rt->dst.dev)
|
||||||
skb2->dev = 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)
|
if (rt)
|
||||||
ip6_rt_put(rt);
|
ip6_rt_put(rt);
|
||||||
|
|
||||||
|
@ -535,11 +535,11 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->parms.iph.daddr == 0)
|
err = 0;
|
||||||
|
if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err = 0;
|
if (t->parms.iph.daddr == 0)
|
||||||
if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
|
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user