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.