From 1585e2218d7ab1b51d5e4f68f5969cf0642cff48 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 27 Jun 2021 18:13:12 +0200 Subject: [PATCH] sys/net/dhcpv6: send final RA after configuring downstream subnets If the upstream router manages a /56 and hands our DHCPv6 IA_PD enabled router a /62 for use in it's downstream network, hosts in the upstream network may still assume that hosts on the new subnet are on-link. To fix this, we include the route information option about the subnets routed via our router in the last router advertisement. This means we must delay sending the last router advertisement until the downstream interface(s) have been configured. To speed up configuration, start with RAs disabled and only enable sending them once we have received a valid configuration via DHCPv6. --- sys/net/application_layer/dhcpv6/client.c | 29 ++++++++++++++++- sys/net/gnrc/Makefile.dep | 1 + .../dhcpv6/client_simple_pd.c | 31 +++++++++++++------ sys/net/gnrc/network_layer/ipv6/nib/Kconfig | 1 + 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/sys/net/application_layer/dhcpv6/client.c b/sys/net/application_layer/dhcpv6/client.c index f5890cb32e58..79f211a77589 100644 --- a/sys/net/application_layer/dhcpv6/client.c +++ b/sys/net/application_layer/dhcpv6/client.c @@ -99,6 +99,29 @@ static event_t request = { .handler = _request }; static event_t renew = { .handler = _renew }; static event_t rebind = { .handler = _rebind }; +/** + * @brief Signal that we received a and processed valid configuration via DHCPv6 + * + * @param[in] iface Upstream network interface. + */ +__attribute__ ((weak)) +void dhcpv6_client_conf_done(unsigned iface) +{ + (void)iface; +} + +/** + * @brief Signal that an interface has been configured with a prefix obtained + * via DHCPv6 + * + * @param[in] iface Interface that has been configured + */ +__attribute__ ((weak)) +void dhcpv6_client_conf_prefix_done(unsigned iface) +{ + (void)iface; +} + #ifdef MODULE_AUTO_INIT_DHCPV6_CLIENT static char _thread_stack[DHCPV6_CLIENT_STACK_SIZE]; static void *_thread(void *args); @@ -731,10 +754,12 @@ static bool _parse_reply(uint8_t *rep, size_t len) &iapfx->pfx, iapfx->pfx_len); if (iapfx->pfx_len > 0) { + unsigned netif = lease->parent.ia_id.info.netif; dhcpv6_client_conf_prefix( - lease->parent.ia_id.info.netif, &lease->pfx, + netif, &lease->pfx, lease->pfx_len, valid, pref ); + dhcpv6_client_conf_prefix_done(netif); } } } @@ -903,6 +928,8 @@ static void _request_renew_rebind(uint8_t type) if (!_parse_reply(recv_buf, res)) { /* try again */ event_post(event_queue, &request); + } else { + dhcpv6_client_conf_done(local.netif); } } else if (type == DHCPV6_REBIND) { diff --git a/sys/net/gnrc/Makefile.dep b/sys/net/gnrc/Makefile.dep index 0ec70ba6d905..b577ca245ce4 100644 --- a/sys/net/gnrc/Makefile.dep +++ b/sys/net/gnrc/Makefile.dep @@ -58,6 +58,7 @@ endif ifneq (,$(filter gnrc_dhcpv6_client_simple_pd,$(USEMODULE))) USEMODULE += gnrc_dhcpv6_client USEMODULE += dhcpv6_client_ia_pd + CFLAGS += -DCONFIG_GNRC_IPV6_NIB_ADV_ROUTER=0 endif ifneq (,$(filter gnrc_uhcpc,$(USEMODULE))) diff --git a/sys/net/gnrc/application_layer/dhcpv6/client_simple_pd.c b/sys/net/gnrc/application_layer/dhcpv6/client_simple_pd.c index 1de9fca0e5db..3f766cf53d3f 100644 --- a/sys/net/gnrc/application_layer/dhcpv6/client_simple_pd.c +++ b/sys/net/gnrc/application_layer/dhcpv6/client_simple_pd.c @@ -84,15 +84,6 @@ static void _configure_upstream_netif(gnrc_netif_t *upstream_netif) addr.u8[15] = 2; gnrc_netif_ipv6_addr_add(upstream_netif, &addr, 64, 0); } - - /* Disable router advertisements on upstream interface. With this, the border - * router - * 1. Does not confuse the upstream router to add the border router to its - * default router list and - * 2. Solicits upstream Router Advertisements quicker to auto-configure its - * upstream global address. - */ - gnrc_ipv6_nib_change_rtr_adv_iface(upstream_netif, false); } /** @@ -113,6 +104,28 @@ static void _configure_dhcpv6_client(void) } } +void dhcpv6_client_conf_done(unsigned iface) +{ + gnrc_netif_t *netif = gnrc_netif_get_by_pid(iface); + + /* Disable router advertisements on upstream interface. With this, the border + * router + * 1. Does not confuse the upstream router to add the border router to its + * default router list and + * 2. Solicits upstream Router Advertisements quicker to auto-configure its + * upstream global address. + */ + gnrc_ipv6_nib_change_rtr_adv_iface(netif, false); +} + +void dhcpv6_client_conf_prefix_done(unsigned iface) +{ + gnrc_netif_t *netif = gnrc_netif_get_by_pid(iface); + + /* start advertising subnet obtained via DHCPv6 */ + gnrc_ipv6_nib_change_rtr_adv_iface(netif, true); +} + /** * @brief The DHCPv6 client thread */ diff --git a/sys/net/gnrc/network_layer/ipv6/nib/Kconfig b/sys/net/gnrc/network_layer/ipv6/nib/Kconfig index 2903a87aa43a..58b26adbb85b 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/Kconfig +++ b/sys/net/gnrc/network_layer/ipv6/nib/Kconfig @@ -56,6 +56,7 @@ config GNRC_IPV6_NIB_DNS config GNRC_IPV6_NIB_ADV_ROUTER bool "Activate router advertising at interface start-up" + default n if USEMODULE_GNRC_DHCPV6_CLIENT_SIMPLE_PD default y if GNRC_IPV6_NIB_ROUTER && (!GNRC_IPV6_NIB_6LR || GNRC_IPV6_NIB_6LBR) config GNRC_IPV6_NIB_DC