]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: add support for Anycast-SIDs
authorRenato Westphal <renato@opensourcerouting.org>
Sun, 20 Sep 2020 05:42:32 +0000 (02:42 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Fri, 23 Oct 2020 13:31:39 +0000 (10:31 -0300)
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>
doc/user/isisd.rst
isisd/isis_cli.c
isisd/isis_nb.c
isisd/isis_nb.h
isisd/isis_nb_config.c
isisd/isis_sr.c
isisd/isis_sr.h
yang/frr-isisd.yang

index d71f4246fd359148604162ed8029738a0a353aac..98f5aff7dbdb759c6c527a92252243cb782bbbb5 100644 (file)
@@ -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
index a270636dde053201c396ef9996e8f3779aeb4e88..383f23758ab05b0a0a6858779a43ce323a47de70 100644 (file)
@@ -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");
 }
 
index d04012c4dac6b9cf4d7691983873cd15e1cc4d91..2d3c7e1e38b31d50176eb48b20969513ec3068c0 100644 (file)
@@ -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,
                        },
                },
+               {
+                       .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 = {
index 303a7b46963ae227bafb30cbad5d9bde7f5f6985..fb843131d9fe943ab6da24b679d4669b4500f235 100644 (file)
@@ -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);
index 2710c3c13fad1f73201f56586ecf521b3a0df1a9..1019c638a769386a6da321e5a39e58d57aa29b5c 100644 (file)
@@ -1837,6 +1837,23 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_mo
        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
  */
index deb0767d170ce0eaa322fad978b58500c967b86b..140cf5e66caec8f2ad4810a8c158f34f4ffd70b3 100644 (file)
@@ -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);
                }
index ce97b024afd1b7e238f0cd6e98b42a62b7245986..b012dfb00a03e50a0ff9dfff44755074d801504c 100644 (file)
@@ -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;
 
index 06d1a793b5a91df0001c384f987e2335d687b126..c3b39e3750800e1ead3a60c75e6e47093187e1d0 100644 (file)
@@ -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";
+            }
           }
         }
       }