summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/rde_rib.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2006-01-04 16:13:08 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2006-01-04 16:13:08 +0000
commitbc9995a86616025edba5bf10694600012edb8fbc (patch)
tree64733b2dd3bb6c9545bfce2592875a65f7c3cceb /usr.sbin/bgpd/rde_rib.c
parent31353baf13951091e2d82513ebdd7c0a95869891 (diff)
Fix a mem leak of the unusual kind. In some cases a new aspath was added
to the RIB without checking if there was a equal path already available. Modify path_update() so that we do not link a new aspath without calling path_lookup() before to check if the aspath is not already in the RIB. Found via bgpctl show rib mem. OK henning
Diffstat (limited to 'usr.sbin/bgpd/rde_rib.c')
-rw-r--r--usr.sbin/bgpd/rde_rib.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index bef5b9c4f2b..58fb145f72a 100644
--- a/usr.sbin/bgpd/rde_rib.c
+++ b/usr.sbin/bgpd/rde_rib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_rib.c,v 1.72 2006/01/03 22:49:17 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.73 2006/01/04 16:13:07 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -86,25 +86,33 @@ path_update(struct rde_peer *peer, struct rde_aspath *nasp,
rde_send_pftable_commit();
if ((p = prefix_get(peer, prefix, prefixlen)) != NULL) {
- if (path_compare(nasp, p->aspath) != 0) {
- /* non equal path attributes create new path */
- path_link(nasp, peer);
- prefix_move(nasp, p);
- } else {
+ if (path_compare(nasp, p->aspath) == 0) {
/* already registered */
path_put(nasp);
/* update last change */
p->lastchange = time(NULL);
+ return;
}
- } else if ((asp = path_lookup(nasp, peer)) == NULL) {
- /* path not available */
+ }
+
+ /*
+ * Either the prefix does not exist or the path changed.
+ * In both cases lookup the new aspath to make sure it is not
+ * already in the RIB.
+ */
+ if ((asp = path_lookup(nasp, peer)) == NULL) {
+ /* path not available, link new */
path_link(nasp, peer);
- prefix_add(nasp, prefix, prefixlen);
- } else {
- /* path found, just add prefix */
- prefix_add(asp, prefix, prefixlen);
+ asp = nasp;
+ } else
+ /* path found, new aspath no longer needed */
path_put(nasp);
- }
+
+ /* if the prefix was found move it else add it to the aspath */
+ if (p != NULL)
+ prefix_move(asp, p);
+ else
+ prefix_add(asp, prefix, prefixlen);
}
int
@@ -183,8 +191,7 @@ path_lookup(struct rde_aspath *aspath, struct rde_peer *peer)
head = PATH_HASH(aspath->aspath);
LIST_FOREACH(asp, head, path_l) {
- if (path_compare(aspath, asp) == 0 &&
- peer == asp->peer)
+ if (peer == asp->peer && path_compare(aspath, asp) == 0)
return (asp);
}
return (NULL);