]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: Max multipath config support 8058/head
authorrgirada <rgirada@vmware.com>
Thu, 11 Feb 2021 10:05:12 +0000 (02:05 -0800)
committerrgirada <rgirada@vmware.com>
Tue, 30 Mar 2021 05:04:46 +0000 (22:04 -0700)
Description:
OSPF does not have an option to control the maximum multiple
equal cost paths to reach a destination/route(ECMP).
Currently, it is using the system specific max multiple paths.
But Somtimes, It requires to control the multiple paths from ospf.
This cli helps to configure the max number multiple paths in ospf.

Signed-off-by: Rajesh Girada <rgirada@vmware.com>
doc/user/ospfd.rst
ospfd/ospf_spf.c
ospfd/ospf_spf.h
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospfd.c
ospfd/ospfd.h

index af9a7844a2f485bd7c5175b84e249309488b65f6..d4006fc42e5ab4214ecd182028fb1b2ebe9f744d 100644 (file)
@@ -299,6 +299,16 @@ To start OSPF process you have to specify the OSPF router.
    command can be used when the neighbor state get stuck at some state and
    this can be used to recover it from that state.
 
+.. index:: maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM)
+.. clicmd:: maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM)
+
+.. index:: maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM)
+.. clicmd:: no maximum-paths
+
+   CLI to control maximum number of equal cost paths to reach a specific
+   destination.(ECMP)
+   Reset CLI, resets the maximum supported multi path to the default value.
+
 .. _ospf-area:
 
 Areas
index 1e0814764bb5bc3ee583d25bf8faeda96a02255e..95553dacdfdf064785b4e610e01ce1bf7a4dfe80 100644 (file)
@@ -1987,3 +1987,27 @@ void ospf_spf_calculate_schedule(struct ospf *ospf, ospf_spf_reason_t reason)
        thread_add_timer_msec(master, ospf_spf_calculate_schedule_worker, ospf,
                              delay, &ospf->t_spf_calc);
 }
