All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 03/13] netconfig: Create routes from Router Advertisements
@ 2022-05-13 13:39 Denis Kenzior
  0 siblings, 0 replies; 4+ messages in thread
From: Denis Kenzior @ 2022-05-13 13:39 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 343 bytes --]

Hi Andrew,

>> Ugh, can we use l_queue_get_entries loop directly or a helper function instead?
> 
> Ok.  We could also add a l_queue_match_ptr in queue.h since IIRC we
> also have a copy in IWD.
> 

I don't like the idea of adding a matching function for comparing pointers.  How 
about l_queue_find_ptr() instead?

Regards,
-Denis

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 03/13] netconfig: Create routes from Router Advertisements
@ 2022-05-13 12:46 Andrew Zaborowski
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Zaborowski @ 2022-05-13 12:46 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 6136 bytes --]

On Thu, 12 May 2022 at 18:14, Denis Kenzior <denkenz(a)gmail.com> wrote:
> On 5/5/22 18:15, Andrew Zaborowski wrote:
> > +static bool netconfig_match_ptr(const void *a, const void *b)
> > +{
> > +     return a == b;
> > +}
> > +
>
> Ugh, can we use l_queue_get_entries loop directly or a helper function instead?

Ok.  We could also add a l_queue_match_ptr in queue.h since IIRC we
also have a copy in IWD.

>
> >   static void netconfig_update_cleanup(struct l_netconfig *nc)
> >   {
> >       l_queue_clear(nc->addresses.added, NULL);
> > @@ -356,6 +367,224 @@ static void netconfig_dhcp_event_handler(struct l_dhcp_client *client,
> >       }
> >   }
> >
> > +static struct l_rtnl_route *netconfig_find_icmp6_route(
> > +                                             struct l_netconfig *nc,
> > +                                             const uint8_t *gateway,
> > +                                             const struct route_info *dst)
> > +{
> > +     const struct l_queue_entry *entry;
> > +
> > +     for (entry = l_queue_get_entries(nc->routes.current); entry;
> > +                     entry = entry->next) {
> > +             struct l_rtnl_route *route = entry->data;
> > +             const uint8_t *route_gateway;
> > +             const uint8_t *route_dst;
> > +             uint8_t route_prefix_len = 0;
> > +
> > +             if (l_rtnl_route_get_family(route) != AF_INET6 ||
> > +                             l_rtnl_route_get_protocol(route) != RTPROT_RA)
> > +                     continue;
> > +
> > +             route_gateway = l_rtnl_route_get_gateway_in_addr(route);
> > +             if ((gateway || route_gateway) &&
> > +                             (!gateway || !route_gateway ||
> > +                              memcmp(gateway, route_gateway, 16)))
> > +                     continue;
> > +
> > +             route_dst = l_rtnl_route_get_dst_in_addr(route,
> > +                                                     &route_prefix_len);
> > +             if ((dst || route_prefix_len) &&
> > +                             (!dst || !route_prefix_len ||
> > +                              dst->prefix_len != route_prefix_len ||
> > +                              memcmp(dst->address, route_dst,
> > +                                      (dst->prefix_len + 7) / 8)))
>
> This might need a utility function, something like l_net_prefix_matches?

Well this could just be switched to l_net_prefix_matches() but since
we know the host bits of the address (interface ID) are zero, let me
just memcmp() the 16 bytes.

>
> > +                     continue;
> > +
> > +             return route;
> > +     }
> > +
> > +     return NULL;
> > +}
> > +
> > +static struct l_rtnl_route *netconfig_add_icmp6_route(struct l_netconfig *nc,
> > +                                             const uint8_t *gateway,
> > +                                             const struct route_info *dst,
> > +                                             uint8_t preference)
> > +{
> > +     struct l_rtnl_route *rt;
> > +     char buf1[INET6_ADDRSTRLEN];
> > +     char buf2[INET6_ADDRSTRLEN];
> > +
> > +     if (gateway && !dst)
> > +             rt = l_rtnl_route_new_gateway(inet_ntop(AF_INET6, gateway,
> > +                                                     buf1, sizeof(buf1)));
> > +     else if (dst && !gateway)
> > +             rt = l_rtnl_route_new_prefix(inet_ntop(AF_INET6, dst->address,
> > +                                                     buf2, sizeof(buf2)),
> > +                                             dst->prefix_len);
> > +     else
> > +             rt = l_rtnl_route_new_static(inet_ntop(AF_INET6, gateway,
> > +                                                     buf1, sizeof(buf1)),
> > +                                             inet_ntop(AF_INET6,
> > +                                                     dst->address,
> > +                                                     buf2, sizeof(buf2)),
> > +                                             dst->prefix_len);
>
> We can move l_rtnl_route structure definition into rtnl-private.h if you prefer
> to fill these in directly?

Ok.

>
> > +
> > +     if (L_WARN_ON(!rt))
> > +             return NULL;
> > +
> > +     l_rtnl_route_set_preference(rt, preference);
> > +     l_rtnl_route_set_protocol(rt, RTPROT_RA);
> > +     l_rtnl_route_set_priority(rt, nc->route_priority);
> > +     l_queue_push_tail(nc->routes.current, rt);
> > +     l_queue_push_tail(nc->routes.added, rt);
> > +     return rt;
> > +}
> > +
>
> <snip>
>
> > @@ -398,6 +634,7 @@ LIB_EXPORT void l_netconfig_destroy(struct l_netconfig *netconfig)
> >       l_netconfig_set_domain_names_override(netconfig, AF_INET6, NULL);
> >
> >       l_dhcp_client_destroy(netconfig->dhcp_client);
> > +     l_dhcp6_client_destroy(netconfig->dhcp6_client);
> >       l_netconfig_set_event_handler(netconfig, NULL, NULL, NULL);
> >       l_queue_destroy(netconfig->addresses.current, NULL);
> >       l_queue_destroy(netconfig->addresses.added, NULL);
> > @@ -731,16 +968,22 @@ configure_ipv6:
> >       if (!netconfig->v6_enabled)
> >               goto done;
> >
> > -     if (netconfig->v6_static_addr && !netconfig->do_static_work) {
> > +     if (netconfig->v6_static_addr) {
> >               /*
> >                * We're basically ready to configure the interface
> >                * but do this in an idle callback.
> >                */
> > -             netconfig->do_static_work = l_idle_create(
> > +             if (!netconfig->do_static_work)
> > +                     netconfig->do_static_work = l_idle_create(
> >                                               netconfig_do_static_config,
> >                                               netconfig, NULL);
> > +
> > +             goto done;
> >       }
> >
> > +     if (!l_dhcp6_client_start(netconfig->dhcp6_client))
> > +             return false;
>
> What about the dhcp4 client started earlier?

Good point, I'll add proper cleanup for this.

Best regards

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 03/13] netconfig: Create routes from Router Advertisements
@ 2022-05-12 16:14 Denis Kenzior
  0 siblings, 0 replies; 4+ messages in thread
From: Denis Kenzior @ 2022-05-12 16:14 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 4622 bytes --]

