]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd,yang: add algorithm-prefix-sid configuration tree
authorHiroki Shirokura <hiroki.shirokura@linecorp.com>
Sun, 12 Dec 2021 11:56:44 +0000 (11:56 +0000)
committerLouis Scalbert <louis.scalbert@6wind.com>
Tue, 18 Apr 2023 08:11:53 +0000 (10:11 +0200)
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>
isisd/isis_cli.c
isisd/isis_nb.c
isisd/isis_nb.h
isisd/isis_nb_config.c
yang/frr-isisd.yang

index ee51e468587009a15b709b903593f84c874217a7..e752103415ffc9a86fa2bdd8c2213f60d6fd1a01 100644 (file)
@@ -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
index 9141bfc46ce7b10e5dc1112a56e46f59e3d1a66b..38817a01ee26fd569938a2f5495c3a139e61fb47 100644 (file)
@@ -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,
                        }
                },
+               {
+                       .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 = {
index 9a1f1f786f41febcc2f0705b1bca35cb3af1213f..72d6617c688115bed3bd67b89eab2997f38fc282 100644 (file)
@@ -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);
index 17706279bd4d20a99424c17437bfdaf5a915f830..697281a0d765d5e072914f156aedb5d1dffa5292 100644 (file)
@@ -2466,6 +2466,214 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
        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
  */
index de925b48238a887dd62f37e0f5edafe775ff71c9..264d5fd3c28471b8157bcb7148daba5af8a0a838 100644 (file)
@@ -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 {