Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd081e4b authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ipv6-better-traceroute-sit-gre'



Eric Dumazet says:

====================
ipv6: better traceroute support in sit and gre

In commit ca15a078 ("sit: generate icmpv6 error when receiving icmpv4
error"), Oussama Ghorbel added minimal support for SIT tunnels to
generate ICMPv6 messages when receiving ICMPv4 messages.

This patch series extends this to GRE tunnels.

It also adds support for ICMPV6_TIME_EXCEED.

Partial support for RFC 4884 is added, to forward ICMP Multi-part
extensions eventually found in the ICMPv4 message.

v2: replaced an overlapping memcpy() by memmove()
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents adc01582 20e1954f
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -14,9 +14,12 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
#if IS_ENABLED(CONFIG_IPV6)
#if IS_ENABLED(CONFIG_IPV6)
extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);


typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info);
typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
			     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 type,
			       unsigned int data_len);


#else
#else


+1 −0
Original line number Original line Diff line number Diff line
@@ -157,6 +157,7 @@ struct tnl_ptk_info {
	__be16 proto;
	__be16 proto;
	__be32 key;
	__be32 key;
	__be32 seq;
	__be32 seq;
	int hdr_len;
};
};


#define PACKET_RCVD	0
#define PACKET_RCVD	0
+1 −0
Original line number Original line Diff line number Diff line
@@ -79,6 +79,7 @@ struct icmphdr {
		__be16	__unused;
		__be16	__unused;
		__be16	mtu;
		__be16	mtu;
	} frag;
	} frag;
	__u8	reserved[4];
  } un;
  } un;
};
};


+1 −0
Original line number Original line Diff line number Diff line
@@ -117,6 +117,7 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
		if ((*(u8 *)options & 0xF0) != 0x40)
		if ((*(u8 *)options & 0xF0) != 0x40)
			hdr_len += 4;
			hdr_len += 4;
	}
	}
	tpi->hdr_len = hdr_len;
	return hdr_len;
	return hdr_len;
}
}
EXPORT_SYMBOL(gre_parse_header);
EXPORT_SYMBOL(gre_parse_header);
+9 −0
Original line number Original line Diff line number Diff line
@@ -144,6 +144,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
	const struct iphdr *iph;
	const struct iphdr *iph;
	const int type = icmp_hdr(skb)->type;
	const int type = icmp_hdr(skb)->type;
	const int code = icmp_hdr(skb)->code;
	const int code = icmp_hdr(skb)->code;
	unsigned int data_len = 0;
	struct ip_tunnel *t;
	struct ip_tunnel *t;


	switch (type) {
	switch (type) {
@@ -169,6 +170,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
	case ICMP_TIME_EXCEEDED:
	case ICMP_TIME_EXCEEDED:
		if (code != ICMP_EXC_TTL)
		if (code != ICMP_EXC_TTL)
			return;
			return;
		data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */
		break;
		break;


	case ICMP_REDIRECT:
	case ICMP_REDIRECT:
@@ -187,6 +189,13 @@ static void ipgre_err(struct sk_buff *skb, u32 info,
	if (!t)
	if (!t)
		return;
		return;


#if IS_ENABLED(CONFIG_IPV6)
       if (tpi->proto == htons(ETH_P_IPV6) &&
           !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len,
				       type, data_len))
               return;
#endif

	if (t->parms.iph.daddr == 0 ||
	if (t->parms.iph.daddr == 0 ||
	    ipv4_is_multicast(t->parms.iph.daddr))
	    ipv4_is_multicast(t->parms.iph.daddr))
		return;
		return;
Loading