mirror of
https://github.com/espressif/openthread.git
synced 2026-11-02 20:43:11 +00:00
`processNetlinkEvent()` required every message from the routing socket to be at least `sizeof(struct rt_msghdr)` (92 bytes on macOS) before it looked at the type. Address and membership messages have 20- and 16-byte headers: on a macOS 26 host the kernel's reports of OpenThread's own /64 addresses are 84 bytes and every membership report 64 bytes, so all of them were dropped with "Unexpected netlink recv() result"; on macOS 14 the address reports are long enough and only the membership reports were lost. `processNetifAddrEvent()` therefore never ran for a multicast membership, which the daemon learns from netlink and the MLD monitor on Linux, and on current macOS not for OpenThread's own addresses either. Check the common prelude first, then require the message's own rtm_msglen to hold the header of its type, as the kernel builds it (rt_msg1 picks the header the same way), and to fit in the bytes received. Walk the socket addresses within rtm_msglen: each must fit, a sa_len of 0 (a /0 netmask trimmed to nothing) is skipped without reading a family, and the walk ends with the message, which XNU does not pad after the last address. With the handler reachable, clear the embedded interface index from both scope bytes of link-local addresses and link-local groups, copy the sockaddrs no further than their sa_len (the kernel trims the netmask), and fill the otNetifAddress passed to otIp6AddUnicastAddress() completely in both the BSD and the Linux branch: an address the host added is valid and of manual origin, as one added with `ipaddr add` is, and preferred unless Linux reports it tentative or deprecated (the BSD message carries no address flags); the flags were uninitialised. The groups the kernel joins on its own for every IPv6 interface and address (ff01::1, the solicited-node group of each unicast address, the node information group) are ignored: the host's applications did not ask for them, each would take one of the OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS external slots, and Linux never reports them for a tun interface. Groups an application joins become external subscriptions, as the MLD monitor's reports do on Linux. check-posix-pty expects the daemon's log to show the reports of its own addresses and memberships, adds an address to the interface on the host and removes it again, which `ot-ctl ipaddr -v` must follow with origin, prefix length and flags, and runs the multicast join test on macOS too.