* [PATCH 1/6] net: Allow padding in net_domain_list_parse
@ 2022-09-20 13:31 Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 2/6] unit: Update net_domain_list_parse test Andrew Zaborowski
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2022-09-20 13:31 UTC (permalink / raw)
To: ell
The domain name lists in ICMPv6 options may be 0-padded meaning that a
0-byte at the beginning of a domain record (ie. a domain with no labels)
is allowed and should be treated as the end of the list. Add a boolean
parameter to tell net_domain_list_parse() whether to allow this.
Fixes: 4b1ce9b3e3d0 ("icmp6: Parse RDNSS and DNSSL options")
---
ell/dhcp6-lease.c | 2 +-
ell/icmp6.c | 6 +++---
ell/net-private.h | 2 +-
ell/net.c | 8 +++++++-
4 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/ell/dhcp6-lease.c b/ell/dhcp6-lease.c
index 978176a..a92cff9 100644
--- a/ell/dhcp6-lease.c
+++ b/ell/dhcp6-lease.c
@@ -312,7 +312,7 @@ struct l_dhcp6_lease *_dhcp6_lease_parse_options(
lease->rapid_commit = true;
break;
case L_DHCP6_OPTION_DOMAIN_LIST:
- lease->domain_list = net_domain_list_parse(v, l);
+ lease->domain_list = net_domain_list_parse(v, l, false);
if (!lease->domain_list)
goto error;
diff --git a/ell/icmp6.c b/ell/icmp6.c
index a2765ea..5ddc494 100644
--- a/ell/icmp6.c
+++ b/ell/icmp6.c
@@ -1104,11 +1104,11 @@ struct l_icmp6_router *_icmp6_router_parse(const struct nd_router_advert *ra,
{
struct domain_info *info = &r->domains[n_domains];
_auto_(l_free) char **domain_list =
- net_domain_list_parse(opts + 8, l - 8);
+ net_domain_list_parse(opts + 8, l - 8, true);
char **i;
- /* Ignore invalid option */
- if (!domain_list)
+ /* Ignore malformed option */
+ if (!domain_list || !domain_list[0])
break;
for (i = domain_list; *i; i++) {
diff --git a/ell/net-private.h b/ell/net-private.h
index 39d4d98..a864034 100644
--- a/ell/net-private.h
+++ b/ell/net-private.h
@@ -21,7 +21,7 @@
*/
char *net_domain_name_parse(const uint8_t *raw, size_t raw_len);
-char **net_domain_list_parse(const uint8_t *raw, size_t raw_len);
+char **net_domain_list_parse(const uint8_t *raw, size_t raw_len, bool padded);
static inline const void *net_prefix_from_ipv6(const uint8_t *address,
uint8_t prefix_len)
diff --git a/ell/net.c b/ell/net.c
index 378b9f2..aa7fc20 100644
--- a/ell/net.c
+++ b/ell/net.c
@@ -295,7 +295,7 @@ char *net_domain_name_parse(const uint8_t *raw, size_t raw_len)
/*
* Parse list of domain names encoded according to RFC 1035 Section 3.1
*/
-char **net_domain_list_parse(const uint8_t *raw, size_t raw_len)
+char **net_domain_list_parse(const uint8_t *raw, size_t raw_len, bool padded)
{
size_t remaining = raw_len;
const uint8_t *p = raw;
@@ -305,6 +305,9 @@ char **net_domain_list_parse(const uint8_t *raw, size_t raw_len)
struct l_string *growable = NULL;
while (remaining) {
+ if (padded && p[0] == 0)
+ break;
+
r = validate_next_domain_name(p, remaining);
if (r < 0)
return NULL;
@@ -323,6 +326,9 @@ char **net_domain_list_parse(const uint8_t *raw, size_t raw_len)
remaining -= *p + 1;
if (*p == 0) {
+ if (!growable)
+ break;
+
p += 1;
ret[nitems++] = l_string_unwrap(growable);
growable = NULL;
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/6] unit: Update net_domain_list_parse test
2022-09-20 13:31 [PATCH 1/6] net: Allow padding in net_domain_list_parse Andrew Zaborowski
@ 2022-09-20 13:31 ` Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 3/6] netconfig: Set .v6_configured when we set an address Andrew Zaborowski
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2022-09-20 13:31 UTC (permalink / raw)
To: ell
---
unit/test-net.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/unit/test-net.c b/unit/test-net.c
index ff5d2b0..f3f1522 100644
--- a/unit/test-net.c
+++ b/unit/test-net.c
@@ -113,11 +113,13 @@ static void test_net_domain_list_parse(const void *data)
static const uint8_t l1[] = { 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
3, 'c', 'o', 'm', 0,
4, 't', 'e', 's', 't', 0 };
- static const uint8_t l2[] = { 0, 0};
+ static const uint8_t l2[] = { 0, 0 };
static const uint8_t l3[] = { 4, '.', '=', '2', '3', 0 };
+ static const uint8_t l4[] = { 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 3, 'c', 'o', 'm', 0, 0 };
char **domains;
- domains = net_domain_list_parse(l1, sizeof(l1));
+ domains = net_domain_list_parse(l1, sizeof(l1), false);
assert(domains);
assert(domains[0]);
assert(!strcmp(domains[0], "example.com"));
@@ -126,14 +128,21 @@ static void test_net_domain_list_parse(const void *data)
assert(!domains[2]);
l_strfreev(domains);
- assert(!net_domain_list_parse(l2, sizeof(l2)));
+ assert(!net_domain_list_parse(l2, sizeof(l2), false));
- domains = net_domain_list_parse(l3, sizeof(l3));
+ domains = net_domain_list_parse(l3, sizeof(l3), false);
assert(domains);
assert(domains[0]);
assert(!strcmp(domains[0], "\\.\\06123"));
assert(!domains[1]);
l_strfreev(domains);
+
+ domains = net_domain_list_parse(l4, sizeof(l4), true);
+ assert(domains);
+ assert(domains[0]);
+ assert(!strcmp(domains[0], "example.com"));
+ assert(!domains[1]);
+ l_strfreev(domains);
}
int main(int argc, char *argv[])
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/6] netconfig: Set .v6_configured when we set an address
2022-09-20 13:31 [PATCH 1/6] net: Allow padding in net_domain_list_parse Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 2/6] unit: Update net_domain_list_parse test Andrew Zaborowski
@ 2022-09-20 13:31 ` Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 4/6] netconfig: Handle DNS data from l_icmp6_router Andrew Zaborowski
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2022-09-20 13:31 UTC (permalink / raw)
To: ell
The DNS getters won't work without this as they return NULL if
.v6_configured is false.
Fixes: 6adf0f5db455 ("netconfig: Create SLAAC address")
---
ell/netconfig.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/ell/netconfig.c b/ell/netconfig.c
index 7a9ee89..e5c7b51 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -750,6 +750,7 @@ static void netconfig_add_slaac_address(struct l_netconfig *nc,
l_queue_push_tail(nc->addresses.current, nc->v6_address);
l_queue_push_tail(nc->addresses.added, nc->v6_address);
+ nc->v6_configured = true;
netconfig_emit_event(nc, AF_INET6, L_NETCONFIG_EVENT_CONFIGURE);
/* TODO: set a renew timeout */
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/6] netconfig: Handle DNS data from l_icmp6_router
2022-09-20 13:31 [PATCH 1/6] net: Allow padding in net_domain_list_parse Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 2/6] unit: Update net_domain_list_parse test Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 3/6] netconfig: Set .v6_configured when we set an address Andrew Zaborowski
@ 2022-09-20 13:31 ` Andrew Zaborowski
2022-09-20 13:32 ` [PATCH 5/6] icmp6,netconfig: Skip SLLAO if RS sent from optimistic address Andrew Zaborowski
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2022-09-20 13:31 UTC (permalink / raw)
To: ell
Track the lists of DNSes and search domains based on Router Advertisement
options parsed by l_icmp6_client. Return them in
l_netconfig_get_dns_list, l_netconfig_get_domain_names.
---
ell/netconfig.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 154 insertions(+), 6 deletions(-)
diff --git a/ell/netconfig.c b/ell/netconfig.c
index e5c7b51..765703b 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -98,6 +98,8 @@ struct l_netconfig {
NETCONFIG_V6_METHOD_DHCP,
NETCONFIG_V6_METHOD_SLAAC,
} v6_auto_method;
+ struct l_queue *slaac_dnses;
+ struct l_queue *slaac_domains;
/* These objects, if not NULL, are owned by @addresses and @routes */
struct l_rtnl_address *v4_address;
@@ -151,6 +153,8 @@ static struct l_queue *addr_wait_list;
static unsigned int rtnl_id;
static const unsigned int max_icmp6_routes = 100;
+static const unsigned int max_icmp6_dnses = 10;
+static const unsigned int max_icmp6_domains = 10;
static void netconfig_update_cleanup(struct l_netconfig *nc)
{
@@ -681,6 +685,16 @@ static bool netconfig_match(const void *a, const void *b)
return a == b;
}
+static bool netconfig_match_addr(const void *a, const void *b)
+{
+ return memcmp(a, b, 16) == 0;
+}
+
+static bool netconfig_match_str(const void *a, const void *b)
+{
+ return strcmp(a, b) == 0;
+}
+
static bool netconfig_check_start_dhcp6(struct l_netconfig *nc)
{
/* Don't start DHCPv6 until we get an RA with the managed bit set */
@@ -809,6 +823,88 @@ static void netconfig_set_slaac_address_lifetimes(struct l_netconfig *nc,
l_queue_push_tail(nc->addresses.updated, nc->v6_address);
}
+static bool netconfig_process_slaac_dns_info(struct l_netconfig *nc,
+ const struct l_icmp6_router *r)
+{
+ bool updated = false;
+ unsigned int i;
+ unsigned int n_dns = l_queue_length(nc->slaac_dnses);
+ unsigned int n_domains = l_queue_length(nc->slaac_domains);
+
+ for (i = 0; i < r->n_dns; i++) {
+ const struct dns_info *info = &r->dns_list[i];
+
+ /*
+ * For simplicity don't track lifetimes (TODO), add entries
+ * when the lifetime is non-zero, remove them when the
+ * lifetime is zero. We have no API to add time-limited
+ * entries to the system either.
+ *
+ * RFC8106 Section 5.1: "A value of zero means that the RDNSS
+ * addresses MUST no longer be used."
+ */
+ if (info->lifetime) {
+ if (n_dns >= max_icmp6_dnses)
+ continue;
+
+ if (l_queue_find(nc->slaac_dnses, netconfig_match_addr,
+ info->address))
+ continue;
+
+ l_queue_push_tail(nc->slaac_dnses,
+ l_memdup(info->address, 16));
+ n_dns++;
+ } else {
+ void *addr = l_queue_remove_if(nc->slaac_dnses,
+ netconfig_match_addr,
+ info->address);
+
+ if (!addr)
+ continue;
+
+ l_free(addr);
+ n_dns--;
+ }
+
+ updated = true;
+ }
+
+ for (i = 0; i < r->n_domains; i++) {
+ const struct domain_info *info = &r->domains[i];
+
+ /*
+ * RFC8106 Section 5.2: "A value of zero means that the DNSSL
+ * domain names MUST no longer be used."
+ */
+ if (info->lifetime) {
+ if (n_domains >= max_icmp6_domains)
+ continue;
+
+ if (l_queue_find(nc->slaac_domains, netconfig_match_str,
+ info->domain))
+ continue;
+
+ l_queue_push_tail(nc->slaac_domains,
+ l_strdup(info->domain));
+ n_domains++;
+ } else {
+ void *str = l_queue_remove_if(nc->slaac_domains,
+ netconfig_match_str,
+ info->domain);
+
+ if (!str)
+ continue;
+
+ l_free(str);
+ n_domains--;
+ }
+
+ updated = true;
+ }
+
+ return updated;
+}
+
static uint64_t now;
static bool netconfig_check_route_expired(void *data, void *user_data)
@@ -1027,6 +1123,7 @@ static void netconfig_icmp6_event_handler(struct l_icmp6_client *client,
const struct l_icmp6_router *r;
struct netconfig_route_data *default_rd;
unsigned int i;
+ bool dns_updated = false;
if (event != L_ICMP6_CLIENT_EVENT_ROUTER_FOUND)
return;
@@ -1122,6 +1219,14 @@ process_nondefault_routes:
r->n_ac_prefixes) {
nc->v6_auto_method = NETCONFIG_V6_METHOD_SLAAC;
+ /*
+ * Do this first so that any changes are included in the
+ * CONFIGURE event emitted next.
+ */
+ nc->slaac_dnses = l_queue_new();
+ nc->slaac_domains = l_queue_new();
+ netconfig_process_slaac_dns_info(nc, r);
+
/*
* The DAD for the link-local address may be still running
* but again we can generate the global address already and
@@ -1156,6 +1261,7 @@ process_nondefault_routes:
* and allows us to extend its lifetime.
*/
netconfig_set_slaac_address_lifetimes(nc, r);
+ dns_updated = netconfig_process_slaac_dns_info(nc, r);
emit_event:
/*
@@ -1168,7 +1274,8 @@ emit_event:
!l_queue_isempty(nc->routes.updated) ||
!l_queue_isempty(nc->routes.removed) ||
!l_queue_isempty(nc->routes.expired) ||
- !l_queue_isempty(nc->addresses.updated))
+ !l_queue_isempty(nc->addresses.updated) ||
+ dns_updated)
netconfig_emit_event(nc, AF_INET6, L_NETCONFIG_EVENT_UPDATE);
}
@@ -2007,6 +2114,8 @@ LIB_EXPORT void l_netconfig_stop(struct l_netconfig *netconfig)
l_queue_clear(netconfig->routes.current,
(l_queue_destroy_func_t) l_rtnl_route_free);
l_queue_clear(netconfig->icmp_route_data, l_free);
+ l_queue_clear(netconfig->slaac_dnses, l_free);
+ l_queue_clear(netconfig->slaac_domains, l_free);
netconfig->v4_address = NULL;
netconfig->v4_subnet_route = NULL;
netconfig->v4_default_route = NULL;
@@ -2255,9 +2364,31 @@ append_v6:
if (netconfig->v6_dns_override)
netconfig_strv_cat(&ret, netconfig->v6_dns_override, false);
- else if ((v6_lease =
- l_dhcp6_client_get_lease(netconfig->dhcp6_client)))
+ else if (netconfig->v6_auto_method == NETCONFIG_V6_METHOD_DHCP &&
+ (v6_lease = l_dhcp6_client_get_lease(
+ netconfig->dhcp6_client)))
netconfig_strv_cat(&ret, l_dhcp6_lease_get_dns(v6_lease), true);
+ else if (netconfig->v6_auto_method == NETCONFIG_V6_METHOD_SLAAC &&
+ !l_queue_isempty(netconfig->slaac_dnses)) {
+ unsigned int dest_len = l_strv_length(ret);
+ unsigned int src_len = l_queue_length(netconfig->slaac_dnses);
+ char **i;
+ const struct l_queue_entry *entry;
+
+ ret = l_realloc(ret, sizeof(char *) * (dest_len + src_len + 1));
+ i = ret + dest_len;
+
+ for (entry = l_queue_get_entries(netconfig->slaac_dnses);
+ entry; entry = entry->next) {
+ char addr_str[INET6_ADDRSTRLEN];
+
+ if (inet_ntop(AF_INET6, entry->data, addr_str,
+ sizeof(addr_str)))
+ *i++ = l_strdup(addr_str);
+ }
+
+ *i = NULL;
+ }
done:
return ret;
@@ -2288,13 +2419,30 @@ append_v6:
if (!netconfig->v6_configured)
goto done;
- if (netconfig->v6_dns_override)
+ if (netconfig->v6_domain_names_override)
netconfig_strv_cat(&ret, netconfig->v6_domain_names_override,
false);
- else if ((v6_lease =
- l_dhcp6_client_get_lease(netconfig->dhcp6_client)))
+ else if (netconfig->v6_auto_method == NETCONFIG_V6_METHOD_DHCP &&
+ (v6_lease = l_dhcp6_client_get_lease(
+ netconfig->dhcp6_client)))
netconfig_strv_cat(&ret, l_dhcp6_lease_get_domains(v6_lease),
true);
+ else if (netconfig->v6_auto_method == NETCONFIG_V6_METHOD_SLAAC &&
+ !l_queue_isempty(netconfig->slaac_domains)) {
+ unsigned int dest_len = l_strv_length(ret);
+ unsigned int src_len = l_queue_length(netconfig->slaac_domains);
+ char **i;
+ const struct l_queue_entry *entry;
+
+ ret = l_realloc(ret, sizeof(char *) * (dest_len + src_len + 1));
+ i = ret + dest_len;
+
+ for (entry = l_queue_get_entries(netconfig->slaac_domains);
+ entry; entry = entry->next)
+ *i++ = l_strdup(entry->data);
+
+ *i = NULL;
+ }
done:
return ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/6] icmp6,netconfig: Skip SLLAO if RS sent from optimistic address
2022-09-20 13:31 [PATCH 1/6] net: Allow padding in net_domain_list_parse Andrew Zaborowski
` (2 preceding siblings ...)
2022-09-20 13:31 ` [PATCH 4/6] netconfig: Handle DNS data from l_icmp6_router Andrew Zaborowski
@ 2022-09-20 13:32 ` Andrew Zaborowski
2022-09-20 13:32 ` [PATCH 6/6] netconfig: Handle missing optimistic_dad /proc file Andrew Zaborowski
2022-09-20 15:06 ` [PATCH 1/6] net: Allow padding in net_domain_list_parse Denis Kenzior
5 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2022-09-20 13:32 UTC (permalink / raw)
To: ell
Make sure we don't include de Source Link-Local Address Option in our
Router Solicitations until the source link-local address completes DAD.
Extand the recently added l_icmp6_client_set_link_local_address() with a
parameter to tell us whether the address is optimistic. Don't change
the l_dhcp6_client_set_link_local_address signature to avoid breaking
existing users.
---
ell/dhcp6.c | 2 +-
ell/icmp6.c | 29 +++++++++++++++++++++--------
ell/icmp6.h | 3 ++-
ell/netconfig.c | 30 ++++++++++++++++++++++++++----
4 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/ell/dhcp6.c b/ell/dhcp6.c
index e234eb0..2792ff2 100644
--- a/ell/dhcp6.c
+++ b/ell/dhcp6.c
@@ -1623,7 +1623,7 @@ LIB_EXPORT bool l_dhcp6_client_set_link_local_address(
return false;
if (!client->nora)
- l_icmp6_client_set_link_local_address(client->icmp6, ll);
+ l_icmp6_client_set_link_local_address(client->icmp6, ll, false);
return true;
}
diff --git a/ell/icmp6.c b/ell/icmp6.c
index 5ddc494..f087ba3 100644
--- a/ell/icmp6.c
+++ b/ell/icmp6.c
@@ -206,7 +206,8 @@ static uint16_t icmp6_checksum(const struct iovec *iov, unsigned int iov_len)
static int icmp6_send_router_solicitation(int s, int ifindex,
const uint8_t src_mac[static 6],
- const struct in6_addr *src_ip)
+ const struct in6_addr *src_ip,
+ bool src_ip_optimistic)
{
struct nd_router_solicit rs = {
.nd_rs_type = ND_ROUTER_SOLICIT,
@@ -247,11 +248,17 @@ static int icmp6_send_router_solicitation(int s, int ifindex,
memcpy(&ip_hdr.ip6_src, src_ip, 16);
- if (l_memeqzero(src_ip, 16)) {
+ if (l_memeqzero(src_ip, 16) || src_ip_optimistic) {
/*
- * radvd will discard and warn about RSs from the unspecified
- * address with the SLLAO, omit that option by dropping the
- * last two iov buffers.
+ * RFC 4429 Section 3.2: "A node MUST NOT send a Router
+ * Solicitation with a SLLAO from an Optimistic Address.
+ * Router Solicitations SHOULD be sent from a non-Optimistic
+ * or the Unspecified Address; however, they MAY be sent from
+ * an Optimistic Address as long as the SLLAO is not included."
+ *
+ * Additionally radvd will also discard and warn about RSs
+ * from the unspecified address with the SLLAO. Omit that
+ * option by dropping the last two iov buffers.
*/
msg.msg_iovlen -= 2;
ip_hdr.ip6_plen = htons(ntohs(ip_hdr.ip6_plen) - rs_sllao_size);
@@ -347,6 +354,7 @@ struct l_icmp6_client {
uint64_t retransmit_time;
struct l_io *io;
struct in6_addr src_ip;
+ bool src_ip_optimistic;
struct l_icmp6_router *ra;
struct l_netlink *rtnl;
@@ -547,7 +555,8 @@ static void icmp6_client_timeout_send(struct l_timeout *timeout,
r = icmp6_send_router_solicitation(l_io_get_fd(client->io),
client->ifindex, client->mac,
- &client->src_ip);
+ &client->src_ip,
+ client->src_ip_optimistic);
if (r < 0) {
CLIENT_DEBUG("Error sending Router Solicitation: %s",
strerror(-r));
@@ -766,7 +775,7 @@ LIB_EXPORT bool l_icmp6_client_set_route_priority(
LIB_EXPORT bool l_icmp6_client_set_link_local_address(
struct l_icmp6_client *client,
- const char *ll)
+ const char *ll, bool optimistic)
{
if (unlikely(!client))
return false;
@@ -777,7 +786,11 @@ LIB_EXPORT bool l_icmp6_client_set_link_local_address(
* is fine. Once we have a confirmed link-local address we use that
* as the source address.
*/
- return inet_pton(AF_INET6, ll, &client->src_ip) == 1;
+ if (inet_pton(AF_INET6, ll, &client->src_ip) != 1)
+ return false;
+
+ client->src_ip_optimistic = optimistic;
+ return true;
}
struct l_icmp6_router *_icmp6_router_new()
diff --git a/ell/icmp6.h b/ell/icmp6.h
index ffbb8a8..ad3d661 100644
--- a/ell/icmp6.h
+++ b/ell/icmp6.h
@@ -66,7 +66,8 @@ bool l_icmp6_client_set_rtnl(struct l_icmp6_client *client,
bool l_icmp6_client_set_route_priority(struct l_icmp6_client *client,
uint32_t priority);
bool l_icmp6_client_set_link_local_address(struct l_icmp6_client *client,
- const char *ll);
+ const char *ll,
+ bool optimistic);
char *l_icmp6_router_get_address(const struct l_icmp6_router *r);
bool l_icmp6_router_get_managed(const struct l_icmp6_router *r);
diff --git a/ell/netconfig.c b/ell/netconfig.c
index 765703b..c558cad 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -93,6 +93,7 @@ struct l_netconfig {
unsigned int orig_optimistic_dad;
uint8_t mac[ETH_ALEN];
struct l_timeout *ra_timeout;
+ bool have_lla;
enum {
NETCONFIG_V6_METHOD_UNSET,
NETCONFIG_V6_METHOD_DHCP,
@@ -702,7 +703,7 @@ static bool netconfig_check_start_dhcp6(struct l_netconfig *nc)
return true;
/* Don't start DHCPv6 while waiting for the link-local address */
- if (l_queue_find(addr_wait_list, netconfig_match, nc))
+ if (!nc->have_lla)
return true;
return l_dhcp6_client_start(nc->dhcp6_client);
@@ -1844,6 +1845,7 @@ static void netconfig_ifaddr_ipv6_added(struct l_netconfig *nc,
{
struct in6_addr in6;
_auto_(l_free) char *ip = NULL;
+ bool new_lla;
if ((ifa->ifa_flags & IFA_F_TENTATIVE) &&
!(ifa->ifa_flags & IFA_F_OPTIMISTIC))
@@ -1858,16 +1860,28 @@ static void netconfig_ifaddr_ipv6_added(struct l_netconfig *nc,
if (!IN6_IS_ADDR_LINKLOCAL(&in6))
return;
- netconfig_addr_wait_unregister(nc, true);
+ new_lla = !nc->have_lla;
+ nc->have_lla = true;
+
+ if (!(ifa->ifa_flags & IFA_F_TENTATIVE))
+ netconfig_addr_wait_unregister(nc, true);
+ else if (nc->ifaddr6_dump_cmd_id) {
+ struct l_netlink *rtnl = l_rtnl_get();
+ unsigned int cmd_id = nc->ifaddr6_dump_cmd_id;
+
+ nc->ifaddr6_dump_cmd_id = 0;
+ l_netlink_cancel(rtnl, cmd_id);
+ }
l_dhcp6_client_set_link_local_address(nc->dhcp6_client, ip);
- l_icmp6_client_set_link_local_address(nc->icmp6_client, ip);
+ l_icmp6_client_set_link_local_address(nc->icmp6_client, ip,
+ !!(ifa->ifa_flags & IFA_F_OPTIMISTIC));
/*
* Only now that we have a link-local address see if we can start
* actual DHCPv6 setup.
*/
- if (netconfig_check_start_dhcp6(nc))
+ if (new_lla && netconfig_check_start_dhcp6(nc))
return;
netconfig_emit_event(nc, AF_INET6, L_NETCONFIG_EVENT_FAILED);
@@ -2022,6 +2036,13 @@ configure_ipv6:
* before we start the dump, instead of after it ends, to eliminate
* the possibility of missing an RTM_NEWADDR between the end of
* the dump command and registering for the events.
+ *
+ * We stay on that list until we receive a non-tentative LL address.
+ * Note that we may set .have_lla earlier, specifically when we
+ * receive a tentative LL address that is also optimistic. We will
+ * however stay on addr_wait_list because we want to notify
+ * l_icmp6_client again when the LL address completes DAD and becomes
+ * non-tentative.
*/
if (!addr_wait_list) {
addr_wait_list = l_queue_new();
@@ -2041,6 +2062,7 @@ configure_ipv6:
goto unregister;
l_queue_push_tail(addr_wait_list, netconfig);
+ netconfig->have_lla = false;
if (!l_net_get_mac_address(netconfig->ifindex, netconfig->mac))
goto unregister;
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6/6] netconfig: Handle missing optimistic_dad /proc file
2022-09-20 13:31 [PATCH 1/6] net: Allow padding in net_domain_list_parse Andrew Zaborowski
` (3 preceding siblings ...)
2022-09-20 13:32 ` [PATCH 5/6] icmp6,netconfig: Skip SLLAO if RS sent from optimistic address Andrew Zaborowski
@ 2022-09-20 13:32 ` Andrew Zaborowski
2022-09-20 15:06 ` [PATCH 1/6] net: Allow padding in net_domain_list_parse Denis Kenzior
5 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2022-09-20 13:32 UTC (permalink / raw)
To: ell
Handle netconfig_proc_read_ipv6_uint_setting(..., "optimistic_dad")
failures more cleanly in case CONFIG_IPV6_OPTIMISTIC_DAD has not been
enabled in the kernel config. This commit makes no noticeable
difference to the user.
---
ell/netconfig.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/ell/netconfig.c b/ell/netconfig.c
index c558cad..fe5bf40 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -90,7 +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;
+ long orig_optimistic_dad;
uint8_t mac[ETH_ALEN];
struct l_timeout *ra_timeout;
bool have_lla;
@@ -2010,7 +2010,8 @@ configure_ipv6:
netconfig_proc_read_ipv6_uint_setting(netconfig,
"optimistic_dad");
- if (!!netconfig->orig_optimistic_dad != optimistic_dad)
+ if (netconfig->orig_optimistic_dad >= 0 &&
+ !!netconfig->orig_optimistic_dad != optimistic_dad)
netconfig_proc_write_ipv6_uint_setting(netconfig,
"optimistic_dad",
optimistic_dad ? 1 : 0);
@@ -2160,7 +2161,8 @@ LIB_EXPORT void l_netconfig_stop(struct l_netconfig *netconfig)
optimistic_dad = netconfig->optimistic_dad_enabled &&
!netconfig->v6_static_addr;
- if (!!netconfig->orig_optimistic_dad != optimistic_dad)
+ if (netconfig->orig_optimistic_dad >= 0 &&
+ !!netconfig->orig_optimistic_dad != optimistic_dad)
netconfig_proc_write_ipv6_uint_setting(netconfig,
"optimistic_dad",
netconfig->orig_optimistic_dad);
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/6] net: Allow padding in net_domain_list_parse
2022-09-20 13:31 [PATCH 1/6] net: Allow padding in net_domain_list_parse Andrew Zaborowski
` (4 preceding siblings ...)
2022-09-20 13:32 ` [PATCH 6/6] netconfig: Handle missing optimistic_dad /proc file Andrew Zaborowski
@ 2022-09-20 15:06 ` Denis Kenzior
5 siblings, 0 replies; 7+ messages in thread
From: Denis Kenzior @ 2022-09-20 15:06 UTC (permalink / raw)
To: Andrew Zaborowski, ell
Hi Andrew,
On 9/20/22 08:31, Andrew Zaborowski wrote:
> The domain name lists in ICMPv6 options may be 0-padded meaning that a
> 0-byte at the beginning of a domain record (ie. a domain with no labels)
> is allowed and should be treated as the end of the list. Add a boolean
> parameter to tell net_domain_list_parse() whether to allow this.
>
> Fixes: 4b1ce9b3e3d0 ("icmp6: Parse RDNSS and DNSSL options")
> ---
> ell/dhcp6-lease.c | 2 +-
> ell/icmp6.c | 6 +++---
> ell/net-private.h | 2 +-
> ell/net.c | 8 +++++++-
> 4 files changed, 12 insertions(+), 6 deletions(-)
>
All applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-09-20 15:22 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-20 13:31 [PATCH 1/6] net: Allow padding in net_domain_list_parse Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 2/6] unit: Update net_domain_list_parse test Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 3/6] netconfig: Set .v6_configured when we set an address Andrew Zaborowski
2022-09-20 13:31 ` [PATCH 4/6] netconfig: Handle DNS data from l_icmp6_router Andrew Zaborowski
2022-09-20 13:32 ` [PATCH 5/6] icmp6,netconfig: Skip SLLAO if RS sent from optimistic address Andrew Zaborowski
2022-09-20 13:32 ` [PATCH 6/6] netconfig: Handle missing optimistic_dad /proc file Andrew Zaborowski
2022-09-20 15:06 ` [PATCH 1/6] net: Allow padding in net_domain_list_parse Denis Kenzior
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).