zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.85k stars 6.61k forks source link

Receive ping reply from ::: when Border Router pings a multicast group (NRF52840/OpenThread) #65762

Closed qnquangg closed 10 months ago

qnquangg commented 11 months ago

Hi team, I'm new to OpenThread and Zephyr. Could you please provide some guidance? Thank you.

SCENARIO

ISSUE

The problem I'm encountering is that when the border router pings the multicast group using a command, it also receives a packet from :::. I don't want to see ::: in the output as it causes duplicate packets in my log. Could you please review my setup and code, which I've attached below, and let me know if everything is correct?

$ ping -6 -t 1 -I wpan0 ff06::abcd
PING ff06::abcd(ff06::abcd) from fdaa:fb3:4d49:1:8a41:7df0:abb3:3811 wpan0: 56 data bytes
64 bytes from fd31:9326:2ca1:b79e:e776:b4ee:5770:d7b9: icmp_seq=1 ttl=64 time=31.3 ms
64 bytes from ::: icmp_seq=1 ttl=64 time=37.9 ms
64 bytes from fd31:9326:2ca1:b79e:e776:b4ee:5770:d7b9: icmp_seq=2 ttl=64 time=18.3 ms
64 bytes from ::: icmp_seq=2 ttl=64 time=44.9 ms
64 bytes from fd31:9326:2ca1:b79e:e776:b4ee:5770:d7b9: icmp_seq=3 ttl=64 time=17.2 ms
64 bytes from ::: icmp_seq=3 ttl=64 time=32.2 ms
64 bytes from fd31:9326:2ca1:b79e:e776:b4ee:5770:d7b9: icmp_seq=4 ttl=64 time=15.6 ms
64 bytes from ::: icmp_seq=4 ttl=64 time=20.8 ms
^C
--- ff06::abcd ping statistics ---
4 packets transmitted, 4 received, +4 duplicates, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 15.552/27.266/44.900/10.151 ms

My code to subscribe multicast IP address:

prj.conf

# nRF board library
CONFIG_DK_LIBRARY=y

# Generic networking options
CONFIG_NETWORKING=y

# Network shell
CONFIG_SHELL=y
CONFIG_SHELL_ARGC_MAX=26
CONFIG_SHELL_CMD_BUFF_SIZE=416

# Network sockets
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_SOCKETS_POLL_MAX=4

# Enable Openthread FTD features set
CONFIG_OPENTHREAD=y
CONFIG_OPENTHREAD_THREAD_VERSION_1_3_1=y
CONFIG_OPENTHREAD_FTD=y

# Openthread settings
CONFIG_OPENTHREAD_PANID=4660
CONFIG_OPENTHREAD_CHANNEL=15
CONFIG_OPENTHREAD_NETWORK_NAME="OpenThreadDemo"
CONFIG_OPENTHREAD_NETWORKKEY="00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"
CONFIG_OPENTHREAD_XPANID="1111111122222222"

# L2 OpenThread enabling
CONFIG_NET_L2_OPENTHREAD=y
CONFIG_OPENTHREAD_SHELL=y
# CONFIG_IEEE802154_NET_IF_NO_AUTO_START=y

# CONFIG_MBEDTLS_SHA1_C=n
# CONFIG_FPU=y

main.c

static void on_thread_state_changed(otChangedFlags flags, struct openthread_context *ot_context,
                                    void *user_data)
{
    if (flags & OT_CHANGED_THREAD_ROLE)
    {
        switch (otThreadGetDeviceRole(ot_context->instance))
        {

        case OT_DEVICE_ROLE_ROUTER:
            LOG_INF("OT_DEVICE_ROLE_ROUTER");
            struct otIp6Address addr;
            inet_pton(AF_INET6, "ff06::abcd", &addr);
            openthread_api_mutex_lock(ot_context);
            otIp6SubscribeMulticastAddress(ot_context->instance, &addr);
            openthread_api_mutex_unlock(ot_context);
            break;

        default:
            LOG_INF("OT DEFAULT STATE");
            break;
        }
    }
}

I also have workaround solution, but I don't think it is good. My solution is to subscribe 2 multicast groups at the same time.

                         inet_pton(AF_INET6, "ff06::abcd", &addr);
            openthread_api_mutex_lock(ot_context);
            otIp6SubscribeMulticastAddress(ot_context->instance, &addr);
            openthread_api_mutex_unlock(ot_context);
                         inet_pton(AF_INET6, "ff07::abcd", &addr);
            openthread_api_mutex_lock(ot_context);
            otIp6SubscribeMulticastAddress(ot_context->instance, &addr);
            openthread_api_mutex_unlock(ot_context);

