]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: don't use kernel nexthops for blackhole routes
authorIgor Ryzhov <iryzhov@nfware.com>
Thu, 25 Feb 2021 15:28:51 +0000 (18:28 +0300)
committerIgor Ryzhov <iryzhov@nfware.com>
Tue, 2 Mar 2021 16:58:33 +0000 (19:58 +0300)
Fixes #6522 and #8149.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
zebra/rt_netlink.c

index 67519e2f408750f6982cbc12a3735d4b13348e5d..770feb52bd1a97b440e1387992b37107b7c97242 100644 (file)
@@ -1743,6 +1743,33 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
                nl_attr_nest_end(&req->n, nest);
        }
 
+       /*
+        * 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 (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+                       nexthop = nexthop->resolved;
+
+               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;
+                       }
+                       return NLMSG_ALIGN(req->n.nlmsg_len);
+               }
+       }
+
        if ((!fpm && kernel_nexthops_supported()) || (fpm && force_nhg)) {
                /* Kernel supports nexthop objects */
                if (IS_ZEBRA_DEBUG_KERNEL)
@@ -1793,27 +1820,6 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
        if (nexthop_num == 1) {
                nexthop_num = 0;
                for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), 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;
-                               }
-                               return NLMSG_ALIGN(req->n.nlmsg_len);
-                       }
                        if (CHECK_FLAG(nexthop->flags,
                                       NEXTHOP_FLAG_RECURSIVE)) {