summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvivek <vivek@cumulusnetworks.com>2016-07-26 10:45:51 -0700
committervivek <vivek@cumulusnetworks.com>2016-07-26 10:45:51 -0700
commit711093b5ebfd059f433396e4bca98216e02482fb (patch)
tree043fe0d877d921e97d2a634d34802524943c1736
parent598a479fb34f837b76a29fb3560da2dcbcd3de12 (diff)
bgpd: Fix attribute handling upon redistribution metric change
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
-rw-r--r--bgpd/bgp_zebra.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 4a39bc2b2e..888a819d06 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -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;
}