Files
Clara 8571fa3cf7 [posix] accept short routing socket messages on BSD (#13744)
`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.
2026-11-02 11:58:07 -08:00
..