From d223a8167e471c9297a6b33cd97fec37e97ca3c5 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 9 Feb 2023 19:11:05 +0100 Subject: [PATCH] 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 --- isisd/isis_zebra.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index b245b09bba..4813173f45 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -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) -- 2.39.5