summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2020-09-20 02:42:32 -0300
committerRenato Westphal <renato@opensourcerouting.org>2020-10-23 10:31:39 -0300
commit01983712cc8f000d97ef2385a7f1fc3a8b79891c (patch)
tree9dc0e4e496eeb1d3c81da95df563f458927f987c
parent4c75f7c7730220bf4c86f62bb6ca86d527eabf60 (diff)
isisd: add support for Anycast-SIDs
Add the "n-flag-clear" option to the "segment-routing prefix" command. The only thing that option does is to clear the node flag of the Prefix-SID, even if it corresponds to a local loopback address. No changes are necessary other than that in order to fully support Anycast-SIDs. isisd already supports multiple routers advertising the same route with the same Prefix-SID after the recent refactoring. Clearing the node flag for such anycast routes isn't strictly required, but failure to do so can lead to problems like TI-LFA picking the wrong Prefix-SID when calculating repair paths. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
-rw-r--r--doc/user/isisd.rst8
-rw-r--r--isisd/isis_cli.c17
-rw-r--r--isisd/isis_nb.c6
-rw-r--r--isisd/isis_nb.h2
-rw-r--r--isisd/isis_nb_config.c17
-rw-r--r--isisd/isis_sr.c4
-rw-r--r--isisd/isis_sr.h3
-rw-r--r--yang/frr-isisd.yang6
8 files changed, 54 insertions, 9 deletions
diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst
index d71f4246fd..98f5aff7db 100644
--- a/doc/user/isisd.rst
+++ b/doc/user/isisd.rst
@@ -515,14 +515,16 @@ Known limitations:
MPLS dataplane. E.g. for Linux kernel, since version 4.13 the maximum value
is 32.
-.. index:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535)> [no-php-flag|explicit-null]
-.. clicmd:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null]
+.. index:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535)> [no-php-flag|explicit-null] [n-flag-clear]
+.. clicmd:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null] [n-flag-clear]
Set the Segment Routing index or absolute label value for the specified
prefix. The 'no-php-flag' means NO Penultimate Hop Popping that allows SR
node to request to its neighbor to not pop the label. The 'explicit-null'
flag allows SR node to request to its neighbor to send IP packet with the
- EXPLICIT-NULL label.
+ EXPLICIT-NULL label. The 'n-flag-clear' option can be used to explicitly
+ clear the Node flag that is set by default for Prefix-SIDs associated to
+ loopback addresses. This option is necessary to configure Anycast-SIDs.
.. index:: show isis segment-routing prefix-sids
.. clicmd:: show isis segment-routing prefix-sids
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index a270636dde..383f23758a 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -1628,7 +1628,7 @@ DEFPY_YANG (isis_sr_prefix_sid,
"segment-routing prefix\
<A.B.C.D/M|X:X::X:X/M>$prefix\
<absolute$sid_type (16-1048575)$sid_value|index$sid_type (0-65535)$sid_value>\
- [<no-php-flag|explicit-null>$lh_behavior]",
+ [<no-php-flag|explicit-null>$lh_behavior] [n-flag-clear$n_flag_clear]",
SR_STR
"Prefix SID\n"
"IPv4 Prefix\n"
@@ -1638,7 +1638,8 @@ DEFPY_YANG (isis_sr_prefix_sid,
"Specify the index of Prefix Segement ID\n"
"The Prefix Segment ID index\n"
"Don't request Penultimate Hop Popping (PHP)\n"
- "Upstream neighbor must replace prefix-sid with explicit null label\n")
+ "Upstream neighbor must replace prefix-sid with explicit null label\n"
+ "Not a node SID\n")
{
nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
nb_cli_enqueue_change(vty, "./sid-value-type", NB_OP_MODIFY, sid_type);
@@ -1656,6 +1657,8 @@ DEFPY_YANG (isis_sr_prefix_sid,
} else
nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY,
NULL);
+ nb_cli_enqueue_change(vty, "./n-flag-clear", NB_OP_MODIFY,
+ n_flag_clear ? "true" : "false");
return nb_cli_apply_changes(
vty, "./segment-routing/prefix-sid-map/prefix-sid[prefix='%s']",
@@ -1665,7 +1668,8 @@ DEFPY_YANG (isis_sr_prefix_sid,
DEFPY_YANG (no_isis_sr_prefix_sid,
no_isis_sr_prefix_sid_cmd,
"no segment-routing prefix <A.B.C.D/M|X:X::X:X/M>$prefix\
- [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]",
+ [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]\
+ [n-flag-clear]",
NO_STR
SR_STR
"Prefix SID\n"
@@ -1676,7 +1680,8 @@ DEFPY_YANG (no_isis_sr_prefix_sid,
"Specify the index of Prefix Segement ID\n"
"The Prefix Segment ID index\n"
"Don't request Penultimate Hop Popping (PHP)\n"
- "Upstream neighbor must replace prefix-sid with explicit null label\n")
+ "Upstream neighbor must replace prefix-sid with explicit null label\n"
+ "Not a node SID\n")
{
nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
@@ -1692,11 +1697,13 @@ void cli_show_isis_prefix_sid(struct vty *vty, struct lyd_node *dnode,
const char *lh_behavior;
const char *sid_value_type;
const char *sid_value;
+ bool n_flag_clear;
prefix = yang_dnode_get_string(dnode, "./prefix");
lh_behavior = yang_dnode_get_string(dnode, "./last-hop-behavior");
sid_value_type = yang_dnode_get_string(dnode, "./sid-value-type");
sid_value = yang_dnode_get_string(dnode, "./sid-value");
+ n_flag_clear = yang_dnode_get_bool(dnode, "./n-flag-clear");
vty_out(vty, " segment-routing prefix %s", prefix);
if (strmatch(sid_value_type, "absolute"))
@@ -1708,6 +1715,8 @@ void cli_show_isis_prefix_sid(struct vty *vty, struct lyd_node *dnode,
vty_out(vty, " no-php-flag");
else if (strmatch(lh_behavior, "explicit-null"))
vty_out(vty, " explicit-null");
+ if (n_flag_clear)
+ vty_out(vty, " n-flag-clear");
vty_out(vty, "\n");
}
diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c
index d04012c4da..2d3c7e1e38 100644
--- a/isisd/isis_nb.c
+++ b/isisd/isis_nb.c
@@ -538,6 +538,12 @@ const struct frr_yang_module_info frr_isisd_info = {
},
},
{
+ .xpath = "/frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/n-flag-clear",
+ .cbs = {
+ .modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify,
+ }
+ },
+ {
.xpath = "/frr-isisd:isis/instance/mpls/ldp-sync",
.cbs = {
.cli_show = cli_show_isis_mpls_ldp_sync,
diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h
index 303a7b4696..fb843131d9 100644
--- a/isisd/isis_nb.h
+++ b/isisd/isis_nb.h
@@ -206,6 +206,8 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_sid_value_modify(
struct nb_cb_modify_args *args);
int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify(
struct nb_cb_modify_args *args);
+int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
+ struct nb_cb_modify_args *args);
int isis_instance_mpls_ldp_sync_destroy(struct nb_cb_destroy_args *args);
int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args);
int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args);
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 2710c3c13f..1019c638a7 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -1838,6 +1838,23 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_mo
}
/*
+ * XPath: /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/n-flag-clear
+ */
+int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct sr_prefix_cfg *pcfg;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ pcfg = nb_running_get_entry(args->dnode, NULL, true);
+ pcfg->n_flag_clear = yang_dnode_get_bool(args->dnode, NULL);
+
+ return NB_OK;
+}
+
+/*
* XPath: /frr-isisd:isis/instance/mpls/ldp-sync
*/
int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args)
diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c
index deb0767d17..140cf5e66c 100644
--- a/isisd/isis_sr.c
+++ b/isisd/isis_sr.c
@@ -363,7 +363,7 @@ struct sr_prefix_cfg *isis_sr_cfg_prefix_add(struct isis_area *area,
/* Set the N-flag when appropriate. */
ifp = if_lookup_prefix(prefix, VRF_DEFAULT);
- if (ifp && sr_prefix_is_node_sid(ifp, prefix))
+ if (ifp && sr_prefix_is_node_sid(ifp, prefix) && !pcfg->n_flag_clear)
pcfg->node_sid = true;
/* Save prefix-sid configuration. */
@@ -949,7 +949,7 @@ static int sr_if_new_hook(struct interface *ifp)
continue;
if (sr_prefix_is_node_sid(ifp, &pcfg->prefix)
- && !pcfg->node_sid) {
+ && !pcfg->n_flag_clear) {
pcfg->node_sid = true;
lsp_regenerate_schedule(area, area->is_type, 0);
}
diff --git a/isisd/isis_sr.h b/isisd/isis_sr.h
index ce97b024af..b012dfb00a 100644
--- a/isisd/isis_sr.h
+++ b/isisd/isis_sr.h
@@ -152,6 +152,9 @@ struct sr_prefix_cfg {
/* SID last hop behavior. */
enum sr_last_hop_behavior last_hop_behavior;
+ /* Indicates whether the node flag must be explicitly unset. */
+ bool n_flag_clear;
+
/* Does this Prefix-SID refer to a loopback address (Node-SID)? */
bool node_sid;
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
index 06d1a793b5..c3b39e3750 100644
--- a/yang/frr-isisd.yang
+++ b/yang/frr-isisd.yang
@@ -1381,6 +1381,12 @@ module frr-isisd {
description
"Configure last hop behavior.";
}
+ leaf n-flag-clear {
+ type boolean;
+ default "false";
+ description
+ "Not a node SID";
+ }
}
}
}