Please advise if I am doing correctly or not. Thanks for your time.

github-actions[bot] commented 11 months ago

Hi @qnquangg! We appreciate you submitting your first issue for our open-source project. 🌟

Even though I'm a bot, I can assure you that the whole community is genuinely grateful for your time and effort. 🤖💙

rlubos commented 11 months ago

The duplicate reply seems to be caused by both, OT and Zephyr stack processing the ping request. Try the following code to disable ICMP Echo Request processing int the OT stack:

otIcmp6SetEchoMode(openthread_get_default_instance(), OT_ICMP6_ECHO_HANDLER_DISABLED);

It's not possible to disable ICMP Echo Requests in the Zehpyr side.

As for the missing source address in replies (I assume from Zephyr), it looks like some IP address misconfiguration. From the Zephyr perspective, you'd need a global address to reply to a multicast of scope larger than mesh-local (> ff03). Can you paste the output of the following commands?

net iface
ot ipaddr
ot ipmaddr
qnquangg commented 11 months ago

Hi @rlubos ,

Thank you for your reply. When I attempted to use your code to disable ICMP Echo Request (otIcmp6SetEchoMode), the log was a bit different. The Border Router did not receive multicast packets from the node's address, but it still received them from :::, which is not what I expected. Here is the log from the Border Router::

quang.nguyen@raspberrypi:~ $ ping -6 -t 1 -I wpan0 ff06:0:0:0:0:0:0:abcd
PING ff06:0:0:0:0:0:0:abcd(ff06::abcd) from fdaa:fb3:4d49:1:8a41:7df0:abb3:3811 wpan0: 56 data bytes
64 bytes from ::: icmp_seq=1 ttl=64 time=27.3 ms
64 bytes from ::: icmp_seq=2 ttl=64 time=17.3 ms
64 bytes from ::: icmp_seq=3 ttl=64 time=16.1 ms
64 bytes from ::: icmp_seq=4 ttl=64 time=23.3 ms
64 bytes from ::: icmp_seq=5 ttl=64 time=15.0 ms
^C
--- ff06:0:0:0:0:0:0:abcd ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 15.034/19.778/27.251/4.700 ms

On the node side, I also enabled RTT logging and observed that the node sends an IPv6 packet. Here is the log from node:

00:03:24.586,059] <dbg> net_l2_openthread: openthread_recv: (rx_q[0]): Got 802.15.4 packet, sending to OT
[00:03:24.586,090] <dbg> net_l2_openthread: net_pkt_hexdump: Received 802.15.4 frame
[00:03:24.586,181] <dbg> net_l2_openthread: net_pkt_hexdump: 0x2001a6c0
                                            49 98 70 34 12 ff ff 00  f4 0d 82 dd 00 00 01 2b |I.p4.... .......+
                                            29 98 05 ee 0b ad 0c d4  54 21 20 f7 94 ad df fd |)....... T! .....
                                            a5 ba 6b 1f 3a a7 ab 14  d0 67 a2 1f c9 a0 c6 cf |..k.:... .g......
                                            eb 9a 40 8e 41 31 41 eb  c9 d4 34 8a b8 15 78 00 |..@.A1A. ..4...x.
                                            ac 63 19 4b a5 cf dc 4b  0a 5f 89 27 3f 0f 05 fc |.c.K...K ._.'?...
                                            98 94 59 f2 51 a3 73 d1  2e 43 e8 08 d2 fd 9e b5 |..Y.Q.s. .C......
                                            1f 3d e4 54 d2 42 5e af  d3 c7 ed 04 fc 3c ac 7e |.=.T.B^. .....<.~
                                            3e aa 61 d2 11 19 01 e3  8f 4f be 13 ac 2b 00    |>.a..... .O...+. 
