Re: bgpd more kroute refactor

2022-07-28 Thread Claudio Jeker
On Thu, Jul 28, 2022 at 03:09:18PM +0200, Theo Buehler wrote:
> On Thu, Jul 28, 2022 at 12:48:05PM +0200, Claudio Jeker wrote:
> > Next step on the epic saga of cleaning up kroute.c
> > 
> > Refactor kroute_remove() so that a struct kroute_full can be passed to the
> > function. It updates the struct kroute_full with the route that got removed.
> > 
> > I split the code into kroute[46]_remove() to make kroute_remove() less
> > cluttered. The return value of those two functions is a bit overloaded but
> > I hope to make this better further down the road.
> 
> That's fine for now. An obvious suggestion would be to use an out parameter 
> for
> multipath. Let kroute[46]_remove() return -1, 0 (where -1 and 0 have the same
> meaning as -2 and -1 in your diff), otherwise return 1. Then you can do:
> 
>   case AID_INET:
>   ret = kroute4_remove(kt, kf, any, );
>   if (ret <= 0)
>   return ret;
>   break;

Yes, since I want to tackle multipath routes (and nexthops) as one of the
next steps I think this will hopefully solve itself.
 
> Diff looks good, some comments inline.
> 
> ok tb
> 
> > 
> > -- 
> > :wq Claudio
> > 
> > Index: kroute.c
> > ===
> > RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
> > retrieving revision 1.283
> > diff -u -p -r1.283 kroute.c
> > --- kroute.c27 Jul 2022 17:23:17 -  1.283
> > +++ kroute.c28 Jul 2022 09:20:50 -

