summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--isisd/isis_circuit.h1
-rw-r--r--isisd/isis_cli.c36
-rw-r--r--isisd/isis_lfa.c5
-rw-r--r--isisd/isis_nb.c12
-rw-r--r--isisd/isis_nb.h4
-rw-r--r--isisd/isis_nb_config.c48
-rw-r--r--yang/frr-isisd.yang7
7 files changed, 110 insertions, 3 deletions
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index 45c0a7e0e..84c3ca3ff 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -152,6 +152,7 @@ struct isis_circuit {
struct hash *lfa_excluded_ifaces[ISIS_LEVELS];
bool tilfa_protection[ISIS_LEVELS];
bool tilfa_node_protection[ISIS_LEVELS];
+ bool tilfa_link_fallback[ISIS_LEVELS];
/*
* Counters as in 10589--11.2.5.9
*/
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index 3e719df4b..f316e0279 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -2647,6 +2647,7 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode,
{
bool l1_enabled, l2_enabled;
bool l1_node_protection, l2_node_protection;
+ bool l1_link_fallback, l2_link_fallback;
/* Classic LFA */
l1_enabled = yang_dnode_get_bool(dnode, "./level-1/lfa/enable");
@@ -2692,13 +2693,21 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode,
yang_dnode_get_bool(dnode, "./level-1/ti-lfa/node-protection");
l2_node_protection =
yang_dnode_get_bool(dnode, "./level-2/ti-lfa/node-protection");
+ l1_link_fallback =
+ yang_dnode_get_bool(dnode, "./level-1/ti-lfa/link-fallback");
+ l2_link_fallback =
+ yang_dnode_get_bool(dnode, "./level-2/ti-lfa/link-fallback");
+
if (l1_enabled || l2_enabled) {
if (l1_enabled == l2_enabled
- && l1_node_protection == l2_node_protection) {
+ && l1_node_protection == l2_node_protection
+ && l1_link_fallback == l2_link_fallback) {
vty_out(vty, " isis fast-reroute ti-lfa");
if (l1_node_protection)
vty_out(vty, " node-protection");
+ if (l1_link_fallback)
+ vty_out(vty, " link-fallback");
vty_out(vty, "\n");
} else {
if (l1_enabled) {
@@ -2706,6 +2715,8 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode,
" isis fast-reroute ti-lfa level-1");
if (l1_node_protection)
vty_out(vty, " node-protection");
+ if (l1_link_fallback)
+ vty_out(vty, " link-fallback");
vty_out(vty, "\n");
}
if (l2_enabled) {
@@ -2713,6 +2724,8 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode,
" isis fast-reroute ti-lfa level-2");
if (l2_node_protection)
vty_out(vty, " node-protection");
+ if (l2_link_fallback)
+ vty_out(vty, " link-fallback");
vty_out(vty, "\n");
}
}
@@ -2917,14 +2930,15 @@ void cli_show_frr_remote_lfa_max_metric(struct vty *vty, struct lyd_node *dnode,
* XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/ti-lfa/enable
*/
DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
- "[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection]",
+ "[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection [link-fallback$link_fallback]]",
NO_STR
"IS-IS routing protocol\n"
"Interface IP Fast-reroute configuration\n"
"Enable TI-LFA computation\n"
"Enable TI-LFA computation for Level 1 only\n"
"Enable TI-LFA computation for Level 2 only\n"
- "Protect against node failures\n")
+ "Protect against node failures\n"
+ "Enable link-protection fallback\n")
{
if (!level || strmatch(level, "level-1")) {
if (no) {
@@ -2936,6 +2950,10 @@ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
vty,
"./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection",
NB_OP_MODIFY, "false");
+ nb_cli_enqueue_change(
+ vty,
+ "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback",
+ NB_OP_MODIFY, "false");
} else {
nb_cli_enqueue_change(
vty,
@@ -2946,6 +2964,10 @@ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
"./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection",
NB_OP_MODIFY,
node_protection ? "true" : "false");
+ nb_cli_enqueue_change(
+ vty,
+ "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback",
+ NB_OP_MODIFY, link_fallback ? "true" : "false");
}
}
if (!level || strmatch(level, "level-2")) {
@@ -2958,6 +2980,10 @@ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
vty,
"./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection",
NB_OP_MODIFY, "false");
+ nb_cli_enqueue_change(
+ vty,
+ "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback",
+ NB_OP_MODIFY, "false");
} else {
nb_cli_enqueue_change(
vty,
@@ -2968,6 +2994,10 @@ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
"./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection",
NB_OP_MODIFY,
node_protection ? "true" : "false");
+ nb_cli_enqueue_change(
+ vty,
+ "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback",
+ NB_OP_MODIFY, link_fallback ? "true" : "false");
}
}
diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c
index b535924e9..e033c28fe 100644
--- a/isisd/isis_lfa.c
+++ b/isisd/isis_lfa.c
@@ -2258,6 +2258,11 @@ static void isis_spf_run_tilfa(struct isis_area *area,
spftree_pc_node = isis_tilfa_compute(area, spftree,
spftree_reverse, resource);
isis_spftree_del(spftree_pc_node);
+
+ /* don't do link protection unless link-fallback is configured
+ */
+ if (!circuit->tilfa_link_fallback[spftree->level - 1])
+ return;
}
/* Compute link protecting repair paths. */
diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c
index 4eac8de2c..ecad16229 100644
--- a/isisd/isis_nb.c
+++ b/isisd/isis_nb.c
@@ -978,6 +978,12 @@ const struct frr_yang_module_info frr_isisd_info = {
}
},
{
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback",
+ .cbs = {
+ .modify = lib_interface_isis_fast_reroute_level_1_ti_lfa_link_fallback_modify,
+ }
+ },
+ {
.xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/lfa/enable",
.cbs = {
.modify = lib_interface_isis_fast_reroute_level_2_lfa_enable_modify,
@@ -1018,6 +1024,12 @@ const struct frr_yang_module_info frr_isisd_info = {
}
},
{
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback",
+ .cbs = {
+ .modify = lib_interface_isis_fast_reroute_level_2_ti_lfa_link_fallback_modify,
+ }
+ },
+ {
.xpath = "/frr-interface:lib/interface/state/frr-isisd:isis",
.cbs = {
.get_elem = lib_interface_state_isis_get_elem,
diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h
index 94aa00c97..0c2f7b6b7 100644
--- a/isisd/isis_nb.h
+++ b/isisd/isis_nb.h
@@ -319,6 +319,8 @@ int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify(
struct nb_cb_modify_args *args);
int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify(
struct nb_cb_modify_args *args);
+int lib_interface_isis_fast_reroute_level_1_ti_lfa_link_fallback_modify(
+ struct nb_cb_modify_args *args);
int lib_interface_isis_fast_reroute_level_2_lfa_enable_modify(
struct nb_cb_modify_args *args);
int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_create(
@@ -335,6 +337,8 @@ int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify(
struct nb_cb_modify_args *args);
int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify(
struct nb_cb_modify_args *args);
+int lib_interface_isis_fast_reroute_level_2_ti_lfa_link_fallback_modify(
+ struct nb_cb_modify_args *args);
struct yang_data *
lib_interface_state_isis_get_elem(struct nb_cb_get_elem_args *args);
const void *lib_interface_state_isis_adjacencies_adjacency_get_next(
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index f9028bdd9..5ca2329dd 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -3518,6 +3518,30 @@ int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify(
/*
* XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback
+ */
+int lib_interface_isis_fast_reroute_level_1_ti_lfa_link_fallback_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct isis_area *area;
+ struct isis_circuit *circuit;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ circuit = nb_running_get_entry(args->dnode, NULL, true);
+ circuit->tilfa_link_fallback[0] =
+ yang_dnode_get_bool(args->dnode, NULL);
+
+ area = circuit->area;
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
+
+ return NB_OK;
+}
+
+/*
+ * XPath:
* /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/lfa/enable
*/
int lib_interface_isis_fast_reroute_level_2_lfa_enable_modify(
@@ -3720,3 +3744,27 @@ int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify(
return NB_OK;
}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback
+ */
+int lib_interface_isis_fast_reroute_level_2_ti_lfa_link_fallback_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct isis_area *area;
+ struct isis_circuit *circuit;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ circuit = nb_running_get_entry(args->dnode, NULL, true);
+ circuit->tilfa_link_fallback[1] =
+ yang_dnode_get_bool(args->dnode, NULL);
+
+ area = circuit->area;
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
+
+ return NB_OK;
+}
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
index 46ad8d397..4653e6f00 100644
--- a/yang/frr-isisd.yang
+++ b/yang/frr-isisd.yang
@@ -493,6 +493,13 @@ module frr-isisd {
description
"Node protection is provided by the alternate.";
}
+ leaf link-fallback {
+ type boolean;
+ must ". = 'false' or ../enable = 'true'";
+ default false;
+ description
+ "Fallback to link protection.";
+ }
}
}