]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra,lib: command to only install proto-based nexthops
authorStephen Worley <sworley@cumulusnetworks.com>
Wed, 13 May 2020 19:50:14 +0000 (12:50 -0700)
committerStephen Worley <sworley@cumulusnetworks.com>
Mon, 28 Sep 2020 16:40:59 +0000 (12:40 -0400)
Add a command/functionality to only install proto-based nexthops.
That is nexthops owned/created by upper level protocols, not ones
implicitly created by zebra.

There are some scenarios where you would not want zebra to be
arbitrarily installing nexthop groups and but you still want
to use ones you have control over via lib/nexthop_group config
and an upper level protocol.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
lib/zclient.c
lib/zclient.h
zebra/rt_netlink.c
zebra/zebra_nhg.c
zebra/zebra_nhg.h
zebra/zebra_vty.c

index 17026d13a698fa212469f72de29668c7292007a2..deb5f519bd55de43d5a2217602e8e7cdfa74a6cc 100644 (file)
@@ -4083,3 +4083,11 @@ uint32_t zclient_get_nhg_start(uint32_t proto)
 
        return ZEBRA_NHG_SPACING * proto;
 }
+
+/*
+ * Where do routing protocols IDs start overall (first ID after zebra)
+ */
+uint32_t zclient_get_nhg_lower_bound()
+{
+       return ZEBRA_NHG_SPACING * (ZEBRA_ROUTE_CONNECT + 1);
+}
index b7850cdec7bd8212058809b70f01ee8d191546af..db5e1ce5b91815105d1f4fb9c3db7d7cb4c7d5cd 100644 (file)
@@ -692,6 +692,7 @@ extern struct zclient_options zclient_options_default;
  */
 #define ZEBRA_NHG_SPACING 50000000
 extern uint32_t zclient_get_nhg_start(uint32_t proto);
+extern uint32_t zclient_get_nhg_lower_bound(void);
 
 extern struct zclient *zclient_new(struct thread_master *m,
                                   struct zclient_options *opt);
index 146650f602dff2daa679ad8bba391d3c8ce73aa7..07135b7fc87ab3c75005516a13d682144bbde292 100644 (file)
@@ -125,6 +125,31 @@ static bool kernel_nexthops_supported(void)
                && zebra_nhg_kernel_nexthops_enabled());
 }
 
+/*
+ * Some people may only want to use NHGs created by protos and not
+ * implicitly created by Zebra. This check accounts for that.
+ */
+static bool proto_nexthops_only(void)
+{
+       return zebra_nhg_proto_nexthops_only();
+}
+
+/* Is this a proto created NHG? */
+static bool is_proto_nhg(uint32_t id, int type)
+{
+       /* If type is available, use it as the source of truth */
+       if (type) {
+               if (type != ZEBRA_ROUTE_NHG)
+                       return true;
+               return false;
+       }
+
+       if (id >= zclient_get_nhg_lower_bound())
+               return true;
+
+       return false;
+}
+
 /*
  * The ipv4_ll data structure is used for all 5549
  * additions to the kernel.  Let's figure out the
@@ -1748,7 +1773,10 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
                nl_attr_nest_end(&req->n, nest);
        }
 
-       if ((!fpm && kernel_nexthops_supported()) || (fpm && force_nhg)) {
+       if ((!fpm && kernel_nexthops_supported()
+            && (!proto_nexthops_only()
+                || is_proto_nhg(dplane_ctx_get_nhe_id(ctx), 0)))
+           || (fpm && force_nhg)) {
                /* Kernel supports nexthop objects */
                if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug("%s: %pFX nhg_id is %u", __func__, p,
@@ -2073,6 +2101,16 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
        char label_buf[256];
        int num_labels = 0;
 
+       /*
+        * Nothing to do if the kernel doesn't support nexthop objects or
+        * we dont want to install this type of NHG
+        */
+       if (!kernel_nexthops_supported()
+           || (proto_nexthops_only()
+               && !is_proto_nhg(dplane_ctx_get_nhe_id(ctx),
+                                dplane_ctx_get_nhe_type(ctx))))
+               return 0;
+
        label_buf[0] = '\0';
 
        if (buflen < sizeof(*req))
index 59df45420bbee13a3e3aa13ea3e39374b6b8cf55..dbf5adafe13ce9a1723a5dfecf1961af0de8bbc5 100644 (file)
@@ -53,6 +53,7 @@ uint32_t id_counter;
 
 /*  */
 static bool g_nexthops_enabled = true;
+static bool proto_nexthops_only = false;
 
 static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi,
                                           int type);
