On Wed, Jun 08, 2022 at 06:10:21PM +0200, Theo Buehler wrote:
> On Wed, Jun 08, 2022 at 01:28:14PM +0200, Claudio Jeker wrote:
> > The idea behind this diff is to use struct kroute_full in more places.
> > Mainly when parsing route messages. This allows to factor out the pure
> > route message parsing into dispatch_rtmsg_addr() and use it in both the
> > gerneral routing socket code but also in fetchtables(). Which removes some
> > duplicated code.
> >
> > As a second step then this kroute_full is applied to the kroute tree. Here
> > I limited my changes to be minimal for now. A follow up will look more
> > into kr_fib_change() and tries to streamline that code and the bits in
> > fetchtable().
> >
> > Also struct kroute_full could be used in more places with the goal to have
> > less mostly similar function for IPv4, IPv6 and the L3VPNs. Again this is
> > for later.
> >
> > This should behave the same as before but dispatch_rtmsg_addr() decides
> > now in a different way if a route is connected or not (using the
> > RTF_GATEWAY flag for this). With this loopback routes show now up as
> > connected. It should have no noticable impact on routing.
> >
> > Please give this a good test.
>
> I spent some time with this diff. This is outside my comfort zone. I'll
> need to read this once more with a fresh head.
>
> I like the direction and less spaghetti is good.
>
> Some small remarks and questions inline.
Thanks for looking into this. Not many people around that actually
understand the route socket so I know this is way out of everyones comfort
zone. The kroute code got hammered into shape and then copied around way
to many times. A lot of the code is pure spahetti. I try to work with
smaller diffs to make review somewhat possible.
> > Index: kroute.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
> > retrieving revision 1.251
> > diff -u -p -r1.251 kroute.c
> > --- kroute.c 7 Jun 2022 16:42:07 -0000 1.251
> > +++ kroute.c 7 Jun 2022 17:05:37 -0000
> > @@ -3482,23 +3385,34 @@ dispatch_rtmsg(u_int rdomain)
> > case RTM_ADD:
> > case RTM_CHANGE:
> > case RTM_DELETE:
> > - sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
> > - get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
> > -
> > if (rtm->rtm_pid == kr_state.pid) /* cause by us */
> > continue;
> >
> > - if (rtm->rtm_errno) /* failed attempts */
> > - continue;
> > + /* failed attempts */
> > + if (rtm->rtm_errno || !(rtm->rtm_flags & RTF_DONE))
> > + return (-1);
> >
> > - if (rtm->rtm_flags & RTF_LLINFO) /* arp cache */
> > + if ((kt = ktable_get(rtm->rtm_tableid)) == NULL)
> > continue;
> >
> > - if ((kt = ktable_get(rtm->rtm_tableid)) == NULL)
> > + if (dispatch_rtmsg_addr(rtm, &kl) == -1)
> > continue;
> >
> > - if (dispatch_rtmsg_addr(rtm, rti_info, kt) == -1)
> > - return (-1);
> > + if (rtm->rtm_flags & RTF_MPATH)
> > + mpath = 1;
>
> I guess the #ifdef RTF_MPATH was dropped since kroute.c is no longer
> built outside of OpenBSD with recent -portable changes?
Yes, also the time when OpenBSD had no RTF_MPATH has long passed. So
I see no reason to clutter this code with #ifdefs.
For portable I would love to split the code further up so that the kroute
code is portable but the routing socket bits are per platform. Right now
changes to kroute.c are a pain since I need to track also the protable
files.
> > @@ -3517,191 +3431,190 @@ dispatch_rtmsg(u_int rdomain)
> > }
> >
> > int
> > -dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct sockaddr
> > *rti_info[RTAX_MAX],
> > - struct ktable *kt)
> > +dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct kroute_full *kr)
>
> This is the only kroute_full called kr in the entire file. I would
> prefer calling it kl (or kf as in the older code you don't touch).
Naming is hard. I agree using kl may be better here. Will adjust the code.
> > case AF_INET:
> > - prefix.aid = AID_INET;
> > - prefix.v4.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
> > sa_in = (struct sockaddr_in *)rti_info[RTAX_NETMASK];
> > if (sa_in != NULL) {
> > if (sa_in->sin_len != 0)
> > - prefixlen = mask2prefixlen(
> > + kr->prefixlen = mask2prefixlen(
> > sa_in->sin_addr.s_addr);
>
> I would wrap this the same way as the assignment a few lines down:
>
> kr->prefixlen =
> mask2prefixlen(sa_in->sin_addr.s_addr);
Yes, indeed.
> > case AID_INET:
> > - sa_in = (struct sockaddr_in *)sa;
> > - if ((kr = kroute_find(kt, prefix.v4.s_addr, prefixlen,
> > - prio)) != NULL) {
> > + if ((kr = kroute_find(kt, kl->prefix.v4.s_addr, kl->prefixlen,
> > + kl->priority)) != NULL) {
> > if (kr->r.flags & F_KERNEL) {
> > /* get the correct route */
> > - if (mpath && rtm->rtm_type == RTM_CHANGE &&
> > - (kr = kroute_matchgw(kr, sa_in)) == NULL) {
> > + if (mpath && type == RTM_CHANGE &&
> > + (kr = kroute_matchgw(kr, &kl->nexthop)) ==
> > + NULL) {
> > log_warnx("%s[change]: "
> > "mpath route not found", __func__);
> > goto add4;
> > - } else if (mpath && rtm->rtm_type == RTM_ADD)
> > + } else if (mpath && type == RTM_ADD)
> > goto add4;
> >
> > - if (sa_in != NULL) {
> > + if (kl->nexthop.aid == AID_INET) {
> > if (kr->r.nexthop.s_addr !=
> > - sa_in->sin_addr.s_addr)
> > + kl->nexthop.v4.s_addr)
> > changed = 1;
> > kr->r.nexthop.s_addr =
> > - sa_in->sin_addr.s_addr;
> > + kl->nexthop.v4.s_addr;
>
> why is there no kr->r.ifindex assignment here?
I don't know. The old code was already like this. I remember that ifindex
was unreliable in the old times but again that is like 5+ years ago.
I did not want to introduce code changes which I'm sure wont cause
trouble. I think this is something to tackle at a later stage.
--
:wq Claudio