Hi Martin,

On Mon, 4 Sep 2017 14:18:50 +0200 Martin Pieuchot <m...@openbsd.org> wrote:
> On 04/09/17(Mon) 13:10, Gerhard Roth wrote:
> > Hi,
> > 
> > I noticed a problem with the routing table that is easy to reproduce: put
> > multiple IPs on the same carp interface:
> 
> Great bug analysis, however returning EAGAIN for every route update is a
> no go if you have a big routing table like BGP full feeds.
> 
> We should return EAGAIN only if the multipath list contains multiple
> elements.
> 
> But since we're now returning EAGAIN much often we want to skip route
> entries that have already been borough UP/taken down.
> 
> Diff below does that, does it work for you?  Do you mind adding a
> regression test?

I can confirm that your version works for me. Thanks for the improvement.

Regarding the regression test: gimme some time ;)

Gerhard


> 
> Index: net/route.c
> ===================================================================
> RCS file: /cvs/src/sys/net/route.c,v
> retrieving revision 1.366
> diff -u -p -r1.366 route.c
> --- net/route.c       11 Aug 2017 21:24:19 -0000      1.366
> +++ net/route.c       4 Sep 2017 12:08:16 -0000
> @@ -1550,6 +1550,7 @@ rt_if_linkstate_change(struct rtentry *r
>  {
>       struct ifnet *ifp = arg;
>       struct sockaddr_in6 sa_mask;
> +     int error;
>  
>       if (rt->rt_ifidx != ifp->if_index)
>               return (0);
> @@ -1561,38 +1562,37 @@ rt_if_linkstate_change(struct rtentry *r
>       }
>  
>       if (LINK_STATE_IS_UP(ifp->if_link_state) && ifp->if_flags & IFF_UP) {
> -             if (!(rt->rt_flags & RTF_UP)) {
> -                     /* bring route up */
> -                     rt->rt_flags |= RTF_UP;
> -                     rtable_mpath_reprio(id, rt_key(rt),
> -                         rt_plen2mask(rt, &sa_mask),
> -                         rt->rt_priority & RTP_MASK, rt);
> -             }
> +             if (ISSET(rt->rt_flags, RTF_UP))
> +                     return (0);
> +
> +             /* bring route up */
> +             rt->rt_flags |= RTF_UP;
> +             error = rtable_mpath_reprio(id, rt_key(rt),
> +                 rt_plen2mask(rt, &sa_mask), rt->rt_priority & RTP_MASK, rt);
>       } else {
> -             if (rt->rt_flags & RTF_UP) {
> -                     /*
> -                      * Remove redirected and cloned routes (mainly ARP)
> -                      * from down interfaces so we have a chance to get
> -                      * new routes from a better source.
> -                      */
> -                     if (ISSET(rt->rt_flags, RTF_CLONED|RTF_DYNAMIC) &&
> -                         !ISSET(rt->rt_flags, RTF_CACHED|RTF_BFD)) {
> -                             int error;
> -
> -                             if ((error = rtdeletemsg(rt, ifp, id)))
> -                                     return (error);
> -                             return (EAGAIN);
> -                     }
> -                     /* take route down */
> -                     rt->rt_flags &= ~RTF_UP;
> -                     rtable_mpath_reprio(id, rt_key(rt),
> -                         rt_plen2mask(rt, &sa_mask),
> -                         rt->rt_priority | RTP_DOWN, rt);
> +             /*
> +              * Remove redirected and cloned routes (mainly ARP)
> +              * from down interfaces so we have a chance to get
> +              * new routes from a better source.
> +              */
> +             if (ISSET(rt->rt_flags, RTF_CLONED|RTF_DYNAMIC) &&
> +                 !ISSET(rt->rt_flags, RTF_CACHED|RTF_BFD)) {
> +                     if ((error = rtdeletemsg(rt, ifp, id)))
> +                             return (error);
> +                     return (EAGAIN);
>               }
> +
> +             if (!ISSET(rt->rt_flags, RTF_UP))
> +                     return (0);
> +
> +             /* take route down */
> +             rt->rt_flags &= ~RTF_UP;
> +             error = rtable_mpath_reprio(id, rt_key(rt),
> +                 rt_plen2mask(rt, &sa_mask), rt->rt_priority | RTP_DOWN, rt);
>       }
>       if_group_routechange(rt_key(rt), rt_plen2mask(rt, &sa_mask));
>  
> -     return (0);
> +     return (error);
>  }
>  
>  struct sockaddr *
> Index: net/rtable.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtable.c,v
> retrieving revision 1.61
> diff -u -p -r1.61 rtable.c
> --- net/rtable.c      30 Jul 2017 18:18:08 -0000      1.61
> +++ net/rtable.c      4 Sep 2017 12:02:00 -0000
> @@ -751,6 +751,7 @@ rtable_mpath_reprio(unsigned int rtablei
>               rt->rt_priority = prio;
>               rtable_mpath_insert(an, rt);
>               rtfree(rt);
> +             error = EAGAIN;
>       }
>       rw_exit_write(&ar->ar_lock);
>  

Reply via email to