From 2c9fd7e07283b8904ef20030c9dadb032e999b12 Mon Sep 17 00:00:00 2001 From: Michael Lambert Date: Sat, 24 Jul 2010 12:44:07 -0400 Subject: bgpd: "Intern" communities in route maps * bgp_community.[ch]: (community_lookup) New helper function to look up a community list in the hash table. * bgp_routemap.c: A new community structure was being allocated for every BGP update which matched a route map which set a community. This behavior led to rapid growth in the memory consumed by bgpd. Adding the communities to the hash table addresses the memory growth, but may introduce a problem in modifying or deleting the 'set community' statement in the route map. --- bgpd/bgp_community.c | 7 +++++++ bgpd/bgp_community.h | 1 + bgpd/bgp_routemap.c | 8 +++++--- 3 files changed, 13 insertions(+), 3 deletions(-) (limited to 'bgpd') diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c index ae1d7a15..68383adf 100644 --- a/bgpd/bgp_community.c +++ b/bgpd/bgp_community.c @@ -292,6 +292,13 @@ community_com2str (struct community *com) return str; } +/* Find an 'intern'ed community structure */ +struct community * +community_lookup (struct community *com) +{ + return (struct community *) hash_lookup (comhash, com); +} + /* Intern communities attribute. */ struct community * community_intern (struct community *com) diff --git a/bgpd/bgp_community.h b/bgpd/bgp_community.h index bc1e56ef..78cbfe2b 100644 --- a/bgpd/bgp_community.h +++ b/bgpd/bgp_community.h @@ -70,5 +70,6 @@ extern int community_include (struct community *, u_int32_t); extern void community_del_val (struct community *, u_int32_t *); extern unsigned long community_count (void); extern struct hash *community_hash (void); +extern struct community *community_lookup (struct community *); #endif /* _QUAGGA_BGP_COMMUNITY_H */ diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 81ff48db..2b05e898 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1297,7 +1297,7 @@ route_set_community (void *rule, struct prefix *prefix, new = community_dup (rcs->com); /* will be interned by caller if required */ - attr->community = new; + attr->community = community_intern (new); attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); } @@ -1311,6 +1311,7 @@ route_set_community_compile (const char *arg) { struct rmap_com_set *rcs; struct community *com = NULL; + struct community *comint; char *sp; int additive = 0; int none = 0; @@ -1337,8 +1338,9 @@ route_set_community_compile (const char *arg) return NULL; } + comint = community_intern (com); rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set)); - rcs->com = com; + rcs->com = comint; rcs->additive = additive; rcs->none = none; @@ -1401,7 +1403,7 @@ route_set_community_delete (void *rule, struct prefix *prefix, } else { - binfo->attr->community = new; + binfo->attr->community = community_intern (new); binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); } } -- cgit v1.2.1