Florian Obser(flor...@openbsd.org) 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.
> 

Reply via email to