Hi Andrew,

On 5/5/22 18:15, Andrew Zaborowski wrote:
> If IPv6 is enabled, create the ICMP6 client and handle Router
> Advertisements received by creating, updating and removing routes per
> the data in the Router Advertisements.  Timeouts aren't handled yet.
> ---
>   ell/netconfig.c | 248 +++++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 246 insertions(+), 2 deletions(-)
> 

<snip>

>   
> +static bool netconfig_match_ptr(const void *a, const void *b)
> +{
> +	return a == b;
> +}
> +

Ugh, can we use l_queue_get_entries loop directly or a helper function instead?

>   static void netconfig_update_cleanup(struct l_netconfig *nc)
>   {
>   	l_queue_clear(nc->addresses.added, NULL);
> @@ -356,6 +367,224 @@ static void netconfig_dhcp_event_handler(struct l_dhcp_client *client,
>   	}
>   }
>   
> +static struct l_rtnl_route *netconfig_find_icmp6_route(
> +						struct l_netconfig *nc,
> +						const uint8_t *gateway,
> +						const struct route_info *dst)
> +{
> +	const struct l_queue_entry *entry;
> +
> +	for (entry = l_queue_get_entries(nc->routes.current); entry;
> +			entry = entry->next) {
> +		struct l_rtnl_route *route = entry->data;
> +		const uint8_t *route_gateway;
> +		const uint8_t *route_dst;
> +		uint8_t route_prefix_len = 0;
> +
> +		if (l_rtnl_route_get_family(route) != AF_INET6 ||
> +				l_rtnl_route_get_protocol(route) != RTPROT_RA)
> +			continue;
> +
> +		route_gateway = l_rtnl_route_get_gateway_in_addr(route);
> +		if ((gateway || route_gateway) &&
> +				(!gateway || !route_gateway ||
> +				 memcmp(gateway, route_gateway, 16)))
> +			continue;
> +
> +		route_dst = l_rtnl_route_get_dst_in_addr(route,
> +							&route_prefix_len);
> +		if ((dst || route_prefix_len) &&
> +				(!dst || !route_prefix_len ||
> +				 dst->prefix_len != route_prefix_len ||
> +				 memcmp(dst->address, route_dst,
> +					 (dst->prefix_len + 7) / 8)))

This might need a utility function, something like l_net_prefix_matches?

> +			continue;
> +
> +		return route;
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct l_rtnl_route *netconfig_add_icmp6_route(struct l_netconfig *nc,
> +						const uint8_t *gateway,
> +						const struct route_info *dst,
> +						uint8_t preference)
> +{
> +	struct l_rtnl_route *rt;
> +	char buf1[INET6_ADDRSTRLEN];
> +	char buf2[INET6_ADDRSTRLEN];
> +
> +	if (gateway && !dst)
> +		rt = l_rtnl_route_new_gateway(inet_ntop(AF_INET6, gateway,
> +							buf1, sizeof(buf1)));
> +	else if (dst && !gateway)
> +		rt = l_rtnl_route_new_prefix(inet_ntop(AF_INET6, dst->address,
> +							buf2, sizeof(buf2)),
> +						dst->prefix_len);
> +	else
> +		rt = l_rtnl_route_new_static(inet_ntop(AF_INET6, gateway,
> +							buf1, sizeof(buf1)),
> +						inet_ntop(AF_INET6,
> +							dst->address,
> +							buf2, sizeof(buf2)),
> +						dst->prefix_len);

We can move l_rtnl_route structure definition into rtnl-private.h if you prefer 
to fill these in directly?

> +
> +	if (L_WARN_ON(!rt))
> +		return NULL;
> +
> +	l_rtnl_route_set_preference(rt, preference);
> +	l_rtnl_route_set_protocol(rt, RTPROT_RA);
> +	l_rtnl_route_set_priority(rt, nc->route_priority);
> +	l_queue_push_tail(nc->routes.current, rt);
> +	l_queue_push_tail(nc->routes.added, rt);
> +	return rt;
> +}
> +

<snip>

> @@ -398,6 +634,7 @@ LIB_EXPORT void l_netconfig_destroy(struct l_netconfig *netconfig)
>   	l_netconfig_set_domain_names_override(netconfig, AF_INET6, NULL);
>   
>   	l_dhcp_client_destroy(netconfig->dhcp_client);
> +	l_dhcp6_client_destroy(netconfig->dhcp6_client);
>   	l_netconfig_set_event_handler(netconfig, NULL, NULL, NULL);
>   	l_queue_destroy(netconfig->addresses.current, NULL);
>   	l_queue_destroy(netconfig->addresses.added, NULL);
> @@ -731,16 +968,22 @@ configure_ipv6:
>   	if (!netconfig->v6_enabled)
>   		goto done;
>   
> -	if (netconfig->v6_static_addr && !netconfig->do_static_work) {
> +	if (netconfig->v6_static_addr) {
>   		/*
>   		 * We're basically ready to configure the interface
>   		 * but do this in an idle callback.
>   		 */
> -		netconfig->do_static_work = l_idle_create(
> +		if (!netconfig->do_static_work)
> +			netconfig->do_static_work = l_idle_create(
>   						netconfig_do_static_config,
>   						netconfig, NULL);
> +
> +		goto done;
>   	}
>   
> +	if (!l_dhcp6_client_start(netconfig->dhcp6_client))
> +		return false;

What about the dhcp4 client started earlier?

> +
>   done:
>   	netconfig->started = true;
>   	return true;

<snip>

Regards,
-Denis

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 03/13] netconfig: Create routes from Router Advertisements
@ 2022-05-05 23:15 Andrew Zaborowski
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Zaborowski @ 2022-05-05 23:15 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 10532 bytes --]

If IPv6 is enabled, create the ICMP6 client and handle Router
Advertisements received by creating, updating and removing routes per
the data in the Router Advertisements.  Timeouts aren't handled yet.
---
 ell/netconfig.c | 248 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 246 insertions(+), 2 deletions(-)

diff --git a/ell/netconfig.c b/ell/netconfig.c
index 6736913..81cca82 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -27,12 +27,16 @@
 #include <linux/types.h>
 #include <netinet/ip.h>
 #include <arpa/inet.h>
+#include <netinet/icmp6.h>
 
 #include "private.h"
 #include "useful.h"
 #include "log.h"
 #include "dhcp.h"
 #include "dhcp-private.h"
+#include "icmp6.h"
+#include "icmp6-private.h"
+#include "dhcp6.h"
 #include "netlink.h"
 #include "rtnl.h"
 #include "queue.h"
@@ -63,6 +67,8 @@ struct l_netconfig {
 	bool v4_configured;
 	struct l_dhcp_client *dhcp_client;
 	bool v6_configured;
+	struct l_icmp6_client *icmp6_client;
+	struct l_dhcp6_client *dhcp6_client;
 
 	/* These objects, if not NULL, are owned by @addresses and @routes */
 	struct l_rtnl_address *v4_address;
@@ -101,6 +107,11 @@ union netconfig_addr {
 	struct in6_addr v6;
 };
 
+static bool netconfig_match_ptr(const void *a, const void *b)
+{
+	return a == b;
+}
+
 static void netconfig_update_cleanup(struct l_netconfig *nc)
 {
 	l_queue_clear(nc->addresses.added, NULL);
@@ -356,6 +367,224 @@ static void netconfig_dhcp_event_handler(struct l_dhcp_client *client,
 	}
 }
 
+static struct l_rtnl_route *netconfig_find_icmp6_route(
+						struct l_netconfig *nc,
+						const uint8_t *gateway,
+						const struct route_info *dst)
+{
+	const struct l_queue_entry *entry;
+
+	for (entry = l_queue_get_entries(nc->routes.current); entry;
+			entry = entry->next) {
+		struct l_rtnl_route *route = entry->data;
+		const uint8_t *route_gateway;
+		const uint8_t *route_dst;
+		uint8_t route_prefix_len = 0;
+
+		if (l_rtnl_route_get_family(route) != AF_INET6 ||
+				l_rtnl_route_get_protocol(route) != RTPROT_RA)
+			continue;
+
+		route_gateway = l_rtnl_route_get_gateway_in_addr(route);
+		if ((gateway || route_gateway) &&
+				(!gateway || !route_gateway ||
+				 memcmp(gateway, route_gateway, 16)))
+			continue;
+
+		route_dst = l_rtnl_route_get_dst_in_addr(route,
+							&route_prefix_len);
+		if ((dst || route_prefix_len) &&
+				(!dst || !route_prefix_len ||
+				 dst->prefix_len != route_prefix_len ||
+				 memcmp(dst->address, route_dst,
+					 (dst->prefix_len + 7) / 8)))
+			continue;
+
+		return route;
+	}
+
+	return NULL;
+}
+
+static struct l_rtnl_route *netconfig_add_icmp6_route(struct l_netconfig *nc,
+						const uint8_t *gateway,
+						const struct route_info *dst,
+						uint8_t preference)
+{
+	struct l_rtnl_route *rt;
+	char buf1[INET6_ADDRSTRLEN];
+	char buf2[INET6_ADDRSTRLEN];
+
+	if (gateway && !dst)
+		rt = l_rtnl_route_new_gateway(inet_ntop(AF_INET6, gateway,
+							buf1, sizeof(buf1)));
+	else if (dst && !gateway)
+		rt = l_rtnl_route_new_prefix(inet_ntop(AF_INET6, dst->address,
+							buf2, sizeof(buf2)),
+						dst->prefix_len);
+	else
+		rt = l_rtnl_route_new_static(inet_ntop(AF_INET6, gateway,
+							buf1, sizeof(buf1)),
+						inet_ntop(AF_INET6,
+							dst->address,
+							buf2, sizeof(buf2)),
+						dst->prefix_len);
+
+	if (L_WARN_ON(!rt))
+		return NULL;
+
+	l_rtnl_route_set_preference(rt, preference);
+	l_rtnl_route_set_protocol(rt, RTPROT_RA);
+	l_rtnl_route_set_priority(rt, nc->route_priority);
+	l_queue_push_tail(nc->routes.current, rt);
+	l_queue_push_tail(nc->routes.added, rt);
+	return rt;
+}
+
+static void netconfig_set_icmp6_route_data(struct l_netconfig *nc,
+						struct l_rtnl_route *rt,
+						uint64_t start_time,
+						uint32_t preferred_lifetime,
+						uint32_t valid_lifetime,
+						uint32_t mtu, bool updated)
+{
+	uint64_t expiry = start_time + valid_lifetime * L_USEC_PER_SEC;
+	uint64_t old_expiry = l_rtnl_route_get_expiry(rt);
+	bool differs = false;
+
+	if (mtu != l_rtnl_route_get_mtu(rt)) {
+		l_rtnl_route_set_mtu(rt, mtu);
+		differs = true;
+	}
+
+	/*
+	 * valid_lifetime of 0 from a route_info means the route is being
+	 * removed so we wouldn't be here.  valid_lifetime of 0xffffffff
+	 * means no timeout.  Check if the lifetime is changing between
+	 * finite and infinite, or two finite values that result in expiry
+	 * time difference of more than a second -- to avoid emitting
+	 * updates for changes resulting only from the valid_lifetime one
+	 * second resolution and RA transmission jitter.  As FC4861
+	 * Section 6.2.7 puts it: "Due to link propagation delays and
+	 * potentially poorly synchronized clocks between the routers such
+	 * comparison SHOULD allow some time skew."  The RFC talks about
+	 * routers processing one another's RAs but the same logic applies
+	 * here.
+	 */
+	if (valid_lifetime == 0xffffffff)
+		expiry = 0;
+
+	if ((expiry || old_expiry) &&
+			(!expiry || !old_expiry ||
+			 l_time_diff(expiry, old_expiry) > L_USEC_PER_SEC)) {
+		l_rtnl_route_set_lifetime(rt, valid_lifetime);
+		l_rtnl_route_set_expiry(rt, expiry);
+		differs = true;
+	}
+
+	if (updated && differs &&
+			!l_queue_find(nc->routes.added, netconfig_match_ptr,
+					rt))
+		l_queue_push_tail(nc->routes.updated, rt);
+}
+
+static void netconfig_remove_icmp6_route(struct l_netconfig *nc,
+						struct l_rtnl_route *route)
+{
+	l_queue_remove(nc->routes.current, route);
+	l_queue_push_tail(nc->routes.removed, route);
+}
+
+static void netconfig_icmp6_event_handler(struct l_icmp6_client *client,
+						enum l_icmp6_client_event event,
+						void *event_data,
+						void *user_data)
+{
+	struct l_netconfig *nc = user_data;
+	const struct l_icmp6_router *r;
+	struct l_rtnl_route *default_route;
+	unsigned int i;
+
+	if (event != L_ICMP6_CLIENT_EVENT_ROUTER_FOUND)
+		return;
+
+	r = event_data;
+
+	/*
+	 * Note: If this is the first RA received, the l_dhcp6_client
+	 * will have received the event before us and will be acting
+	 * on it by now.
+	 */
+
+	if (nc->v4_gateway_override)
+		return;
+
+	/* Process the default gateway information */
+	default_route = netconfig_find_icmp6_route(nc, r->address, NULL);
+
+	if (!default_route && r->lifetime) {
+		default_route = netconfig_add_icmp6_route(nc, r->address, NULL,
+								r->pref);
+		if (unlikely(!default_route))
+			return;
+
+		/*
+		 * r->lifetime is 16-bit only so there's no risk it gets
+		 * confused for the special 0xffffffff value in
+		 * netconfig_set_icmp6_route_data.
+		 */
+		netconfig_set_icmp6_route_data(nc, default_route, r->start_time,
+						r->lifetime, r->lifetime,
+						r->mtu, false);
+	} else if (default_route && r->lifetime)
+		netconfig_set_icmp6_route_data(nc, default_route, r->start_time,
+						r->lifetime, r->lifetime,
+						r->mtu, true);
+	else if (default_route && !r->lifetime)
+		netconfig_remove_icmp6_route(nc, default_route);
+
+	/*
+	 * Process the onlink and offlink routes, from the Router
+	 * Advertisement's Prefix Information options and Route
+	 * Information options respectively.
+	 */
+	for (i = 0; i < r->n_routes; i++) {
+		const struct route_info *info = &r->routes[i];
+		const uint8_t *gateway = info->onlink ? NULL : r->address;
+		struct l_rtnl_route *route =
+			netconfig_find_icmp6_route(nc, gateway, info);
+
+		if (!route && info->valid_lifetime) {
+			route = netconfig_add_icmp6_route(nc, gateway, info,
+							info->preference);
+			if (unlikely(!route))
+				continue;
+
+			netconfig_set_icmp6_route_data(nc, route, r->start_time,
+						info->preferred_lifetime,
+						info->valid_lifetime,
+						gateway ? r->mtu : 0, false);
+		} else if (route && info->valid_lifetime)
+			netconfig_set_icmp6_route_data(nc, route, r->start_time,
+						info->preferred_lifetime,
+						info->valid_lifetime,
+						gateway ? r->mtu : 0, true);
+		else if (route && !info->valid_lifetime)
+			netconfig_remove_icmp6_route(nc, route);
+	}
+
+	/*
+	 * Note: we may be emitting this before L_NETCONFIG_EVENT_CONFIGURE.
+	 * We should probably instead save the affected routes in separate
+	 * lists and add them to the _CONFIGURE event, suppressing any _UPDATE
+	 * events while nc->v6_configured is false.
+	 */
+	if (!l_queue_isempty(nc->routes.added) ||
+			!l_queue_isempty(nc->routes.updated) ||
+			!l_queue_isempty(nc->routes.removed))
+		netconfig_emit_event(nc, AF_INET6, L_NETCONFIG_EVENT_UPDATE);
+}
+
 LIB_EXPORT struct l_netconfig *l_netconfig_new(uint32_t ifindex)
 {
 	struct l_netconfig *nc;
@@ -378,6 +607,13 @@ LIB_EXPORT struct l_netconfig *l_netconfig_new(uint32_t ifindex)
 					netconfig_dhcp_event_handler,
 					nc, NULL);
 
+	nc->dhcp6_client = l_dhcp6_client_new(ifindex);
+
+	nc->icmp6_client = l_dhcp6_client_get_icmp6(nc->dhcp6_client);
+	l_icmp6_client_add_event_handler(nc->icmp6_client,
+					netconfig_icmp6_event_handler,
+					nc, NULL);
+
 	return nc;
 }
 
@@ -398,6 +634,7 @@ LIB_EXPORT void l_netconfig_destroy(struct l_netconfig *netconfig)
 	l_netconfig_set_domain_names_override(netconfig, AF_INET6, NULL);
 
 	l_dhcp_client_destroy(netconfig->dhcp_client);
+	l_dhcp6_client_destroy(netconfig->dhcp6_client);
 	l_netconfig_set_event_handler(netconfig, NULL, NULL, NULL);
 	l_queue_destroy(netconfig->addresses.current, NULL);
 	l_queue_destroy(netconfig->addresses.added, NULL);
@@ -731,16 +968,22 @@ configure_ipv6:
 	if (!netconfig->v6_enabled)
 		goto done;
 
-	if (netconfig->v6_static_addr && !netconfig->do_static_work) {
+	if (netconfig->v6_static_addr) {
 		/*
 		 * We're basically ready to configure the interface
 		 * but do this in an idle callback.
 		 */
-		netconfig->do_static_work = l_idle_create(
+		if (!netconfig->do_static_work)
+			netconfig->do_static_work = l_idle_create(
 						netconfig_do_static_config,
 						netconfig, NULL);
+
+		goto done;
 	}
 
+	if (!l_dhcp6_client_start(netconfig->dhcp6_client))
+		return false;
+
 done:
 	netconfig->started = true;
 	return true;
@@ -767,6 +1010,7 @@ LIB_EXPORT void l_netconfig_stop(struct l_netconfig *netconfig)
 	netconfig->v6_address = NULL;
 
 	l_dhcp_client_stop(netconfig->dhcp_client);
+	l_dhcp6_client_stop(netconfig->dhcp6_client);
 }
 
 LIB_EXPORT struct l_dhcp_client *l_netconfig_get_dhcp_client(
-- 
2.32.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-05-13 13:39 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-13 13:39 [PATCH 03/13] netconfig: Create routes from Router Advertisements Denis Kenzior
  -- strict thread matches above, loose matches on Subject: below --
2022-05-13 12:46 Andrew Zaborowski
2022-05-12 16:14 Denis Kenzior
2022-05-05 23:15 Andrew Zaborowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.