florian@ noticed that his bgpd-spamd box was leaking memory on reload. The problem comes from a fact that when the same network is readded this is actually being leaked instead of just freeing the 2nd copy. Following diff fixes this problem.
-- :wq Claudio Index: kroute.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v retrieving revision 1.233 diff -u -p -r1.233 kroute.c --- kroute.c 21 Feb 2019 11:17:22 -0000 1.233 +++ kroute.c 28 Feb 2019 20:18:52 -0000 @@ -1226,16 +1226,21 @@ kr_net_redist_add(struct ktable *kt, str r->dynamic = dynamic; xr = RB_INSERT(kredist_tree, &kt->kredist, r); - if (xr != NULL && dynamic != xr->dynamic) { - if (dynamic) { + if (xr != NULL) { + if (dynamic == xr->dynamic || dynamic) { /* - * ignore update, a non-dynamic announcement - * is already present. + * ignore update, equal announcement already present, + * or a non-dynamic announcement is already present + * which has preference. */ free(r); return 0; } - /* non-dynamic announcments are preferred */ + /* + * only the case where xr->dynamic == 1 and dynamic == 0 + * ends up here and in this case non-dynamic announcments + * are preferred. Override dynamic flag. + */ xr->dynamic = dynamic; } @@ -1266,7 +1271,7 @@ kr_net_redist_del(struct ktable *kt, str free(r); if (send_network(IMSG_NETWORK_REMOVE, net, NULL) == -1) - log_warnx("%s: faild to send network update", __func__); + log_warnx("%s: faild to send network removal", __func__); } int @@ -1340,8 +1345,6 @@ kr_net_reload(u_int rtableid, u_int64_t fatalx("%s: non-existent rtableid %d", __func__, rtableid); while ((n = TAILQ_FIRST(nh)) != NULL) { - log_debug("%s: processing %s/%u", __func__, - log_addr(&n->net.prefix), n->net.prefixlen); TAILQ_REMOVE(nh, n, entry); n->net.old = 0; n->net.rd = rd;