Skip to content

dhcpv6_relay: initial import of a lightweight DHCPv6 relay agent#16606

Merged
miri64 merged 2 commits intoRIOT-OS:masterfrom
miri64:dhcpv6_relay/feat/init
Aug 11, 2021
Merged

dhcpv6_relay: initial import of a lightweight DHCPv6 relay agent#16606
miri64 merged 2 commits intoRIOT-OS:masterfrom
miri64:dhcpv6_relay/feat/init

Conversation

@miri64
Copy link
Copy Markdown
Member

@miri64 miri64 commented Jul 2, 2021

Contribution description

This provides a DHCPv6 relay agent based on sock_async which allows for multihop-operation with DHCPv6.

This PR is very much WIP as it is to this point only compile tested, I just wanted to publish it already so people know this is coming ;-).

Testing procedure

A test application is provided which can be run with

BOARD="<board>" make -C tests/gnrc_dhcpv6_relay flash -j test-as-root

If you want to see the relay in action

  1. Apply the following patch to start the relay on the border router and make prefix delegation optional (in a hacky way):

    Details
    diff --git a/examples/gnrc_border_router/main.c b/examples/gnrc_border_router/main.c
    index 654b411a50..03a0906042 100644
    --- a/examples/gnrc_border_router/main.c
    +++ b/examples/gnrc_border_router/main.c
    @@ -18,8 +18,12 @@
      * @}
      */
     
    +#include <assert.h>
     #include <stdio.h>
     
    +#include "event/thread.h"
    +#include "net/dhcpv6/relay.h"
    +#include "net/gnrc/netif/internal.h"
     #include "shell.h"
     #include "msg.h"
     
    @@ -28,6 +32,17 @@ static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
     
     int main(void)
     {
    +    gnrc_netif_t *netif = NULL, *upstream = NULL, *downstream = NULL;
    +    while ((netif = gnrc_netif_iter(netif)) != NULL) {
    +        if (gnrc_netif_is_6lo(netif)) {
    +            downstream = netif;
    +        }
    +        else {
    +            upstream = netif;
    +        }
    +    }
    +    assert(upstream && downstream);
    +    dhcpv6_relay_init(EVENT_PRIO_LOWEST, downstream->pid, upstream->pid);
         /* we need a message queue for the thread running the shell in order to
          * receive potentially fast incoming networking packets */
         msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
    diff --git a/sys/net/application_layer/dhcpv6/client.c b/sys/net/application_layer/dhcpv6/client.c
    index bab8b14e71..8b43ab017b 100644
    --- a/sys/net/application_layer/dhcpv6/client.c
    +++ b/sys/net/application_layer/dhcpv6/client.c
    @@ -454,7 +454,8 @@ static int _preparse_advertise(uint8_t *adv, size_t len, uint8_t **buf)
                     break;
             }
         }
    -    if ((cid == NULL) || (sid == NULL) || (ia_pd == NULL)) {
    +    (void)ia_pd;
    +    if ((cid == NULL) || (sid == NULL)) {
             DEBUG("DHCPv6 client: ADVERTISE does not contain either server ID, "
                   "client ID or IA_PD option\n");
             return -1;
    @@ -618,7 +619,7 @@ static bool _parse_reply(uint8_t *rep, size_t len)
                     break;
             }
         }
    -    if ((cid == NULL) || (sid == NULL) || (ia_pd == NULL)) {
    +    if ((cid == NULL) || (sid == NULL)) {
             DEBUG("DHCPv6 client: ADVERTISE does not contain either server ID, "
                   "client ID or IA_PD option\n");
             return false;
  2. flash the border router example to a board with DHCPv6 and the dhcpv6_relay module and the event_thread module to run it in. I used an nrf52840dongle (which needs some additional config to be able to communicate with the samr21-xpro I used as client) so I can just plug it into my home router for DHCPv6 services:

    UPLINK=cdc-ecm USE_DHCPV6=1 BOARD=nrf52840dongle \
      USEMODULE="auto_init_dhcpv6_relay event_thread" \
      CFLAGS=-DCONFIG_IEEE802154_CCA_THRESH_DEFAULT=-30 \
        make -C examples/gnrc_border_router/ flash -j
  3. flash the gnrc_networking example with DNS support and the DHCPv6 client to a board. I used a samr21-xpro, but any board using 6LoWPAN should work here:

    BOARD=samr21-xpro \
      USEMODULE="auto_init_dhcpv6_client dhcpv6_client_dns gnrc_dhcpv6_client sock_dns" \
        make -C examples/gnrc_networking flash -j term
  4. Ping a host by name from the gnrc_networking node

    2021-07-15 08:24:55,102 # main(): This is RIOT! (Version: 2021.10-devel-8-gb7cae-dhcpv6_relay/feat/init)
    2021-07-15 08:24:55,109 # RIOT network stack example application
    2021-07-15 08:24:55,112 # All up, running the shell now
    > ping riot-os.org
    2021-07-15 08:25:05,836 # ping riot-os.org
    2021-07-15 08:25:05,886 # 12 bytes from 2001:67c:254:b0b0::1: icmp_seq=0 ttl=56 rssi=-56 dBm time=28.994 ms
    2021-07-15 08:25:06,887 # 12 bytes from 2001:67c:254:b0b0::1: icmp_seq=1 ttl=56 rssi=-57 dBm time=28.376 ms
    2021-07-15 08:25:07,889 # 12 bytes from 2001:67c:254:b0b0::1: icmp_seq=2 ttl=56 rssi=-56 dBm time=28.258 ms
    2021-07-15 08:25:07,889 # 
    2021-07-15 08:25:07,892 # --- riot-os.org PING statistics ---
    2021-07-15 08:25:07,897 # 3 packets transmitted, 3 packets received, 0% packet loss
    2021-07-15 08:25:07,902 # round-trip min/avg/max = 28.258/28.542/28.994 ms

Issues/PRs references

Requires #16643 for the tests to pass.

@miri64 miri64 added Area: network Area: Networking State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet Type: new feature The issue requests / The PR implemements a new feature for RIOT labels Jul 2, 2021
@miri64 miri64 requested a review from benpicco July 2, 2021 15:51
@github-actions github-actions bot added Area: build system Area: Build system Area: sys Area: System labels Jul 2, 2021
@github-actions github-actions bot added the Area: tests Area: tests and testing framework label Jul 13, 2021
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 13, 2021

I added a scapy-based test application (i.e. it requires root) and applied fixes in accordance to that. One-by-one the tests pass, but altogether (or on a non-native board for that matter) they have some issues. Will investigate later. I am also planning to provide a routine to hook this into the DHCPv6 client thread when run on a border router (BR) so the BR can run as a relay agent without an extra thread when the DHCPv6 client is compiled in.

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 14, 2021

I am also planning to provide a routine to hook this into the DHCPv6 client thread when run on a border router (BR) so the BR can run as a relay agent without an extra thread when the DHCPv6 client is compiled in.

This is currently not possible, since the DHCPv6 client does not use sock_async. I.e. it could happen that waiting for a reply from the DHCPv6 server (calling sock_udp_recv on the client sock) causes DHCPv6 relay messages to be lost in the meantime.

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 14, 2021

With #16643, this PR's tests should now pass on native.

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 14, 2021

Ok, I refactored the tests to an object-oriented unittest.TestCase which allowed me to store most of the state I need for the tests in the object, which reduces the number of UART-operations I need to do with the samr21-xpro. As such, now that the "medium" is much cleaner, the tests are able to succeed with samr21-xpro, as expected packets are not lost. Now the only thing missing to get this PR out of WIP is the promised border router setup which I will provide ASAP.

@miri64 miri64 removed the State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet label Jul 15, 2021
@miri64 miri64 marked this pull request as ready for review July 15, 2021 06:27
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 15, 2021

Updated testing description, no longer WIP.

@miri64 miri64 force-pushed the dhcpv6_relay/feat/init branch from b7cae9c to b1431cf Compare July 15, 2021 06:31
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 15, 2021

And squashed and rebased to current master.

@miri64 miri64 force-pushed the dhcpv6_relay/feat/init branch from b1431cf to 6b08e64 Compare July 15, 2021 06:39
@github-actions github-actions bot added the Area: Kconfig Area: Kconfig integration label Jul 15, 2021
@miri64 miri64 force-pushed the dhcpv6_relay/feat/init branch from b2ab80c to f790b79 Compare July 21, 2021 09:35
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 21, 2021

Rebased and squashed to current master to resolve merge conflicts. @benpicco want to take a look?

Copy link
Copy Markdown
Contributor

@benpicco benpicco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

changes to the example
--- 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];

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)

