forked from Mirror/frr
isisd,yang: add algorithm-prefix-sid configuration tree
Add the ability to configure a Segment-Routing prefix SID for a given algorithm. For example: > segment-routing prefix 10.10.10.10/32 algorithm 128 index 100 Signed-off-by: Hiroki Shirokura <hiroki.shirokura@linecorp.com> Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
parent
d4f58e0b84
commit
cc4926c128
|
@ -1769,6 +1769,44 @@ void cli_show_isis_prefix_sid(struct vty *vty, const struct lyd_node *dnode,
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid
|
||||||
|
*/
|
||||||
|
void cli_show_isis_prefix_sid_algorithm(struct vty *vty,
|
||||||
|
const struct lyd_node *dnode,
|
||||||
|
bool show_defaults)
|
||||||
|
{
|
||||||
|
const char *prefix;
|
||||||
|
const char *lh_behavior;
|
||||||
|
const char *sid_value_type;
|
||||||
|
const char *sid_value;
|
||||||
|
bool n_flag_clear;
|
||||||
|
uint32_t algorithm;
|
||||||
|
|
||||||
|
prefix = yang_dnode_get_string(dnode, "./prefix");
|
||||||
|
sid_value_type = yang_dnode_get_string(dnode, "./sid-value-type");
|
||||||
|
sid_value = yang_dnode_get_string(dnode, "./sid-value");
|
||||||
|
algorithm = yang_dnode_get_uint32(dnode, "./algo");
|
||||||
|
lh_behavior = yang_dnode_get_string(dnode, "./last-hop-behavior");
|
||||||
|
n_flag_clear = yang_dnode_get_bool(dnode, "./n-flag-clear");
|
||||||
|
|
||||||
|
vty_out(vty, " segment-routing prefix %s", prefix);
|
||||||
|
vty_out(vty, " algorithm %u", algorithm);
|
||||||
|
if (strmatch(sid_value_type, "absolute"))
|
||||||
|
vty_out(vty, " absolute");
|
||||||
|
else
|
||||||
|
vty_out(vty, " index");
|
||||||
|
vty_out(vty, " %s", sid_value);
|
||||||
|
|
||||||
|
if (strmatch(lh_behavior, "no-php"))
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-isisd:isis/instance/fast-reroute/level-{1,2}/lfa/priority-limit
|
* XPath: /frr-isisd:isis/instance/fast-reroute/level-{1,2}/lfa/priority-limit
|
||||||
|
|
|
@ -688,6 +688,40 @@ const struct frr_yang_module_info frr_isisd_info = {
|
||||||
.modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify,
|
.modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid",
|
||||||
|
.cbs = {
|
||||||
|
.create = isis_instance_segment_routing_algorithm_prefix_sid_create,
|
||||||
|
.destroy = isis_instance_segment_routing_algorithm_prefix_sid_destroy,
|
||||||
|
.pre_validate = isis_instance_segment_routing_algorithm_prefix_sid_pre_validate,
|
||||||
|
.apply_finish = isis_instance_segment_routing_algorithm_prefix_sid_apply_finish,
|
||||||
|
.cli_show = cli_show_isis_prefix_sid_algorithm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid/sid-value-type",
|
||||||
|
.cbs = {
|
||||||
|
.modify = isis_instance_segment_routing_algorithm_prefix_sid_sid_value_type_modify,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid/sid-value",
|
||||||
|
.cbs = {
|
||||||
|
.modify = isis_instance_segment_routing_algorithm_prefix_sid_sid_value_modify,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid/last-hop-behavior",
|
||||||
|
.cbs = {
|
||||||
|
.modify = isis_instance_segment_routing_algorithm_prefix_sid_last_hop_behavior_modify,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid/n-flag-clear",
|
||||||
|
.cbs = {
|
||||||
|
.modify = isis_instance_segment_routing_algorithm_prefix_sid_n_flag_clear_modify,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.xpath = "/frr-isisd:isis/instance/mpls/ldp-sync",
|
.xpath = "/frr-isisd:isis/instance/mpls/ldp-sync",
|
||||||
.cbs = {
|
.cbs = {
|
||||||
|
|
|
@ -249,6 +249,22 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_mo
|
||||||
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(
|
int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
|
||||||
struct nb_cb_modify_args *args);
|
struct nb_cb_modify_args *args);
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_create(
|
||||||
|
struct nb_cb_create_args *args);
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_destroy(
|
||||||
|
struct nb_cb_destroy_args *args);
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_pre_validate(
|
||||||
|
struct nb_cb_pre_validate_args *args);
|
||||||
|
void isis_instance_segment_routing_algorithm_prefix_sid_apply_finish(
|
||||||
|
struct nb_cb_apply_finish_args *args);
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_sid_value_type_modify(
|
||||||
|
struct nb_cb_modify_args *args);
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_sid_value_modify(
|
||||||
|
struct nb_cb_modify_args *args);
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_last_hop_behavior_modify(
|
||||||
|
struct nb_cb_modify_args *args);
|
||||||
|
int isis_instance_segment_routing_algorithm_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);
|
||||||
|
@ -538,6 +554,9 @@ void cli_show_isis_node_msd(struct vty *vty, const struct lyd_node *dnode,
|
||||||
bool show_defaults);
|
bool show_defaults);
|
||||||
void cli_show_isis_prefix_sid(struct vty *vty, const struct lyd_node *dnode,
|
void cli_show_isis_prefix_sid(struct vty *vty, const struct lyd_node *dnode,
|
||||||
bool show_defaults);
|
bool show_defaults);
|
||||||
|
void cli_show_isis_prefix_sid_algorithm(struct vty *vty,
|
||||||
|
const struct lyd_node *dnode,
|
||||||
|
bool show_defaults);
|
||||||
void cli_show_isis_frr_lfa_priority_limit(struct vty *vty,
|
void cli_show_isis_frr_lfa_priority_limit(struct vty *vty,
|
||||||
const struct lyd_node *dnode,
|
const struct lyd_node *dnode,
|
||||||
bool show_defaults);
|
bool show_defaults);
|
||||||
|
|
|
@ -2466,6 +2466,214 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid
|
||||||
|
*/
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_create(
|
||||||
|
struct nb_cb_create_args *args)
|
||||||
|
{
|
||||||
|
struct isis_area *area;
|
||||||
|
struct prefix prefix;
|
||||||
|
struct sr_prefix_cfg *pcfg;
|
||||||
|
uint32_t algorithm;
|
||||||
|
|
||||||
|
if (args->event != NB_EV_APPLY)
|
||||||
|
return NB_OK;
|
||||||
|
|
||||||
|
area = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
|
||||||
|
algorithm = yang_dnode_get_uint32(args->dnode, "./algo");
|
||||||
|
|
||||||
|
pcfg = isis_sr_cfg_prefix_add(area, &prefix, algorithm);
|
||||||
|
pcfg->algorithm = algorithm;
|
||||||
|
nb_running_set_entry(args->dnode, pcfg);
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_destroy(
|
||||||
|
struct nb_cb_destroy_args *args)
|
||||||
|
{
|
||||||
|
struct sr_prefix_cfg *pcfg;
|
||||||
|
struct isis_area *area;
|
||||||
|
|
||||||
|
if (args->event != NB_EV_APPLY)
|
||||||
|
return NB_OK;
|
||||||
|
|
||||||
|
pcfg = nb_running_unset_entry(args->dnode);
|
||||||
|
area = pcfg->area;
|
||||||
|
isis_sr_cfg_prefix_del(pcfg);
|
||||||
|
lsp_regenerate_schedule(area, area->is_type, 0);
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_pre_validate(
|
||||||
|
struct nb_cb_pre_validate_args *args)
|
||||||
|
{
|
||||||
|
const struct lyd_node *area_dnode;
|
||||||
|
struct isis_area *area;
|
||||||
|
struct prefix prefix;
|
||||||
|
uint32_t srgb_lbound;
|
||||||
|
uint32_t srgb_ubound;
|
||||||
|
uint32_t srgb_range;
|
||||||
|
uint32_t sid;
|
||||||
|
enum sr_sid_value_type sid_type;
|
||||||
|
struct isis_prefix_sid psid = {};
|
||||||
|
|
||||||
|
yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
|
||||||
|
srgb_lbound = yang_dnode_get_uint32(
|
||||||
|
args->dnode, "../../label-blocks/srgb/lower-bound");
|
||||||
|
srgb_ubound = yang_dnode_get_uint32(
|
||||||
|
args->dnode, "../../label-blocks/srgb/upper-bound");
|
||||||
|
sid = yang_dnode_get_uint32(args->dnode, "./sid-value");
|
||||||
|
sid_type = yang_dnode_get_enum(args->dnode, "./sid-value-type");
|
||||||
|
|
||||||
|
/* Check for invalid indexes/labels. */
|
||||||
|
srgb_range = srgb_ubound - srgb_lbound + 1;
|
||||||
|
psid.value = sid;
|
||||||
|
switch (sid_type) {
|
||||||
|
case SR_SID_VALUE_TYPE_INDEX:
|
||||||
|
if (sid >= srgb_range) {
|
||||||
|
snprintf(args->errmsg, args->errmsg_len,
|
||||||
|
"SID index %u falls outside local SRGB range",
|
||||||
|
sid);
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SR_SID_VALUE_TYPE_ABSOLUTE:
|
||||||
|
if (!IS_MPLS_UNRESERVED_LABEL(sid)) {
|
||||||
|
snprintf(args->errmsg, args->errmsg_len,
|
||||||
|
"Invalid absolute SID %u", sid);
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
SET_FLAG(psid.flags, ISIS_PREFIX_SID_VALUE);
|
||||||
|
SET_FLAG(psid.flags, ISIS_PREFIX_SID_LOCAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for Prefix-SID collisions. */
|
||||||
|
area_dnode = yang_dnode_get_parent(args->dnode, "instance");
|
||||||
|
area = nb_running_get_entry(area_dnode, NULL, false);
|
||||||
|
if (!area)
|
||||||
|
return NB_OK;
|
||||||
|
|
||||||
|
for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
|
||||||
|
for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
|
||||||
|
struct isis_spftree *spftree;
|
||||||
|
struct isis_vertex *vertex_psid;
|
||||||
|
|
||||||
|
if (!(area->is_type & level))
|
||||||
|
continue;
|
||||||
|
spftree = area->spftree[tree][level - 1];
|
||||||
|
if (!spftree)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vertex_psid =
|
||||||
|
isis_spf_prefix_sid_lookup(spftree, &psid);
|
||||||
|
if (vertex_psid &&
|
||||||
|
!prefix_same(&vertex_psid->N.ip.p.dest, &prefix)) {
|
||||||
|
snprintfrr(
|
||||||
|
args->errmsg, args->errmsg_len,
|
||||||
|
"Prefix-SID collision detected, SID %s %u is already in use by prefix %pFX (L%u)",
|
||||||
|
CHECK_FLAG(psid.flags,
|
||||||
|
ISIS_PREFIX_SID_VALUE)
|
||||||
|
? "label"
|
||||||
|
: "index",
|
||||||
|
psid.value, &vertex_psid->N.ip.p.dest,
|
||||||
|
level);
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void isis_instance_segment_routing_algorithm_prefix_sid_apply_finish(
|
||||||
|
struct nb_cb_apply_finish_args *args)
|
||||||
|
{
|
||||||
|
struct sr_prefix_cfg *pcfg;
|
||||||
|
struct isis_area *area;
|
||||||
|
|
||||||
|
pcfg = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
area = pcfg->area;
|
||||||
|
lsp_regenerate_schedule(area, area->is_type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid/sid-value-type
|
||||||
|
*/
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_sid_value_type_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->sid_type = yang_dnode_get_enum(args->dnode, NULL);
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid/sid-value
|
||||||
|
*/
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_sid_value_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->sid = yang_dnode_get_uint32(args->dnode, NULL);
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-isisd:isis/instance/segment-routing/algorithm-prefix-sid-map/algorithm-prefix-sid/last-hop-behavior
|
||||||
|
*/
|
||||||
|
int isis_instance_segment_routing_algorithm_prefix_sid_last_hop_behavior_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->last_hop_behavior = yang_dnode_get_enum(args->dnode, NULL);
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid/n-flag-clear
|
||||||
|
*/
|
||||||
|
int isis_instance_segment_routing_algorithm_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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1751,6 +1751,87 @@ module frr-isisd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
container algorithm-prefix-sids {
|
||||||
|
description
|
||||||
|
"Algorithm SID Table";
|
||||||
|
list algorithm-prefix-sid {
|
||||||
|
key "prefix algo";
|
||||||
|
description
|
||||||
|
"Assign prefix SID for algorithm to an
|
||||||
|
interface, ISISPHPFlag will be rejected
|
||||||
|
if set to disable, ISISEXPLICITNULLFlag
|
||||||
|
will override the value of ISISPHPFlag";
|
||||||
|
leaf algo {
|
||||||
|
type uint32 {
|
||||||
|
range "128..255";
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"Algorithm";
|
||||||
|
}
|
||||||
|
leaf prefix {
|
||||||
|
type inet:ip-prefix;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"Connected prefix sid.";
|
||||||
|
}
|
||||||
|
leaf sid-value-type {
|
||||||
|
type enumeration {
|
||||||
|
enum "index" {
|
||||||
|
value 0;
|
||||||
|
description
|
||||||
|
"The value will be interpreted as an index.";
|
||||||
|
}
|
||||||
|
enum "absolute" {
|
||||||
|
value 1;
|
||||||
|
description
|
||||||
|
"The value will become interpreted as an absolute
|
||||||
|
value.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default "index";
|
||||||
|
description
|
||||||
|
"This leaf defines how value must be interpreted.";
|
||||||
|
}
|
||||||
|
leaf sid-value {
|
||||||
|
type uint32 {
|
||||||
|
range "0..1048575";
|
||||||
|
}
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"Value associated with prefix. The value must be
|
||||||
|
interpreted in the context of sid-value-type.";
|
||||||
|
}
|
||||||
|
leaf last-hop-behavior {
|
||||||
|
type enumeration {
|
||||||
|
enum "explicit-null" {
|
||||||
|
value 0;
|
||||||
|
description
|
||||||
|
"Use explicit-null for the SID.";
|
||||||
|
}
|
||||||
|
enum "no-php" {
|
||||||
|
value 1;
|
||||||
|
description
|
||||||
|
"Do not use Penultimate Hop Popping (PHP)
|
||||||
|
for the SID.";
|
||||||
|
}
|
||||||
|
enum "php" {
|
||||||
|
value 2;
|
||||||
|
description
|
||||||
|
"Use PHP for the SID.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default "php";
|
||||||
|
description
|
||||||
|
"Configure last hop behavior.";
|
||||||
|
}
|
||||||
|
leaf n-flag-clear {
|
||||||
|
type boolean;
|
||||||
|
default "false";
|
||||||
|
description
|
||||||
|
"Not a node SID";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container mpls {
|
container mpls {
|
||||||
|
|
Loading…
Reference in a new issue