Running this for a little bit, done a bunch of lladdr random tests, as
well as suspend resume tests (which I've added lladdr random on resume).

This fixes the issues I'm seeing, OK.


On 2018 May 17 (Thu) at 14:25:44 +0200 (+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.

-- 
Every nonzero finite dimensional inner product space has an orthonormal basis.

It makes sense, when you don't think about it.

Reply via email to