diff mbox series

[7/7] netconfig: Control optimistic DAD

Message ID 20220919133105.3129080-7-andrew.zaborowski@intel.com (mailing list archive)
State Accepted, archived
Headers show
Series [1/7] icmp6: Save SLAAC prefixes from RAs | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success

Commit Message

Andrew Zaborowski Sept. 19, 2022, 1:31 p.m. UTC
Enable or disable optimistic DAD for the interface using /proc.  Add
l_netconfig_set_optimistic_dad_enabled() for the user to request that
RFC 4429 optimistic DAD be enabled.  As recommended in the RFC, we'll
only actually enable optimistic DAD for the automatic address generation
methods and disable it if a static IPv6 address is configured.  The
default if l_netconfig_set_optimistic_dad_enabled() isn't used is to
disable optimistic DAD always.

Optimistic DAD can shorten practical IPv6 setup time by an amount on
the order of a second by allowing the link-local address and the global
address to be used immediately after being generated.  For the
link-local address this means that DHCPv6 may start sooner and
for the global address, which is added to the kernel by the
L_NETCONFIG_EVENT_CONFIGURE event handler, the user can start
establishing connections sooner.  With DHCPv6 and some luck the two
savings may compound, with SLAAC only the global address's DAD time
should matter.
---
 ell/ell.sym     |  1 +
 ell/netconfig.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 ell/netconfig.h |  2 ++
 3 files changed, 51 insertions(+), 1 deletion(-)

Comments

Denis Kenzior Sept. 19, 2022, 6:43 p.m. UTC | #1
Hi Andrew,

On 9/19/22 08:31, Andrew Zaborowski wrote:
> Enable or disable optimistic DAD for the interface using /proc.  Add
> l_netconfig_set_optimistic_dad_enabled() for the user to request that
> RFC 4429 optimistic DAD be enabled.  As recommended in the RFC, we'll
> only actually enable optimistic DAD for the automatic address generation
> methods and disable it if a static IPv6 address is configured.  The
> default if l_netconfig_set_optimistic_dad_enabled() isn't used is to
> disable optimistic DAD always.
> 
> Optimistic DAD can shorten practical IPv6 setup time by an amount on
> the order of a second by allowing the link-local address and the global
> address to be used immediately after being generated.  For the
> link-local address this means that DHCPv6 may start sooner and
> for the global address, which is added to the kernel by the
> L_NETCONFIG_EVENT_CONFIGURE event handler, the user can start
> establishing connections sooner.  With DHCPv6 and some luck the two
> savings may compound, with SLAAC only the global address's DAD time
> should matter.
> ---
>   ell/ell.sym     |  1 +
>   ell/netconfig.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
>   ell/netconfig.h |  2 ++
>   3 files changed, 51 insertions(+), 1 deletion(-)
> 

I went ahead and applied all patches in this series.  Question:

