|
| 1 | +From 2c69d638436f6e809c9fa2bbf8f2f8f3199f8db3 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Deepak Singhal <deepsinghal@microsoft.com> |
| 3 | +Date: Thu, 2 Apr 2026 05:00:25 +0000 |
| 4 | +Subject: [PATCH] SONiC-ONLY: zebra: skip if_add_update in speed timer for unready |
| 5 | + interfaces |
| 6 | +MIME-Version: 1.0 |
| 7 | +Content-Type: text/plain; charset=UTF-8 |
| 8 | +Content-Transfer-Encoding: 8bit |
| 9 | + |
| 10 | +The if_zebra_speed_update() timer fires 15 seconds after interface creation, |
| 11 | +regardless of whether the interface has received an RTM_NEWLINK from the kernel. |
| 12 | +For interfaces created during FRR config replay (frr.conf), the ifindex is still |
| 13 | +IFINDEX_INTERNAL (0) if RTM_NEWLINK hasn't been processed yet. |
| 14 | + |
| 15 | +Calling if_add_update() with ifindex=0 sets ZEBRA_INTERFACE_ACTIVE prematurely. |
| 16 | +When RTM_NEWLINK later arrives, the interface is already marked active, causing |
| 17 | +the handler to take the "update" branch instead of the "new" branch. The update |
| 18 | +branch calls set_ifindex() but does NOT call if_add_update()/zebra_ns_link_ifp(), |
| 19 | +so the interface is never linked into the per-NS ifindex rbtree. This causes |
| 20 | +if_lookup_by_index_per_ns() to fail silently for that interface, breaking route |
| 21 | +and nexthop resolution — a silent routing failure. |
| 22 | + |
| 23 | +Guard the if_add_update() call in the speed timer so it only runs when the |
| 24 | +interface has a valid (non-zero) kernel ifindex. The speed value is still |
| 25 | +recorded on the interface struct regardless. |
| 26 | + |
| 27 | +Signed-off-by: Deepak Singhal <deepsinghal@microsoft.com> |
| 28 | +--- |
| 29 | + zebra/interface.c | 3 ++- |
| 30 | + 1 file changed, 2 insertions(+), 1 deletion(-) |
| 31 | + |
| 32 | +diff --git a/zebra/interface.c b/zebra/interface.c |
| 33 | +index 52c2619eed..f9b31260a3 100644 |
| 34 | +--- a/zebra/interface.c |
| 35 | ++++ b/zebra/interface.c |
| 36 | +@@ -81,7 +81,8 @@ static void if_zebra_speed_update(struct event *thread) |
| 37 | + zlog_info("%s: %s old speed: %u new speed: %u", __func__, |
| 38 | + ifp->name, ifp->speed, new_speed); |
| 39 | + if_update_state_speed(ifp, new_speed); |
| 40 | +- if_add_update(ifp); |
| 41 | ++ if (ifp->ifindex != IFINDEX_INTERNAL) |
| 42 | ++ if_add_update(ifp); |
| 43 | + changed = true; |
| 44 | + } |
| 45 | + |
| 46 | +-- |
| 47 | +2.34.1 |
| 48 | + |
0 commit comments