[00:03:24.587,615] <dbg> net_l2_openthread: ot_receive_handler: (openthread): Injecting Ip6 packet to Zephyr net stack
[00:03:24.587,646] <dbg> net_l2_openthread: net_pkt_hexdump: Received IPv6 packet
[00:03:24.587,707] <dbg> net_l2_openthread: net_pkt_hexdump: 0x2001a660
                                            60 00 39 c0 00 40 3a 01  fd aa 0f b3 4d 49 00 01 |`.9..@:. ....MI..
                                            8a 41 7d f0 ab b3 38 11  ff 06 00 00 00 00 00 00 |.A}...8. ........
                                            00 00 00 00 00 00 ab cd  80 00 44 9b 00 05 00 01 |........ ..D.....
                                            c1 a7 66 65 2e 60 08 00  08 09 0a 0b 0c 0d 0e 0f |..fe.`.. ........
                                            10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f |........ ........
                                            20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f | !"#$%&' ()*+,-./
                                            30 31 32 33 34 35 36 37                          |01234567         
[00:03:24.587,890] <dbg> net_l2_openthread: openthread_recv: (rx_q[0]): Got injected Ip6 packet, sending to upper layers
[00:03:24.587,890] <dbg> net_l2_openthread: net_pkt_hexdump: Injected IPv6 packet
[00:03:24.587,982] <dbg> net_l2_openthread: net_pkt_hexdump: 0x2001a660
                                            60 00 39 c0 00 40 3a 01  fd aa 0f b3 4d 49 00 01 |`.9..@:. ....MI..
                                            8a 41 7d f0 ab b3 38 11  ff 06 00 00 00 00 00 00 |.A}...8. ........
                                            00 00 00 00 00 00 ab cd  80 00 44 9b 00 05 00 01 |........ ..D.....
                                            c1 a7 66 65 2e 60 08 00  08 09 0a 0b 0c 0d 0e 0f |..fe.`.. ........
                                            10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f |........ ........
                                            20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f | !"#$%&' ()*+,-./
                                            30 31 32 33 34 35 36 37                          |01234567         
[00:03:24.588,195] <dbg> net_l2_openthread: net_pkt_hexdump: IPv6 packet to send
[00:03:24.588,317] <dbg> net_l2_openthread: net_pkt_hexdump: 0x2001a2a0
                                            60 00 00 00 00 40 3a 40  00 00 00 00 00 00 00 00 |`....@:@ ........
                                            00 00 00 00 00 00 00 00  fd aa 0f b3 4d 49 00 01 |........ ....MI..
                                            8a 41 7d f0 ab b3 38 11  81 00 ee 6f 00 05 00 01 |.A}...8. ...o....
                                            c1 a7 66 65 2e 60 08 00  08 09 0a 0b 0c 0d 0e 0f |..fe.`.. ........
                                            10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f |........ ........
                                            20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f | !"#$%&' ()*+,-./
                                            30 31 32 33 34 35 36 37                          |01234567         
