aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2016-06-19 00:52:04 -0400
committerDavid S. Miller <davem@davemloft.net>2016-06-19 01:11:39 -0400
commit2d7a3b276be2d032a6c1a48ced87a474327ee3d3 (patch)
tree7ec3681b46b8aa456e987f7b0248dd94abafddb6 /net/ipv6
parent5fbba8ac9358f1e796c8aedcccc3487364643723 (diff)
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/ipv6')
-rw-r--r--net/ipv6/icmp.c12
-rw-r--r--net/ipv6/sit.c6
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)
564 * Either an IPv4 header for SIT encap 564 * Either an IPv4 header for SIT encap
565 * an IPv4 header + GRE header for GRE encap 565 * an IPv4 header + GRE header for GRE encap
566 */ 566 */
567int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs) 567int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type)
568{ 568{
569 struct in6_addr temp_saddr;
569 struct rt6_info *rt; 570 struct rt6_info *rt;
570 struct sk_buff *skb2; 571 struct sk_buff *skb2;
571 572
@@ -586,8 +587,13 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs)
586 if (rt && rt->dst.dev) 587 if (rt && rt->dst.dev)
587 skb2->dev = rt->dst.dev; 588 skb2->dev = rt->dst.dev;
588 589
589 icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); 590 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &temp_saddr);
590 591 if (type == ICMP_TIME_EXCEEDED)
592 icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
593 0, &temp_saddr);
594 else
595 icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH,
596 0, &temp_saddr);
591 if (rt) 597 if (rt)
592 ip6_rt_put(rt); 598 ip6_rt_put(rt);
593 599
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)
535 goto out; 535 goto out;
536 } 536 }
537 537
538 if (t->parms.iph.daddr == 0) 538 err = 0;
539 if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type))
539 goto out; 540 goto out;
540 541
541 err = 0; 542 if (t->parms.iph.daddr == 0)
542 if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4))
543 goto out; 543 goto out;
544 544
545 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 545 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)