I'm still looking for OKs on this.

On Mon, Apr 02, 2012 at 14:42 +0200, Mike Belopuhov wrote:
> When route priorities were added to the RA/redirects code, all
> of them got set to RTP_CONNECTED.  Most importantly, rt6_flush
> was made to flush only RTP_CONNECTED routes.  The purpose of
> rt6_flush is to flush *all* routes going via a specified gw.
> 
> Now the problem is that the code in rtrequest1/mpath code
> changes routing priorities.  For example for default routes
> which means that rt6_flush won't actually flush anything.
> 
> The problem became evident when tahi test used RA with
> RouterLifetime set to 0 to remove routes and redirects.  This
> obviously doesn't work.  Therefore IMHO rt6_flush should
> actually use RTP_ANY.
> 
> The rest of the change changes RTP_CONNECTED to RTP_DEFAULT
> for default and off-link routes, leaving RTP_CONNECTED for
> directly connected ones.
> 
> Additional rt6_flush is there to faciliate a situation when
> RA with RouterLifetime==0 is sent to clear a redirect.  Consider
> a following situation.  Router R1 sends a redirect to R2 that
> you don't know about and when you try using it, R2 sends you
> a RA saying that it's not a valid router.  In such situation
> redirect is not valid anymore and should be removed.  Obviously
> R1 is misconfigured but it might be fixed before redirect
> expires itself.
> 
> OK?
> 
> diff --git sys/netinet6/nd6_rtr.c sys/netinet6/nd6_rtr.c
> index 5de5cf7..f846063 100644
> --- sys/netinet6/nd6_rtr.c
> +++ sys/netinet6/nd6_rtr.c
> @@ -459,7 +459,7 @@ defrouter_addreq(struct nd_defrouter *new)
>       info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask;
>  
>       s = splsoftnet();
> -     error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &newrt,
> +     error = rtrequest1(RTM_ADD, &info, RTP_DEFAULT, &newrt,
>           new->ifp->if_rdomain);
>       if (newrt) {
>               nd6_rtmsg(RTM_ADD, newrt); /* tell user process */
> @@ -563,7 +563,7 @@ defrouter_delreq(struct nd_defrouter *dr)
>       info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw;
>       info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask;
>  
> -     rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &oldrt,
> +     rtrequest1(RTM_DELETE, &info, RTP_DEFAULT, &oldrt,
>           dr->ifp->if_rdomain);
>       if (oldrt) {
>               nd6_rtmsg(RTM_DELETE, oldrt);
> @@ -788,6 +788,9 @@ defrtrlist_update(struct nd_defrouter *new)
>  
>       /* entry does not exist */
>       if (new->rtlifetime == 0) {
> +             /* flush all possible redirects */
> +             if (!ip6_forwarding && ip6_accept_rtadv)
> +                     rt6_flush(&new->rtaddr, new->ifp);
>               splx(s);
>               return (NULL);
>       }
> @@ -1669,7 +1672,7 @@ nd6_prefix_offlink(struct nd_prefix *pr)
>       bzero(&info, sizeof(info));
>       info.rti_info[RTAX_DST] = (struct sockaddr *)&sa6;
>       info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask6;
> -     error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &rt,
> +     error = rtrequest1(RTM_DELETE, &info, RTP_DEFAULT, &rt,
>           ifp->if_rdomain);
>       if (error == 0) {
>               pr->ndpr_stateflags &= ~NDPRF_ONLINK;
> @@ -1980,7 +1983,7 @@ rt6_deleteroute(struct radix_node *rn, void *arg, u_int 
> id)
>       info.rti_info[RTAX_DST] = rt_key(rt);
>       info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
>       info.rti_info[RTAX_NETMASK] = rt_mask(rt);
> -     return (rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, NULL, id));
> +     return (rtrequest1(RTM_DELETE, &info, RTP_ANY, NULL, id));
>  #undef SIN6
>  }

Reply via email to