Skip to content

Commit

Permalink
zebra: check multipath before using recursively resolved blackhole nh
Browse files Browse the repository at this point in the history
In case a static route is resolving over multiple nexthops (multipath),
if the first nexthop in the list is recursively resolving over a
blackhole, zebra does not bother looking at other nexthops and sends a
netlink update to the kernel marking the route as a blackhole. This
results in complete traffic blackholing even in a multipath setup.

If number of nexthops > 1, do not bother checking for recursively
resolved blackhole nexthop. Let zebra's multipath handling take over.

Signed-off-by: Abhishek Naik <[email protected]>
  • Loading branch information
bhinin committed Sep 28, 2023
1 parent c6440fa commit 8b0b222
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions zebra/rt_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -2308,14 +2308,27 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
nl_attr_nest_end(&req->n, nest);
}

/* Count overall nexthops so we can decide whether to use singlepath
* or multipath case.
*/
nexthop_num = 0;
for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue;
if (!NEXTHOP_IS_ACTIVE(nexthop->flags))
continue;

nexthop_num++;
}

/*
* Always install blackhole routes without using nexthops, because of
* the following kernel problems:
* 1. Kernel nexthops don't suport unreachable/prohibit route types.
* 2. Blackhole kernel nexthops are deleted when loopback is down.
*/
nexthop = dplane_ctx_get_ng(ctx)->nexthop;
if (nexthop) {
if (nexthop && nexthop_num == 1) {
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
nexthop = nexthop->resolved;

Expand Down Expand Up @@ -2372,19 +2385,6 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
return NLMSG_ALIGN(req->n.nlmsg_len);
}

/* Count overall nexthops so we can decide whether to use singlepath
* or multipath case.
*/
nexthop_num = 0;
for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue;
if (!NEXTHOP_IS_ACTIVE(nexthop->flags))
continue;

nexthop_num++;
}

/* Singlepath case. */
if (nexthop_num == 1) {
nexthop_num = 0;
Expand Down

0 comments on commit 8b0b222

Please sign in to comment.