isisd: Deal with SRv6 locator instead of chunk

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>
This commit is contained in:
Carmine Scarpitta 2024-05-09 09:17:49 +02:00
parent 3fce2928e2
commit 9ae38eede8
5 changed files with 53 additions and 51 deletions

View File

@ -1222,17 +1222,11 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
} }
/* Add SRv6 Locator TLV. */ /* Add SRv6 Locator TLV. */
if (area->srv6db.config.enabled && if (area->srv6db.config.enabled && area->srv6db.srv6_locator) {
!list_isempty(area->srv6db.srv6_locator_chunks)) {
struct isis_srv6_locator 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.metric = 0;
locator.prefix = chunk->prefix; locator.prefix = area->srv6db.srv6_locator->prefix;
locator.flags = 0; locator.flags = 0;
locator.algorithm = 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_tlvs_add_ipv6_reach(lsp->tlvs,
isis_area_ipv6_topology(area), 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. /* IPv4 address and TE router ID TLVs.

View 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, sr_debug("Configured SRv6 locator %s for IS-IS area %s", loc_name,
area->area_tag); area->area_tag);
sr_debug("Trying to get a chunk from locator %s for IS-IS area %s", sr_debug("Trying to get locator %s for IS-IS area %s", loc_name,
loc_name, area->area_tag); 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_ERR;
return NB_OK; return NB_OK;

View File

@ -146,6 +146,10 @@ bool isis_srv6_locator_unset(struct isis_area *area)
srv6_locator_chunk_free(&chunk); srv6_locator_chunk_free(&chunk);
} }
/* Clear locator */
srv6_locator_free(area->srv6db.srv6_locator);
area->srv6db.srv6_locator = NULL;
/* Clear locator name */ /* Clear locator name */
memset(area->srv6db.config.srv6_locator_name, 0, memset(area->srv6db.config.srv6_locator_name, 0,
sizeof(area->srv6db.config.srv6_locator_name)); 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. * Request a SID from the SRv6 locator.
* *
* @param area IS-IS area * @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 * @param sid_func The FUNCTION part of the SID to be allocated (a negative
* number will allocate the first available SID) * number will allocate the first available SID)
* *
* @return First available SID on success or in6addr_any if the SRv6 * @return First available SID on success or in6addr_any if the SRv6
* locator chunk is full * locator is full
*/ */
static struct in6_addr static struct in6_addr srv6_locator_request_sid(struct isis_area *area,
srv6_locator_request_sid(struct isis_area *area, struct srv6_locator *locator,
struct srv6_locator_chunk *chunk, int sid_func) int sid_func)
{ {
struct in6_addr sid; struct in6_addr sid;
uint8_t offset = 0; uint8_t offset = 0;
@ -252,22 +256,22 @@ srv6_locator_request_sid(struct isis_area *area,
uint32_t func_max; uint32_t func_max;
bool allocated = false; bool allocated = false;
if (!area || !chunk) if (!area || !locator)
return in6addr_any; return in6addr_any;
sr_debug("ISIS-SRv6 (%s): requested new SID from locator %s", 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 /* Let's build the SID, step by step. A SID has the following structure
(defined in RFC 8986): LOCATOR:FUNCTION:ARGUMENT.*/ (defined in RFC 8986): LOCATOR:FUNCTION:ARGUMENT.*/
/* First, we encode the LOCATOR in the L most significant bits. */ /* 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 /* The next part of the SID is the FUNCTION. Let's compute the length
* and the offset of the FUNCTION in the SID */ * and the offset of the FUNCTION in the SID */
func_len = chunk->function_bits_length; func_len = locator->function_bits_length;
offset = chunk->block_bits_length + chunk->node_bits_length; offset = locator->block_bits_length + locator->node_bits_length;
/* Then, encode the FUNCTION */ /* Then, encode the FUNCTION */
if (sid_func >= 0) { if (sid_func >= 0) {
@ -298,7 +302,7 @@ srv6_locator_request_sid(struct isis_area *area,
if (!allocated) { if (!allocated) {
/* We ran out of available SIDs */ /* We ran out of available SIDs */
zlog_warn("ISIS-SRv6 (%s): no SIDs available in locator %s", 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; return in6addr_any;
} }
@ -312,35 +316,34 @@ srv6_locator_request_sid(struct isis_area *area,
* Allocate an SRv6 SID from an SRv6 locator. * Allocate an SRv6 SID from an SRv6 locator.
* *
* @param area IS-IS area * @param area IS-IS area
* @param chunk SRv6 locator chunk * @param locator SRv6 locator
* @param behavior SRv6 Endpoint Behavior bound to the SID * @param behavior SRv6 Endpoint Behavior bound to the SID
* *
* @result the allocated SID on success, NULL otherwise * @result the allocated SID on success, NULL otherwise
*/ */
struct isis_srv6_sid * 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, enum srv6_endpoint_behavior_codepoint behavior, int sid_func)
int sid_func)
{ {
struct isis_srv6_sid *sid = NULL; struct isis_srv6_sid *sid = NULL;
if (!area || !chunk) if (!area || !locator)
return NULL; return NULL;
sid = XCALLOC(MTYPE_ISIS_SRV6_SID, sizeof(struct isis_srv6_sid)); 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)) { if (IPV6_ADDR_SAME(&sid->sid, &in6addr_any)) {
isis_srv6_sid_free(sid); isis_srv6_sid_free(sid);
return NULL; return NULL;
} }
sid->behavior = behavior; sid->behavior = behavior;
sid->structure.loc_block_len = chunk->block_bits_length; sid->structure.loc_block_len = locator->block_bits_length;
sid->structure.loc_node_len = chunk->node_bits_length; sid->structure.loc_node_len = locator->node_bits_length;
sid->structure.func_len = chunk->function_bits_length; sid->structure.func_len = locator->function_bits_length;
sid->structure.arg_len = chunk->argument_bits_length; sid->structure.arg_len = locator->argument_bits_length;
sid->locator = chunk; sid->locator = locator;
sid->area = area; sid->area = area;
return sid; 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 isis_srv6_lan_endx_sid_subtlv *ladj_sid;
struct in6_addr nexthop; struct in6_addr nexthop;
uint8_t flags = 0; uint8_t flags = 0;
struct srv6_locator_chunk *chunk; struct srv6_locator *locator;
uint32_t behavior; uint32_t behavior;
if (!area || !area->srv6db.srv6_locator_chunks || if (!area || !area->srv6db.srv6_locator)
list_isempty(area->srv6db.srv6_locator_chunks))
return; return;
sr_debug("ISIS-SRv6 (%s): Add %s End.X SID", area->area_tag, 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) if (!circuit->ipv6_router || !adj->ll_ipv6_count)
return; return;
chunk = (struct srv6_locator_chunk *)listgetdata( locator = area->srv6db.srv6_locator;
listhead(area->srv6db.srv6_locator_chunks));
if (!chunk)
return;
nexthop = adj->ll_ipv6_addrs[0]; 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) if (circuit->ext == NULL)
circuit->ext = isis_alloc_ext_subtlvs(); 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_NEXT_CSID
: SRV6_ENDPOINT_BEHAVIOR_END_X; : SRV6_ENDPOINT_BEHAVIOR_END_X;
sra = XCALLOC(MTYPE_ISIS_SRV6_INFO, sizeof(*sra)); sra = XCALLOC(MTYPE_ISIS_SRV6_INFO, sizeof(*sra));
sra->type = backup ? ISIS_SRV6_ADJ_BACKUP : ISIS_SRV6_ADJ_NORMAL; sra->type = backup ? ISIS_SRV6_ADJ_BACKUP : ISIS_SRV6_ADJ_NORMAL;
sra->behavior = behavior; sra->behavior = behavior;
sra->locator = chunk; sra->locator = locator;
sra->structure.loc_block_len = chunk->block_bits_length; sra->structure.loc_block_len = locator->block_bits_length;
sra->structure.loc_node_len = chunk->node_bits_length; sra->structure.loc_node_len = locator->node_bits_length;
sra->structure.func_len = chunk->function_bits_length; sra->structure.func_len = locator->function_bits_length;
sra->structure.arg_len = chunk->argument_bits_length; sra->structure.arg_len = locator->argument_bits_length;
sra->nexthop = nexthop; 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)) { if (IPV6_ADDR_SAME(&sra->sid, &in6addr_any)) {
XFREE(MTYPE_ISIS_SRV6_INFO, sra); XFREE(MTYPE_ISIS_SRV6_INFO, sra);
return; return;
@ -832,6 +831,9 @@ void isis_srv6_area_term(struct isis_area *area)
srv6_locator_chunk_free(&chunk); srv6_locator_chunk_free(&chunk);
list_delete(&srv6db->srv6_locator_chunks); list_delete(&srv6db->srv6_locator_chunks);
srv6_locator_free(area->srv6db.srv6_locator);
area->srv6db.srv6_locator = NULL;
/* Free SRv6 SIDs list */ /* Free SRv6 SIDs list */
list_delete(&srv6db->srv6_sids); list_delete(&srv6db->srv6_sids);
list_delete(&srv6db->srv6_endx_sids); list_delete(&srv6db->srv6_endx_sids);

View File

@ -44,7 +44,7 @@ struct isis_srv6_sid {
struct isis_srv6_sid_structure structure; struct isis_srv6_sid_structure structure;
/* Parent SRv6 locator */ /* Parent SRv6 locator */
struct srv6_locator_chunk *locator; struct srv6_locator *locator;
/* Backpointer to IS-IS area */ /* Backpointer to IS-IS area */
struct isis_area *area; struct isis_area *area;
@ -89,7 +89,7 @@ struct srv6_adjacency {
struct isis_srv6_sid_structure structure; struct isis_srv6_sid_structure structure;
/* Parent SRv6 locator */ /* Parent SRv6 locator */
struct srv6_locator_chunk *locator; struct srv6_locator *locator;
/* Adjacency-SID nexthop information */ /* Adjacency-SID nexthop information */
struct in6_addr nexthop; struct in6_addr nexthop;
@ -109,6 +109,8 @@ struct srv6_adjacency {
/* Per-area IS-IS SRv6 Data Base (SRv6 DB) */ /* Per-area IS-IS SRv6 Data Base (SRv6 DB) */
struct isis_srv6_db { struct isis_srv6_db {
/* List of SRv6 Locator */
struct srv6_locator *srv6_locator;
/* List of SRv6 Locator chunks */ /* List of SRv6 Locator chunks */
struct list *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); void isis_srv6_interface_set(struct isis_area *area, const char *ifname);
struct isis_srv6_sid * 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, enum srv6_endpoint_behavior_codepoint behavior,
int sid_func); int sid_func);
extern void isis_srv6_sid_free(struct isis_srv6_sid *sid); extern void isis_srv6_sid_free(struct isis_srv6_sid *sid);

View 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 /* Regenerate LSPs to advertise that the locator no longer
* exists */ * exists */
lsp_regenerate_schedule(area, area->is_type, 0); lsp_regenerate_schedule(area, area->is_type, 0);