Re: bgpd force fib sync in fetchtable

2022-08-02 Thread Claudio Jeker
On Tue, Aug 02, 2022 at 12:58:13PM +0100, Stuart Henderson wrote:
> On 2022/08/02 12:34, Claudio Jeker wrote:
> > On startup we load the routing table in bgpd and at that moment a cleanup
> > of old bgpd routes should happen. I noticed this is not the case because
> > fib_sync is not set and so send_rtmsg() just returns.
> > I think we need to force fib_sync in fetchtable() to make sure the cleanup
> > happens correctly.
> 
> How much of a problem is it that this clears any existing bgpd routes
> if "fib update no" is set?
> 
> I guess in the common case there won't be any anyway, but is there
> any use-case for running two copies of bgpd, one with fib update, one
> without, on the same machine?

One case I see is if you run two bgpd in on two different rtables (not
rdomains). In that case the table used for nexthop lookups will be used by
both daemons. Not sure if this is an issue or not.

The problem with fib_sync being 0 comes from parse.y::parse_config()

if ((rr = add_rib("Adj-RIB-In")) == NULL)
fatal("add_rib failed");
rr->flags = F_RIB_NOFIB | F_RIB_NOEVALUATE;
if ((rr = add_rib("Loc-RIB")) == NULL)
fatal("add_rib failed");
rib_add_fib(rr, conf->default_tableid);
rr->flags = F_RIB_LOCAL;

First the Adj-RIB-In is added then the Loc-RIB. The Adj-RIB-In has
F_RIB_NOFIB | F_RIB_NOEVALUATE and so fib_sync is off when fetchtable is
called in ktable_new().

Afterwards the ktable is updated by Loc-RIB and fib_sync is enabled but
the cleanup did not happen.

So a quick fix is to switch the order in parse.y but heck that probably
breaks later on if used with other tables.

I guess fetchtable() needs to become smarter so that it can be called more
than once. That would also allow to handle RTM_DESYNC in bgpd.
 
> > OK?
> > -- 
> > :wq Claudio
> > 
> > Index: kroute.c
> > ===
> > RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
> > retrieving revision 1.285
> > diff -u -p -r1.285 kroute.c
> > --- kroute.c28 Jul 2022 14:05:13 -  1.285
> > +++ kroute.c2 Aug 2022 10:13:59 -
> > @@ -2726,6 +2726,7 @@ fetchtable(struct ktable *kt)
> > char*buf = NULL, *next, *lim;
> > struct rt_msghdr*rtm;
> > struct kroute_full   kf;
> > +   int  fib_sync;
> >  
> > mib[0] = CTL_NET;
> > mib[1] = PF_ROUTE;
> > @@ -2754,6 +2755,10 @@ fetchtable(struct ktable *kt)
> > }
> > }
> >  
> > +   /* force fib_sync on during fetch */
> > +   fib_sync = kt->fib_sync;
> > +   kt->fib_sync = 1;
> > +
> > lim = buf + len;
> > for (next = buf; next < lim; next += rtm->rtm_msglen) {
> > rtm = (struct rt_msghdr *)next;
> > @@ -2768,6 +2773,8 @@ fetchtable(struct ktable *kt)
> > else
> > kroute_insert(kt, &kf);
> > }
> > +   kt->fib_sync = fib_sync;
> > +
> > free(buf);
> > return (0);
> >  }
> > 
> 

-- 
:wq Claudio



Re: bgpd force fib sync in fetchtable

2022-08-02 Thread Stuart Henderson
On 2022/08/02 12:34, Claudio Jeker wrote:
> On startup we load the routing table in bgpd and at that moment a cleanup
> of old bgpd routes should happen. I noticed this is not the case because
> fib_sync is not set and so send_rtmsg() just returns.
> I think we need to force fib_sync in fetchtable() to make sure the cleanup
> happens correctly.

How much of a problem is it that this clears any existing bgpd routes
if "fib update no" is set?

I guess in the common case there won't be any anyway, but is there
any use-case for running two copies of bgpd, one with fib update, one
without, on the same machine?

> OK?
> -- 
> :wq Claudio
> 
> Index: kroute.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
> retrieving revision 1.285
> diff -u -p -r1.285 kroute.c
> --- kroute.c  28 Jul 2022 14:05:13 -  1.285
> +++ kroute.c  2 Aug 2022 10:13:59 -
> @@ -2726,6 +2726,7 @@ fetchtable(struct ktable *kt)
>   char*buf = NULL, *next, *lim;
>   struct rt_msghdr*rtm;
>   struct kroute_full   kf;
> + int  fib_sync;
>  
>   mib[0] = CTL_NET;
>   mib[1] = PF_ROUTE;
> @@ -2754,6 +2755,10 @@ fetchtable(struct ktable *kt)
>   }
>   }
>  
> + /* force fib_sync on during fetch */
> + fib_sync = kt->fib_sync;
> + kt->fib_sync = 1;
> +
>   lim = buf + len;
>   for (next = buf; next < lim; next += rtm->rtm_msglen) {
>   rtm = (struct rt_msghdr *)next;
> @@ -2768,6 +2773,8 @@ fetchtable(struct ktable *kt)
>   else
>   kroute_insert(kt, &kf);
>   }
> + kt->fib_sync = fib_sync;
> +
>   free(buf);
>   return (0);
>  }
> 



Re: bgpd force fib sync in fetchtable