> > +   if ((kr = kroute_find(kt, >prefix, kf->prefixlen,
> > +   kf->priority)) == NULL)
> > +   return (-1);
> > +
> > +   if ((kr->flags & F_BGPD) != (kf->flags & F_BGPD)) {
> > +   log_warnx("%s: wrong type for %s/%u", __func__,
> > +   log_addr(>prefix), kf->prefixlen);
> > +   if (!(kf->flags & F_BGPD))
> > +   kr->flags &= ~F_BGPD_INSERTED;
> > return (-1);
> > }
> >  
> > +   /* get the correct route to remove */
> > +   if (any) {
> > +   krm = kr;
> > +   } else {
> 
> I'd probably have done:
> 
>   krm = kr
>   if (!any) {
> 

Good idea. Changed.

> > +   if ((krm = kroute_matchgw(kr, >nexthop)) == NULL) {
> > +   log_warnx("delete %s/%u: route not found",
> > +   log_addr(>prefix), kf->prefixlen);
> > +   return (-2);
> > +   }
> > +   }
> > +
> > if (krm == kr) {
> > /* head element */
> > -   if (RB_REMOVE(kroute_tree, >krt, kr) == NULL) {
> > -   log_warnx("%s: failed for %s/%u", __func__,
> > -   inet_ntoa(kr->prefix), kr->prefixlen);
> > -   return (-1);
> 
> Would it not be easier to initialize multipath to 1 and set it to 0 here
> if kr->next == NULL?

Probably. Let me fix this.
 
> > +   if (multipath < 0)
> > +   return (multipath + 1);
> > +
> > /* check whether a nexthop depends on this kroute */
> > -   if (kr->flags & F_NEXTHOP)
> > -   RB_FOREACH(s, knexthop_tree, KT2KNT(kt))
> > -   if (s->kroute == kr)
> > -   knexthop_validate(kt, s);
> > +   if (kf->flags & F_NEXTHOP)
> > +   RB_FOREACH(n, knexthop_tree, KT2KNT(kt))
> 
> One or two pairs of braces would help
> 

I added some for the first if and the RB_FOREACH().

> > +   if (prefix_compare(>prefix, >nexthop,
> > +   kf->prefixlen) == 0)
> > +   knexthop_validate(kt, n);
> >  
> > -   if (!(kr->flags & F_BGPD) && kr == krm && kr->next == NULL)
> > +   if (!((kf->flags & F_BGPD) || multipath))
> 
> maybe use De Morgan:
> 
>   if (!(kf->flags & F_BGPD) && !multipath)
> 

I used De Morgan since I started with that. Guess the !a && !b form is
better here.

> > /* again remove only once */
> > -   kr_redistribute(IMSG_NETWORK_REMOVE, kt, kr_tofull(kr));
> > +   kr_redistribute(IMSG_NETWORK_REMOVE, kt, kf);
> > +
> > +   if (kf->flags & F_BGPD_INSERTED)
> > +   send_rtmsg(kr_state.fd, RTM_DELETE, kt, kf);
> 
> send_rtmsg() is now called later than before. I suspect that's fine, but I'm
> not 100% sure.

I moved it up before the F_NEXTHOP check. At least then the sequence of
rtmsg generated should be in the expected order.

-- 
:wq Claudio



Re: bgpd more kroute refactor

2022-07-28 Thread Theo Buehler
On Thu, Jul 28, 2022 at 12:48:05PM +0200, Claudio Jeker wrote:
> Next step on the epic saga of cleaning up kroute.c
> 
> Refactor kroute_remove() so that a struct kroute_full can be passed to the
> function. It updates the struct kroute_full with the route that got removed.
> 
> I split the code into kroute[46]_remove() to make kroute_remove() less
> cluttered. The return value of those two functions is a bit overloaded but
> I hope to make this better further down the road.

That's fine for now. An obvious suggestion would be to use an out parameter for
multipath. Let kroute[46]_remove() return -1, 0 (where -1 and 0 have the same
meaning as -2 and -1 in your diff), otherwise return 1. Then you can do:

case AID_INET:
ret = kroute4_remove(kt, kf, any, );
if (ret <= 0)
return ret;
break;

Diff looks good, some comments inline.

ok tb

> 
> -- 
> :wq Claudio
> 
> Index: kroute.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
> retrieving revision 1.283
> diff -u -p -r1.283 kroute.c
> --- kroute.c  27 Jul 2022 17:23:17 -  1.283
> +++ kroute.c  28 Jul 2022 09:20:50 -
> @@ -123,10 +123,6 @@ int  kr4_change(struct ktable *, struct k
>  int  kr6_change(struct ktable *, struct kroute_full *);
>  int  krVPN4_change(struct ktable *, struct kroute_full *);
>  int  krVPN6_change(struct ktable *, struct kroute_full *);
> -int  kr4_delete(struct ktable *, struct kroute_full *);
> -int  kr6_delete(struct ktable *, struct kroute_full *);
> -int  krVPN4_delete(struct ktable *, struct kroute_full *);
> -int  krVPN6_delete(struct ktable *, struct kroute_full *);
>  int  kr_net_match(struct ktable *, struct network_config *, uint16_t, int);
>  struct network *kr_net_find(struct ktable *, struct network *);
>  void kr_net_clear(struct ktable *);
> @@ -144,18 +140,17 @@ struct kroute   *kroute_find(struct ktable
>   uint8_t, uint8_t);
>  struct kroute*kroute_matchgw(struct kroute *, struct bgpd_addr *);
>  int   kroute_insert(struct ktable *, struct kroute_full *);
> -int   kroute_remove(struct ktable *, struct kroute *);
> +int   kroute_remove(struct ktable *, struct kroute_full *, int);
>  void  kroute_clear(struct ktable *);
>  
>  struct kroute6   *kroute6_find(struct ktable *, const struct bgpd_addr *,
>   uint8_t, uint8_t);
>  struct kroute6   *kroute6_matchgw(struct kroute6 *, struct bgpd_addr *);
> -int   kroute6_remove(struct ktable *, struct kroute6 *);
>  void  kroute6_clear(struct ktable *);
>  
>  struct knexthop  *knexthop_find(struct ktable *, struct bgpd_addr *);
>  int   knexthop_insert(struct ktable *, struct knexthop *);
> -int   knexthop_remove(struct ktable *, struct knexthop *);
> +void  knexthop_remove(struct ktable *, struct knexthop *);
>  void  knexthop_clear(struct ktable *);
>  
>  struct kif_node  *kif_find(int);
> @@ -662,18 +657,7 @@ kr_delete(u_int rtableid, struct kroute_
>   return (0);
>   kf->flags |= F_BGPD;
>   kf->priority = RTP_MINE;
> - switch (kf->prefix.aid) {
> - case AID_INET:
> - return (kr4_delete(kt, kf));
> - case AID_INET6:
> - return (kr6_delete(kt, kf));
> - case AID_VPN_IPv4:
> - return (krVPN4_delete(kt, kf));
> - case AID_VPN_IPv6:
> - return (krVPN6_delete(kt, kf));
> - }
> - log_warnx("%s: not handled AID", __func__);
> - return (-1);
> + return kroute_remove(kt, kf, 1);
>  }
>  
>  int
> @@ -689,18 +673,12 @@ kr_flush(u_int rtableid)
>  
>   RB_FOREACH_SAFE(kr, kroute_tree, >krt, next)
>   if ((kr->flags & F_BGPD_INSERTED)) {
> - if (kt->fib_sync)   /* coupled */
> - send_rtmsg(kr_state.fd, RTM_DELETE, kt,
> - kr_tofull(kr));
> - if (kroute_remove(kt, kr) == -1)
> + if (kroute_remove(kt, kr_tofull(kr), 1) == -1)
>   return (-1);
>   }
>   RB_FOREACH_SAFE(kr6, kroute6_tree, >krt6, next6)
>   if ((kr6->flags & F_BGPD_INSERTED)) {
> - if (kt->fib_sync)   /* coupled */
> - send_rtmsg(kr_state.fd, RTM_DELETE, kt,
> - kr6_tofull(kr6));
> - if (kroute6_remove(kt, kr6) == -1)
> + if (kroute_remove(kt, kr6_tofull(kr6), 1) == -1)
>   return (-1);
>   }
>  
> @@ -708,86 +686,6 @@ kr_flush(u_int rtableid)
>   return (0);
>  }
>  
> -int
> -kr4_delete(struct ktable *kt, struct kroute_full *kf)
> -{
> - struct kroute   *kr;
> -
> - if ((kr = kroute_find(kt, >prefix, kf->prefixlen,
> - 

bgpd more kroute refactor

2022-07-28 Thread Claudio Jeker
Next step on the epic saga of cleaning up kroute.c

Refactor kroute_remove() so that a struct kroute_full can be passed to the
function. It updates the struct kroute_full with the route that got removed.

I split the code into kroute[46]_remove() to make kroute_remove() less
cluttered. The return value of those two functions is a bit overloaded but
I hope to make this better further down the road.

-- 
:wq Claudio

Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.283
diff -u -p -r1.283 kroute.c
--- kroute.c27 Jul 2022 17:23:17 -  1.283
+++ kroute.c28 Jul 2022 09:20:50 -
@@ -123,10 +123,6 @@ intkr4_change(struct ktable *, struct k
 intkr6_change(struct ktable *, struct kroute_full *);
 intkrVPN4_change(struct ktable *, struct kroute_full *);
 intkrVPN6_change(struct ktable *, struct kroute_full *);
-intkr4_delete(struct ktable *, struct kroute_full *);
-intkr6_delete(struct ktable *, struct kroute_full *);
-intkrVPN4_delete(struct ktable *, struct kroute_full *);
-intkrVPN6_delete(struct ktable *, struct kroute_full *);
 intkr_net_match(struct ktable *, struct network_config *, uint16_t, int);
 struct network *kr_net_find(struct ktable *, struct network *);
 void   kr_net_clear(struct ktable *);
@@ -144,18 +140,17 @@ struct kroute *kroute_find(struct ktable
uint8_t, uint8_t);
 struct kroute  *kroute_matchgw(struct kroute *, struct bgpd_addr *);
 int kroute_insert(struct ktable *, struct kroute_full *);
-int kroute_remove(struct ktable *, struct kroute *);
+int kroute_remove(struct ktable *, struct kroute_full *, int);
 voidkroute_clear(struct ktable *);
 
 struct kroute6 *kroute6_find(struct ktable *, const struct bgpd_addr *,
uint8_t, uint8_t);
 struct kroute6 *kroute6_matchgw(struct kroute6 *, struct bgpd_addr *);
-int kroute6_remove(struct ktable *, struct kroute6 *);
 voidkroute6_clear(struct ktable *);
 
 struct knexthop*knexthop_find(struct ktable *, struct bgpd_addr *);
 int knexthop_insert(struct ktable *, struct knexthop *);
-int knexthop_remove(struct ktable *, struct knexthop *);
+voidknexthop_remove(struct ktable *, struct knexthop *);
 voidknexthop_clear(struct ktable *);
 
 struct kif_node*kif_find(int);
@@ -662,18 +657,7 @@ kr_delete(u_int rtableid, struct kroute_
return (0);
kf->flags |= F_BGPD;
kf->priority = RTP_MINE;
-   switch (kf->prefix.aid) {
-   case AID_INET:
-   return (kr4_delete(kt, kf));
-   case AID_INET6:
-   return (kr6_delete(kt, kf));
-   case AID_VPN_IPv4:
-   return (krVPN4_delete(kt, kf));
-   case AID_VPN_IPv6:
-   return (krVPN6_delete(kt, kf));
-   }
-   log_warnx("%s: not handled AID", __func__);
-   return (-1);
+   return kroute_remove(kt, kf, 1);
 }
 
 int
@@ -689,18 +673,12 @@ kr_flush(u_int rtableid)
 
RB_FOREACH_SAFE(kr, kroute_tree, >krt, next)
if ((kr->flags & F_BGPD_INSERTED)) {
-   if (kt->fib_sync)   /* coupled */
-   send_rtmsg(kr_state.fd, RTM_DELETE, kt,
-   kr_tofull(kr));
-   if (kroute_remove(kt, kr) == -1)
+   if (kroute_remove(kt, kr_tofull(kr), 1) == -1)
return (-1);
}
RB_FOREACH_SAFE(kr6, kroute6_tree, >krt6, next6)
if ((kr6->flags & F_BGPD_INSERTED)) {
-   if (kt->fib_sync)   /* coupled */
-   send_rtmsg(kr_state.fd, RTM_DELETE, kt,
-   kr6_tofull(kr6));
-   if (kroute6_remove(kt, kr6) == -1)
+   if (kroute_remove(kt, kr6_tofull(kr6), 1) == -1)
return (-1);
}
 
@@ -708,86 +686,6 @@ kr_flush(u_int rtableid)
return (0);
 }
 
-int
-kr4_delete(struct ktable *kt, struct kroute_full *kf)
-{
-   struct kroute   *kr;
-
-   if ((kr = kroute_find(kt, >prefix, kf->prefixlen,
-   kf->priority)) == NULL)
-   return (0);
-
-   if (!(kr->flags & F_BGPD_INSERTED))
-   return (0);
-
-   send_rtmsg(kr_state.fd, RTM_DELETE, kt, kr_tofull(kr));
-
-   if (kroute_remove(kt, kr) == -1)
-   return (-1);
-
-   return (0);
-}
-
-int
-kr6_delete(struct ktable *kt, struct kroute_full *kf)
-{
-   struct kroute6  *kr6;
-
-   if ((kr6 = kroute6_find(kt, >prefix, kf->prefixlen,
-   kf->priority)) == NULL)
-   return (0);
-
-   if (!(kr6->flags & F_BGPD_INSERTED))
-   return (0);
-
-