So I was playing with a usb network adapter and noticed that dhcpleased
and slaacd would hold on to them when I unplugged them.
They would be listed as "unknown" because we can't find the if_name for
the if_index anymore.

Turns out we are not getting a RTM_IFINFO when an interface disappears
but instead we have to handle the RTM_IFANNOUNCE message.
While here fix a bug in slaacd where it would remove the interface only
in the engine process but not in the frontend when we lose an interface
while handing RTM_IFINFO.

OK?


diff --git sbin/dhcpleased/dhcpleased.c sbin/dhcpleased/dhcpleased.c
index 5ff5dcc9480..55c51d53b18 100644
--- sbin/dhcpleased/dhcpleased.c
+++ sbin/dhcpleased/dhcpleased.c
@@ -294,7 +294,8 @@ main(int argc, char *argv[])
            AF_INET)) == -1)
                fatal("route socket");
 
-       rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_PROPOSAL);
+       rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_PROPOSAL) |
+           ROUTE_FILTER(RTM_IFANNOUNCE);
        if (setsockopt(frontend_routesock, AF_ROUTE, ROUTE_MSGFILTER,
            &rtfilter, sizeof(rtfilter)) == -1)
                fatal("setsockopt(ROUTE_MSGFILTER)");
diff --git sbin/dhcpleased/frontend.c sbin/dhcpleased/frontend.c
index 84ae1cda9a4..44a217cb51b 100644
--- sbin/dhcpleased/frontend.c
+++ sbin/dhcpleased/frontend.c
@@ -768,7 +768,10 @@ route_receive(int fd, short events, void *arg)
 void
 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info)
 {
-       struct sockaddr_dl      *sdl = NULL;
+       struct sockaddr_dl              *sdl = NULL;
+       struct if_announcemsghdr        *ifan;
+       uint32_t                         if_index;
+
        switch (rtm->rtm_type) {
        case RTM_IFINFO:
                if (rtm->rtm_addrs & RTA_IFP && rti_info[RTAX_IFP]->sa_family
@@ -776,6 +779,15 @@ handle_route_message(struct rt_msghdr *rtm, struct 
sockaddr **rti_info)
                        sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP];
                update_iface((struct if_msghdr *)rtm, sdl);
                break;
+       case RTM_IFANNOUNCE:
+               ifan = (struct if_announcemsghdr *)rtm;
+               if_index = ifan->ifan_index;
+                if (ifan->ifan_what == IFAN_DEPARTURE) {
+                       frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0,
+                           &if_index, sizeof(if_index));
+                       remove_iface(if_index);
+               }
+               break;
        case RTM_PROPOSAL:
                if (rtm->rtm_priority == RTP_PROPOSAL_SOLICIT) {
                        log_debug("RTP_PROPOSAL_SOLICIT");
@@ -784,7 +796,6 @@ handle_route_message(struct rt_msghdr *rtm, struct sockaddr 
**rti_info)
                }
 #ifndef SMALL
                else if (rtm->rtm_flags & RTF_PROTO3) {
-                       uint32_t         if_index;
                        char             ifnamebuf[IF_NAMESIZE], *if_name;
 
                        if_index = rtm->rtm_index;
diff --git sbin/slaacd/frontend.c sbin/slaacd/frontend.c
index d3cb23a2925..27fbd212a66 100644
--- sbin/slaacd/frontend.c
+++ sbin/slaacd/frontend.c
@@ -778,6 +778,7 @@ void
 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info)
 {
        struct if_msghdr                *ifm;
+       struct if_announcemsghdr        *ifan;
        struct imsg_del_addr             del_addr;
        struct imsg_del_route            del_route;
        struct imsg_dup_addr             dup_addr;
@@ -798,6 +799,7 @@ handle_route_message(struct rt_msghdr *rtm, struct sockaddr 
**rti_info)
                        if_index = ifm->ifm_index;
                        frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0,
                            &if_index, sizeof(if_index));
+                       remove_iface(if_index);
                } else {
                        xflags = get_xflags(if_name);
                        if (xflags == -1 || !(xflags & (IFXF_AUTOCONF6 |
@@ -817,6 +819,15 @@ handle_route_message(struct rt_msghdr *rtm, struct 
sockaddr **rti_info)
                        }
                }
                break;
+       case RTM_IFANNOUNCE:
+               ifan = (struct if_announcemsghdr *)rtm;
+               if_index = ifan->ifan_index;
+                if (ifan->ifan_what == IFAN_DEPARTURE) {
+                       frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0,
+                           &if_index, sizeof(if_index));
+                       remove_iface(if_index);
+               }
+               break;
        case RTM_NEWADDR:
                ifm = (struct if_msghdr *)rtm;
                if_name = if_indextoname(ifm->ifm_index, ifnamebuf);
diff --git sbin/slaacd/slaacd.c sbin/slaacd/slaacd.c
index 0b31934c211..ca5e942af2f 100644
--- sbin/slaacd/slaacd.c
+++ sbin/slaacd/slaacd.c
@@ -255,7 +255,8 @@ main(int argc, char *argv[])
 
        rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |
            ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_DELETE) |
-           ROUTE_FILTER(RTM_CHGADDRATTR) | ROUTE_FILTER(RTM_PROPOSAL);
+           ROUTE_FILTER(RTM_CHGADDRATTR) | ROUTE_FILTER(RTM_PROPOSAL) |
+           ROUTE_FILTER(RTM_IFANNOUNCE);
        if (setsockopt(frontend_routesock, AF_ROUTE, ROUTE_MSGFILTER,
            &rtfilter, sizeof(rtfilter)) == -1)
                fatal("setsockopt(ROUTE_MSGFILTER)");

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

Reply via email to