2022-08-02 Thread Claudio Jeker
On Tue, Aug 02, 2022 at 01:44:42PM +0200, Theo Buehler wrote:
> On Tue, Aug 02, 2022 at 12:34:40PM +0200, Claudio Jeker wrote:
> > On startup we load the routing table in bgpd and at that moment a cleanup
> > of old bgpd routes should happen. I noticed this is not the case because
> > fib_sync is not set and so send_rtmsg() just returns.
> > I think we need to force fib_sync in fetchtable() to make sure the cleanup
> > happens correctly.
> 
> If I understand correctly, this ignores the fs flag of ktable_new() for
> the fetchtable() call. In particular, 'fib-update no' is ignored in this
> situation. Is that intentional?

I think it is. At least I thought that even with 'fib-update no' bgpd
should cleanup the FIB. Now that may be a problem when people run multiple
bgpds with 'fib-update no'.

I see if I can find a solution that is a smaller hammer to fix this.

> > 
> > OK?
> > -- 
> > :wq Claudio
> > 
> > Index: kroute.c
> > ===
> > RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
> > retrieving revision 1.285
> > diff -u -p -r1.285 kroute.c
> > --- kroute.c28 Jul 2022 14:05:13 -  1.285
> > +++ kroute.c2 Aug 2022 10:13:59 -
> > @@ -2726,6 +2726,7 @@ fetchtable(struct ktable *kt)
> > char*buf = NULL, *next, *lim;
> > struct rt_msghdr*rtm;
> > struct kroute_full   kf;
> > +   int  fib_sync;
> >  
> > mib[0] = CTL_NET;
> > mib[1] = PF_ROUTE;
> > @@ -2754,6 +2755,10 @@ fetchtable(struct ktable *kt)
> > }
> > }
> >  
> > +   /* force fib_sync on during fetch */
> > +   fib_sync = kt->fib_sync;
> > +   kt->fib_sync = 1;
> > +
> > lim = buf + len;
> > for (next = buf; next < lim; next += rtm->rtm_msglen) {
> > rtm = (struct rt_msghdr *)next;
> > @@ -2768,6 +2773,8 @@ fetchtable(struct ktable *kt)
> > else
> > kroute_insert(kt, &kf);
> > }
> > +   kt->fib_sync = fib_sync;
> > +
> > free(buf);
> > return (0);
> >  }
> > 
> 

-- 
:wq Claudio



Re: bgpd force fib sync in fetchtable

2022-08-02 Thread Theo Buehler
On Tue, Aug 02, 2022 at 12:34:40PM +0200, Claudio Jeker wrote:
> On startup we load the routing table in bgpd and at that moment a cleanup
> of old bgpd routes should happen. I noticed this is not the case because
> fib_sync is not set and so send_rtmsg() just returns.
> I think we need to force fib_sync in fetchtable() to make sure the cleanup
> happens correctly.

If I understand correctly, this ignores the fs flag of ktable_new() for
the fetchtable() call. In particular, 'fib-update no' is ignored in this
situation. Is that intentional?

> 
> OK?
> -- 
> :wq Claudio
> 
> Index: kroute.c
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
> retrieving revision 1.285
> diff -u -p -r1.285 kroute.c
> --- kroute.c  28 Jul 2022 14:05:13 -  1.285
> +++ kroute.c  2 Aug 2022 10:13:59 -
> @@ -2726,6 +2726,7 @@ fetchtable(struct ktable *kt)
>   char*buf = NULL, *next, *lim;
>   struct rt_msghdr*rtm;
>   struct kroute_full   kf;
> + int  fib_sync;
>  
>   mib[0] = CTL_NET;
>   mib[1] = PF_ROUTE;
> @@ -2754,6 +2755,10 @@ fetchtable(struct ktable *kt)
>   }
>   }
>  
> + /* force fib_sync on during fetch */
> + fib_sync = kt->fib_sync;
> + kt->fib_sync = 1;
> +
>   lim = buf + len;
>   for (next = buf; next < lim; next += rtm->rtm_msglen) {
>   rtm = (struct rt_msghdr *)next;
> @@ -2768,6 +2773,8 @@ fetchtable(struct ktable *kt)
>   else
>   kroute_insert(kt, &kf);
>   }
> + kt->fib_sync = fib_sync;
> +
>   free(buf);
>   return (0);
>  }
> 



bgpd force fib sync in fetchtable

2022-08-02 Thread Claudio Jeker
On startup we load the routing table in bgpd and at that moment a cleanup
of old bgpd routes should happen. I noticed this is not the case because
fib_sync is not set and so send_rtmsg() just returns.
I think we need to force fib_sync in fetchtable() to make sure the cleanup
happens correctly.

OK?
-- 
:wq Claudio

Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.285
diff -u -p -r1.285 kroute.c
--- kroute.c28 Jul 2022 14:05:13 -  1.285
+++ kroute.c2 Aug 2022 10:13:59 -
@@ -2726,6 +2726,7 @@ fetchtable(struct ktable *kt)
char*buf = NULL, *next, *lim;
struct rt_msghdr*rtm;
struct kroute_full   kf;
+   int  fib_sync;
 
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@@ -2754,6 +2755,10 @@ fetchtable(struct ktable *kt)
}
}
 
+   /* force fib_sync on during fetch */
+   fib_sync = kt->fib_sync;
+   kt->fib_sync = 1;
+
lim = buf + len;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
@@ -2768,6 +2773,8 @@ fetchtable(struct ktable *kt)
else
kroute_insert(kt, &kf);
}
+   kt->fib_sync = fib_sync;
+
free(buf);
return (0);
 }