forgot to mention, this needs a fairly recent checkout

On Thu, May 17, 2018 at 02:25:44PM +0200, Florian Obser wrote:
> Peter points out that I never got around to correctly handling
> RTM_DELETE in slaacd. If something deletes the slaacd handled default
> route we should just re-create it. (Something being an explicit
> route(8) delete or if it implicitly disapears because of on
> ifconfig(8) lladdr random).
> 
> Tests, OKs?
> 
> diff --git engine.c engine.c
> index 184b349f650..10a70bee230 100644
> --- engine.c
> +++ engine.c
> @@ -259,6 +259,8 @@ struct address_proposal   
> *find_address_proposal_by_addr(struct slaacd_iface *,
>                            struct sockaddr_in6 *);
>  struct dfr_proposal  *find_dfr_proposal_by_id(struct slaacd_iface *,
>                            int64_t);
> +struct dfr_proposal  *find_dfr_proposal_by_gw(struct slaacd_iface *,
> +                          struct sockaddr_in6 *);
>  void                  find_prefix(struct slaacd_iface *, struct
>                            address_proposal *, struct radv **, struct
>                            radv_prefix **);
> @@ -389,6 +391,7 @@ engine_dispatch_frontend(int fd, short event, void *bula)
>       struct address_proposal         *addr_proposal = NULL;
>       struct dfr_proposal             *dfr_proposal = NULL;
>       struct imsg_del_addr             del_addr;
> +     struct imsg_del_route            del_route;
>       ssize_t                          n;
>       int                              shut = 0;
>  #ifndef      SMALL
> @@ -520,6 +523,28 @@ engine_dispatch_frontend(int fd, short event, void *bula)
>                               free_address_proposal(addr_proposal);
>                       }
>  
> +                     break;
> +             case IMSG_DEL_ROUTE:
> +                     if (imsg.hdr.len != IMSG_HEADER_SIZE +
> +                         sizeof(del_route))
> +                             fatal("%s: IMSG_DEL_ROUTE wrong length: %d",
> +                                 __func__, imsg.hdr.len);
> +                     memcpy(&del_route, imsg.data, sizeof(del_route));
> +                     iface = get_slaacd_iface_by_id(del_addr.if_index);
> +                     if (iface == NULL) {
> +                             log_debug("IMSG_DEL_ROUTE: unknown interface"
> +                                 ", ignoring");
> +                             break;
> +                     }
> +
> +                     dfr_proposal = find_dfr_proposal_by_gw(iface,
> +                         &del_route.gw);
> +
> +                     if (dfr_proposal) {
> +                             dfr_proposal->state = PROPOSAL_WITHDRAWN;
> +                             free_dfr_proposal(dfr_proposal);
> +                             start_probe(iface);
> +                     }
>                       break;
>               default:
>                       log_debug("%s: unexpected imsg %d", __func__,
> @@ -1932,10 +1957,7 @@ configure_dfr(struct dfr_proposal *dfr_proposal)
>  
>       if (prev_state == PROPOSAL_CONFIGURED || prev_state ==
>           PROPOSAL_NEARLY_EXPIRED) {
> -             /*
> -              * nothing to do here, routes do not expire in the kernel
> -              * XXX check if the route got deleted and re-add it?
> -              */
> +             /* nothing to do here, routes do not expire in the kernel */
>               return;
>       }
>  
> @@ -2276,6 +2298,20 @@ find_dfr_proposal_by_id(struct slaacd_iface *iface, 
> int64_t id)
>       return (NULL);
>  }
>  
> +struct dfr_proposal*
> +find_dfr_proposal_by_gw(struct slaacd_iface *iface, struct sockaddr_in6
> +    *addr)
> +{
> +     struct dfr_proposal     *dfr_proposal;
> +
> +     LIST_FOREACH (dfr_proposal, &iface->dfr_proposals, entries) {
> +             if (memcmp(&dfr_proposal->addr, addr, sizeof(*addr)) == 0)
> +                     return (dfr_proposal);
> +     }
> +
> +     return (NULL);
> +}
> +
>  
>  /* XXX currently unused */
>  void
> diff --git frontend.c frontend.c
> index b7d4d13f7d1..56eb3617143 100644
> --- frontend.c
> +++ frontend.c
> @@ -674,7 +674,9 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>       struct if_msghdr                *ifm;
>       struct imsg_proposal_ack         proposal_ack;
>       struct imsg_del_addr             del_addr;
> +     struct imsg_del_route            del_route;
>       struct sockaddr_rtlabel         *rl;
> +     struct in6_addr                 *in6;
>       int64_t                          id, pid;
>       int                              flags, xflags, if_index;
>       char                             ifnamebuf[IFNAMSIZ];
> @@ -728,6 +730,46 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>                       log_debug("RTM_DELADDR: %s[%u]", if_name,
>                           ifm->ifm_index);
>               }
> +             break;
> +     case RTM_DELETE:
> +             ifm = (struct if_msghdr *)rtm;
> +             if ((rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY | RTA_LABEL)) !=
> +                 (RTA_DST | RTA_GATEWAY | RTA_LABEL))
> +                     break;
> +             if (rti_info[RTAX_DST]->sa_family != AF_INET6)
> +                     break;
> +             if (!IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)
> +                 rti_info[RTAX_DST])->sin6_addr))
> +                     break;
> +             if (rti_info[RTAX_GATEWAY]->sa_family != AF_INET6)
> +                     break;
> +             if (rti_info[RTAX_LABEL]->sa_len !=
> +                 sizeof(struct sockaddr_rtlabel))
> +                     break;
> +
> +             rl = (struct sockaddr_rtlabel *)rti_info[RTAX_LABEL];
> +             if (strcmp(rl->sr_label, SLAACD_RTA_LABEL) != 0)
> +                     break;
> +
> +             if_name = if_indextoname(ifm->ifm_index, ifnamebuf);
> +
> +             del_route.if_index = ifm->ifm_index;
> +             memcpy(&del_route.gw, rti_info[RTAX_GATEWAY],
> +                 sizeof(del_route.gw));
> +             in6 = &del_route.gw.sin6_addr;
> +             /* XXX from route(8) p_sockaddr() */
> +             if (IN6_IS_ADDR_LINKLOCAL(in6) ||
> +                 IN6_IS_ADDR_MC_LINKLOCAL(in6) ||
> +                 IN6_IS_ADDR_MC_INTFACELOCAL(in6)) {
> +                     del_route.gw.sin6_scope_id =
> +                         (u_int32_t)ntohs(*(u_short *) &in6->s6_addr[2]);
> +                     *(u_short *)&in6->s6_addr[2] = 0;
> +             }
> +             frontend_imsg_compose_engine(IMSG_DEL_ROUTE,
> +                 0, 0, &del_route, sizeof(del_route));
> +             log_debug("RTM_DELETE: %s[%u]", if_name,
> +                 ifm->ifm_index);
> +
>               break;
>       case RTM_PROPOSAL:
>               ifm = (struct if_msghdr *)rtm;
> diff --git slaacd.c slaacd.c
> index 8acccc26b4a..e6ea184b18a 100644
> --- slaacd.c
> +++ slaacd.c
> @@ -82,6 +82,7 @@ const char* imsg_type_name[] = {
>       "IMSG_PROPOSAL_ACK",
>       "IMSG_CONFIGURE_ADDRESS",
>       "IMSG_DEL_ADDRESS",
> +     "IMSG_DEL_ROUTE",
>       "IMSG_FAKE_ACK",
>       "IMSG_CONFIGURE_DFR",
>       "IMSG_WITHDRAW_DFR",
> @@ -308,7 +309,8 @@ main(int argc, char *argv[])
>               fatal("route socket");
>  
>       rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |
> -         ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_PROPOSAL);
> +         ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_PROPOSAL) |
> +         ROUTE_FILTER(RTM_DELETE);
>       if (setsockopt(frontend_routesock, PF_ROUTE, ROUTE_MSGFILTER,
>           &rtfilter, sizeof(rtfilter)) < 0)
>               fatal("setsockopt(ROUTE_MSGFILTER)");
> diff --git slaacd.h slaacd.h
> index 6f16d8f1849..4378d1987b4 100644
> --- slaacd.h
> +++ slaacd.h
> @@ -70,6 +70,7 @@ enum imsg_type {
>       IMSG_PROPOSAL_ACK,
>       IMSG_CONFIGURE_ADDRESS,
>       IMSG_DEL_ADDRESS,
> +     IMSG_DEL_ROUTE,
>       IMSG_FAKE_ACK,
>       IMSG_CONFIGURE_DFR,
>       IMSG_WITHDRAW_DFR,
> @@ -185,6 +186,11 @@ struct imsg_del_addr {
>       struct sockaddr_in6     addr;
>  };
>  
> +struct imsg_del_route {
> +     uint32_t                if_index;
> +     struct sockaddr_in6     gw;
> +};
> +
>  struct imsg_proposal_ack {
>       int64_t          id;
>       pid_t            pid;
> 
> 
> -- 
> I'm not entirely sure you are real.
> 

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

Reply via email to