From: Mobashshera Rasool Date: Thu, 28 Jan 2021 08:50:39 +0000 (+0000) Subject: ospf6d: add CLI to control maximum paths for routes. X-Git-Tag: base_8.0~427^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=1958143e302c7d4f791404dc9d15a9c017a71b22;p=matthieu%2Ffrr.git ospf6d: add CLI to control maximum paths for routes. CLI added: maximum-paths (1-64) Issue: #7961 Signed-off-by: Mobashshera Rasool --- diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst index b00bdb3ab8..51f7b8f507 100644 --- a/doc/user/ospf6d.rst +++ b/doc/user/ospf6d.rst @@ -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 diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 70771c6060..6b24f27672 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -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) { diff --git a/ospf6d/ospf6_spf.h b/ospf6d/ospf6_spf.h index 853ce4de07..253888d8ce 100644 --- a/ospf6d/ospf6_spf.h +++ b/ospf6d/ospf6_spf.h @@ -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) { diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 4a3697ed3f..31b4ae3e76 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -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); diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 93e25d7599..75dff86cd7 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -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) diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 7a8027a37f..2b7072d34f 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -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);