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

Merge branch 'icmp6-support-rfc-4884'



Willem de Bruijn says:

====================
icmp6: support rfc 4884

Extend the feature merged earlier this week for IPv4 to IPv6.

I expected this to be a single patch, but patch 1 seemed better to be
stand-alone

patch 1: small fix in length calculation
patch 2: factor out ipv4-specific
patch 3: add ipv6

changes v1->v2: add missing static keyword in patch 3
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 623b57be 01370434
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ static inline bool icmp_is_err(int type)
}

void ip_icmp_error_rfc4884(const struct sk_buff *skb,
			   struct sock_ee_data_rfc4884 *out);
			   struct sock_ee_data_rfc4884 *out,
			   int thlen, int off);

#endif	/* _LINUX_ICMP_H */
+1 −0
Original line number Diff line number Diff line
@@ -283,6 +283,7 @@ struct ipv6_pinfo {
				autoflowlabel:1,
				autoflowlabel_set:1,
				mc_all:1,
				recverr_rfc4884:1,
				rtalert_isolate:1;
	__u8			min_hopcount;
	__u8			tclass;
+1 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ struct icmp6hdr {
#define icmp6_mtu		icmp6_dataun.un_data32[0]
#define icmp6_unused		icmp6_dataun.un_data32[0]
#define icmp6_maxdelay		icmp6_dataun.un_data16[0]
#define icmp6_datagram_len	icmp6_dataun.un_data8[0]
#define icmp6_router		icmp6_dataun.u_nd_advt.router
#define icmp6_solicited		icmp6_dataun.u_nd_advt.solicited
#define icmp6_override		icmp6_dataun.u_nd_advt.override
+1 −0
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ struct in6_flowlabel_req {
#define IPV6_LEAVE_ANYCAST	28
#define IPV6_MULTICAST_ALL	29
#define IPV6_ROUTER_ALERT_ISOLATE	30
#define IPV6_RECVERR_RFC4884	31

/* IPV6_MTU_DISCOVER values */
#define IPV6_PMTUDISC_DONT		0
+7 −19
Original line number Diff line number Diff line
@@ -1151,29 +1151,16 @@ static bool ip_icmp_error_rfc4884_validate(const struct sk_buff *skb, int off)
}

void ip_icmp_error_rfc4884(const struct sk_buff *skb,
			   struct sock_ee_data_rfc4884 *out)
			   struct sock_ee_data_rfc4884 *out,
			   int thlen, int off)
{
	int hlen, off;
	int hlen;

	switch (icmp_hdr(skb)->type) {
	case ICMP_DEST_UNREACH:
	case ICMP_TIME_EXCEEDED:
	case ICMP_PARAMETERPROB:
		break;
	default:
		return;
	}

	/* outer headers up to inner iph. skb->data is at inner payload */
	hlen = -skb_transport_offset(skb) - sizeof(struct icmphdr);

	/* per rfc 791: maximum packet length of 576 bytes */
	if (hlen + skb->len > 576)
		return;
	/* original datagram headers: end of icmph to payload (skb->data) */
	hlen = -skb_transport_offset(skb) - thlen;

	/* per rfc 4884: minimal datagram length of 128 bytes */
	off = icmp_hdr(skb)->un.reserved[1] * sizeof(u32);
	if (off < 128)
	if (off < 128 || off < hlen)
		return;

	/* kernel has stripped headers: return payload offset in bytes */
@@ -1186,6 +1173,7 @@ void ip_icmp_error_rfc4884(const struct sk_buff *skb,
	if (!ip_icmp_error_rfc4884_validate(skb, off))
		out->flags |= SO_EE_RFC4884_FLAG_INVALID;
}
EXPORT_SYMBOL_GPL(ip_icmp_error_rfc4884);

int icmp_err(struct sk_buff *skb, u32 info)
{
Loading