mirror of
https://github.com/openbsd/src.git
synced 2025-01-10 06:47:55 -08:00
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@
This commit is contained in:
parent
3e253b4759
commit
965dc109d3
@ -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,
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user