summaryrefslogtreecommitdiffstats
path: root/ospf6d
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2021-02-04 19:32:34 +0100
committerGitHub <noreply@github.com>2021-02-04 19:32:34 +0100
commit4a9178f2f45613e9dd88b16bf8af83542194cee5 (patch)
treef72f8c7bb832628df8b9204bb623ac6619f8d618 /ospf6d
parentMerge pull request #8007 from wesleycoakley/xcompile-writeup (diff)
parentospf6d: add CLI to control maximum paths for routes. (diff)
downloadfrr-4a9178f2f45613e9dd88b16bf8af83542194cee5.tar.xz
frr-4a9178f2f45613e9dd88b16bf8af83542194cee5.zip
Merge pull request #7961 from mobash-rasool/ospfv3-feature
ospf6d: add CLI to control maximum paths for routes.
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_spf.c5
-rw-r--r--ospf6d/ospf6_spf.h1
-rw-r--r--ospf6d/ospf6_top.c69
-rw-r--r--ospf6d/ospf6_top.h5
-rw-r--r--ospf6d/ospf6_zebra.c9
5 files changed, 85 insertions, 4 deletions
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index 70771c606..6b24f2767 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 853ce4de0..253888d8c 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 27d81beae..3f72ec828 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -268,6 +268,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. */
@@ -879,6 +881,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)
{
@@ -917,6 +975,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);
@@ -999,6 +1058,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,
@@ -1257,6 +1317,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);
@@ -1315,6 +1380,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 93e25d759..75dff86cd 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 7a8027a37..2b7072d34 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);