[00:03:24.588,378] <dbg> net_otPlat_radio: openthread_handle_frame_to_send: (openthread): Sending Ip6 packet to ot stack
[00:03:24.600,799] <dbg> net_l2_openthread: openthread_recv: (rx_q[0]): Got 802.15.4 packet, sending to OT
[00:03:24.600,830] <dbg> net_l2_openthread: net_pkt_hexdump: Received 802.15.4 frame
[00:03:24.600,921] <dbg> net_l2_openthread: net_pkt_hexdump: 0x2001a660
                                            49 98 71 34 12 ff ff 00  f4 0d 83 dd 00 00 01 e0 |I.q4.... ........
                                            2d d8 1c b0 b2 b9 09 ae  fa 94 8b 4d d4 f2 8e 73 |-....... ...M...s
                                            fe dc 7b dd 5b a1 28 9c  e9 6b 3c d0 f5 84 9d dd |..{.[.(. .k<.....
                                            0e 6a f3 91 3c 02 f0 ed  29 1b 45 87 88 b4 bd fb |.j..<... ).E.....
                                            f5 c6 34 a2 5a 93 24 e8  24 f5 01 72 8d 34 46 99 |..4.Z.$. $..r.4F.
                                            1c 0f c4 6e fa 99 89 a2  74 3e ef 41 3e 27 c7 07 |...n.... t>.A>'..
                                            bf b6 42 44 8f d6 a7 dd  e8 35 24 d1 e6 86 e8 d6 |..BD.... .5$.....
                                            be 98 37 b1 55 fc c4 fd  d8 12 7a b7 52 2a 00    |..7.U... ..z.R*. 
[00:03:29.916,351] <dbg> net_l2_openthread: openthread_recv: (rx_q[0]): Got 802.15.4 packet, sending to OT
[00:03:29.916,381] <dbg> net_l2_openthread: net_pkt_hexdump: Received 802.15.4 frame
[00:03:29.916,442] <dbg> net_l2_openthread: net_pkt_hexdump: 0x2001a660
                                            41 d8 72 34 12 ff ff 13  8c d3 ea 93 f7 20 82 7f |A.r4.... ..... ..
                                            3b 01 f0 4d 4c 4d 4c 43  6a 00 15 82 48 00 00 00 |;..MLMLC j...H...
                                            00 00 00 01 b7 bb 7d 81  4e b1 86 80 a4 9c 60 19 |......}. N.....`.
                                            35 b1 ad 05 60 e5 5e 6e  a9 cf f4 52 40 a4 38 34 |5...`.^n ...R@.84
                                            44 81 fb 05 2a ca                                |D...*

I think I've set the multicast address to a value greater than ff03, which is ff06::abcd. Here is the output of the requested commands:

uart:~$ net iface

Interface net0 (0x20000a50) (OpenThread) [1]
=====================================
Link addr : F4:CE:36:3E:B4:37:30:5A
MTU       : 1280
Flags     : AUTO_START,IPv6,NO_ND,NO_MLD
IPv6 unicast addresses (max 6):
        fd31:9326:2ca1:b79e:c357:29:54a3:d428 autoconf preferred infinite meshlocal
        fe80::8019:b65:4a81:2b7d autoconf preferred infinite
IPv6 multicast addresses (max 8):
        ff33:40:fd31:9326:2ca1:b79e:0:1
        ff32:40:fd31:9326:2ca1:b79e:0:1
        ff02::1
        ff03::1
        ff03::fc
        ff06::abcd
        ff02::2
        ff03::2
IPv6 prefixes (max 2):
        <none>
IPv6 hop limit           : 64
IPv6 base reachable time : 30000
IPv6 reachable time      : 38925
IPv6 retransmit timer    : 0
uart:~$ ot ipaddr
fd31:9326:2ca1:b79e:0:ff:fe00:7000
fd31:9326:2ca1:b79e:c357:29:54a3:d428
fe80:0:0:0:8019:b65:4a81:2b7d
Done
uart:~$ ot ipmaddr
ff06:0:0:0:0:0:0:abcd
ff33:40:fd31:9326:2ca1:b79e:0:1
ff32:40:fd31:9326:2ca1:b79e:0:1
ff02:0:0:0:0:0:0:2
ff03:0:0:0:0:0:0:2
ff02:0:0:0:0:0:0:1
ff03:0:0:0:0:0:0:1
ff03:0:0:0:0:0:0:fc
Done

Please advise. Thanks for your time.

rlubos commented 11 months ago

Thanks for the details. I see two issues here

  1. Sending ping reply with :: source address is clearly wrong and is a bug on the Zephyr side. If Zephyr cannot match the source address for the reply, it should drop the packet instead of sending it. I'll send a fix shortly.

  2. But for the reason why there is no source address match:

    • OTBR sends ping from fdaa:fb3:4d49:1:8a41:7df0:abb3:3811 which has a different prefix than on mesh prefix
    • Thread device has only fd31:9326:2ca1:b79e:c357:29:54a3:d428 assigned, which is mesh-local ULA. Such address is not routable outside of Thread mesh network, therefore is not selected as a match for OTBR address.

I believe Border Router should assign Supplemantal ULA prefix for the mesh, so that devices can configure an address that can be used for external destination? @konradderda @edmont @canisLupus1313 Thoughts?

canisLupus1313 commented 11 months ago

@qnquangg @rlubos The Thread border router should advertise ULA prefix based on config. Please refer to: https://openthread.io/guides/border-router/docker/test-connectivity#form-the-thread-network

This should do the trick.

edmont commented 11 months ago

On the node device, ot prefix command can be used to show the configured prefixes.

rlubos commented 11 months ago

As for the Zephyr bug, I've opened https://github.com/zephyrproject-rtos/zephyr/pull/65907 with at fix, Zephry should no longer send a reply with unspecified IPv6 source address.

rlubos commented 11 months ago

@qnquangg Ping, any updates? Did you manage to resolve the issue with the suggestions above?

carlescufi commented 10 months ago

Closing due to inactivity. Please reopen if still an issue.