first node
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
second node
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
third node
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)

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 27, 2021

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)

You did note the mention in the DHCPv6 RFC about PD and relay nodes, right? Or did you use IA_NA from #16228 to "get their addresses"?

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 29, 2021

There you go: br0.pcapng.zip

Ah, you seem to have a similar problem like I had the other day (with libCoAP in my case however): For some reason newer Linux kernels decided to rely on some Ethernet offloading which screws up the UDP checksum calculation ([edit] which causes incoming UDP packets to be dropped by RIOT). This seems to be a reoccuring issue, as using this workaround seemed to work for me. So for all bridges and TAP interfaces I did

$ sudo ethtool --offload "<iface>" rx off tx off

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 29, 2021

Will try to reproduce however ASAP.

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 30, 2021

There you go: br0.pcapng.zip

Ah, you seem to have a similar problem like I had the other day (with libCoAP in my case however): For some reason newer Linux kernels decided to rely on some Ethernet offloading which screws up the UDP checksum calculation ([edit] which causes incoming UDP packets to be dropped by RIOT). This seems to be a reoccuring issue, as using this workaround seemed to work for me. So for all bridges and TAP interfaces I did

$ sudo ethtool --offload "<iface>" rx off tx off

Yepp, with

ip link | grep -o -e 'br[0-9]\+' -e 'tap_[abc][0-9]\+' |  xargs -I{} sudo ethtool --offload {} rx off tx off

