From a60b9a3718274a065e825ca881eb4be32d38221c Mon Sep 17 00:00:00 2001 From: vivek Date: Mon, 5 Sep 2016 10:49:16 -0700 Subject: [PATCH] bgpd: Fix route install upon multipath nexthop change In multipath selection, there can be a scenario where the set of route entries selected as multipath can be the same (i.e., from the same peers) but one or more of these may have a change to the BGP next hop. In this case, the route needs to be installed again in zebra even if the best route entry selected has not changed, otherwise the zebra RIB may have a different set of next hops (and first hops) than what the routing protocol selected. This patch handles this scenario by re-installing the route if any BGP attribute has changed for any of the multipaths. Not all BGP attributes are of relevance to the zebra RIB, but this approach follows existing logic used in the code (e.g., when BGP attributes for the best route entry has changed). Signed-off-by: Vivek Venkatraman Reviewed-by: Donald Sharp Reviewed-by: Daniel Walton Reviewed-by: Sid Khot Ticket: CM-12390 Reviewed By: CCR-5135 Testing Done: Manual, bgp-smoke (cherry picked from commit e10720512ef744483ffed8a6ef3b529ec97e130d) --- bgpd/bgp_route.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 26b5ef86d6..da50da9b1a 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1750,8 +1750,8 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp, } /* - * Clear IGP changed flag for a route (all paths). This is called at - * the end of route processing. + * Clear IGP changed flag and attribute changed flag for a route (all paths). + * This is called at the end of route processing. */ static void bgp_zebra_clear_route_change_flags (struct bgp_node *rn) @@ -1763,6 +1763,7 @@ bgp_zebra_clear_route_change_flags (struct bgp_node *rn) if (BGP_INFO_HOLDDOWN (ri)) continue; UNSET_FLAG (ri->flags, BGP_INFO_IGP_CHANGED); + UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); } } @@ -1776,7 +1777,12 @@ bgp_zebra_has_route_changed (struct bgp_node *rn, struct bgp_info *selected) { struct bgp_info *mpinfo; - /* There is a multipath change or best path has some nexthop change. */ + /* If this is multipath, check all selected paths for any nexthop change or + * attribute change. Some attribute changes (e.g., community) aren't of + * relevance to the RIB, but we'll update zebra to ensure we handle the + * case of BGP nexthop change. This is the behavior when the best path has + * an attribute change anyway. + */ if (CHECK_FLAG (selected->flags, BGP_INFO_IGP_CHANGED) || CHECK_FLAG (selected->flags, BGP_INFO_MULTIPATH_CHG)) return 1; @@ -1785,7 +1791,8 @@ bgp_zebra_has_route_changed (struct bgp_node *rn, struct bgp_info *selected) for (mpinfo = bgp_info_mpath_first (selected); mpinfo; mpinfo = bgp_info_mpath_next (mpinfo)) { - if (CHECK_FLAG (mpinfo->flags, BGP_INFO_IGP_CHANGED)) + if (CHECK_FLAG (mpinfo->flags, BGP_INFO_IGP_CHANGED) + || CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED)) return 1; } -- 2.39.5