mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 18:10:23 +00:00
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>
This commit is contained in:
parent
4c75f7c773
commit
01983712cc
@ -515,14 +515,16 @@ Known limitations:
|
|||||||
MPLS dataplane. E.g. for Linux kernel, since version 4.13 the maximum value
|
MPLS dataplane. E.g. for Linux kernel, since version 4.13 the maximum value
|
||||||
is 32.
|
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]
|
.. 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]
|
.. 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
|
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
|
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'
|
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
|
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
|
.. index:: show isis segment-routing prefix-sids
|
||||||
.. clicmd:: show isis segment-routing prefix-sids
|
.. clicmd:: show isis segment-routing prefix-sids
|
||||||
|
@ -1628,7 +1628,7 @@ DEFPY_YANG (isis_sr_prefix_sid,
|
|||||||
"segment-routing prefix\
|
"segment-routing prefix\
|
||||||
<A.B.C.D/M|X:X::X:X/M>$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>\
|
<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
|
SR_STR
|
||||||
"Prefix SID\n"
|
"Prefix SID\n"
|
||||||
"IPv4 Prefix\n"
|
"IPv4 Prefix\n"
|
||||||
@ -1638,7 +1638,8 @@ DEFPY_YANG (isis_sr_prefix_sid,
|
|||||||
"Specify the index of Prefix Segement ID\n"
|
"Specify the index of Prefix Segement ID\n"
|
||||||
"The Prefix Segment ID index\n"
|
"The Prefix Segment ID index\n"
|
||||||
"Don't request Penultimate Hop Popping (PHP)\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, ".", NB_OP_CREATE, NULL);
|
||||||
nb_cli_enqueue_change(vty, "./sid-value-type", NB_OP_MODIFY, sid_type);
|
nb_cli_enqueue_change(vty, "./sid-value-type", NB_OP_MODIFY, sid_type);
|
||||||
@ -1656,6 +1657,8 @@ DEFPY_YANG (isis_sr_prefix_sid,
|
|||||||
} else
|
} else
|
||||||
nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY,
|
nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY,
|
||||||
NULL);
|
NULL);
|
||||||
|
nb_cli_enqueue_change(vty, "./n-flag-clear", NB_OP_MODIFY,
|
||||||
|
n_flag_clear ? "true" : "false");
|
||||||
|
|
||||||
return nb_cli_apply_changes(
|
return nb_cli_apply_changes(
|
||||||
vty, "./segment-routing/prefix-sid-map/prefix-sid[prefix='%s']",
|
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,
|
DEFPY_YANG (no_isis_sr_prefix_sid,
|
||||||
no_isis_sr_prefix_sid_cmd,
|
no_isis_sr_prefix_sid_cmd,
|
||||||
"no segment-routing prefix <A.B.C.D/M|X:X::X:X/M>$prefix\
|
"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
|
NO_STR
|
||||||
SR_STR
|
SR_STR
|
||||||
"Prefix SID\n"
|
"Prefix SID\n"
|
||||||
@ -1676,7 +1680,8 @@ DEFPY_YANG (no_isis_sr_prefix_sid,
|
|||||||
"Specify the index of Prefix Segement ID\n"
|
"Specify the index of Prefix Segement ID\n"
|
||||||
"The Prefix Segment ID index\n"
|
"The Prefix Segment ID index\n"
|
||||||
"Don't request Penultimate Hop Popping (PHP)\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);
|
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 *lh_behavior;
|
||||||
const char *sid_value_type;
|
const char *sid_value_type;
|
||||||
const char *sid_value;
|
const char *sid_value;
|
||||||
|
bool n_flag_clear;
|
||||||
|
|
||||||
prefix = yang_dnode_get_string(dnode, "./prefix");
|
prefix = yang_dnode_get_string(dnode, "./prefix");
|
||||||
lh_behavior = yang_dnode_get_string(dnode, "./last-hop-behavior");
|
lh_behavior = yang_dnode_get_string(dnode, "./last-hop-behavior");
|
||||||
sid_value_type = yang_dnode_get_string(dnode, "./sid-value-type");
|
sid_value_type = yang_dnode_get_string(dnode, "./sid-value-type");
|
||||||
sid_value = yang_dnode_get_string(dnode, "./sid-value");
|
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);
|
vty_out(vty, " segment-routing prefix %s", prefix);
|
||||||
if (strmatch(sid_value_type, "absolute"))
|
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");
|
vty_out(vty, " no-php-flag");
|
||||||
else if (strmatch(lh_behavior, "explicit-null"))
|
else if (strmatch(lh_behavior, "explicit-null"))
|
||||||
vty_out(vty, " explicit-null");
|
vty_out(vty, " explicit-null");
|
||||||
|
if (n_flag_clear)
|
||||||
|
vty_out(vty, " n-flag-clear");
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,6 +537,12 @@ const struct frr_yang_module_info frr_isisd_info = {
|
|||||||
.modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify,
|
.modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.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",
|
.xpath = "/frr-isisd:isis/instance/mpls/ldp-sync",
|
||||||
.cbs = {
|
.cbs = {
|
||||||
|
@ -206,6 +206,8 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_sid_value_modify(
|
|||||||
struct nb_cb_modify_args *args);
|
struct nb_cb_modify_args *args);
|
||||||
int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify(
|
int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify(
|
||||||
struct nb_cb_modify_args *args);
|
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_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_create(struct nb_cb_create_args *args);
|
||||||
int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args);
|
int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args);
|
||||||
|
@ -1837,6 +1837,23 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_mo
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* XPath: /frr-isisd:isis/instance/mpls/ldp-sync
|
||||||
*/
|
*/
|
||||||
|
@ -363,7 +363,7 @@ struct sr_prefix_cfg *isis_sr_cfg_prefix_add(struct isis_area *area,
|
|||||||
|
|
||||||
/* Set the N-flag when appropriate. */
|
/* Set the N-flag when appropriate. */
|
||||||
ifp = if_lookup_prefix(prefix, VRF_DEFAULT);
|
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;
|
pcfg->node_sid = true;
|
||||||
|
|
||||||
/* Save prefix-sid configuration. */
|
/* Save prefix-sid configuration. */
|
||||||
@ -949,7 +949,7 @@ static int sr_if_new_hook(struct interface *ifp)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (sr_prefix_is_node_sid(ifp, &pcfg->prefix)
|
if (sr_prefix_is_node_sid(ifp, &pcfg->prefix)
|
||||||
&& !pcfg->node_sid) {
|
&& !pcfg->n_flag_clear) {
|
||||||
pcfg->node_sid = true;
|
pcfg->node_sid = true;
|
||||||
lsp_regenerate_schedule(area, area->is_type, 0);
|
lsp_regenerate_schedule(area, area->is_type, 0);
|
||||||
}
|
}
|
||||||
|
@ -152,6 +152,9 @@ struct sr_prefix_cfg {
|
|||||||
/* SID last hop behavior. */
|
/* SID last hop behavior. */
|
||||||
enum sr_last_hop_behavior 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)? */
|
/* Does this Prefix-SID refer to a loopback address (Node-SID)? */
|
||||||
bool node_sid;
|
bool node_sid;
|
||||||
|
|
||||||
|
@ -1381,6 +1381,12 @@ module frr-isisd {
|
|||||||
description
|
description
|
||||||
"Configure last hop behavior.";
|
"Configure last hop behavior.";
|
||||||
}
|
}
|
||||||
|
leaf n-flag-clear {
|
||||||
|
type boolean;
|
||||||
|
default "false";
|
||||||
|
description
|
||||||
|
"Not a node SID";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user