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, &multipath);
> 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.c 27 Jul 2022 17:23:17 -0000 1.283
> > +++ kroute.c 28 Jul 2022 09:20:50 -0000
> > + if ((kr = kroute_find(kt, &kf->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(&kf->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, &kf->nexthop)) == NULL) {
> > + log_warnx("delete %s/%u: route not found",
> > + log_addr(&kf->prefix), kf->prefixlen);
> > + return (-2);
> > + }
> > + }
> > +
> > if (krm == kr) {
> > /* head element */
> > - if (RB_REMOVE(kroute_tree, &kt->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(&kf->prefix, &n->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