isisd: Add func to process a deleted SRv6 locator

Add a callback function `isis_zebra_process_srv6_locator_delete()` that
is called when an SRv6 locator is deleted in zebra.

When an existing SRv6 locator is deleted in zebra, zebra sends a
ZEBRA_SRV6_LOCATOR_DELETE notification to all daemons informing them of
the deleted locator.

In IS-IS, we register the new `isis_zebra_process_srv6_locator_delete()`
callback as the handler for ZEBRA_SRV6_LOCATOR_DELETE.

This callback iterates over all areas of the current IS-IS instance and
looks for an area for which the deleted locator was configured.
If a match is found, we remove
the locator's chunks from the area's chunks list and call
`lsp_regenerate_schedule` to remove the locator from the SRv6 Locator
TLV advertised in the LSPs and regenerate the LSPs.
If no match is found, we do nothing.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
This commit is contained in:
Carmine Scarpitta 2023-02-09 19:11:05 +01:00
parent 5b9c03b0d3
commit d223a8167e

View File

@ -930,6 +930,57 @@ static int isis_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS)
return 0;
}
/**
* Callback to process a notification from SRv6 Manager (zebra) of an SRv6
* locator deleted.
*
* @result 0 on success, -1 otherwise
*/
static int isis_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
{
struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
struct srv6_locator loc = {};
struct isis_area *area;
struct listnode *node, *nnode;
struct srv6_locator_chunk *chunk;
/* Decode the received zebra message */
if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
return -1;
sr_debug(
"SRv6 locator deleted in zebra: name %s, "
"prefix %pFX, block_len %u, node_len %u, func_len %u, arg_len %u",
loc.name, &loc.prefix, loc.block_bits_length,
loc.node_bits_length, loc.function_bits_length,
loc.argument_bits_length);
/* Walk through all areas of the ISIS instance */
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
if (strncmp(area->srv6db.config.srv6_locator_name, loc.name,
sizeof(area->srv6db.config.srv6_locator_name)) != 0)
continue;
/* Free the SRv6 locator chunks */
for (ALL_LIST_ELEMENTS(area->srv6db.srv6_locator_chunks, node,
nnode, chunk)) {
if (prefix_match((struct prefix *)&loc.prefix,
(struct prefix *)&chunk->prefix)) {
listnode_delete(
area->srv6db.srv6_locator_chunks,
chunk);
srv6_locator_chunk_free(&chunk);
}
}
/* Regenerate LSPs to advertise that the locator no longer
* exists */
lsp_regenerate_schedule(area, area->is_type, 0);
}
return 0;
}
/**
* Request an SRv6 locator chunk to the SRv6 Manager (zebra) asynchronously.
*
@ -970,6 +1021,7 @@ static zclient_handler *const isis_handlers[] = {
[ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] =
isis_zebra_process_srv6_locator_chunk,
[ZEBRA_SRV6_LOCATOR_ADD] = isis_zebra_process_srv6_locator_add,
[ZEBRA_SRV6_LOCATOR_DELETE] = isis_zebra_process_srv6_locator_delete,
};
void isis_zebra_init(struct event_loop *master, int instance)