being run before I start the DHCPv6 server and then rebooting all nodes (starting with the most upstream one and then going down the tree), I get the downlink prefix for all running native instances.

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 30, 2021

[…] and then rebooting all nodes (starting with the most upstream one and then going down the tree), I get the downlink prefix for all running native instances.

(In case rebooting does not work, restarting the whole native process might get better results ;-)).

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 30, 2021

sudo $RIOTTOOLS/tapsetup/tapsetup -b br1 -t tap_b -c 3
sudo $RIOTTOOLS/tapsetup/tapsetup -b br2 -t tap_c -c 3

Why three btw when I only use two of each bridge?

@benpicco
Copy link
Copy Markdown
Contributor

Why three btw when I only use two of each bridge?

That was just copied from my subnet test where I also have leaf nodes on each level

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Jul 30, 2021

Yepp, with

ip link | grep -o -e 'br[0-9]\+' -e 'tap_[abc][0-9]\+' |  xargs -I{} sudo ethtool --offload {} rx off tx off

being run before I start the DHCPv6 server and then rebooting all nodes (starting with the most upstream one and then going down the tree), I get the downlink prefix for all running native instances.

(as I only get output for the bridges with that snippet, I think setting offloading only for the bridges might suffice:

ip link | grep -e 'br[0-9]\+' |  xargs -I{} sudo ethtool --offload {} rx off tx off

@benpicco
Copy link
Copy Markdown
Contributor

benpicco commented Aug 5, 2021

Hm I think this is a red herring. The UDP packets are dropped because the mbox in gnrc_sock is full and stays full. E.g. when the 1st node in the tree is in the gnrc_sock: dropped message to 0x565b90d0 (was full) state and I reboot the second node (wich previously got a DHCPv6 lease) the first node will still print gnrc_sock: dropped message to 0x565b90d0 (was full) when the second node does it's DHCPv6 request.

I tried with offloading disabled and I still see the same issue.

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Aug 5, 2021

Then I am afraid I can't reproduce your issue locally :-/.

@benpicco
Copy link
Copy Markdown
Contributor

benpicco commented Aug 5, 2021

How many messages can this mbox store?

@benpicco
Copy link
Copy Markdown
Contributor

benpicco commented Aug 6, 2021

When I run this on hardware (same54-xpro with Ethernet uplink, WeAct-F411CE wired up over UART / slipdev_l2) I can only observe the SOLICIT being relayed by the same54-xpro, it gets no reply.

Maybe that's a limitation of my router though. It answers to ff02::1:2 as it should, I also subscribed to that address so I can capture the DHCPv6 request: dhcpv6-relay.pcapng.gz

edit: same with ethos: dhcpv6-relay_ethos.pcapng.gz

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Aug 11, 2021

So how do we continue? I am unable to reproduce your errors (either because the error does not occur for me or because I do not have the hardware).

@benpicco
Copy link
Copy Markdown
Contributor

Well the problem with the multiple relay hops appears to be caused by a lower layer, the code from this PR looks fine.
I would have hoped we could get closer to the cause of this (maybe just a queue that's too small, but then again packets appear to be send multiple times more than expected).

The single-hop relay case works fine though (with KEA), so if you don't want to investigate this further, feel free to squash.

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Aug 11, 2021

[…] so if you don't want to investigate this further, feel free to squash.

In the longtime I'd like to investigate further, if I am able to reproduce this, but for now I just would prefer to have this in (also with #16228 being merged soon and multi-hop in mind).

@miri64 miri64 force-pushed the dhcpv6_relay/feat/init branch from 63b160b to 0755f6c Compare August 11, 2021 09:54
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Aug 11, 2021

Squashed

@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Aug 11, 2021
@miri64 miri64 force-pushed the dhcpv6_relay/feat/init branch from 0755f6c to 07ad90a Compare August 11, 2021 11:17
@miri64 miri64 force-pushed the dhcpv6_relay/feat/init branch from 07ad90a to 264dc93 Compare August 11, 2021 11:19
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Aug 11, 2021

Updated Makefile.ci of the test. Also rebased to resolve merge conflict with current master.

@miri64 miri64 force-pushed the dhcpv6_relay/feat/init branch from 264dc93 to 2d7c613 Compare August 11, 2021 12:30
@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Aug 11, 2021

And fixed the broken Makefile.ci 🙄

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Aug 11, 2021

I give #16228 precedence over merging this PR... its the older PR and there will be merge conflicts :-).

@miri64
Copy link
Copy Markdown
Member Author

miri64 commented Aug 11, 2021

Ok, there need to be some fixes there anyway, so go.

@miri64 miri64 merged commit 057aba8 into RIOT-OS:master Aug 11, 2021
@miri64 miri64 deleted the dhcpv6_relay/feat/init branch August 11, 2021 15:16
@benpicco benpicco added this to the Release 2021.10 milestone Oct 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: build system Area: Build system Area: Kconfig Area: Kconfig integration Area: network Area: Networking Area: sys Area: System Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants