From 4709b4faa43907ed9fcaf5920e56b6664f0523cf Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Mon, 31 Jul 2017 19:49:24 +0000 Subject: [PATCH] bgpd: peer hash expands until we are out of memory Signed-off-by: Daniel Walton Reviewed-by: CCR-6531 Ticket: CM-17352 --- bgpd/bgpd.c | 5 +++-- bgpd/bgpd.h | 1 + lib/hash.c | 4 ++++ lib/hash.h | 3 +++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 0a4600a6f914..0fde22c76ac0 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -747,7 +747,7 @@ static unsigned int peer_hash_key_make(void *p) return sockunion_hash(&peer->su); } -static int peer_hash_cmp(const void *p1, const void *p2) +static int peer_hash_same(const void *p1, const void *p2) { const struct peer *peer1 = p1; const struct peer *peer2 = p2; @@ -2758,7 +2758,8 @@ static struct bgp *bgp_create(as_t *as, const char *name, XSTRDUP(MTYPE_BGP_PEER_HOST, "Static announcement"); bgp->peer = list_new(); bgp->peer->cmp = (int (*)(void *, void *))peer_cmp; - bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_cmp, NULL); + bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same, NULL); + bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE; bgp->group = list_new(); bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 9b2884438bbb..effe67f8f1f0 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -36,6 +36,7 @@ #include "bitfield.h" #define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */ +#define BGP_PEER_MAX_HASH_SIZE 16384 /* Default interval for IPv6 RAs when triggered by BGP unnumbered neighbor. */ #define BGP_UNNUM_DEFAULT_RA_INTERVAL 10 diff --git a/lib/hash.c b/lib/hash.c index a7714f156930..e74e4355dc99 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -94,6 +94,10 @@ static void hash_expand(struct hash *hash) struct hash_backet *hb, *hbnext, **new_index; new_size = hash->size * 2; + + if (hash->max_size && new_size > hash->max_size) + return; + new_index = XCALLOC(MTYPE_HASH_INDEX, sizeof(struct hash_backet *) * new_size); if (new_index == NULL) diff --git a/lib/hash.h b/lib/hash.h index 6ce29f0426dc..236abbbd6a2c 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -64,6 +64,9 @@ struct hash { /* Hash table size. Must be power of 2 */ unsigned int size; + /* If max_size is 0 there is no limit */ + unsigned int max_size; + /* Key make function. */ unsigned int (*hash_key)(void *);