summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--isisd/isis_cli.c38
-rw-r--r--isisd/isis_nb.c34
-rw-r--r--isisd/isis_nb.h19
-rw-r--r--isisd/isis_nb_config.c208
-rw-r--r--yang/frr-isisd.yang81
5 files changed, 380 insertions, 0 deletions
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index ee51e46858..e752103415 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -1769,6 +1769,44 @@ void cli_show_isis_prefix_sid(struct vty *vty, const struct lyd_node *dnode,
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
diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c
index 9141bfc46c..38817a01ee 100644
--- a/isisd/isis_nb.c
+++ b/isisd/isis_nb.c
@@ -689,6 +689,40 @@ const struct frr_yang_module_info frr_isisd_info = {
}
},
{
+ .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",
.cbs = {
.cli_show = cli_show_isis_mpls_ldp_sync,
diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h
index 9a1f1f786f..72d6617c68 100644
--- a/isisd/isis_nb.h
+++ b/isisd/isis_nb.h
@@ -249,6 +249,22 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_mo
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_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_create(struct nb_cb_create_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);
void cli_show_isis_prefix_sid(struct vty *vty, const struct lyd_node *dnode,
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,
const struct lyd_node *dnode,
bool show_defaults);
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 17706279bd..697281a0d7 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -2467,6 +2467,214 @@ int 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
+ */
+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
*/
int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args)
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
index de925b4823..264d5fd3c2 100644
--- a/yang/frr-isisd.yang
+++ b/yang/frr-isisd.yang
@@ -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 {