diff --git a/isisd/isis_srv6.c b/isisd/isis_srv6.c index b08609d360..0e6e36e9a8 100644 --- a/isisd/isis_srv6.c +++ b/isisd/isis_srv6.c @@ -15,6 +15,55 @@ #include "isisd/isisd.h" #include "isisd/isis_misc.h" #include "isisd/isis_srv6.h" +#include "isisd/isis_zebra.h" + +/** + * Unset the SRv6 locator for a given IS-IS area. + * + * @param area IS-IS area + * + * @result True on success, False otherwise + */ +bool isis_srv6_locator_unset(struct isis_area *area) +{ + int ret; + struct listnode *node, *nnode; + struct srv6_locator_chunk *chunk; + + if (strncmp(area->srv6db.config.srv6_locator_name, "", + sizeof(area->srv6db.config.srv6_locator_name)) == 0) { + sr_debug("SRv6 locator not set"); + return true; + } + + /* Inform Zebra that we are releasing the SRv6 locator */ + ret = isis_zebra_srv6_manager_release_locator_chunk( + area->srv6db.config.srv6_locator_name); + if (ret < 0) + return false; + + /* Delete chunks */ + for (ALL_LIST_ELEMENTS(area->srv6db.srv6_locator_chunks, node, nnode, + chunk)) { + sr_debug( + "Releasing chunk of locator %s (prefix %pFX) for IS-IS area %s", + area->srv6db.config.srv6_locator_name, &chunk->prefix, + area->area_tag); + + listnode_delete(area->srv6db.srv6_locator_chunks, chunk); + srv6_locator_chunk_free(&chunk); + } + + /* Clear locator name */ + memset(area->srv6db.config.srv6_locator_name, 0, + sizeof(area->srv6db.config.srv6_locator_name)); + + /* Regenerate LSPs to advertise that the SRv6 locator no longer exists + */ + lsp_regenerate_schedule(area, area->is_type, 0); + + return true; +} /** * Show Segment Routing over IPv6 (SRv6) Node. diff --git a/isisd/isis_srv6.h b/isisd/isis_srv6.h index b0e92c8a5b..40a0faaa99 100644 --- a/isisd/isis_srv6.h +++ b/isisd/isis_srv6.h @@ -44,6 +44,8 @@ struct isis_srv6_db { } config; }; +bool isis_srv6_locator_unset(struct isis_area *area); + extern void isis_srv6_area_init(struct isis_area *area); extern void isis_srv6_area_term(struct isis_area *area);