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 */