diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2006-01-04 16:13:08 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2006-01-04 16:13:08 +0000 |
commit | bc9995a86616025edba5bf10694600012edb8fbc (patch) | |
tree | 64733b2dd3bb6c9545bfce2592875a65f7c3cceb /usr.sbin/bgpd/rde_rib.c | |
parent | 31353baf13951091e2d82513ebdd7c0a95869891 (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.c | 37 |
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); |