]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Fix route install upon multipath nexthop change
authorvivek <vivek@cumulusnetworks.com>
Mon, 5 Sep 2016 17:49:16 +0000 (10:49 -0700)
committervivek <vivek@cumulusnetworks.com>
Tue, 6 Sep 2016 19:38:09 +0000 (12:38 -0700)
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 <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Sid Khot <sidkhot@cumulusnetworks.com>
Ticket: CM-12390
Reviewed By: CCR-5135
Testing Done: Manual, bgp-smoke

(cherry picked from commit e10720512ef744483ffed8a6ef3b529ec97e130d)

bgpd/bgp_route.c

index 26b5ef86d6165ffd20833da61eb6538994188b23..da50da9b1a33ae01be19375ee242dfb99faa77ff 100644 (file)
@@ -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;
     }