bgpd: We try to skip out of updating the multipath aggregate if there are no
changes in the multipath set or attributes, but failed to check for
just a bestpath change. The result is there is no attribute on the new
bestpath and we hit the assert. Added the bestpath check and
rearranged the code to only check attributes when there is no bestpath
or multipath change, so we only scan the for attribute changes when
necessary.
* bgpd/bgp_mpath.c
* bgp_info_mpath_aggregate_update(): Added check for bestpath
change before skipping the aggregate generation. Skip the attribute
check if either the multipath set or bestpath has changed.
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index 1709c24..d07830d 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -626,25 +626,32 @@
/*
* Bail out here if the following is true:
* - MULTIPATH_CHG bit is not set on new_best, and
+ * - No change in bestpath, and
* - ATTR_CHANGED bit is not set on new_best or any of the multipaths
*/
- attr_chg = 0;
- if (CHECK_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED))
- attr_chg = 1;
- else
- for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
- mpinfo = bgp_info_mpath_next (mpinfo))
- {
- if (CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED))
- {
- attr_chg = 1;
- break;
- }
- }
- if (!CHECK_FLAG (new_best->flags, BGP_INFO_MULTIPATH_CHG) && !attr_chg)
+ if (!CHECK_FLAG (new_best->flags, BGP_INFO_MULTIPATH_CHG) &&
+ (old_best == new_best))
{
- assert (bgp_info_mpath_attr (new_best));
- return;
+ attr_chg = 0;
+
+ if (CHECK_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED))
+ attr_chg = 1;
+ else
+ for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
+ mpinfo = bgp_info_mpath_next (mpinfo))
+ {
+ if (CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED))
+ {
+ attr_chg = 1;
+ break;
+ }
+ }
+
+ if (!attr_chg)
+ {
+ assert (bgp_info_mpath_attr (new_best));
+ return;
+ }
}
bgp_attr_dup (&attr, new_best->attr);