]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospf6d: add CLI to control maximum paths for routes. 7961/head
authorMobashshera Rasool <mrasool@vmware.com>
Thu, 28 Jan 2021 08:50:39 +0000 (08:50 +0000)
committerMobashshera Rasool <mrasool@vmware.com>
Mon, 1 Feb 2021 09:05:52 +0000 (09:05 +0000)
CLI added:
maximum-paths (1-64)

Issue: #7961

Signed-off-by: Mobashshera Rasool <mrasool@vmware.com>
doc/user/ospf6d.rst
ospf6d/ospf6_spf.c
ospf6d/ospf6_spf.h
ospf6d/ospf6_top.c
ospf6d/ospf6_top.h
ospf6d/ospf6_zebra.c

index b00bdb3ab8f4e49a6287ca774fa02011310ecc13..51f7b8f5071c7c6e394de614847524d247756f5a 100644 (file)
@@ -83,6 +83,12 @@ OSPF6 router
    This configuration setting MUST be consistent across all routers
    within the OSPF domain.
 
+.. index:: maximum-paths (1-64)
+.. clicmd::[no] maximum-paths (1-64)
+
+   Use this command to control the maximum number of parallel routes that
+   OSPFv3 can support. The default is 64.
+
 .. _ospf6-area:
 
 OSPF6 area
index 70771c6060f9359511fb50c99eb9b6ca63d42f31..6b24f276720868a8c1865287a4e2921cc8bf3fc7 100644 (file)
@@ -432,9 +432,8 @@ void ospf6_spf_table_finish(struct ospf6_route_table *result_table)
        }
 }
 
