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

Commit adc176c5 authored by Erik Nordmark's avatar Erik Nordmark Committed by David S. Miller
Browse files

ipv6 addrconf: Implemented enhanced DAD (RFC7527)



Implemented RFC7527 Enhanced DAD.
IPv6 duplicate address detection can fail if there is some temporary
loopback of Ethernet frames. RFC7527 solves this by including a random
nonce in the NS messages used for DAD, and if an NS is received with the
same nonce it is assumed to be a looped back DAD probe and is ignored.
RFC7527 is enabled by default. Can be disabled by setting both of
conf/{all,interface}/enhanced_dad to zero.

Signed-off-by: default avatarErik Nordmark <nordmark@arista.com>
Signed-off-by: default avatarBob Gilligan <gilligan@arista.com>
Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce84c7c6
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1734,6 +1734,15 @@ drop_unsolicited_na - BOOLEAN

	By default this is turned off.

enhanced_dad - BOOLEAN
	Include a nonce option in the IPv6 neighbor solicitation messages used for
	duplicate address detection per RFC7527. A received DAD NS will only signal
	a duplicate address if the nonce is different. This avoids any false
	detection of duplicates due to loopback of the NS messages that we send.
	The nonce option will be sent on an interface unless both of
	conf/{all,interface}/enhanced_dad are set to FALSE.
	Default: TRUE

icmp/*:
ratelimit - INTEGER
	Limit the maximal rates for sending ICMPv6 packets.
+1 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ struct ipv6_devconf {
#ifdef CONFIG_IPV6_SEG6_HMAC
	__s32		seg6_require_hmac;
#endif
	__u32		enhanced_dad;

	struct ctl_table_header *sysctl_header;
};
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ struct inet6_ifaddr {
	__u8			stable_privacy_retry;

	__u16			scope;
	__u64			dad_nonce;

	unsigned long		cstamp;	/* created timestamp */
	unsigned long		tstamp; /* updated timestamp */
+4 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ enum {
	ND_OPT_PREFIX_INFO = 3,		/* RFC2461 */
	ND_OPT_REDIRECT_HDR = 4,	/* RFC2461 */
	ND_OPT_MTU = 5,			/* RFC2461 */
	ND_OPT_NONCE = 14,              /* RFC7527 */
	__ND_OPT_ARRAY_MAX,
	ND_OPT_ROUTE_INFO = 24,		/* RFC4191 */
	ND_OPT_RDNSS = 25,		/* RFC5006 */
@@ -121,6 +122,7 @@ struct ndisc_options {
#define nd_opts_pi_end			nd_opt_array[__ND_OPT_PREFIX_INFO_END]
#define nd_opts_rh			nd_opt_array[ND_OPT_REDIRECT_HDR]
#define nd_opts_mtu			nd_opt_array[ND_OPT_MTU]
#define nd_opts_nonce			nd_opt_array[ND_OPT_NONCE]
#define nd_802154_opts_src_lladdr	nd_802154_opt_array[ND_OPT_SOURCE_LL_ADDR]
#define nd_802154_opts_tgt_lladdr	nd_802154_opt_array[ND_OPT_TARGET_LL_ADDR]

@@ -398,7 +400,8 @@ void ndisc_cleanup(void);
int ndisc_rcv(struct sk_buff *skb);

void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
		   const struct in6_addr *daddr, const struct in6_addr *saddr);
		   const struct in6_addr *daddr, const struct in6_addr *saddr,
		   u64 nonce);

void ndisc_send_rs(struct net_device *dev,
		   const struct in6_addr *saddr, const struct in6_addr *daddr);
+1 −0
Original line number Diff line number Diff line
@@ -181,6 +181,7 @@ enum {
	DEVCONF_RTR_SOLICIT_MAX_INTERVAL,
	DEVCONF_SEG6_ENABLED,
	DEVCONF_SEG6_REQUIRE_HMAC,
	DEVCONF_ENHANCED_DAD,
	DEVCONF_MAX
};

Loading