While searching a bigger memory leak in one of my diffs I found these
others. Most of them are harmless cleanup on shutdown problems. The only
one that may be problematic is the missing vertex_nexthop_clear() in
vertex_free().

Please test and OK :)
-- 
:wq Claudio

Index: neighbor.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/neighbor.c,v
retrieving revision 1.41
diff -u -p -r1.41 neighbor.c
--- neighbor.c  7 May 2010 22:32:34 -0000       1.41
+++ neighbor.c  4 Mar 2011 13:11:48 -0000
@@ -342,7 +342,8 @@ nbr_del(struct nbr *nbr)
        db_sum_list_clr(nbr);
        ls_req_list_clr(nbr);
 
-       LIST_REMOVE(nbr, entry);
+       if (nbr->peerid != NBR_IDSELF)
+               LIST_REMOVE(nbr, entry);
        LIST_REMOVE(nbr, hash);
 
        free(nbr);
Index: ospfd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
retrieving revision 1.75
diff -u -p -r1.75 ospfd.c
--- ospfd.c     2 Sep 2010 14:03:22 -0000       1.75
+++ ospfd.c     4 Mar 2011 13:11:48 -0000
@@ -309,7 +309,8 @@ main(int argc, char *argv[])
 void
 ospfd_shutdown(void)
 {
-       pid_t            pid;
+       pid_t                    pid;
+       struct redistribute     *r;
 
        if (ospfe_pid)
                kill(ospfe_pid, SIGTERM);
@@ -318,6 +319,10 @@ ospfd_shutdown(void)
                kill(rde_pid, SIGTERM);
 
        control_cleanup(ospfd_conf->csock);
+       while ((r = SIMPLEQ_FIRST(&ospfd_conf->redist_list)) != NULL) {
+               SIMPLEQ_REMOVE_HEAD(&ospfd_conf->redist_list, entry);
+               free(r);
+       }
        kr_shutdown();
        carp_demote_shutdown();
 
Index: ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v
retrieving revision 1.77
diff -u -p -r1.77 ospfe.c
--- ospfe.c     1 Oct 2010 13:29:25 -0000       1.77
+++ ospfe.c     4 Mar 2011 13:11:14 -0000
@@ -223,6 +223,8 @@ ospfe_shutdown(void)
                area_del(area);
        }
 
