Skip to content

Commit

Permalink
zebra: Prevent a kernel route from being there when a connected should
Browse files Browse the repository at this point in the history
There exists a series of events where a kernel route is learned
first( that happens to be exactly what a connected route should be )
and FRR ends up with both a kernel route and a connected route,
leaving us in a very strange spot.  This code change just mirrors
the existing code of if there is a connected route drop the kernel
route.  Here we just do the reverse, if we have a kernel route
already and a connected should be created, remove the kernel and
keep the connected.

Signed-off-by: Donald Sharp <[email protected]>
(cherry picked from commit 74e2519)
  • Loading branch information
donaldsharp authored and mergify[bot] committed Oct 15, 2024
1 parent a2d4087 commit 289e1e5
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions zebra/connected.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,40 @@ static void connected_update(struct interface *ifp, struct connected *ifc)
connected_announce(ifp, ifc);
}

/*
* This function goes through and handles the deletion of a kernel route that happened
* to be the exact same as the connected route, so that the connected route wins.
* This can happen during processing if we happen to receive events in a slightly
* unexpected order. This is similiar to code in the other direction where if we
* have a kernel route don't install it if it perfectly matches a connected route.
*/
static void connected_remove_kernel_for_connected(afi_t afi, safi_t safi, struct zebra_vrf *zvrf,
struct prefix *p, struct nexthop *nh)
{
struct route_node *rn;
struct route_entry *re;
rib_dest_t *dest;
struct route_table *table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf->vrf->vrf_id);

rn = route_node_match(table, p);
if (!rn)
return;

if (!prefix_same(&rn->p, p))
return;

dest = rib_dest_from_rnode(rn);
if (!dest || !dest->selected_fib)
return;

re = dest->selected_fib;
if (re->type != ZEBRA_ROUTE_KERNEL)
return;

rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_KERNEL, 0, 0, p, NULL, nh, 0,
zvrf->table_id, 0, 0, false);
}

/* Called from if_up(). */
void connected_up(struct interface *ifp, struct connected *ifc)
{
Expand Down Expand Up @@ -283,10 +317,13 @@ void connected_up(struct interface *ifp, struct connected *ifc)
}

if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_NOPREFIXROUTE)) {
connected_remove_kernel_for_connected(afi, SAFI_UNICAST, zvrf, &p, &nh);

rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id,
ZEBRA_ROUTE_CONNECT, 0, flags, &p, NULL, &nh, 0,
zvrf->table_id, metric, 0, 0, 0, false);

connected_remove_kernel_for_connected(afi, SAFI_MULTICAST, zvrf, &p, &nh);
rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id,
ZEBRA_ROUTE_CONNECT, 0, flags, &p, NULL, &nh, 0,
zvrf->table_id, metric, 0, 0, 0, false);
Expand Down

0 comments on commit 289e1e5

Please sign in to comment.