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.