]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Fix attribute handling upon redistribution metric change
authorvivek <vivek@cumulusnetworks.com>
Tue, 26 Jul 2016 17:45:51 +0000 (10:45 -0700)
committervivek <vivek@cumulusnetworks.com>
Tue, 26 Jul 2016 17:45:51 +0000 (10:45 -0700)
When the metric for a redistributed route is changed through configuration,
the path attribute for the route/routes need to be "re-created" as the hash
entry would change. In the absence of this, the entry would have the correct
values but when a hash lookup is done at a later time (e.g., when trying to
free the entry), it would fail. This patch addresses the "re-creation"

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-11168
Reviewed By: CCR-4990
Testing Done: Manual, bgp-smoke

bgpd/bgp_zebra.c

index 4a39bc2b2e7ab26794557fe55a29de79af065550..888a819d06be16db238637add899abf436ee492e 100644 (file)
@@ -1891,16 +1891,30 @@ bgp_redistribute_metric_set (struct bgp *bgp, struct bgp_redist *red, afi_t afi,
   red->redist_metric_flag = 1;
   red->redist_metric = metric;
 
-  for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; rn = bgp_route_next(rn)) {
-    for (ri = rn->info; ri; ri = ri->next) {
-      if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE && ri->type == type &&
-         ri->instance == red->instance) {
-         ri->attr->med = red->redist_metric;
-         bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
-         bgp_process(bgp, rn, afi, SAFI_UNICAST);
-      }
+  for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; rn = bgp_route_next(rn))
+    {
+      for (ri = rn->info; ri; ri = ri->next)
+        {
+          if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE &&
+              ri->type == type &&
+              ri->instance == red->instance)
+            {
+              struct attr *old_attr;
+              struct attr new_attr;
+              struct attr_extra new_extra;
+
+              new_attr.extra = &new_extra;
+              bgp_attr_dup (&new_attr, ri->attr);
+              new_attr.med = red->redist_metric;
+              old_attr = ri->attr;
+              ri->attr = bgp_attr_intern (&new_attr);
+              bgp_attr_unintern (&old_attr);
+
+              bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
+              bgp_process(bgp, rn, afi, SAFI_UNICAST);
+            }
+        }
     }
-  }
 
   return 1;
 }