From 1f1d24a8f1f183d6d0a4598b854b459f5b5d7e5c Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 12 Sep 2017 08:14:50 -0400 Subject: [PATCH] zebra: Allow recursively resolved blackhole routes to be installed So the current code for a blackhole route assumed that you would never want a recursively resolved blackhole to work. Suppose you have this setup: 1) ip route 192.0.2.1/32 Null0 2) BGP installed with a route-map that rewrites the nexthop to 192.0.2.1. Zebra will end up with a recursive nexthop that resolves to the blackhole. The original rib install function assumed that we would never want the ability to recursively resolve a blackhole route. Instead just handle the blackhole as part of the nexthop_num = 1 case. Signed-off-by: Donald Sharp --- zebra/rt_netlink.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 12b6185395..ef59f26f21 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1321,23 +1321,6 @@ static int netlink_route_multipath(int cmd, struct prefix *p, req.r.rtm_scope = RT_SCOPE_UNIVERSE; req.r.rtm_type = RTN_UNICAST; - if (re->nexthop_num == 1 - && re->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) { - discard = 1; - - switch (re->nexthop->bh_type) { - case BLACKHOLE_ADMINPROHIB: - req.r.rtm_type = RTN_PROHIBIT; - break; - case BLACKHOLE_REJECT: - req.r.rtm_type = RTN_UNREACHABLE; - break; - default: - req.r.rtm_type = RTN_BLACKHOLE; - break; - } - } - addattr_l(&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen); if (src_p) addattr_l(&req.n, sizeof req, RTA_SRC, &src_p->u.prefix, @@ -1396,6 +1379,27 @@ static int netlink_route_multipath(int cmd, struct prefix *p, if (nexthop_num == 1 || multipath_num == 1) { nexthop_num = 0; for (ALL_NEXTHOPS(re->nexthop, nexthop)) { + /* + * So we want to cover 2 types of blackhole + * routes here: + * 1) A normal blackhole route( ala from a static + * install. + * 2) A recursively resolved blackhole route + */ + if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) { + switch (nexthop->bh_type) { + case BLACKHOLE_ADMINPROHIB: + req.r.rtm_type = RTN_PROHIBIT; + break; + case BLACKHOLE_REJECT: + req.r.rtm_type = RTN_UNREACHABLE; + break; + default: + req.r.rtm_type = RTN_BLACKHOLE; + break; + } + goto skip; + } if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) { if (!setsrc) { -- 2.39.5