]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: Deal with SRv6 locator instead of chunk
authorCarmine Scarpitta <cscarpit@cisco.com>
Thu, 9 May 2024 07:17:49 +0000 (09:17 +0200)
committerCarmine Scarpitta <cscarpit@cisco.com>
Tue, 18 Jun 2024 16:33:29 +0000 (18:33 +0200)
Currently, when SRv6 is enabled in IS-IS, IS-IS requests a locator chunk
from Zebra. Zebra assigns a locator chunk to IS-IS, and then IS-IS can
allocate SIDs from the locator chunk.

Recently, the implementation of SRv6 in Zebra has been improved, and a
new API has been introduced for obtaining/releasing the SIDs.

Now, the daemons no longer need to request a chunk.

Instead, the daemons interact with Zebra to obtain information about the
locator and subsequently to allocate/release the SIDs.

This commit extends IS-IS to use the new SRv6 API. In particular, it
removes the chunk throughout the IS-IS code and modifies IS-IS to
request/save/advertise the locator instead of the chunk.

Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
isisd/isis_lsp.c
isisd/isis_nb_config.c
isisd/isis_srv6.c
isisd/isis_srv6.h
isisd/isis_zebra.c

index c98cee06a5687f2adfb93847291326066588d10d..13f5148d4ab508d7166e2b9677c32bf1e134adc7 100644 (file)
@@ -1222,17 +1222,11 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
        }
 
        /* Add SRv6 Locator TLV. */
-       if (area->srv6db.config.enabled &&
-           !list_isempty(area->srv6db.srv6_locator_chunks)) {
+       if (area->srv6db.config.enabled && area->srv6db.srv6_locator) {
                struct isis_srv6_locator locator = {};
-               struct srv6_locator_chunk *chunk;
-
-               /* TODO: support more than one locator */
-               chunk = (struct srv6_locator_chunk *)listgetdata(
-                       listhead(area->srv6db.srv6_locator_chunks));
 
                locator.metric = 0;
-               locator.prefix = chunk->prefix;
+               locator.prefix = area->srv6db.srv6_locator->prefix;
                locator.flags = 0;
                locator.algorithm = 0;
 
@@ -1252,7 +1246,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
 
                isis_tlvs_add_ipv6_reach(lsp->tlvs,
                                         isis_area_ipv6_topology(area),
-                                        &chunk->prefix, 0, false, NULL);
+                                        &area->srv6db.srv6_locator->prefix, 0,
+                                        false, NULL);
        }
 
        /* IPv4 address and TE router ID TLVs.
index 763b8b73d270ffbc45dca589160c06747930b5c6..30c90baa5432719a3860c9839ac7b62c95d14c3f 100644 (file)
@@ -3518,10 +3518,10 @@ int isis_instance_segment_routing_srv6_locator_modify(
        sr_debug("Configured SRv6 locator %s for IS-IS area %s", loc_name,
                 area->area_tag);
 
-       sr_debug("Trying to get a chunk from locator %s for IS-IS area %s",
-                loc_name, area->area_tag);
+       sr_debug("Trying to get locator %s for IS-IS area %s", loc_name,
+                area->area_tag);
 
-       if (isis_zebra_srv6_manager_get_locator_chunk(loc_name) < 0)
+       if (isis_zebra_srv6_manager_get_locator(loc_name) < 0)
                return NB_ERR;
 
        return NB_OK;
index 44fd599cbbcfc1f6b931322d14a303885c60fc64..7cf1d91b4638db30d0580662fee9d5b350a2de87 100644 (file)
@@ -146,6 +146,10 @@ bool isis_srv6_locator_unset(struct isis_area *area)
                srv6_locator_chunk_free(&chunk);
        }
 
+       /* Clear locator */
+       srv6_locator_free(area->srv6db.srv6_locator);
+       area->srv6db.srv6_locator = NULL;
+
        /* Clear locator name */
        memset(area->srv6db.config.srv6_locator_name, 0,
               sizeof(area->srv6db.config.srv6_locator_name));
@@ -235,16 +239,16 @@ static bool sid_exist(struct isis_area *area, const struct in6_addr *sid)
  * Request a SID from the SRv6 locator.
  *
  * @param area         IS-IS area
- * @param chunk                SRv6 locator chunk
+ * @param locator      SRv6 locator
  * @param sid_func     The FUNCTION part of the SID to be allocated (a negative
  * number will allocate the first available SID)
  *
  * @return     First available SID on success or in6addr_any if the SRv6
- * locator chunk is full
+ * locator is full
  */