-static const char *const ospf6_spf_reason_str[] = {
-       "R+", "R-", "N+", "N-", "L+", "L-", "R*", "N*",
-};
+static const char *const ospf6_spf_reason_str[] = {"R+", "R-", "N+", "N-", "L+",
+                                                  "L-", "R*", "N*", "C"};
 
 void ospf6_spf_reason_string(unsigned int reason, char *buf, int size)
 {
index 853ce4de07db1a6ca43cdd35878749a0803684bf..253888d8ce91219261442749e3908f4491466e0b 100644 (file)
@@ -88,6 +88,7 @@ struct ospf6_vertex {
 #define OSPF6_SPF_FLAGS_LINK_LSA_REMOVED         (1 << 5)
 #define OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED    (1 << 6)
 #define OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED   (1 << 7)
+#define OSPF6_SPF_FLAGS_CONFIG_CHANGE            (1 << 8)
 
 static inline void ospf6_set_spf_reason(struct ospf6 *ospf, unsigned int reason)
 {
index 4a3697ed3f3ea6e4d167f09beaef0d4dcc4bea13..31b4ae3e76335d7c54e3c32a7f6d481271b93827 100644 (file)
@@ -267,6 +267,8 @@ static struct ospf6 *ospf6_create(const char *name)
        o->distance_table = route_table_init();
        o->fd = -1;
 
+       o->max_multipath = MULTIPATH_NUM;
+
        QOBJ_REG(o, ospf6);
 
        /* Make ospf protocol socket. */
@@ -878,6 +880,62 @@ DEFUN (no_ospf6_stub_router_admin,
        return CMD_SUCCESS;
 }
 
+/* Restart OSPF SPF algorithm*/
+static void ospf6_restart_spf(struct ospf6 *ospf6)
+{
+       ospf6_route_remove_all(ospf6->route_table);
+       ospf6_route_remove_all(ospf6->brouter_table);
+       ospf6_route_remove_all(ospf6->external_table);
+
+       /* Trigger SPF */
+       ospf6_spf_schedule(ospf6, OSPF6_SPF_FLAGS_CONFIG_CHANGE);
+}
+
+/* Set the max paths */
+static void ospf6_maxpath_set(struct ospf6 *ospf6, uint16_t paths)
+{
+       if (ospf6->max_multipath == paths)
+               return;
+
+       ospf6->max_multipath = paths;
+
+       /* Send deletion to zebra to delete all
+        * ospf specific routes and reinitiate
+        * SPF to reflect the new max multipath.
+        */
+       ospf6_restart_spf(ospf6);
+}
+
+/* Ospf Maximum-paths config support */
+DEFUN(ospf6_max_multipath,
+      ospf6_max_multipath_cmd,
+      "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
+      "Max no of multiple paths for ECMP support\n"
+      "Number of paths\n")
+{
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+       int idx_number = 1;
+       int maximum_paths = strtol(argv[idx_number]->arg, NULL, 10);
+
+       ospf6_maxpath_set(ospf6, maximum_paths);
+
+       return CMD_SUCCESS;
+}
+
+DEFUN(no_ospf6_max_multipath,
+      no_ospf6_max_multipath_cmd,
+     "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM)"]",
+      NO_STR
+      "Max no of multiple paths for ECMP support\n"
+      "Number of paths\n")
+{
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       ospf6_maxpath_set(ospf6, MULTIPATH_NUM);
+
+       return CMD_SUCCESS;
+}
+
 static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
                       bool use_json)
 {
@@ -916,6 +974,7 @@ static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
                json_object_int_add(json, "holdTimeMultiplier",
                                    o->spf_hold_multiplier);
 
+               json_object_int_add(json, "maximumPaths", o->max_multipath);
 
                if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
                        timersub(&now, &o->ts_spf, &result);
@@ -998,6 +1057,7 @@ static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
                vty_out(vty, " LSA minimum arrival %d msecs\n",
                        o->lsa_minarrival);
 
+               vty_out(vty, " Maximum-paths %u\n", o->max_multipath);
 
                /* Show SPF parameters */
                vty_out(vty,
@@ -1251,6 +1311,11 @@ static int config_write_ospf6(struct vty *vty)
                        vty_out(vty, " timers lsa min-arrival %d\n",
                                ospf6->lsa_minarrival);
 
+               /* ECMP max path config */
+               if (ospf6->max_multipath != MULTIPATH_NUM)
+                       vty_out(vty, " maximum-paths %d\n",
+                               ospf6->max_multipath);
+
                ospf6_stub_router_config_write(vty, ospf6);
                ospf6_redistribute_config_write(vty, ospf6);
                ospf6_area_config_write(vty, ospf6);
@@ -1309,6 +1374,10 @@ void ospf6_top_init(void)
        install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
        install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
 
+       /* maximum-paths command */
+       install_element(OSPF6_NODE, &ospf6_max_multipath_cmd);
+       install_element(OSPF6_NODE, &no_ospf6_max_multipath_cmd);
+
        install_element(OSPF6_NODE, &ospf6_distance_cmd);
        install_element(OSPF6_NODE, &no_ospf6_distance_cmd);
        install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd);
index 93e25d75995688c09f4f27e0036b7dccba6a76ab..75dff86cd70da16bf24e41dbd09729d26800f649 100644 (file)
@@ -127,6 +127,11 @@ struct ospf6 {
         * update to neighbors immediatly */
        uint8_t inst_shutdown;
 
+       /* Max number of multiple paths
+        * to support ECMP.
+        */
+       uint16_t max_multipath;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(ospf6)
index 7a8027a37fab8b8e8928ff412dd932015a0f4392..2b7072d34f741187b3538df6d944f51e60e260b1 100644 (file)
@@ -343,7 +343,14 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
        api.safi = SAFI_UNICAST;
        api.prefix = *dest;
        SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
-       api.nexthop_num = MIN(nhcount, MULTIPATH_NUM);
+
+       if (nhcount > ospf6->max_multipath) {
+               if (IS_OSPF6_DEBUG_ZEBRA(SEND))
+                       zlog_debug(
+                               "  Nexthop count is greater than configured maximum-path, hence ignore the extra nexthops");
+       }
+       api.nexthop_num = MIN(nhcount, ospf6->max_multipath);
+
        ospf6_route_zebra_copy_nexthops(request, api.nexthops, api.nexthop_num,
                                        api.vrf_id);
        SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);