+
+/* Restart OSPF SPF algorithm*/
+void ospf_restart_spf(struct ospf *ospf)
+{
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("%s: Restart SPF.", __PRETTY_FUNCTION__);
+
+       /* Handling inter area and intra area routes*/
+       if (ospf->new_table) {
+               ospf_route_delete(ospf, ospf->new_table);
+               ospf_route_table_free(ospf->new_table);
+               ospf->new_table = route_table_init();
+       }
+
+       /* Handling of TYPE-5 lsa(external routes) */
+       if (ospf->old_external_route) {
+               ospf_route_delete(ospf, ospf->old_external_route);
+               ospf_route_table_free(ospf->old_external_route);
+               ospf->old_external_route = route_table_init();
+       }
+
+       /* Trigger SPF */
+       ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE);
+}
index 835caab288ea945f90cb377c7f60a48ae04db68b..4ff4a6d125a1d93654a9eaf6554de9f75d608439 100644 (file)
@@ -98,6 +98,6 @@ extern struct vertex_parent *ospf_spf_vertex_parent_find(struct in_addr id,
 extern int vertex_parent_cmp(void *aa, void *bb);
 
 extern void ospf_spf_print(struct vty *vty, struct vertex *v, int i);
-
+extern void ospf_restart_spf(struct ospf *ospf);
 /* void ospf_spf_calculate_timer_add (); */
 #endif /* _QUAGGA_OSPF_SPF_H */
index 6436c20f921c889414284ba5df303f0106e94c13..f3583c26f21c92e2f5f471f4a75605bf4df24601 100644 (file)
@@ -2697,6 +2697,50 @@ DEFUN(no_ospf_ti_lfa, no_ospf_ti_lfa_cmd,
        return CMD_SUCCESS;
 }
 
+static void ospf_maxpath_set(struct vty *vty, struct ospf *ospf, uint16_t paths)
+{
+       if (ospf->max_multipath == paths)
+               return;
+
+       ospf->max_multipath = paths;
+
+       /* Send deletion notification to zebra to delete all
+        * ospf specific routes and reinitiat SPF to reflect
+        * the new max multipath.
+        */
+       ospf_restart_spf(ospf);
+}
+
+/* Ospf Maximum multiple paths config support */
+DEFUN (ospf_max_multipath,
+       ospf_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_INSTANCE_CONTEXT(ospf, ospf);
+       int idx_number = 1;
+       uint16_t maxpaths;
+
+       maxpaths = strtol(argv[idx_number]->arg, NULL, 10);
+
+       ospf_maxpath_set(vty, ospf, maxpaths);
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_ospf_max_multipath,
+       no_ospf_max_multipath_cmd,
+       "no maximum-paths",
+       NO_STR
+       "Max no of multiple paths for ECMP support\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+       uint16_t maxpaths = MULTIPATH_NUM;
+
+       ospf_maxpath_set(vty, ospf, maxpaths);
+       return CMD_SUCCESS;
+}
+
 static const char *const ospf_abr_type_descr_str[] = {
        "Unknown", "Standard (RFC2328)", "Alternative IBM",
        "Alternative Cisco", "Alternative Shortcut"
@@ -3226,6 +3270,10 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
                /* Show refresh parameters. */
                vty_out(vty, " Refresh timer %d secs\n",
                        ospf->lsa_refresh_interval);
+
+               /* show max multipath */
+               vty_out(vty, " Maximum multiple paths(ECMP) supported  %d\n",
+                       ospf->max_multipath);
        }
 
        /* Show ABR/ASBR flags. */
@@ -12277,6 +12325,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
                vty_out(vty, " ospf write-multiplier %d\n",
                        ospf->write_oi_count);
 
+       if (ospf->max_multipath != MULTIPATH_NUM)
+               vty_out(vty, " maximum-paths %d\n", ospf->max_multipath);
+
        /* Max-metric router-lsa print */
        config_write_stub_router(vty, ospf);
 
@@ -12805,6 +12856,10 @@ void ospf_vty_init(void)
        install_element(OSPF_NODE, &ospf_ti_lfa_cmd);
        install_element(OSPF_NODE, &no_ospf_ti_lfa_cmd);
 
+       /* Max path configurations */
+       install_element(OSPF_NODE, &ospf_max_multipath_cmd);
+       install_element(OSPF_NODE, &no_ospf_max_multipath_cmd);
+
        /* Init interface related vty commands. */
        ospf_vty_if_init();
 
index 56b2f8d6603964c4e602defe17ca5516cb9afc95..2e51629bb4a4fec86788514b0d11db7dfb4a3637 100644 (file)
@@ -297,7 +297,7 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
        }
 
        for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) {
-               if (api.nexthop_num >= MULTIPATH_NUM)
+               if (api.nexthop_num >= ospf->max_multipath)
                        break;
 
                ospf_zebra_add_nexthop(ospf, path, &api);
index f126577aeb96d9a5cc870d847fa18a1baba8ffb7..39296c413dffa6c6083f93b4d5c5f017018ea20e 100644 (file)
@@ -367,6 +367,9 @@ struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
        new->maxage_lsa = route_table_init();
        new->t_maxage_walker = NULL;
 
+       /* Max paths initialization */
+       new->max_multipath = MULTIPATH_NUM;
+
        /* Distance table init. */
        new->distance_table = route_table_init();
 
@@ -900,6 +903,7 @@ static void ospf_finish_final(struct ospf *ospf)
        close(ospf->fd);
        stream_free(ospf->ibuf);
        ospf->fd = -1;
+       ospf->max_multipath = MULTIPATH_NUM;
        ospf_delete(ospf);
 
        if (ospf->name) {
index a3f78b074e855111adfed93f9f3f6a22cc8cb8ba..da6ab56ba8ca9d93cc9dd0dab8bf8c67d2c9ce08 100644 (file)
@@ -379,6 +379,11 @@ struct ospf {
         */
        int aggr_action;
 
+       /* Max number of multiple paths
+        * to support ECMP.
+        */
+       uint16_t max_multipath;
+
        /* MPLS LDP-IGP Sync */
        struct ldp_sync_info_cmd ldp_sync_cmd;