summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Jakma <paul.jakma@sun.com>2006-02-18 10:49:04 +0000
committerPaul Jakma <paul.jakma@sun.com>2006-02-18 10:49:04 +0000
commitaa94ca86ba0323d61fc3bc9b881718567ee943b3 (patch)
treef4c41a1d40c6321482defa436ebfb2eeb31d22ab
parent3fff6ffc697e362959de95b6cc292fd6fb7502a6 (diff)
[bug #89] Fix leak of community when set community is used
2006-02-18 Paul Jakma <paul.jakma@sun.com> * bgp_routemap.c: (route_set_community) Quick, very hacky, fix for the set-community leak, bug #89. True fix will be to detangle the web of *_intern caching and provide saner object caching for Quagga, future work.
-rw-r--r--bgpd/ChangeLog7
-rw-r--r--bgpd/bgp_routemap.c12
2 files changed, 17 insertions, 2 deletions
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index 6101b50e..78a22e67 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -1,3 +1,10 @@
+2006-02-18 Paul Jakma <paul.jakma@sun.com>
+
+ * bgp_routemap.c: (route_set_community) Quick, very hacky, fix
+ for the set-community leak, bug #89. True fix will be to
+ detangle the web of *_intern caching and provide saner object
+ caching for Quagga, future work.
+
2006-02-05 Paul Jakma <paul.jakma@sun.com>
* bgp_route.h: Add BGP_INFO_COUNTED to track whether
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 15ba9452..806a5072 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1195,7 +1195,7 @@ route_set_community (void *rule, struct prefix *prefix,
struct community *new = NULL;
struct community *old;
struct community *merge;
-
+
if (type == RMAP_BGP)
{
rcs = rule;
@@ -1215,12 +1215,20 @@ route_set_community (void *rule, struct prefix *prefix,
if (rcs->additive && old)
{
merge = community_merge (community_dup (old), rcs->com);
+
+ /* HACK: if the old community is not intern'd,
+ * we should free it here, or all reference to it may be lost.
+ * Really need to cleanup attribute caching sometime.
+ */
+ if (old->refcnt == 0)
+ community_free (old);
new = community_uniq_sort (merge);
community_free (merge);
}
else
new = community_dup (rcs->com);
-
+
+ /* will be interned by caller if required */
attr->community = new;
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);