diff options
author | 2019-08-05 08:46:55 +0000 | |
---|---|---|
committer | 2019-08-05 08:46:55 +0000 | |
commit | 965dc109d3052b85628e526001d4d3b71a1f71cd (patch) | |
tree | dbdd9b38a8e198184532ba2b5e1abb7ca70a0b2d | |
parent | Favor vn_close() in the error path of diskmapioctl() since side-effects (diff) | |
download | wireguard-openbsd-965dc109d3052b85628e526001d4d3b71a1f71cd.tar.xz wireguard-openbsd-965dc109d3052b85628e526001d4d3b71a1f71cd.zip |
Cleanup config reload in the RDE. Use the bgpd_conf struct to store sets
and l3vpns instead of temporary globals. Also rework rde_reload_done to
free filters and sets earlier. The soft-reconfiguration process no longer
needs the previous filters / sets to do its work since there is a full
Adj-RIB-Out.
OK benno@
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 6 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/config.c | 14 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 4 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 94 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_sets.c | 3 |
7 files changed, 50 insertions, 84 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index c276c398d7c..4a666a3cff0 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.223 2019/08/05 08:36:19 claudio Exp $ */ +/* $OpenBSD: bgpd.c,v 1.224 2019/08/05 08:46:55 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -610,12 +610,12 @@ reconfigure(char *conffile, struct bgpd_config *conf) } /* as-sets for filters in the RDE */ - while ((aset = SIMPLEQ_FIRST(conf->as_sets)) != NULL) { + while ((aset = SIMPLEQ_FIRST(&conf->as_sets)) != NULL) { struct ibuf *wbuf; u_int32_t *as; size_t i, l, n; - SIMPLEQ_REMOVE_HEAD(conf->as_sets, entry); + SIMPLEQ_REMOVE_HEAD(&conf->as_sets, entry); as = set_get(aset->set, &n); if ((wbuf = imsg_create(ibuf_rde, IMSG_RECONF_AS_SET, 0, 0, diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 56c99e9f585..ed6ca19fc4e 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.390 2019/07/23 06:26:44 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.391 2019/08/05 08:46:55 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -284,7 +284,7 @@ struct bgpd_config { struct rde_prefixset_head rde_prefixsets; struct rde_prefixset_head rde_originsets; struct rde_prefixset rde_roa; - struct as_set_head *as_sets; + struct as_set_head as_sets; char *csock; char *rcsock; int flags; @@ -1170,6 +1170,7 @@ int control_imsg_relay(struct imsg *); /* config.c */ struct bgpd_config *new_config(void); void copy_config(struct bgpd_config *, struct bgpd_config *); +void free_l3vpns(struct l3vpn_head *); void free_config(struct bgpd_config *); void free_prefixsets(struct prefixset_head *); void free_rde_prefixsets(struct rde_prefixset_head *); diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c index 32057ec5d70..0d04a4ee333 100644 --- a/usr.sbin/bgpd/config.c +++ b/usr.sbin/bgpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.90 2019/05/29 08:48:00 claudio Exp $ */ +/* $OpenBSD: config.c,v 1.91 2019/08/05 08:46:55 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -33,7 +33,6 @@ int host_ip(const char *, struct bgpd_addr *, u_int8_t *); void free_networks(struct network_head *); -void free_l3vpns(struct l3vpn_head *); struct bgpd_config * new_config(void) @@ -43,8 +42,6 @@ new_config(void) if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL) fatal(NULL); - if ((conf->as_sets = calloc(1, sizeof(struct as_set_head))) == NULL) - fatal(NULL); if ((conf->filters = calloc(1, sizeof(struct filter_head))) == NULL) fatal(NULL); if ((conf->listen_addrs = calloc(1, sizeof(struct listen_addrs))) == @@ -62,7 +59,7 @@ new_config(void) SIMPLEQ_INIT(&conf->rde_prefixsets); SIMPLEQ_INIT(&conf->rde_originsets); RB_INIT(&conf->roa); - SIMPLEQ_INIT(conf->as_sets); + SIMPLEQ_INIT(&conf->as_sets); TAILQ_INIT(conf->filters); TAILQ_INIT(conf->listen_addrs); @@ -168,8 +165,8 @@ free_config(struct bgpd_config *conf) free_prefixsets(&conf->originsets); free_rde_prefixsets(&conf->rde_prefixsets); free_rde_prefixsets(&conf->rde_originsets); + as_sets_free(&conf->as_sets); free_prefixtree(&conf->roa); - as_sets_free(conf->as_sets); while ((la = TAILQ_FIRST(conf->listen_addrs)) != NULL) { TAILQ_REMOVE(conf->listen_addrs, la, entry); @@ -250,9 +247,8 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config *conf) SIMPLEQ_CONCAT(&xconf->originsets, &conf->originsets); /* switch the as_sets, first remove the old ones */ - as_sets_free(xconf->as_sets); - xconf->as_sets = conf->as_sets; - conf->as_sets = NULL; + as_sets_free(&xconf->as_sets); + SIMPLEQ_CONCAT(&xconf->as_sets, &conf->as_sets); /* switch the network statements, but first remove the old ones */ free_networks(&xconf->networks); diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index e48fdb4009e..5c8a28309ed 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.396 2019/07/24 20:25:27 benno Exp $ */ +/* $OpenBSD: parse.y,v 1.397 2019/08/05 08:46:55 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -1947,7 +1947,7 @@ filter_as_t : filter_as_type filter_as { a->a.type = $1; } | filter_as_type ASSET STRING { - if (as_sets_lookup(conf->as_sets, $3) == NULL) { + if (as_sets_lookup(&conf->as_sets, $3) == NULL) { yyerror("as-set \"%s\" not defined", $3); free($3); YYERROR; @@ -4412,12 +4412,12 @@ new_as_set(char *name) { struct as_set *aset; - if (as_sets_lookup(conf->as_sets, name) != NULL) { + if (as_sets_lookup(&conf->as_sets, name) != NULL) { yyerror("as-set \"%s\" already exists", name); return -1; } - aset = as_sets_new(conf->as_sets, name, 0, sizeof(u_int32_t)); + aset = as_sets_new(&conf->as_sets, name, 0, sizeof(u_int32_t)); if (aset == NULL) fatal(NULL); diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index 81bfdba4ee4..0b5c7ec8e4b 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.138 2019/07/24 20:25:27 benno Exp $ */ +/* $OpenBSD: printconf.c,v 1.139 2019/08/05 08:46:55 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -996,7 +996,7 @@ print_config(struct bgpd_config *conf, struct rib_names *rib_l) print_mainconf(conf); print_roa(&conf->roa); - print_as_sets(conf->as_sets); + print_as_sets(&conf->as_sets); print_prefixsets(&conf->prefixsets); print_originsets(&conf->originsets); TAILQ_FOREACH(n, &conf->networks, entry) diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index dadaf52945a..775d39a165b 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.480 2019/08/05 08:36:19 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.481 2019/08/05 08:46:55 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -117,12 +117,7 @@ struct bgpd_config *conf, *nconf; time_t reloadtime; struct rde_peer_head peerlist; struct rde_peer *peerself; -struct rde_prefixset_head prefixsets_old; -struct rde_prefixset_head originsets_old; -struct rde_prefixset roa_old; -struct as_set_head *as_sets_tmp, *as_sets_old; struct filter_head *out_rules, *out_rules_tmp; -struct l3vpn_head *l3vpns_l, *newdomains; struct imsgbuf *ibuf_se; struct imsgbuf *ibuf_se_ctl; struct imsgbuf *ibuf_main; @@ -225,11 +220,6 @@ rde_main(int debug, int verbose) fatal(NULL); TAILQ_INIT(out_rules); - l3vpns_l = calloc(1, sizeof(struct l3vpn_head)); - if (l3vpns_l == NULL) - fatal(NULL); - SIMPLEQ_INIT(l3vpns_l); - conf = new_config(); log_info("route decision engine ready"); @@ -776,19 +766,10 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) sizeof(struct bgpd_config)) fatalx("IMSG_RECONF_CONF bad len"); reloadtime = time(NULL); - as_sets_tmp = calloc(1, - sizeof(struct as_set_head)); - if (as_sets_tmp == NULL) - fatal(NULL); - SIMPLEQ_INIT(as_sets_tmp); out_rules_tmp = calloc(1, sizeof(struct filter_head)); if (out_rules_tmp == NULL) fatal(NULL); TAILQ_INIT(out_rules_tmp); - newdomains = calloc(1, sizeof(struct l3vpn_head)); - if (newdomains == NULL) - fatal(NULL); - SIMPLEQ_INIT(newdomains); nconf = new_config(); copy_config(nconf, imsg.data); @@ -854,7 +835,7 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) if (r->match.as.flags & AS_FLAG_AS_SET_NAME) { struct as_set * aset; - aset = as_sets_lookup(as_sets_tmp, + aset = as_sets_lookup(&nconf->as_sets, r->match.as.name); if (aset == NULL) { log_warnx("%s: no as-set for %s", @@ -951,9 +932,9 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) fatalx("IMSG_RECONF_AS_SET bad len"); memcpy(&nmemb, imsg.data, sizeof(nmemb)); name = (char *)imsg.data + sizeof(nmemb); - if (as_sets_lookup(as_sets_tmp, name) != NULL) + if (as_sets_lookup(&nconf->as_sets, name) != NULL) fatalx("duplicate as-set %s", name); - last_as_set = as_sets_new(as_sets_tmp, name, nmemb, + last_as_set = as_sets_new(&nconf->as_sets, name, nmemb, sizeof(u_int32_t)); break; case IMSG_RECONF_AS_SET_ITEMS: @@ -975,7 +956,8 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) memcpy(vpn, imsg.data, sizeof(struct l3vpn)); TAILQ_INIT(&vpn->import); TAILQ_INIT(&vpn->export); - SIMPLEQ_INSERT_TAIL(newdomains, vpn, entry); + TAILQ_INIT(&vpn->net_l); + SIMPLEQ_INSERT_TAIL(&nconf->l3vpns, vpn, entry); break; case IMSG_RECONF_VPN_EXPORT: if (vpn == NULL) { @@ -2730,7 +2712,7 @@ rde_send_kroute(struct rib *rib, struct prefix *new, struct prefix *old) /* not Loc-RIB, no update for VPNs */ break; - SIMPLEQ_FOREACH(vpn, l3vpns_l, entry) { + SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry) { if (!rde_l3vpn_import(prefix_communities(p), vpn)) continue; /* must send exit_nexthop so that correct MPLS tunnel @@ -3016,9 +2998,12 @@ rde_send_nexthop(struct bgpd_addr *next, int valid) void rde_reload_done(void) { - struct l3vpn *vpn; struct rde_peer *peer; struct filter_head *fh; + struct rde_prefixset_head prefixsets_old; + struct rde_prefixset_head originsets_old; + struct rde_prefixset roa_old; + struct as_set_head as_sets_old; u_int16_t rid; int reload = 0; @@ -3033,19 +3018,25 @@ rde_reload_done(void) SIMPLEQ_INIT(&prefixsets_old); SIMPLEQ_INIT(&originsets_old); + SIMPLEQ_INIT(&as_sets_old); SIMPLEQ_CONCAT(&prefixsets_old, &conf->rde_prefixsets); SIMPLEQ_CONCAT(&originsets_old, &conf->rde_originsets); + SIMPLEQ_CONCAT(&as_sets_old, &conf->as_sets); roa_old = conf->rde_roa; - as_sets_old = conf->as_sets; copy_config(conf, nconf); /* need to copy the sets and roa table and clear them in nconf */ SIMPLEQ_CONCAT(&conf->rde_prefixsets, &nconf->rde_prefixsets); SIMPLEQ_CONCAT(&conf->rde_originsets, &nconf->rde_originsets); + SIMPLEQ_CONCAT(&conf->as_sets, &nconf->as_sets); + conf->rde_roa = nconf->rde_roa; - conf->as_sets = nconf->as_sets; memset(&nconf->rde_roa, 0, sizeof(nconf->rde_roa)); - nconf->as_sets = NULL; + + /* apply new set of l3vpn, sync will be done later */ + free_l3vpns(&conf->l3vpns); + SIMPLEQ_CONCAT(&conf->l3vpns, &nconf->l3vpns); + /* XXX WHERE IS THE SYNC ??? */ free_config(nconf); nconf = NULL; @@ -3059,17 +3050,6 @@ rde_reload_done(void) peerself->conf.remote_masklen = 32; peerself->short_as = conf->short_as; - /* apply new set of l3vpn, sync will be done later */ - while ((vpn = SIMPLEQ_FIRST(l3vpns_l)) != NULL) { - SIMPLEQ_REMOVE_HEAD(l3vpns_l, entry); - filterset_free(&vpn->import); - filterset_free(&vpn->export); - free(vpn); - } - free(l3vpns_l); - l3vpns_l = newdomains; - /* XXX WHERE IS THE SYNC ??? */ - /* check if roa changed */ if (trie_equal(&conf->rde_roa.th, &roa_old.th) == 0) { log_debug("roa change: reloading Adj-RIB-In"); @@ -3080,11 +3060,7 @@ rde_reload_done(void) rde_mark_prefixsets_dirty(&prefixsets_old, &conf->rde_prefixsets); rde_mark_prefixsets_dirty(&originsets_old, &conf->rde_originsets); - as_sets_mark_dirty(as_sets_old, as_sets_tmp); - - /* swap the as_sets */ - conf->as_sets = as_sets_tmp; - as_sets_tmp = NULL; + as_sets_mark_dirty(&as_sets_old, &conf->as_sets); /* * make the new filter rules the active one but keep the old for @@ -3162,6 +3138,14 @@ rde_reload_done(void) filterlist_free(ribs[rid].in_rules_tmp); ribs[rid].in_rules_tmp = NULL; } + + filterlist_free(out_rules_tmp); + out_rules_tmp = NULL; + /* old filters removed, free all sets */ + free_rde_prefixsets(&prefixsets_old); + free_rde_prefixsets(&originsets_old); + as_sets_free(&as_sets_old); + log_info("RDE reconfigured"); if (reload > 0) { @@ -3253,19 +3237,12 @@ rde_softreconfig_done(void) { u_int16_t rid; - filterlist_free(out_rules_tmp); - out_rules_tmp = NULL; for (rid = 0; rid < rib_size; rid++) { if (!rib_valid(rid)) continue; ribs[rid].state = RECONF_NONE; } - free_rde_prefixsets(&prefixsets_old); - free_rde_prefixsets(&originsets_old); - as_sets_free(as_sets_old); - as_sets_old = NULL; - log_info("RDE soft reconfiguration done"); imsg_compose(ibuf_main, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0); @@ -3850,7 +3827,7 @@ network_add(struct network_config *nc, struct filterstate *state) u_int16_t i; if (nc->rd != 0) { - SIMPLEQ_FOREACH(vpn, l3vpns_l, entry) { + SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry) { if (vpn->rd != nc->rd) continue; switch (nc->prefix.aid) { @@ -3935,7 +3912,7 @@ network_delete(struct network_config *nc) u_int32_t i; if (nc->rd) { - SIMPLEQ_FOREACH(vpn, l3vpns_l, entry) { + SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry) { if (vpn->rd != nc->rd) continue; switch (nc->prefix.aid) { @@ -4064,7 +4041,6 @@ network_flush_upcall(struct rib_entry *re, void *ptr) void rde_shutdown(void) { - struct l3vpn *vpn; struct rde_peer *p; u_int32_t i; @@ -4083,13 +4059,7 @@ rde_shutdown(void) filterlist_free(out_rules_tmp); /* kill the VPN configs */ - while ((vpn = SIMPLEQ_FIRST(l3vpns_l)) != NULL) { - SIMPLEQ_REMOVE_HEAD(l3vpns_l, entry); - filterset_free(&vpn->import); - filterset_free(&vpn->export); - free(vpn); - } - free(l3vpns_l); + free_l3vpns(&conf->l3vpns); /* now check everything */ rib_shutdown(); diff --git a/usr.sbin/bgpd/rde_sets.c b/usr.sbin/bgpd/rde_sets.c index 338080284f4..2a8b393d0e4 100644 --- a/usr.sbin/bgpd/rde_sets.c +++ b/usr.sbin/bgpd/rde_sets.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_sets.c,v 1.8 2019/02/14 10:23:28 claudio Exp $ */ +/* $OpenBSD: rde_sets.c,v 1.9 2019/08/05 08:46:55 claudio Exp $ */ /* * Copyright (c) 2018 Claudio Jeker <claudio@openbsd.org> @@ -84,7 +84,6 @@ as_sets_free(struct as_set_head *as_sets) set_free(aset->set); free(aset); } - free(as_sets); } void |