Commit 01370434 authored by Willem de Bruijn's avatar Willem de Bruijn Committed by David S. Miller
Browse files

icmp6: support rfc 4884



Extend the rfc 4884 read interface introduced for ipv4 in
commit eba75c58 ("icmp: support rfc 4884") to ipv6.

Add socket option SOL_IPV6/IPV6_RECVERR_RFC4884.

Changes v1->v2:
  - make ipv6_icmp_error_rfc4884 static (file scope)

Signed-off-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 178c49d9
Loading
Loading
Loading
Loading
+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
+1 −0
Original line number Diff line number Diff line
@@ -1173,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)
{
+16 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/route.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/icmp.h>

#include <net/ipv6.h>
#include <net/ndisc.h>
@@ -284,6 +285,17 @@ int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *uaddr,
}
EXPORT_SYMBOL_GPL(ip6_datagram_connect_v6_only);

static void ipv6_icmp_error_rfc4884(const struct sk_buff *skb,
				    struct sock_ee_data_rfc4884 *out)
{
	switch (icmp6_hdr(skb)->icmp6_type) {
	case ICMPV6_TIME_EXCEED:
	case ICMPV6_DEST_UNREACH:
		ip_icmp_error_rfc4884(skb, out, sizeof(struct icmp6hdr),
				      icmp6_hdr(skb)->icmp6_datagram_len * 8);
	}
}

void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
		     __be16 port, u32 info, u8 *payload)
{
@@ -313,6 +325,10 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
	serr->port = port;

	__skb_pull(skb, payload - skb->data);

	if (inet6_sk(sk)->recverr_rfc4884)
		ipv6_icmp_error_rfc4884(skb, &serr->ee.ee_rfc4884);

	skb_reset_transport_header(skb);

	if (sock_queue_err_skb(sk, skb))
Loading