When sending a router solicitation use the link-layer (mac) address of
the outgoing interface in the source link-layer address ICMPv6 option
instead of the address of the last configured autoconf interface.

It is not the most efficient way to first transform an if_index into
and interface name and then iterate over all addresses but this is
also not in the hot path. Under normal operations slaacd will send
one solicitation when an interface is set to autoconf and then
never again because it will see unsolicitated router advertisements
before addresses expire.

Tests, OKs?

diff --git frontend.c frontend.c
index 2adbdb0f97a..4b94af5ec8c 100644
--- frontend.c
+++ frontend.c
@@ -520,9 +520,6 @@ update_iface(uint32_t if_index, char* if_name)
        imsg_ifinfo.soii = !(xflags & IFXF_INET6_NOSOII);
        get_lladdr(if_name, &imsg_ifinfo.hw_address, &imsg_ifinfo.ll_address);
 
-       memcpy(&nd_opt_source_link_addr, &imsg_ifinfo.hw_address,
-           sizeof(nd_opt_source_link_addr));
-
        frontend_imsg_compose_main(IMSG_UPDATE_IF, 0, &imsg_ifinfo,
            sizeof(imsg_ifinfo));
 }
@@ -1023,9 +1020,20 @@ send_solicitation(uint32_t if_index)
 {
        struct in6_pktinfo              *pi;
        struct cmsghdr                  *cm;
+       struct ether_addr                hw_address;
+       struct sockaddr_in6              ll_address;
+       char                             if_name[IF_NAMESIZE];
 
        log_debug("%s(%u)", __func__, if_index);
 
+       if (if_indextoname(if_index, if_name) == NULL)
+               return;
+
+       get_lladdr(if_name, &hw_address, &ll_address);
+
+       memcpy(&nd_opt_source_link_addr, &hw_address,
+           sizeof(nd_opt_source_link_addr));
+
        dst.sin6_scope_id = if_index;
 
        cm = CMSG_FIRSTHDR(&sndmhdr);


-- 
I'm not entirely sure you are real.

Reply via email to