@@ -2661,6 +2662,24 @@ bool zebra_nhg_kernel_nexthops_enabled(void)
        return g_nexthops_enabled;
 }
 
+/*
+ * Global control to only use kernel nexthops for protocol created NHGs.
+ * There are some use cases where you may not want zebra to implicitly
+ * create kernel nexthops for all routes and only create them for NHGs
+ * passed down by upper level protos.
+ *
+ * Default is off.
+ */
+void zebra_nhg_set_proto_nexthops_only(bool set)
+{
+       proto_nexthops_only = set;
+}
+
+bool zebra_nhg_proto_nexthops_only(void)
+{
+       return proto_nexthops_only;
+}
+
 /* Add NHE from upper level proto */
 struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
                                           struct nexthop_group *nhg, afi_t afi)
index 44d768648f09349e1ce04403bd64425736ef42da..02858779b34a89838a29c7f085322198686dc983 100644 (file)
@@ -182,6 +182,10 @@ struct nhg_ctx {
 void zebra_nhg_enable_kernel_nexthops(bool set);
 bool zebra_nhg_kernel_nexthops_enabled(void);
 
+/* Global control for zebra to only use proto-owned nexthops */
+void zebra_nhg_set_proto_nexthops_only(bool set);
+bool zebra_nhg_proto_nexthops_only(void);
+
 /**
  * NHE abstracted tree functions.
  * Use these where possible instead of direct access.
index baf7d2c14d449db469dfde0bcc3c143e985fa822..7e73b3f724eff9f3637156a27c1cf9e6dd1ab109 100644 (file)
@@ -1566,6 +1566,19 @@ DEFPY_HIDDEN(nexthop_group_use_enable,
        return CMD_SUCCESS;
 }
 
+DEFPY_HIDDEN (proto_nexthop_group_only,
+              proto_nexthop_group_only_cmd,
+              "[no] zebra nexthop proto only",
+              NO_STR
+              ZEBRA_STR
+              "Nexthop configuration\n"
+              "Configure exclusive use of proto nexthops\n"
+              "Only use proto nexthops\n")
+{
+       zebra_nhg_set_proto_nexthops_only(!no);
+       return CMD_SUCCESS;
+}
+
 DEFUN (no_ip_nht_default_route,
        no_ip_nht_default_route_cmd,
        "no ip nht resolve-via-default",
@@ -3448,6 +3461,9 @@ static int config_write_protocol(struct vty *vty)
        if (!zebra_nhg_kernel_nexthops_enabled())
                vty_out(vty, "no zebra nexthop kernel enable\n");
 
+       if (zebra_nhg_proto_nexthops_only())
+               vty_out(vty, "zebra nexthop proto only\n");
+
 #ifdef HAVE_NETLINK
        /* Include netlink info */
        netlink_config_write_helper(vty);
@@ -3882,6 +3898,7 @@ void zebra_vty_init(void)
        install_element(CONFIG_NODE, &zebra_packet_process_cmd);
        install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
        install_element(CONFIG_NODE, &nexthop_group_use_enable_cmd);
+       install_element(CONFIG_NODE, &proto_nexthop_group_only_cmd);
 
        install_element(VIEW_NODE, &show_nexthop_group_cmd);
        install_element(VIEW_NODE, &show_interface_nexthop_group_cmd);