So the reshuffling made it possible to simply run the reconfigure
of the RIBs in the background and no longer lock up the RDE for
extended times. In short this means that during 'bgpctl reload'
other bgpctl calls no longer block and that also UPDATE from neighbors
are fully processed.
This does not really spead up anything (apart from maybe some cache
related speedups) but it makes it look faster :)
--
:wq Claudio
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.407
diff -u -p -r1.407 rde.c
--- rde.c 3 Aug 2018 14:10:39 -0000 1.407
+++ rde.c 3 Aug 2018 14:18:42 -0000
@@ -90,7 +90,10 @@ void rde_rib_free(struct rib_desc *);
int rde_rdomain_import(struct rde_aspath *, struct rdomain *);
void rde_reload_done(void);
-static void rde_softreconfig_done(void *);
+static void rde_reload_runner(void);
+static void rde_softreconfig_in_done(void *);
+static void rde_softreconfig_out_done(void *);
+static void rde_softreconfig_done(void);
static void rde_softreconfig_out(struct rib_entry *, void *);
static void rde_softreconfig_in(struct rib_entry *, void *);
static void rde_softreconfig_unload_peer(struct rib_entry *, void *);
@@ -132,6 +135,7 @@ struct imsgbuf *ibuf_se;
struct imsgbuf *ibuf_se_ctl;
struct imsgbuf *ibuf_main;
struct rde_memstats rdemem;
+int softreconfig;
struct rde_dump_ctx {
LIST_ENTRY(rde_dump_ctx) entry;
@@ -322,6 +326,9 @@ rde_main(int debug, int verbose)
if (rde_dump_pending() &&
ibuf_se_ctl && ibuf_se_ctl->w.queued <= 10)
rde_dump_runner();
+ if (softreconfig) {
+ rde_reload_runner();
+ }
}
/* do not clean up on shutdown on production, it takes ages. */
@@ -2697,6 +2704,7 @@ rde_reload_done(void)
struct rdomain *rd;
struct rde_peer *peer;
struct filter_head *fh;
+ struct rib_context *ctx;
u_int16_t rid;
int reload = 0;
@@ -2817,14 +2825,55 @@ rde_reload_done(void)
filterlist_free(ribs[rid].in_rules_tmp);
ribs[rid].in_rules_tmp = NULL;
}
+ log_info("RDE reconfigured");
- if (reload > 0)
- rib_dump(&ribs[RIB_ADJ_IN].rib, rde_softreconfig_in, NULL,
- AID_UNSPEC);
+ softreconfig++;
+ if (reload > 0) {
+ ctx = &ribs[RIB_ADJ_IN].ribctx;
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->ctx_rib = &ribs[RIB_ADJ_IN].rib;
+ ctx->ctx_arg = &ribs[RIB_ADJ_IN];
+ ctx->ctx_upcall = rde_softreconfig_in;
+ ctx->ctx_done = rde_softreconfig_in_done;
+ ctx->ctx_aid = AID_UNSPEC;
+ ctx->ctx_count = RDE_RUNNER_ROUNDS;
+ ribs[RIB_ADJ_IN].dumping = 1;
+ log_info("running softreconfig in");
+ } else {
+ rde_softreconfig_in_done(&ribs[RIB_ADJ_IN]);
+ }
+}
+
+static void
+rde_reload_runner(void)
+{
+ u_int16_t rid;
+
+ for (rid = 0; rid < rib_size; rid++) {
+ if (*ribs[rid].name == '\0')
+ continue;
+ if (ribs[rid].dumping)
+ rib_dump_r(&ribs[rid].ribctx);
+ }
+}
+
+static void
+rde_softreconfig_in_done(void *arg)
+{
+ struct rib_desc *rib = arg;
+ struct rde_peer *peer;
+ u_int16_t rid;
+
+ /* Adj-RIB-In run is done */
+ softreconfig--;
+ rib->dumping = 0;
/* now do the Adj-RIB-Out sync */
- for (rid = 0; rid < rib_size; rid++)
+ for (rid = 0; rid < rib_size; rid++) {
+ if (*ribs[rid].name == '\0')
+ continue;
ribs[rid].state = RECONF_NONE;
+ }
LIST_FOREACH(peer, &peerlist, peer_l) {
if (peer->reconf_out)
@@ -2834,18 +2883,53 @@ rde_reload_done(void)
peer_dump(peer->conf.id, AID_UNSPEC);
}
- for (rid = 0; rid < rib_size; rid++)
- if (ribs[rid].state == RECONF_RELOAD)
- rib_dump(&ribs[rid].rib, rde_softreconfig_out, NULL,
- AID_UNSPEC);
+ for (rid = 0; rid < rib_size; rid++) {
+ if (*ribs[rid].name == '\0')
+ continue;
+ if (ribs[rid].state == RECONF_RELOAD) {
+ struct rib_context *ctx;
+
+ ctx = &ribs[rid].ribctx;
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->ctx_rib = &ribs[rid].rib;
+ ctx->ctx_arg = &ribs[rid];
+ ctx->ctx_upcall = rde_softreconfig_out;
+ ctx->ctx_done = rde_softreconfig_out_done;
+ ctx->ctx_aid = AID_UNSPEC;
+ ctx->ctx_count = RDE_RUNNER_ROUNDS;
+ ribs[rid].dumping = 1;
+ softreconfig++;
+ log_info("starting softreconfig out for rib %s",
+ ribs[rid].name);
+ }
+ }
- rde_softreconfig_done(NULL);
+ /* if nothing to do move to last stage */
+ if (softreconfig == 0)
+ rde_softreconfig_done();
}
static void
-rde_softreconfig_done(void *arg)
+rde_softreconfig_out_done(void *arg)
{
- u_int16_t rid;
+ struct rib_desc *rib = arg;
+
+ /* this RIB dump is done */
+ softreconfig--;
+ rib->dumping = 0;
+ log_info("softreconfig out done for %s", rib->name);
+
+ /* but other dumps are still running */
+ if (softreconfig > 0)
+ return;
+
+ rde_softreconfig_done();
+}
+
+static void
+rde_softreconfig_done(void)
+{
+ u_int16_t rid;
filterlist_free(out_rules_tmp);
out_rules_tmp = NULL;
@@ -2858,7 +2942,7 @@ rde_softreconfig_done(void *arg)
free_prefixsets(prefixsets_old);
prefixsets_old = NULL;
- log_info("RDE reconfigured");
+ log_info("RDE soft reconfiguration done");
imsg_compose(ibuf_main, IMSG_RECONF_DONE, 0, 0,
-1, NULL, 0);
}
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.182
diff -u -p -r1.182 rde.h
--- rde.h 31 Jul 2018 15:30:04 -0000 1.182
+++ rde.h 3 Aug 2018 14:18:42 -0000
@@ -293,9 +293,11 @@ struct rib {
struct rib_desc {
char name[PEER_DESCR_LEN];
struct rib rib;
+ struct rib_context ribctx;
struct filter_head *in_rules;
struct filter_head *in_rules_tmp;
enum reconf_action state;
+ u_int8_t dumping;
};
#define RIB_ADJ_IN 0