From 098519caf8836f1bb0df9568ecd5daa5b4d5140b Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Mon, 19 Jun 2023 10:21:28 +0800 Subject: [PATCH] zebra: fix wrong nexthop check for kernel routes When changing one interface's vrf, the kernel routes are wrongly kept in old vrf. Finally, the forwarding table in that old vrf can't forward traffic correctly for those residual entries. Follow these steps to make this problem happen: ( Firstly, "x1" interface of default vrf is with address of "6.6.6.6/24". ) ``` anlan# ip route add 4.4.4.0/24 via 6.6.6.8 dev x1 anlan# ip link add vrf1 type vrf table 1 anlan# ip link set vrf1 up anlan# ip link set x1 master vrf1 ``` Then check `show ip route`, the route of "4.4.4.0/24" is still selected in default vrf. If the interface goes down, the kernel routes will be reevaluated. Those kernel routes with active interface of nexthop can be kept no change, it is a fast path. Otherwise, it enters into slow path to do careful examination on this nexthop. After the interface's vrf had been changed into new vrf, the down message of this interface came. It means the interface is not in old vrf although it still exists during that checking, so the kernel routes should be dropped after this nexthop matching against a default route in slow path. But, in current code they are wrongly kept in fast path for not checking vrf. So, modified the checking active nexthop with vrf comparision for the interface during reevaluation. Signed-off-by: anlan_cs --- zebra/zebra_nhg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index fb474b1add..68fce701c4 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2582,6 +2582,8 @@ static unsigned nexthop_active_check(struct route_node *rn, if (IS_ZEBRA_DEBUG_NHG_DETAIL) zlog_debug("%s: re %p, nexthop %pNHv", __func__, re, nexthop); + vrf_id = zvrf_id(rib_dest_vrf(rib_dest_from_rnode(rn))); + /* * If this is a kernel route, then if the interface is *up* then * by golly gee whiz it's a good route. @@ -2591,13 +2593,12 @@ static unsigned nexthop_active_check(struct route_node *rn, ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); - if (ifp && if_is_up(ifp)) { + if (ifp && ifp->vrf->vrf_id == vrf_id && if_is_up(ifp)) { SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); goto skip_check; } } - vrf_id = zvrf_id(rib_dest_vrf(rib_dest_from_rnode(rn))); switch (nexthop->type) { case NEXTHOP_TYPE_IFINDEX: if (nexthop_active(nexthop, nhe, &rn->p, re->type, re->flags,