diff options
author | rgirada <rgirada@vmware.com> | 2021-02-11 11:05:12 +0100 |
---|---|---|
committer | rgirada <rgirada@vmware.com> | 2021-03-30 07:04:46 +0200 |
commit | 3d5b9855779357e51e1b8ab6a9010b1e702f5b2d (patch) | |
tree | 69a15f08732b51f3098785f7ec05a1c578927467 /ospfd | |
parent | Merge pull request #8351 from volta-networks/fix_ospf6_abr_examin_summary_che... (diff) | |
download | frr-3d5b9855779357e51e1b8ab6a9010b1e702f5b2d.tar.xz frr-3d5b9855779357e51e1b8ab6a9010b1e702f5b2d.zip |
ospfd: Max multipath config support
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>
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_spf.c | 24 | ||||
-rw-r--r-- | ospfd/ospf_spf.h | 2 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 55 | ||||
-rw-r--r-- | ospfd/ospf_zebra.c | 2 | ||||
-rw-r--r-- | ospfd/ospfd.c | 4 | ||||
-rw-r--r-- | ospfd/ospfd.h | 5 |
6 files changed, 90 insertions, 2 deletions
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 1e0814764..95553dacd 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -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); +} diff --git a/ospfd/ospf_spf.h b/ospfd/ospf_spf.h index 835caab28..4ff4a6d12 100644 --- a/ospfd/ospf_spf.h +++ b/ospfd/ospf_spf.h @@ -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 */ diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 6436c20f9..f3583c26f 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -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(); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 56b2f8d66..2e51629bb 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -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); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index f126577ae..39296c413 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -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) { diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index a3f78b074..da6ab56ba 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -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; |