[riot-notifications] [RIOT-OS/RIOT] dhcpv6_relay: initial import of a lightweight DHCPv6 relay agent (#16606)

benpicco notifications at github.com
Tue Jul 27 23:17:56 CEST 2021


@benpicco commented on this pull request.

This looks pretty good!

I tested it with the `setup_taps.sh` script from #16536 (`examples/gnrc_networking-subnets`) on `native`.

It works quite well with one relay node, but I see some problems if I introduce a second hop / relay node.

<details><summary>changes to the example</summary>

```patch
--- a/examples/gnrc_networking-subnets/Makefile
+++ b/examples/gnrc_networking-subnets/Makefile
@@ -24,13 +24,16 @@ USEMODULE += ps
 USEMODULE += netstats_l2
 USEMODULE += netstats_ipv6
 
+USEMODULE += event_thread
+USEMODULE += dhcpv6_relay
+
 CFLAGS += -DDEBUG_ASSERT_VERBOSE=1
 CFLAGS += -DCONFIG_GNRC_IPV6_NIB_NUMOF=16
 CFLAGS += -DCONFIG_GNRC_IPV6_NIB_RIO_IN_LAST_RA=1
 
 ifeq (native, $(BOARD))
   USEMODULE += netdev_tap
-  CFLAGS += -DCONFIG_GNRC_DHCPV6_CLIENT_6LBR_UPSTREAM=6
+  CFLAGS += -DCONFIG_GNRC_DHCPV6_CLIENT_6LBR_UPSTREAM=7
 else ifeq (1, $(SLIP))
   USEMODULE += slipdev_l2addr
   CFLAGS += -DCONFIG_GNRC_DHCPV6_CLIENT_6LBR_UPSTREAM=5
diff --git a/examples/gnrc_networking/main.c b/examples/gnrc_networking/main.c
index 6301f4291d..3b703cc767 100644
--- a/examples/gnrc_networking/main.c
+++ b/examples/gnrc_networking/main.c
@@ -23,6 +23,10 @@
 #include "shell.h"
 #include "msg.h"
 
+#include "event/thread.h"
+#include "net/dhcpv6/relay.h"
+#include "net/gnrc/netif/internal.h"
+
 #define MAIN_QUEUE_SIZE     (8)
 static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
 
@@ -40,6 +44,17 @@ int main(void)
     msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
     puts("RIOT network stack example application");
 
+    gnrc_netif_t *netif = NULL, *upstream = NULL, *downstream = NULL;
+    while ((netif = gnrc_netif_iter(netif)) != NULL) {
+        if (netif->pid == CONFIG_GNRC_DHCPV6_CLIENT_6LBR_UPSTREAM) {
+            upstream = netif;
+        }
+        else {
+            downstream = netif;
+        }
+    }
+    dhcpv6_relay_init(EVENT_PRIO_LOWEST, downstream->pid, upstream->pid);
+
     /* start shell */
     puts("All up, running the shell now");
     char line_buf[SHELL_DEFAULT_BUFSIZE];
```

</details>

The nodes are then started with

 - `make BOARD=native GATEWAY=1 PORT="tap_a0 tap_b0" all term`
 - `make BOARD=native GATEWAY=1 PORT="tap_b1 tap_c0" term`
 - `make BOARD=native GATEWAY=1 PORT="tap_c1 tap_d0" term`

The first two nodes get their addresses just fine, when the third node is introduced I see dropped messages. (This might be a limitation of `netdev_tap` though)

<details><summary>first node</summary>

```
main(): This is RIOT! (Version: 2021.10-devel-246-g1515c-serial-routing-3)
RIOT network stack example application
All up, running the shell now
> DHCPv6 client: send SOLICIT
DHCPv6 client: resend SOLICIT
DHCPv6 client: received ADVERTISE
DHCPv6 client: scheduling REQUEST
DHCPv6 client: send REQUEST
DHCPv6 client: received REPLY
DHCPv6 client: scheduling RENEW in 10000 sec
DHCPv6 client: scheduling REBIND in 20000 sec
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
gnrc_sock: dropped message to 0x566370d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::c8f4:13ff:fece:3f43%8]:547
```

</details>

<details><summary>second node</summary>

```
RIOT network stack example application
All up, running the shell now
> DHCPv6 client: send SOLICIT
DHCPv6 client: resend SOLICIT
DHCPv6 client: received ADVERTISE
DHCPv6 client: scheduling REQUEST
DHCPv6 client: send REQUEST
DHCPv6 client: discarding 81 stale bytes
DHCPv6 client: discarding 81 stale bytes
DHCPv6 client: discarding 81 stale bytes
DHCPv6 client: received REPLY
DHCPv6 client: scheduling RENEW in 10000 sec
DHCPv6 client: scheduling REBIND in 20000 sec
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [::%8]:546
DHCPv6 relay: forwarding reply towards target failed: 22
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
gnrc_sock: dropped message to 0x565d40d0 (was full)
gnrc_sock: dropped message to 0x565d41b0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
gnrc_sock: dropped message to 0x565d41b0 (was full)
gnrc_sock: dropped message to 0x565d40d0 (was full)
gnrc_sock: dropped message to 0x565d41b0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
gnrc_sock: dropped message to 0x565d40d0 (was full)
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
DHCPv6 relay: forwarding reply towards target [fe80::3c27:6dff:fe25:e95d%8]:546
```

</details>

<details><summary>third node</summary>

```
RIOT network stack example application
All up, running the shell now
> DHCPv6 client: send SOLICIT
DHCPv6 client: resend SOLICIT
DHCPv6 client: received ADVERTISE
DHCPv6 client: scheduling REQUEST
DHCPv6 client: send REQUEST
DHCPv6 client: discarding 81 stale bytes
DHCPv6 client: resend REQUEST
DHCPv6 client: resend REQUEST
DHCPv6 client: resend REQUEST
DHCPv6 client: resend REQUEST
DHCPv6 client: resend REQUEST
DHCPv6 client: resend REQUEST
DHCPv6 client: resend REQUEST
DHCPv6 client: resend REQUEST
DHCPv6 client: resend REQUEST
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
gnrc_sock: dropped message to 0x565acbb0 (was full)
```

</details>

> +{
+    if (IS_USED(MODULE_AUTO_INIT_DHCPV6_RELAY)) {
+        int16_t netif = _only_one_netif();
+        if (netif > 0) {
+            if (IS_USED(MODULE_EVENT_THREAD)) {
+                dhcpv6_relay_init(EVENT_PRIO_LOWEST, netif, netif);
+            }
+            else {
+                thread_create(_auto_init_stack, ARRAY_SIZE(_auto_init_stack),
+                              AUTO_INIT_PRIO, THREAD_CREATE_STACKTEST,
+                              _dhcpv6_relay_auto_init_thread,
+                              (void *)(intptr_t)netif, "dhcpv6_relay");
+            }
+        }
+        else {
+            LOG_WARNING("DHCPv6 relay: auto init failed, more than 1 interface\n");

How is a DHCPv6 relay useful if there is only a single interface? 

> +
+void dhcpv6_relay_init(event_queue_t *eq, uint16_t listen_netif,
+                       uint16_t fwd_netif)
+{
+    sock_udp_ep_t local = { .family = AF_INET6, .port = DHCPV6_SERVER_PORT,
+                            .netif = listen_netif };
+    static sock_udp_t listen_sock;
+    int res;
+
+    assert(eq->waiter != NULL);
+    memset(&listen_sock, 0, sizeof(listen_sock));
+    _relay_state.fwd_netif = fwd_netif;
+    res = _join_all_relays_and_server(listen_netif);
+    if (res < 0) {
+        DEBUG("DHCPv6 relay: unable to join All_DHCP_Relay_Agents_and_Servers: "
+

```suggestion
```
empty line

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/16606#pullrequestreview-716346741
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20210727/7b42053b/attachment-0001.htm>


More information about the notifications mailing list