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;

Reply via email to