While looking into the memory leak reported by florian@ I found a few
other troubles when it comes to properly cleanup on exit. Doing that helps
a lot when looking for leaks :)
This diff is doing general more cleanup in the shutdown paths (removing
config bits and other data structures that have nore been removed before).
It also is a start in making the config handling a bit easier to handle.
Mainly you get a new config with new_config() and after that call
free_config() can be used to remove that config again. The config is a bit
annoying since there is a lot of pointers present and they are also sent
via imsg. This diff introduces a copy_config() to only move the values
we're interested in (and not copying the invalid pointers).
In general more work is needed but this is a decent start.
OK?
--
:wq Claudio
Index: bgpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
retrieving revision 1.212
diff -u -p -r1.212 bgpd.c
--- bgpd.c 14 Feb 2019 14:34:31 -0000 1.212
+++ bgpd.c 1 Mar 2019 10:47:48 -0000
@@ -101,6 +101,7 @@ main(int argc, char *argv[])
{
struct bgpd_config *conf;
struct peer *peer_l, *p;
+ struct rde_rib *rr;
struct pollfd pfd[POLL_MAX];
time_t timeout;
pid_t se_pid = 0, rde_pid = 0, pid;
@@ -124,7 +125,6 @@ main(int argc, char *argv[])
if (saved_argv0 == NULL)
saved_argv0 = "bgpd";
- conf = new_config();
peer_l = NULL;
while ((ch = getopt(argc, argv, "cdD:f:nRSv")) != -1) {
@@ -169,6 +169,7 @@ main(int argc, char *argv[])
usage();
if (cmd_opts & BGPD_OPT_NOACTION) {
+ conf = new_config();
if (parse_config(conffile, conf, &peer_l))
exit(1);
@@ -177,6 +178,16 @@ main(int argc, char *argv[])
conf->filters, conf->mrt, &conf->l3vpns);
else
fprintf(stderr, "configuration OK\n");
+
+ while ((p = peer_l) != NULL) {
+ peer_l = p->next;
+ free(p);
+ }
+ while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
+ free(rr);
+ }
+ free_config(conf);
exit(0);
}
@@ -249,6 +260,7 @@ BROKEN if (pledge("stdio rpath wpath cpa
if (imsg_send_sockets(ibuf_se, ibuf_rde))
fatal("could not establish imsg links");
+ conf = new_config();
quit = reconfigure(conffile, conf, &peer_l);
if (pftable_clear_all() != 0)
quit = 1;
@@ -337,17 +349,23 @@ BROKEN if (pledge("stdio rpath wpath cpa
msgbuf_clear(&ibuf_se->w);
close(ibuf_se->fd);
free(ibuf_se);
+ ibuf_se = NULL;
}
if (ibuf_rde) {
msgbuf_clear(&ibuf_rde->w);
close(ibuf_rde->fd);
free(ibuf_rde);
+ ibuf_rde = NULL;
}
while ((p = peer_l) != NULL) {
peer_l = p->next;
free(p);
}
+ while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
+ free(rr);
+ }
carp_demote_shutdown();
kr_shutdown(conf->fib_priority, conf->default_tableid);
@@ -895,6 +913,8 @@ send_imsg_session(int type, pid_t pid, v
int
send_network(int type, struct network_config *net, struct filter_set_head *h)
{
+ if (quit)
+ return (0);
if (imsg_compose(ibuf_rde, type, 0, 0, -1, net,
sizeof(struct network_config)) == -1)
return (-1);
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.376
diff -u -p -r1.376 bgpd.h
--- bgpd.h 27 Feb 2019 04:31:56 -0000 1.376
+++ bgpd.h 1 Mar 2019 10:57:33 -0000
@@ -1160,14 +1160,18 @@ int control_imsg_relay(struct imsg *);
/* config.c */
struct bgpd_config *new_config(void);
-void free_config(struct bgpd_config *);
-void free_prefixsets(struct prefixset_head *);
-void free_prefixtree(struct prefixset_tree *);
-void filterlist_free(struct filter_head *);
-int host(const char *, struct bgpd_addr *, u_int8_t *);
-void copy_filterset(struct filter_set_head *, struct filter_set_head *);
-void expand_networks(struct bgpd_config *);
-int prefixset_cmp(struct prefixset_item *, struct prefixset_item *);
+void copy_config(struct bgpd_config *, struct bgpd_config *);
+void free_config(struct bgpd_config *);
+void free_prefixsets(struct prefixset_head *);
+void free_rde_prefixsets(struct rde_prefixset_head *);
+void free_prefixtree(struct prefixset_tree *);
+void filterlist_free(struct filter_head *);
+int host(const char *, struct bgpd_addr *, u_int8_t *);
+u_int32_t get_bgpid(void);
+void copy_filterset(struct filter_set_head *,
+ struct filter_set_head *);
+void expand_networks(struct bgpd_config *);
+int prefixset_cmp(struct prefixset_item *, struct prefixset_item *);
RB_PROTOTYPE(prefixset_tree, prefixset_item, entry, prefixset_cmp);
/* kroute.c */
@@ -1213,7 +1217,7 @@ time_t mrt_timeout(struct mrt_head *);
void mrt_reconfigure(struct mrt_head *);
void mrt_handler(struct mrt_head *);
struct mrt *mrt_get(struct mrt_head *, struct mrt *);
-int mrt_mergeconfig(struct mrt_head *, struct mrt_head *);
+void mrt_mergeconfig(struct mrt_head *, struct mrt_head *);
/* name2id.c */
u_int16_t rib_name2id(const char *);
@@ -1264,6 +1268,18 @@ void set_prep(struct set_table *);
void *set_match(const struct set_table *, u_int32_t);
int set_equal(const struct set_table *,
const struct set_table *);
+
+/* rde_trie.c */
+int trie_add(struct trie_head *, struct bgpd_addr *, u_int8_t, u_int8_t,
+ u_int8_t);
+int trie_roa_add(struct trie_head *, struct bgpd_addr *, u_int8_t,
+ struct set_table *);
+void trie_free(struct trie_head *);
+int trie_match(struct trie_head *, struct bgpd_addr *, u_int8_t, int);
+int trie_roa_check(struct trie_head *, struct bgpd_addr *, u_int8_t,
+ u_int32_t);
+void trie_dump(struct trie_head *);
+int trie_equal(struct trie_head *, struct trie_head *);
/* util.c */
const char *log_addr(const struct bgpd_addr *);
Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
retrieving revision 1.84
diff -u -p -r1.84 config.c
--- config.c 27 Feb 2019 04:31:56 -0000 1.84
+++ config.c 1 Mar 2019 11:00:57 -0000
@@ -31,7 +31,6 @@
#include "session.h"
#include "log.h"
-u_int32_t get_bgpid(void);
int host_ip(const char *, struct bgpd_addr *, u_int8_t *);
void free_networks(struct network_head *);
void free_l3vpns(struct l3vpn_head *);
@@ -40,24 +39,10 @@ struct bgpd_config *
new_config(void)
{
struct bgpd_config *conf;
- u_int rdomid;
if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
fatal(NULL);
- conf->min_holdtime = MIN_HOLDTIME;
- conf->bgpid = get_bgpid();
- conf->fib_priority = RTP_BGP;
- conf->default_tableid = getrtable();
- ktable_exists(conf->default_tableid, &rdomid);
- if (rdomid != conf->default_tableid)
- fatalx("current routing table %u is not a routing domain",
- conf->default_tableid);
-
- if (asprintf(&conf->csock, "%s.%d", SOCKET_NAME,
- conf->default_tableid) == -1)
- 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)
@@ -73,6 +58,8 @@ new_config(void)
SIMPLEQ_INIT(&conf->l3vpns);
SIMPLEQ_INIT(&conf->prefixsets);
SIMPLEQ_INIT(&conf->originsets);
+ SIMPLEQ_INIT(&conf->rde_prefixsets);
+ SIMPLEQ_INIT(&conf->rde_originsets);
RB_INIT(&conf->roa);
SIMPLEQ_INIT(conf->as_sets);
@@ -84,6 +71,22 @@ new_config(void)
}
void
+copy_config(struct bgpd_config *to, struct bgpd_config *from)
+{
+ to->flags = from->flags;
+ to->log = from->log;
+ to->default_tableid = from->default_tableid;
+ to->bgpid = from->bgpid;
+ to->clusterid = from->clusterid;
+ to->as = from->as;
+ to->short_as = from->short_as;
+ to->holdtime = from->holdtime;
+ to->min_holdtime = from->min_holdtime;
+ to->connectretry = from->connectretry;
+ to->fib_priority = from->fib_priority;
+}
+
+void
free_networks(struct network_head *networks)
{
struct network *n;
@@ -123,6 +126,22 @@ free_prefixsets(struct prefixset_head *p
}
void
+free_rde_prefixsets(struct rde_prefixset_head *psh)
+{
+ struct rde_prefixset *ps;
+
+ if (psh == NULL)
+ return;
+
+ while (!SIMPLEQ_EMPTY(psh)) {
+ ps = SIMPLEQ_FIRST(psh);
+ trie_free(&ps->th);
+ SIMPLEQ_REMOVE_HEAD(psh, entry);
+ free(ps);
+ }
+}
+
+void
free_prefixtree(struct prefixset_tree *p)
{
struct prefixset_item *psi, *npsi;
@@ -145,6 +164,8 @@ free_config(struct bgpd_config *conf)
filterlist_free(conf->filters);
free_prefixsets(&conf->prefixsets);
free_prefixsets(&conf->originsets);
+ free_rde_prefixsets(&conf->rde_prefixsets);
+ free_rde_prefixsets(&conf->rde_originsets);
free_prefixtree(&conf->roa);
as_sets_free(conf->as_sets);
@@ -166,7 +187,7 @@ free_config(struct bgpd_config *conf)
free(conf);
}
-int
+void
merge_config(struct bgpd_config *xconf, struct bgpd_config *conf,
struct peer *peer_l)
{
@@ -176,11 +197,6 @@ merge_config(struct bgpd_config *xconf,
/*
* merge the freshly parsed conf into the running xconf
*/
- if (!conf->as) {
- log_warnx("configuration error: AS not given");
- return (1);
- }
-
if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0)
conf->clusterid = conf->bgpid;
@@ -194,16 +210,7 @@ merge_config(struct bgpd_config *xconf,
}
/* take over the easy config changes */
- xconf->flags = conf->flags;
- xconf->log = conf->log;
- xconf->bgpid = conf->bgpid;
- xconf->clusterid = conf->clusterid;
- xconf->as = conf->as;
- xconf->short_as = conf->short_as;
- xconf->holdtime = conf->holdtime;
- xconf->min_holdtime = conf->min_holdtime;
- xconf->connectretry = conf->connectretry;
- xconf->fib_priority = conf->fib_priority;
+ copy_config(xconf, conf);
/* clear old control sockets and use new */
free(xconf->csock);
@@ -292,8 +299,6 @@ merge_config(struct bgpd_config *xconf,
/* conf is merged so free it */
free_config(conf);
-
- return (0);
}
u_int32_t
Index: kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.234
diff -u -p -r1.234 kroute.c
--- kroute.c 1 Mar 2019 09:24:56 -0000 1.234
+++ kroute.c 1 Mar 2019 10:47:48 -0000
@@ -112,6 +112,7 @@ int krVPN6_delete(struct ktable *, struc
void kr_net_delete(struct network *);
int kr_net_match(struct ktable *, struct network_config *, u_int16_t);
struct network *kr_net_find(struct ktable *, struct network *);
+void kr_net_clear(struct ktable *);
void kr_redistribute(int, struct ktable *, struct kroute *);
void kr_redistribute6(int, struct ktable *, struct kroute6 *);
struct kroute_full *kr_tofull(struct kroute *);
@@ -353,6 +354,7 @@ ktable_destroy(struct ktable *kt, u_int8
knexthop_clear(kt);
kroute_clear(kt);
kroute6_clear(kt);
+ kr_net_clear(kt);
krt[kt->rtableid] = NULL;
free(kt);
@@ -855,6 +857,7 @@ kr_shutdown(u_int8_t fib_prio, u_int rdo
for (i = krt_size; i > 0; i--)
ktable_free(i - 1, fib_prio);
kif_clear(rdomain);
+ free(krt);
}
void
@@ -1356,6 +1359,19 @@ kr_net_reload(u_int rtableid, u_int64_t
kr_net_delete(n);
} else
TAILQ_INSERT_TAIL(&kt->krn, n, entry);
+ }
+}
+
+void
+kr_net_clear(struct ktable *kt)
+{
+ struct network *n, *xn;
+
+ TAILQ_FOREACH_SAFE(n, &kt->krn, entry, xn) {
+ TAILQ_REMOVE(&kt->krn, n, entry);
+ if (n->net.type == NETWORK_DEFAULT)
+ kr_net_redist_del(kt, &n->net, 0);
+ kr_net_delete(n);
}
}
Index: mrt.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/mrt.c,v
retrieving revision 1.93
diff -u -p -r1.93 mrt.c
--- mrt.c 27 Feb 2019 04:31:56 -0000 1.93
+++ mrt.c 1 Mar 2019 10:57:13 -0000
@@ -995,7 +995,7 @@ mrt_get(struct mrt_head *c, struct mrt *
return (NULL);
}
-int
+void
mrt_mergeconfig(struct mrt_head *xconf, struct mrt_head *nconf)
{
struct mrt *m, *xm;
@@ -1031,6 +1031,4 @@ mrt_mergeconfig(struct mrt_head *xconf,
LIST_REMOVE(m, entry);
free(m);
}
-
- return (0);
}
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.381
diff -u -p -r1.381 parse.y
--- parse.y 27 Feb 2019 04:16:02 -0000 1.381
+++ parse.y 1 Mar 2019 11:04:53 -0000
@@ -3242,6 +3242,24 @@ popfile(void)
return (file ? 0 : EOF);
}
+static void
+init_config(struct bgpd_config *c)
+{
+ u_int rdomid;
+
+ c->min_holdtime = MIN_HOLDTIME;
+ c->bgpid = get_bgpid();
+ c->fib_priority = RTP_BGP;
+ c->default_tableid = getrtable();
+ ktable_exists(c->default_tableid, &rdomid);
+ if (rdomid != c->default_tableid)
+ fatalx("current routing table %u is not a routing domain",
+ c->default_tableid);
+
+ if (asprintf(&c->csock, "%s.%d", SOCKET_NAME, c->default_tableid) == -1)
+ fatal(NULL);
+}
+
int
parse_config(char *filename, struct bgpd_config *xconf, struct peer **xpeers)
{
@@ -3252,6 +3270,7 @@ parse_config(char *filename, struct bgpd
int errors = 0;
conf = new_config();
+ init_config(conf);
if ((filter_l = calloc(1, sizeof(struct filter_head))) == NULL)
fatal(NULL);
@@ -3277,10 +3296,8 @@ parse_config(char *filename, struct bgpd
F_RIB_NOFIB | F_RIB_NOEVALUATE);
add_rib("Loc-RIB", conf->default_tableid, F_RIB_LOCAL);
- if ((file = pushfile(filename, 1)) == NULL) {
- free(conf);
- return (-1);
- }
+ if ((file = pushfile(filename, 1)) == NULL)
+ goto errors;
topfile = file;
yyparse();
@@ -3309,7 +3326,13 @@ parse_config(char *filename, struct bgpd
}
}
+ if (!conf->as) {
+ log_warnx("configuration error: AS not given");
+ errors++;
+ }
+
if (errors) {
+errors:
for (p = peer_l; p != NULL; p = pnext) {
pnext = p->next;
free(p);
@@ -3325,6 +3348,7 @@ parse_config(char *filename, struct bgpd
filterlist_free(groupfilter_l);
free_config(conf);
+ return -1;
} else {
/*
* Concatenate filter list and static group and peer filtersets
@@ -3337,8 +3361,8 @@ parse_config(char *filename, struct bgpd
optimize_filters(conf->filters);
- errors += mrt_mergeconfig(xconf->mrt, conf->mrt);
- errors += merge_config(xconf, conf, peer_l);
+ mrt_mergeconfig(xconf->mrt, conf->mrt);
+ merge_config(xconf, conf, peer_l);
*xpeers = peer_l;
for (p = peer_l_old; p != NULL; p = pnext) {
@@ -3349,9 +3373,8 @@ parse_config(char *filename, struct bgpd
free(filter_l);
free(peerfilter_l);
free(groupfilter_l);
+ return 0;
}
-
- return (errors ? -1 : 0);
}
int
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.464
diff -u -p -r1.464 rde.c
--- rde.c 27 Feb 2019 04:31:56 -0000 1.464
+++ rde.c 1 Mar 2019 10:47:48 -0000
@@ -86,7 +86,6 @@ int rde_update_queue_pending(void);
void rde_update_queue_runner(void);
void rde_update6_queue_runner(u_int8_t);
struct rde_prefixset *rde_find_prefixset(char *, struct rde_prefixset_head *);
-void rde_free_prefixsets(struct rde_prefixset_head *);
void rde_mark_prefixsets_dirty(struct rde_prefixset_head *,
struct rde_prefixset_head *);
u_int8_t rde_roa_validity(struct rde_prefixset *,
@@ -232,8 +231,7 @@ rde_main(int debug, int verbose)
fatal(NULL);
SIMPLEQ_INIT(l3vpns_l);
- if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
- fatal(NULL);
+ conf = new_config();
log_info("route decision engine ready");
while (rde_quit == 0) {
@@ -324,6 +322,9 @@ rde_main(int debug, int verbose)
if (debug)
rde_shutdown();
+ free_config(conf);
+ free(pfd);
+
/* close pipes */
if (ibuf_se) {
msgbuf_clear(&ibuf_se->w);
@@ -346,7 +347,6 @@ rde_main(int debug, int verbose)
free(mctx);
}
-
log_info("route decision engine exiting");
exit(0);
}
@@ -768,18 +768,14 @@ rde_dispatch_imsg_parent(struct imsgbuf
if (newdomains == NULL)
fatal(NULL);
SIMPLEQ_INIT(newdomains);
- if ((nconf = malloc(sizeof(struct bgpd_config))) ==
- NULL)
- fatal(NULL);
- memcpy(nconf, imsg.data, sizeof(struct bgpd_config));
+ nconf = new_config();
+ copy_config(nconf, imsg.data);
+
for (rid = 0; rid < rib_size; rid++) {
if (!rib_valid(rid))
continue;
ribs[rid].state = RECONF_DELETE;
}
- SIMPLEQ_INIT(&nconf->rde_prefixsets);
- SIMPLEQ_INIT(&nconf->rde_originsets);
- memset(&nconf->rde_roa, 0, sizeof(nconf->rde_roa));
break;
case IMSG_RECONF_RIB:
if (imsg.hdr.len - IMSG_HEADER_SIZE !=
@@ -2903,15 +2899,12 @@ rde_reload_done(void)
roa_old = conf->rde_roa;
as_sets_old = conf->as_sets;
- memcpy(conf, nconf, sizeof(struct bgpd_config));
- conf->listen_addrs = NULL;
- conf->csock = NULL;
- conf->rcsock = NULL;
+ copy_config(conf, nconf);
SIMPLEQ_INIT(&conf->rde_prefixsets);
SIMPLEQ_INIT(&conf->rde_originsets);
SIMPLEQ_CONCAT(&conf->rde_prefixsets, &nconf->rde_prefixsets);
SIMPLEQ_CONCAT(&conf->rde_originsets, &nconf->rde_originsets);
- free(nconf);
+ free_config(nconf);
nconf = NULL;
/* sync peerself with conf */
@@ -3127,8 +3120,8 @@ rde_softreconfig_done(void)
ribs[rid].state = RECONF_NONE;
}
- rde_free_prefixsets(&prefixsets_old);
- rde_free_prefixsets(&originsets_old);
+ free_rde_prefixsets(&prefixsets_old);
+ free_rde_prefixsets(&originsets_old);
as_sets_free(as_sets_old);
as_sets_old = NULL;
@@ -3925,6 +3918,7 @@ network_flush_upcall(struct rib_entry *r
void
rde_shutdown(void)
{
+ struct l3vpn *vpn;
struct rde_peer *p;
u_int32_t i;
@@ -3945,6 +3939,15 @@ rde_shutdown(void)
filterlist_free(out_rules);
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);
+
/* now check everything */
rib_shutdown();
nexthop_shutdown();
@@ -4003,22 +4006,6 @@ rde_find_prefixset(char *name, struct rd
return (ps);
}
return (NULL);
-}
-
-void
-rde_free_prefixsets(struct rde_prefixset_head *psh)
-{
- struct rde_prefixset *ps;
-
- if (psh == NULL)
- return;
-
- while (!SIMPLEQ_EMPTY(psh)) {
- ps = SIMPLEQ_FIRST(psh);
- trie_free(&ps->th);
- SIMPLEQ_REMOVE_HEAD(psh, entry);
- free(ps);
- }
}
void
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.210
diff -u -p -r1.210 rde.h
--- rde.h 26 Feb 2019 10:49:15 -0000 1.210
+++ rde.h 1 Mar 2019 10:47:48 -0000
@@ -570,16 +570,4 @@ int up_dump_mp_unreach(u_char *, int,
int up_dump_attrnlri(u_char *, int, struct rde_peer *);
int up_dump_mp_reach(u_char *, int, struct rde_peer *, u_int8_t);
-/* rde_trie.c */
-int trie_add(struct trie_head *, struct bgpd_addr *, u_int8_t, u_int8_t,
- u_int8_t);
-int trie_roa_add(struct trie_head *, struct bgpd_addr *, u_int8_t,
- struct set_table *);
-void trie_free(struct trie_head *);
-int trie_match(struct trie_head *, struct bgpd_addr *, u_int8_t, int);
-int trie_roa_check(struct trie_head *, struct bgpd_addr *, u_int8_t,
- u_int32_t);
-void trie_dump(struct trie_head *);
-int trie_equal(struct trie_head *, struct trie_head *);
-
#endif /* __RDE_H__ */
Index: rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.189
diff -u -p -r1.189 rde_rib.c
--- rde_rib.c 21 Jan 2019 02:07:56 -0000 1.189
+++ rde_rib.c 1 Mar 2019 10:47:48 -0000
@@ -236,6 +236,13 @@ rib_shutdown(void)
ribs[id].name);
rib_free(&ribs[id].rib);
}
+ for (id = 0; id <= RIB_LOC_START; id++) {
+ struct rib_desc *rd = &ribs[id];
+ filterlist_free(rd->in_rules_tmp);
+ filterlist_free(rd->in_rules);
+ bzero(rd, sizeof(struct rib_desc));
+ }
+ free(ribs);
}
struct rib_entry *
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.374
diff -u -p -r1.374 session.c
--- session.c 27 Feb 2019 04:31:56 -0000 1.374
+++ session.c 1 Mar 2019 10:47:48 -0000
@@ -247,13 +247,7 @@ session_main(int debug, int verbose)
peer_cnt = 0;
ctl_cnt = 0;
- if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
- fatal(NULL);
- if ((conf->listen_addrs = calloc(1, sizeof(struct listen_addrs))) ==
- NULL)
- fatal(NULL);
- TAILQ_INIT(conf->listen_addrs);
-
+ conf = new_config();
log_info("session engine ready");
while (session_quit == 0) {
@@ -551,6 +545,7 @@ session_main(int debug, int verbose)
"bgpd shutting down",
sizeof(p->conf.shutcomm));
session_stop(p, ERR_CEASE_ADMIN_DOWN);
+ timer_remove_all(p);
pfkey_remove(p);
free(p);
}
@@ -561,11 +556,7 @@ session_main(int debug, int verbose)
free(m);
}
- while ((la = TAILQ_FIRST(conf->listen_addrs)) != NULL) {
- TAILQ_REMOVE(conf->listen_addrs, la, entry);
- free(la);
- }
- free(conf->listen_addrs);
+ free_config(conf);
free(peer_l);
free(mrt_l);
free(pfd);
@@ -2624,15 +2615,10 @@ session_dispatch_imsg(struct imsgbuf *ib
case IMSG_RECONF_CONF:
if (idx != PFD_PIPE_MAIN)
fatalx("reconf request not from parent");
- if ((nconf = malloc(sizeof(struct bgpd_config))) ==
- NULL)
- fatal(NULL);
- memcpy(nconf, imsg.data, sizeof(struct bgpd_config));
- if ((nconf->listen_addrs = calloc(1,
- sizeof(struct listen_addrs))) == NULL)
- fatal(NULL);
- TAILQ_INIT(nconf->listen_addrs);
+ nconf = new_config();
npeers = NULL;
+
+ copy_config(nconf, imsg.data);
init_conf(nconf);
pending_reconf = 1;
break;
@@ -2747,15 +2733,7 @@ session_dispatch_imsg(struct imsgbuf *ib
fatalx("reconf request not from parent");
if (nconf == NULL)
fatalx("got IMSG_RECONF_DONE but no config");
- conf->flags = nconf->flags;
- conf->log = nconf->log;
- conf->bgpid = nconf->bgpid;
- conf->clusterid = nconf->clusterid;
- conf->as = nconf->as;
- conf->short_as = nconf->short_as;
- conf->holdtime = nconf->holdtime;
- conf->min_holdtime = nconf->min_holdtime;
- conf->connectretry = nconf->connectretry;
+ copy_config(conf, nconf);
/* add new peers */
for (p = npeers; p != NULL; p = next) {
@@ -2798,8 +2776,7 @@ session_dispatch_imsg(struct imsgbuf *ib
}
setup_listeners(listener_cnt);
- free(nconf->listen_addrs);
- free(nconf);
+ free_config(nconf);
nconf = NULL;
pending_reconf = 0;
log_info("SE reconfigured");
Index: session.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.h,v
retrieving revision 1.133
diff -u -p -r1.133 session.h
--- session.h 27 Feb 2019 04:31:56 -0000 1.133
+++ session.h 1 Mar 2019 11:01:26 -0000
@@ -247,7 +247,7 @@ int carp_demote_get(char *);
int carp_demote_set(char *, int);
/* config.c */
-int merge_config(struct bgpd_config *, struct bgpd_config *,
+void merge_config(struct bgpd_config *, struct bgpd_config *,
struct peer *);
int prepare_listeners(struct bgpd_config *);