Skip to content

Commit 46044a4

Browse files
committed
zebra: Allow nhg's to be reused when multiple interfaces are going amuck
Currently if there are multiple interfaces going down it is possible to have a ships in the night situation with trying to reuse a nhg. Imagine that you have a route w/ 4 way ecmp nexthop A interface a nexthop B interface b nexthop C interface c nexthop D interface d Suppose interface a goes down, zebra receives this data marks singleton nexthop A down and then recurses up the tree to the 4 way ecmp and sets nexthop A as inactive. Zebra then will notify the upper level protocol. The upper level protocol will refigure the route and send it down with 3 way ecmp. At the same time if interface b goes down and zebra handles that interface down event before the new route installation, then when zebra_nhg_rib_compare_old_nhe is called it will not match the old and new ones up as that the old will be: nexthop A <inactive> nexthop B <inactive> nexthop C nexthop D New will be: nexthop B <inactive> nexthop C nexthop D Currently zebra_nhg_nexthop_compare on the old skips all the inactive but it never skips the nexthops at are inactive on the new. Modify the code to allow the new nhop to be skipped if it is the same nexthop being looked at as the old and it is not active as well. This allows zebra to choose the same nhg in the above case to continue working. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
1 parent 66f552c commit 46044a4

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

zebra/zebra_nhg.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,13 +3041,27 @@ static bool zebra_nhg_nexthop_compare(const struct nexthop *nhop,
30413041

30423042
while (nhop && old_nhop) {
30433043
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
3044-
zlog_debug("%s: %pRN Comparing %pNHvv(%u) to old: %pNHvv(%u)",
3045-
__func__, rn, nhop, nhop->flags, old_nhop,
3046-
old_nhop->flags);
3044+
zlog_debug("%s: %pRN Comparing %pNHvv(%u) ACTIVE: %d to old: %pNHvv(%u) ACTIVE: %d nexthop same: %d",
3045+
__func__, rn, nhop, nhop->flags,
3046+
CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_ACTIVE), old_nhop,
3047+
old_nhop->flags, CHECK_FLAG(old_nhop->flags, NEXTHOP_FLAG_ACTIVE),
3048+
nexthop_same_no_ifindex(nhop, old_nhop));
30473049
if (!CHECK_FLAG(old_nhop->flags, NEXTHOP_FLAG_ACTIVE)) {
30483050
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
30493051
zlog_debug("%s: %pRN Old is not active going to the next one",
30503052
__func__, rn);
3053+
3054+
/*
3055+
* If the new nexthop is not active and the old nexthop is also not active,
3056+
* then we know that we can skip both the old and new nexthops.
3057+
*/
3058+
if (!CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_ACTIVE) &&
3059+
nexthop_same_no_ifindex(nhop, old_nhop)) {
3060+
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
3061+
zlog_debug("%s: %pRN new is not active going to the next one",
3062+
__func__, rn);
3063+
nhop = nhop->next;
3064+
}
30513065
old_nhop = old_nhop->next;
30523066
continue;
30533067
}

0 commit comments

Comments
 (0)