Merge pull request #8058 from rgirada/ospf-ecmp

ospfd: Max multipath config support
This commit is contained in:
Mark Stapp 2021-03-30 11:57:33 -04:00 committed by GitHub
commit ea631ac834
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 100 additions and 2 deletions

View 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 command can be used when the neighbor state get stuck at some state and
this can be used to recover it from that state. 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: .. _ospf-area:
Areas Areas

View 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, thread_add_timer_msec(master, ospf_spf_calculate_schedule_worker, ospf,
delay, &ospf->t_spf_calc); 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);
}

View 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 int vertex_parent_cmp(void *aa, void *bb);
extern void ospf_spf_print(struct vty *vty, struct vertex *v, int i); 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 (); */ /* void ospf_spf_calculate_timer_add (); */
#endif /* _QUAGGA_OSPF_SPF_H */ #endif /* _QUAGGA_OSPF_SPF_H */

View file

@ -2699,6 +2699,50 @@ DEFUN(no_ospf_ti_lfa, no_ospf_ti_lfa_cmd,
return CMD_SUCCESS; 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[] = { static const char *const ospf_abr_type_descr_str[] = {
"Unknown", "Standard (RFC2328)", "Alternative IBM", "Unknown", "Standard (RFC2328)", "Alternative IBM",
"Alternative Cisco", "Alternative Shortcut" "Alternative Cisco", "Alternative Shortcut"
@ -3228,6 +3272,10 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
/* Show refresh parameters. */ /* Show refresh parameters. */
vty_out(vty, " Refresh timer %d secs\n", vty_out(vty, " Refresh timer %d secs\n",
ospf->lsa_refresh_interval); ospf->lsa_refresh_interval);
/* show max multipath */
vty_out(vty, " Maximum multiple paths(ECMP) supported %d\n",
ospf->max_multipath);
} }
/* Show ABR/ASBR flags. */ /* Show ABR/ASBR flags. */
@ -12274,6 +12322,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
vty_out(vty, " ospf write-multiplier %d\n", vty_out(vty, " ospf write-multiplier %d\n",
ospf->write_oi_count); 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 */ /* Max-metric router-lsa print */
config_write_stub_router(vty, ospf); config_write_stub_router(vty, ospf);
@ -12802,6 +12853,10 @@ void ospf_vty_init(void)
install_element(OSPF_NODE, &ospf_ti_lfa_cmd); install_element(OSPF_NODE, &ospf_ti_lfa_cmd);
install_element(OSPF_NODE, &no_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. */ /* Init interface related vty commands. */
ospf_vty_if_init(); ospf_vty_if_init();

View 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)) { for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) {
if (api.nexthop_num >= MULTIPATH_NUM) if (api.nexthop_num >= ospf->max_multipath)
break; break;
ospf_zebra_add_nexthop(ospf, path, &api); ospf_zebra_add_nexthop(ospf, path, &api);

View file

@ -367,6 +367,9 @@ struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
new->maxage_lsa = route_table_init(); new->maxage_lsa = route_table_init();
new->t_maxage_walker = NULL; new->t_maxage_walker = NULL;
/* Max paths initialization */
new->max_multipath = MULTIPATH_NUM;
/* Distance table init. */ /* Distance table init. */
new->distance_table = route_table_init(); new->distance_table = route_table_init();
@ -887,6 +890,7 @@ static void ospf_finish_final(struct ospf *ospf)
close(ospf->fd); close(ospf->fd);
stream_free(ospf->ibuf); stream_free(ospf->ibuf);
ospf->fd = -1; ospf->fd = -1;
ospf->max_multipath = MULTIPATH_NUM;
ospf_delete(ospf); ospf_delete(ospf);
if (ospf->name) { if (ospf->name) {

View file

@ -374,6 +374,11 @@ struct ospf {
*/ */
int aggr_action; int aggr_action;
/* Max number of multiple paths
* to support ECMP.
*/
uint16_t max_multipath;
/* MPLS LDP-IGP Sync */ /* MPLS LDP-IGP Sync */
struct ldp_sync_info_cmd ldp_sync_cmd; struct ldp_sync_info_cmd ldp_sync_cmd;