Re: slaacd(8) handle RTM_DELETE of default route

2018-05-17 Thread Peter Hessler
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_routedel_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_routedel_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;

Re: slaacd(8) handle RTM_DELETE of default route

2018-05-17 Thread Florian Obser
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_routedel_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_routedel_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;
> +