> @@ -1724,7 +1737,8 @@ static void netconfig_ifaddr_ipv6_added(struct l_netconfig *nc,
>   	struct in6_addr in6;
>   	_auto_(l_free) char *ip = NULL;
>   
> -	if (ifa->ifa_flags & IFA_F_TENTATIVE)
> +	if ((ifa->ifa_flags & IFA_F_TENTATIVE) &&
> +			!(ifa->ifa_flags & IFA_F_OPTIMISTIC))
>   		return;

This implies that we set the link local address even if it is still OPTIMISTIC. 
  Do we now need to update icmp6_send_router_solicitation() logic to make sure 
we do not include SLLAO from optimistic addresses?

>   
>   	if (!nc->started)

Regards,
-Denis
Andrew Zaborowski Sept. 19, 2022, 11:56 p.m. UTC | #2
Hi Denis,

On Mon, 19 Sept 2022 at 20:59, Denis Kenzior <denkenz@gmail.com> wrote:
> > @@ -1724,7 +1737,8 @@ static void netconfig_ifaddr_ipv6_added(struct l_netconfig *nc,
> >       struct in6_addr in6;
> >       _auto_(l_free) char *ip = NULL;
> >
> > -     if (ifa->ifa_flags & IFA_F_TENTATIVE)
> > +     if ((ifa->ifa_flags & IFA_F_TENTATIVE) &&
> > +                     !(ifa->ifa_flags & IFA_F_OPTIMISTIC))
> >               return;
>
> This implies that we set the link local address even if it is still OPTIMISTIC.
>   Do we now need to update icmp6_send_router_solicitation() logic to make sure
> we do not include SLLAO from optimistic addresses?

Good point.  I'll add an extra l_icmp6_client_set_link_local_address()
parameter to indicate whether the address is optimistic and make sure
we call it again after DAD finishes.

Best regards
diff mbox series

Patch

diff --git a/ell/ell.sym b/ell/ell.sym
index d76b2ea..6df9024 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -751,6 +751,7 @@  global:
 	l_netconfig_set_dns_override;
 	l_netconfig_set_domain_names_override;
 	l_netconfig_set_acd_enabled;
+	l_netconfig_set_optimistic_dad_enabled;
 	l_netconfig_check_config;
 	l_netconfig_reset_config;
 	l_netconfig_start;
diff --git a/ell/netconfig.c b/ell/netconfig.c
index 3336b30..7a9ee89 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -76,6 +76,7 @@  struct l_netconfig {
 	char *v6_gateway_override;
 	char **v6_dns_override;
 	char **v6_domain_names_override;
+	bool optimistic_dad_enabled;
 
 	bool started;
 	struct l_idle *do_static_work;
@@ -89,6 +90,7 @@  struct l_netconfig {
 	struct l_queue *icmp_route_data;
 	struct l_acd *acd;
 	unsigned int orig_disable_ipv6;
+	unsigned int orig_optimistic_dad;
 	uint8_t mac[ETH_ALEN];
 	struct l_timeout *ra_timeout;
 	enum {
@@ -1490,6 +1492,17 @@  LIB_EXPORT bool l_netconfig_set_acd_enabled(struct l_netconfig *netconfig,
 	return true;
 }
 
+LIB_EXPORT bool l_netconfig_set_optimistic_dad_enabled(
+						struct l_netconfig *netconfig,
+						bool enabled)
+{
+	if (unlikely(!netconfig || netconfig->started))
+		return false;
+
+	netconfig->optimistic_dad_enabled = enabled;
+	return true;
+}
+
 static bool netconfig_check_family_config(struct l_netconfig *nc,
 						uint8_t family)
 {
@@ -1724,7 +1737,8 @@  static void netconfig_ifaddr_ipv6_added(struct l_netconfig *nc,
 	struct in6_addr in6;
 	_auto_(l_free) char *ip = NULL;
 
-	if (ifa->ifa_flags & IFA_F_TENTATIVE)
+	if ((ifa->ifa_flags & IFA_F_TENTATIVE) &&
+			!(ifa->ifa_flags & IFA_F_OPTIMISTIC))
 		return;
 
 	if (!nc->started)
@@ -1828,6 +1842,8 @@  static void netconfig_ifaddr_ipv6_dump_done_cb(void *user_data)
 
 LIB_EXPORT bool l_netconfig_start(struct l_netconfig *netconfig)
 {
+	bool optimistic_dad;
+
 	if (unlikely(!netconfig || netconfig->started))
 		return false;
 
@@ -1855,6 +1871,28 @@  configure_ipv6:
 	if (!netconfig->v6_enabled)
 		goto done;
 
+	/*
+	 * Enable optimistic DAD if the user has requested it *and* it is
+	 * recommended by RFC 4429 Section 3.1 for the address generation
+	 * method in use:
+	 *   * mac-based Interface ID such as EUI-64
+	 *   * random
+	 *   * well-distributed hash function
+	 *   * DHCPv6
+	 * i.e. all autoconfiguration methods.  In any other case disable
+	 * it.
+	 */
+	optimistic_dad = netconfig->optimistic_dad_enabled &&
+		!netconfig->v6_static_addr;
+	netconfig->orig_optimistic_dad =
+		netconfig_proc_read_ipv6_uint_setting(netconfig,
+							"optimistic_dad");
+
+	if (!!netconfig->orig_optimistic_dad != optimistic_dad)
+		netconfig_proc_write_ipv6_uint_setting(netconfig,
+							"optimistic_dad",
+							optimistic_dad ? 1 : 0);
+
 	if (netconfig->v6_static_addr) {
 		/*
 		 * We're basically ready to configure the interface
@@ -1944,6 +1982,8 @@  unregister:
 
 LIB_EXPORT void l_netconfig_stop(struct l_netconfig *netconfig)
 {
+	bool optimistic_dad;
+
 	if (unlikely(!netconfig || !netconfig->started))
 		return;
 
@@ -1985,6 +2025,13 @@  LIB_EXPORT void l_netconfig_stop(struct l_netconfig *netconfig)
 						netconfig->orig_disable_ipv6);
 		netconfig->orig_disable_ipv6 = 0;
 	}
+
+	optimistic_dad = netconfig->optimistic_dad_enabled &&
+		!netconfig->v6_static_addr;
+	if (!!netconfig->orig_optimistic_dad != optimistic_dad)
+		netconfig_proc_write_ipv6_uint_setting(netconfig,
+						"optimistic_dad",
+						netconfig->orig_optimistic_dad);
 }
 
 /*
diff --git a/ell/netconfig.h b/ell/netconfig.h
index fb3c536..3c024fe 100644
--- a/ell/netconfig.h
+++ b/ell/netconfig.h
@@ -69,6 +69,8 @@  bool l_netconfig_set_dns_override(struct l_netconfig *netconfig, uint8_t family,
 bool l_netconfig_set_domain_names_override(struct l_netconfig *netconfig,
 						uint8_t family, char **names);
 bool l_netconfig_set_acd_enabled(struct l_netconfig *netconfig, bool enabled);
+bool l_netconfig_set_optimistic_dad_enabled(struct l_netconfig *netconfig,
+						bool enabled);
 bool l_netconfig_check_config(struct l_netconfig *netconfig);
 bool l_netconfig_reset_config(struct l_netconfig *netconfig);