-static struct in6_addr
-srv6_locator_request_sid(struct isis_area *area,
-                        struct srv6_locator_chunk *chunk, int sid_func)
+static struct in6_addr srv6_locator_request_sid(struct isis_area *area,
+                                               struct srv6_locator *locator,
+                                               int sid_func)
 {
        struct in6_addr sid;
        uint8_t offset = 0;
@@ -252,22 +256,22 @@ srv6_locator_request_sid(struct isis_area *area,
        uint32_t func_max;
        bool allocated = false;
 
-       if (!area || !chunk)
+       if (!area || !locator)
                return in6addr_any;
 
        sr_debug("ISIS-SRv6 (%s): requested new SID from locator %s",
-                area->area_tag, chunk->locator_name);
+                area->area_tag, locator->name);
 
        /* Let's build the SID, step by step. A SID has the following structure
        (defined in RFC 8986): LOCATOR:FUNCTION:ARGUMENT.*/
 
        /* First, we encode the LOCATOR in the L most significant bits. */
-       sid = chunk->prefix.prefix;
+       sid = locator->prefix.prefix;
 
        /* The next part of the SID is the FUNCTION. Let's compute the length
         * and the offset of the FUNCTION in the SID */
-       func_len = chunk->function_bits_length;
-       offset = chunk->block_bits_length + chunk->node_bits_length;
+       func_len = locator->function_bits_length;
+       offset = locator->block_bits_length + locator->node_bits_length;
 
        /* Then, encode the FUNCTION */
        if (sid_func >= 0) {
@@ -298,7 +302,7 @@ srv6_locator_request_sid(struct isis_area *area,
        if (!allocated) {
                /* We ran out of available SIDs */
                zlog_warn("ISIS-SRv6 (%s): no SIDs available in locator %s",
-                         area->area_tag, chunk->locator_name);
+                         area->area_tag, locator->name);
                return in6addr_any;
        }
 
@@ -312,35 +316,34 @@ srv6_locator_request_sid(struct isis_area *area,
  * Allocate an SRv6 SID from an SRv6 locator.
  *
  * @param area         IS-IS area
- * @param chunk                SRv6 locator chunk
+ * @param locator      SRv6 locator
  * @param behavior     SRv6 Endpoint Behavior bound to the SID
  *
  * @result the allocated SID on success, NULL otherwise
  */
 struct isis_srv6_sid *
-isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator_chunk *chunk,
-                   enum srv6_endpoint_behavior_codepoint behavior,
-                   int sid_func)
+isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator *locator,
+                   enum srv6_endpoint_behavior_codepoint behavior, int sid_func)
 {
        struct isis_srv6_sid *sid = NULL;
 
-       if (!area || !chunk)
+       if (!area || !locator)
                return NULL;
 
        sid = XCALLOC(MTYPE_ISIS_SRV6_SID, sizeof(struct isis_srv6_sid));
 
-       sid->sid = srv6_locator_request_sid(area, chunk, sid_func);
+       sid->sid = srv6_locator_request_sid(area, locator, sid_func);
        if (IPV6_ADDR_SAME(&sid->sid, &in6addr_any)) {
                isis_srv6_sid_free(sid);
                return NULL;
        }
 
        sid->behavior = behavior;
-       sid->structure.loc_block_len = chunk->block_bits_length;
-       sid->structure.loc_node_len = chunk->node_bits_length;
-       sid->structure.func_len = chunk->function_bits_length;
-       sid->structure.arg_len = chunk->argument_bits_length;
-       sid->locator = chunk;
+       sid->structure.loc_block_len = locator->block_bits_length;
+       sid->structure.loc_node_len = locator->node_bits_length;
+       sid->structure.func_len = locator->function_bits_length;
+       sid->structure.arg_len = locator->argument_bits_length;
+       sid->locator = locator;
        sid->area = area;
 
        return sid;
@@ -387,11 +390,10 @@ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup,
        struct isis_srv6_lan_endx_sid_subtlv *ladj_sid;
        struct in6_addr nexthop;
        uint8_t flags = 0;
-       struct srv6_locator_chunk *chunk;
+       struct srv6_locator *locator;
        uint32_t behavior;
 
-       if (!area || !area->srv6db.srv6_locator_chunks ||
-           list_isempty(area->srv6db.srv6_locator_chunks))
+       if (!area || !area->srv6db.srv6_locator)
                return;
 
        sr_debug("ISIS-SRv6 (%s): Add %s End.X SID", area->area_tag,
@@ -401,10 +403,7 @@ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup,
        if (!circuit->ipv6_router || !adj->ll_ipv6_count)
                return;
 
-       chunk = (struct srv6_locator_chunk *)listgetdata(
-               listhead(area->srv6db.srv6_locator_chunks));
-       if (!chunk)
-               return;
+       locator = area->srv6db.srv6_locator;
 
        nexthop = adj->ll_ipv6_addrs[0];
 
@@ -415,21 +414,21 @@ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup,
        if (circuit->ext == NULL)
                circuit->ext = isis_alloc_ext_subtlvs();
 
-       behavior = (CHECK_FLAG(chunk->flags, SRV6_LOCATOR_USID))
+       behavior = (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
                           ? SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID
                           : SRV6_ENDPOINT_BEHAVIOR_END_X;
 
        sra = XCALLOC(MTYPE_ISIS_SRV6_INFO, sizeof(*sra));
        sra->type = backup ? ISIS_SRV6_ADJ_BACKUP : ISIS_SRV6_ADJ_NORMAL;
        sra->behavior = behavior;
-       sra->locator = chunk;
-       sra->structure.loc_block_len = chunk->block_bits_length;
-       sra->structure.loc_node_len = chunk->node_bits_length;
-       sra->structure.func_len = chunk->function_bits_length;
-       sra->structure.arg_len = chunk->argument_bits_length;
+       sra->locator = locator;
+       sra->structure.loc_block_len = locator->block_bits_length;
+       sra->structure.loc_node_len = locator->node_bits_length;
+       sra->structure.func_len = locator->function_bits_length;
+       sra->structure.arg_len = locator->argument_bits_length;
        sra->nexthop = nexthop;
 
-       sra->sid = srv6_locator_request_sid(area, chunk, -1);
+       sra->sid = srv6_locator_request_sid(area, locator, -1);
        if (IPV6_ADDR_SAME(&sra->sid, &in6addr_any)) {
                XFREE(MTYPE_ISIS_SRV6_INFO, sra);
                return;
@@ -832,6 +831,9 @@ void isis_srv6_area_term(struct isis_area *area)
                srv6_locator_chunk_free(&chunk);
        list_delete(&srv6db->srv6_locator_chunks);
 
+       srv6_locator_free(area->srv6db.srv6_locator);
+       area->srv6db.srv6_locator = NULL;
+
        /* Free SRv6 SIDs list */
        list_delete(&srv6db->srv6_sids);
        list_delete(&srv6db->srv6_endx_sids);
index 7f16712ae3064e24b22d0d9dfaf2299448dc56ec..6abc6d73451acafe92ad2bed51426b5eb6fd7ee6 100644 (file)
@@ -44,7 +44,7 @@ struct isis_srv6_sid {
        struct isis_srv6_sid_structure structure;
 
        /* Parent SRv6 locator */
-       struct srv6_locator_chunk *locator;
+       struct srv6_locator *locator;
 
        /* Backpointer to IS-IS area */
        struct isis_area *area;
@@ -89,7 +89,7 @@ struct srv6_adjacency {
        struct isis_srv6_sid_structure structure;
 
        /* Parent SRv6 locator */
-       struct srv6_locator_chunk *locator;
+       struct srv6_locator *locator;
 
        /* Adjacency-SID nexthop information */
        struct in6_addr nexthop;
@@ -109,6 +109,8 @@ struct srv6_adjacency {
 
 /* Per-area IS-IS SRv6 Data Base (SRv6 DB) */
 struct isis_srv6_db {
+       /* List of SRv6 Locator */
+       struct srv6_locator *srv6_locator;
 
        /* List of SRv6 Locator chunks */
        struct list *srv6_locator_chunks;
@@ -149,7 +151,7 @@ bool isis_srv6_locator_unset(struct isis_area *area);
 void isis_srv6_interface_set(struct isis_area *area, const char *ifname);
 
 struct isis_srv6_sid *
-isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator_chunk *chunk,
+isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator *locator,
                    enum srv6_endpoint_behavior_codepoint behavior,
                    int sid_func);
 extern void isis_srv6_sid_free(struct isis_srv6_sid *sid);
index 226ee567967552090c3dd422d866994f5aef92cc..44ef182ba97f7df8dfc130323ac10c58a3b4d3d3 100644 (file)
@@ -1369,6 +1369,9 @@ static int isis_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
                        }
                }
 
+               srv6_locator_free(area->srv6db.srv6_locator);
+               area->srv6db.srv6_locator = NULL;
+
                /* Regenerate LSPs to advertise that the locator no longer
                 * exists */
                lsp_regenerate_schedule(area, area->is_type, 0);