+       nbr_del(nbr_find_peerid(NBR_IDSELF));
+       kr_shutdown();
        close(oeconf->ospf_socket);
 
        /* clean up */
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde.c,v
retrieving revision 1.91
diff -u -p -r1.91 rde.c
--- rde.c       18 Jan 2011 20:46:06 -0000      1.91
+++ rde.c       4 Mar 2011 12:58:28 -0000
@@ -59,6 +59,7 @@ void           rde_req_list_free(struct rde_nbr 
 struct iface   *rde_asext_lookup(u_int32_t, int);
 void            rde_asext_get(struct kroute *);
 void            rde_asext_put(struct kroute *);
+void            rde_asext_free(void);
 struct lsa     *orig_asext_lsa(struct kroute *, u_int32_t, u_int16_t);
 
 struct lsa     *orig_sum_lsa(struct rt_node *, struct area *, u_int8_t, int);
@@ -194,6 +195,7 @@ void
 rde_shutdown(void)
 {
        struct area     *a;
+       struct vertex   *v, *nv;
 
        stop_spf_timer(rdeconf);
        cand_list_clr();
@@ -203,7 +205,13 @@ rde_shutdown(void)
                LIST_REMOVE(a, entry);
                area_del(a);
        }
+       for (v = RB_MIN(lsa_tree, &asext_tree); v != NULL; v = nv) {
+               nv = RB_NEXT(lsa_tree, &area->lsa_tree, v);
+               vertex_free(v);
+       }
+       rde_asext_free();
        rde_nbr_free();
+       kr_shutdown();
 
        msgbuf_clear(&iev_ospfe->ibuf.w);
        free(iev_ospfe);
@@ -366,8 +374,11 @@ rde_dispatch_imsg(int fd, short event, v
                                if ((v = lsa_find(nbr->area,
                                    ntohl(req_hdr.type), req_hdr.ls_id,
                                    req_hdr.adv_rtr)) == NULL) {
-                                       imsg_compose_event(iev_ospfe, 
IMSG_LS_BADREQ,
-                                           imsg.hdr.peerid, 0, -1, NULL, 0);
+                                       log_debug("rde_dispatch_imsg: "
+                                           "requested LSA not found");
+                                       imsg_compose_event(iev_ospfe,
+                                           IMSG_LS_BADREQ, imsg.hdr.peerid,
+                                           0, -1, NULL, 0);
                                        continue;
                                }
                                imsg_compose_event(iev_ospfe, IMSG_LS_UPD,
@@ -396,7 +407,7 @@ rde_dispatch_imsg(int fd, short event, v
                        }
 
                        v = lsa_find(nbr->area, lsa->hdr.type, lsa->hdr.ls_id,
-                                   lsa->hdr.adv_rtr);
+                           lsa->hdr.adv_rtr);
                        if (v == NULL)
                                db_hdr = NULL;
                        else
@@ -1198,6 +1209,18 @@ rde_asext_put(struct kroute *rr)
 
        RB_REMOVE(asext_tree, &ast, an);
        free(an);
+}
+
+void
+rde_asext_free(void)
+{
+       struct asext_node       *an, *nan;
+
+       for (an = RB_MIN(asext_tree, &ast); an != NULL; an = nan) {
+               nan = RB_NEXT(asext_tree, &ast, an);
+               RB_REMOVE(asext_tree, &ast, an);
+               free(an);
+       }
 }
 
 struct lsa *
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde.h,v
retrieving revision 1.35
diff -u -p -r1.35 rde.h
--- rde.h       7 Jan 2009 21:16:36 -0000       1.35
+++ rde.h       4 Mar 2011 13:06:19 -0000
@@ -124,6 +124,9 @@ struct lsa  *orig_sum_lsa(struct rt_node 
 void            lsa_init(struct lsa_tree *);
 int             lsa_compare(struct vertex *, struct vertex *);
 void            vertex_free(struct vertex *);
+void            vertex_nexthop_clear(struct vertex *);
+void            vertex_nexthop_add(struct vertex *, struct vertex *,
+                   u_int32_t);
 int             lsa_newer(struct lsa_hdr *, struct lsa_hdr *);
 int             lsa_check(struct rde_nbr *, struct lsa *, u_int16_t);
 int             lsa_self(struct rde_nbr *, struct lsa *, struct vertex *);
Index: rde_lsdb.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde_lsdb.c,v
retrieving revision 1.44
diff -u -p -r1.44 rde_lsdb.c
--- rde_lsdb.c  19 Jul 2010 09:11:08 -0000      1.44
+++ rde_lsdb.c  4 Mar 2011 13:04:51 -0000
@@ -98,8 +98,38 @@ vertex_free(struct vertex *v)
                RB_REMOVE(lsa_tree, &v->area->lsa_tree, v);
 
        (void)evtimer_del(&v->ev);
+       vertex_nexthop_clear(v);
        free(v->lsa);
        free(v);
+}
+
+void
+vertex_nexthop_clear(struct vertex *v)
+{
+       struct v_nexthop        *vn;
+
+       while ((vn = TAILQ_FIRST(&v->nexthop))) {
+               TAILQ_REMOVE(&v->nexthop, vn, entry);
+               free(vn);
+       }
+}
+
+void
+vertex_nexthop_add(struct vertex *dst, struct vertex *parent, u_int32_t 
nexthop)
+{
+       struct v_nexthop        *vn;
+
+       if (nexthop == 0)
+               /* invalid nexthop, skip it */
+               return;
+
+       if ((vn = calloc(1, sizeof(*vn))) == NULL)
+               fatal("calc_nexthop_add");
+
+       vn->prev = parent;
+       vn->nexthop.s_addr = nexthop;
+
+       TAILQ_INSERT_TAIL(&dst->nexthop, vn, entry);
 }
 
 /* returns -1 if a is older, 1 if newer and 0 if equal to b */
Index: rde_spf.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde_spf.c,v
retrieving revision 1.69
diff -u -p -r1.69 rde_spf.c
--- rde_spf.c   16 Feb 2010 08:22:42 -0000      1.69
+++ rde_spf.c   4 Mar 2011 13:08:06 -0000
@@ -35,8 +35,6 @@ RB_PROTOTYPE(rt_tree, rt_node, entry, rt
 RB_GENERATE(rt_tree, rt_node, entry, rt_compare)
 struct vertex                  *spf_root = NULL;
 
-void            calc_nexthop_clear(struct vertex *);
-void            calc_nexthop_add(struct vertex *, struct vertex *, u_int32_t);
 void            calc_nexthop(struct vertex *, struct vertex *,
                     struct area *, struct lsa_rtr_link *);
 void            rt_nexthop_clear(struct rt_node *);
@@ -133,7 +131,7 @@ spf_calc(struct area *area)
                                        continue;
                                if (d < w->cost) {
                                        w->cost = d;
-                                       calc_nexthop_clear(w);
+                                       vertex_nexthop_clear(w);
                                        calc_nexthop(w, v, area, rtr_link);
                                        /*
                                         * need to readd to candidate list
@@ -147,7 +145,7 @@ spf_calc(struct area *area)
                        } else if (w->cost == LS_INFINITY && d < LS_INFINITY) {
                                w->cost = d;
 
-                               calc_nexthop_clear(w);
+                               vertex_nexthop_clear(w);
                                calc_nexthop(w, v, area, rtr_link);
                                cand_list_add(w);
                        }
@@ -237,9 +235,9 @@ rt_calc(struct vertex *v, struct area *a
                        return;
 
                /* copy nexthops */
-               calc_nexthop_clear(v);  /* XXX needed ??? */
+               vertex_nexthop_clear(v);        /* XXX needed ??? */
                TAILQ_FOREACH(vn, &w->nexthop, entry)
-                       calc_nexthop_add(v, w, vn->nexthop.s_addr);
+                       vertex_nexthop_add(v, w, vn->nexthop.s_addr);
 
                v->cost = w->cost +
                    (ntohl(v->lsa->data.sum.metric) & LSA_METRIC_MASK);
@@ -317,20 +315,20 @@ asext_calc(struct vertex *v)
                adv_rtr.s_addr = htonl(v->adv_rtr);
                addr.s_addr = htonl(v->ls_id) & v->lsa->data.asext.mask;
 
-               calc_nexthop_clear(v);
+               vertex_nexthop_clear(v);
                TAILQ_FOREACH(rn, &r->nexthop, entry) {
                        if (rn->invalid)
                                continue;
 
                        if (rn->connected && r->d_type == DT_NET) {
                                if (v->lsa->data.asext.fw_addr != 0)
-                                       calc_nexthop_add(v, NULL,
+                                       vertex_nexthop_add(v, NULL,
                                            v->lsa->data.asext.fw_addr);
                                else
-                                       calc_nexthop_add(v, NULL,
+                                       vertex_nexthop_add(v, NULL,
                                            htonl(v->adv_rtr));
                        } else
-                               calc_nexthop_add(v, NULL, rn->nexthop.s_addr);
+                               vertex_nexthop_add(v, NULL, rn->nexthop.s_addr);
                }
 
                rt_update(addr, mask2prefixlen(v->lsa->data.asext.mask),
@@ -350,40 +348,11 @@ spf_tree_clr(struct area *area)
 
        RB_FOREACH(v, lsa_tree, tree) {
                v->cost = LS_INFINITY;
-               calc_nexthop_clear(v);
+               vertex_nexthop_clear(v);
        }
 }
 
 void
-calc_nexthop_clear(struct vertex *v)
-{
-       struct v_nexthop        *vn;
-
-       while ((vn = TAILQ_FIRST(&v->nexthop))) {
-               TAILQ_REMOVE(&v->nexthop, vn, entry);
-               free(vn);
-       }
-}
-
-void
-calc_nexthop_add(struct vertex *dst, struct vertex *parent, u_int32_t nexthop)
-{
-       struct v_nexthop        *vn;
-
-       if (nexthop == 0)
-               /* invalid nexthop, skip it */
-               return;
-
-       if ((vn = calloc(1, sizeof(*vn))) == NULL)
-               fatal("calc_nexthop_add");
-
-       vn->prev = parent;
-       vn->nexthop.s_addr = nexthop;
-
-       TAILQ_INSERT_TAIL(&dst->nexthop, vn, entry);
-}
-
-void
 calc_nexthop(struct vertex *dst, struct vertex *parent,
     struct area *area, struct lsa_rtr_link *rtr_link)
 {
@@ -399,7 +368,7 @@ calc_nexthop(struct vertex *dst, struct 
                                fatalx("inconsistent SPF tree");
                        LIST_FOREACH(iface, &area->iface_list, entry) {
                                if (rtr_link->data == iface->addr.s_addr) {
-                                       calc_nexthop_add(dst, parent,
+                                       vertex_nexthop_add(dst, parent,
                                            iface->dst.s_addr);
                                        return;
                                }
@@ -416,7 +385,7 @@ calc_nexthop(struct vertex *dst, struct 
                                    dst->lsa->data.net.mask) ==
                                    (rtr_link->data &
                                     dst->lsa->data.net.mask)) {
-                                       calc_nexthop_add(dst, parent,
+                                       vertex_nexthop_add(dst, parent,
                                            rtr_link->data);
                                }
                                break;
@@ -443,11 +412,11 @@ calc_nexthop(struct vertex *dst, struct 
                                            parent->lsa->data.net.mask) ==
                                            (htonl(parent->ls_id) &
                                            parent->lsa->data.net.mask))
-                                               calc_nexthop_add(dst, parent,
+                                               vertex_nexthop_add(dst, parent,
                                                    rtr_link->data);
                                }
                        } else {
-                               calc_nexthop_add(dst, parent,
+                               vertex_nexthop_add(dst, parent,
                                    vn->nexthop.s_addr);
                        }
                }
@@ -456,7 +425,7 @@ calc_nexthop(struct vertex *dst, struct 
 
        /* case 3 */
        TAILQ_FOREACH(vn, &parent->nexthop, entry)
-               calc_nexthop_add(dst, parent, vn->nexthop.s_addr);
+               vertex_nexthop_add(dst, parent, vn->nexthop.s_addr);
 }
 
 /* candidate list */

Reply via email to