Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ospfd: Max multipath config support #8058

Merged
merged 1 commit into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/user/ospfd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions ospfd/ospf_spf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
2 changes: 1 addition & 1 deletion ospfd/ospf_spf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
55 changes: 55 additions & 0 deletions ospfd/ospf_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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();

Expand Down
2 changes: 1 addition & 1 deletion ospfd/ospf_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions ospfd/ospfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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) {
Expand Down
5 changes: 5 additions & 0 deletions ospfd/ospfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down