Florian Obser([email protected]) on 2021.08.23 20:30:07 +0200:
> So I was playing with a usb network adapter and noticed that dhcpleased
> and slaacd would hold on to them when I unplugged them.
don't do that :P
> 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?
ok benno@
>
>
> 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.
>