From f8da4a29e58ec301c72a17f238686a59b62edef0 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 15:50:24 +0100 Subject: [PATCH] zebra: Repond to `GET_LOCATOR` ZAPI request The previous commits introduced a new operation, `ZEBRA_SRV6_MANAGER_GET_LOCATOR`, allowing a daemon to request information about a specific SRv6 locator from the SRv6 SID Manager. This commit extends the SID Manager to respond to a `ZEBRA_SRV6_MANAGER_GET_LOCATOR` request and provide the requested locator information. Signed-off-by: Carmine Scarpitta --- zebra/zapi_msg.c | 29 +++++++++++++++++++++++++++++ zebra/zapi_msg.h | 3 +++ zebra/zebra_srv6.c | 37 +++++++++++++++++++++++++++++++++++++ zebra/zebra_srv6.h | 8 ++++++++ 4 files changed, 77 insertions(+) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 2d580e2972..21c18a1445 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3006,6 +3006,31 @@ stream_failure: return; } +/** + * Handle SRv6 locator get request received from a client daemon protocol. + * + * @param client The client zapi session + * @param msg The request message + */ +static void zread_srv6_manager_get_locator(struct zserv *client, + struct stream *msg) +{ + struct stream *s = msg; + uint16_t len; + char locator_name[SRV6_LOCNAME_SIZE] = { 0 }; + struct srv6_locator *locator = NULL; + + /* Get data */ + STREAM_GETW(s, len); + STREAM_GET(locator_name, s, len); + + /* Call hook to get the locator info using wrapper */ + srv6_manager_get_locator_call(&locator, client, locator_name); + +stream_failure: + return; +} + static void zread_srv6_manager_request(ZAPI_HANDLER_ARGS) { switch (hdr->command) { @@ -3017,6 +3042,9 @@ static void zread_srv6_manager_request(ZAPI_HANDLER_ARGS) zread_srv6_manager_release_locator_chunk(client, msg, zvrf_id(zvrf)); break; + case ZEBRA_SRV6_MANAGER_GET_LOCATOR: + zread_srv6_manager_get_locator(client, msg); + break; default: zlog_err("%s: unknown SRv6 Manager command", __func__); break; @@ -3965,6 +3993,7 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_MLAG_FORWARD_MSG] = zebra_mlag_forward_client_msg, [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] = zread_srv6_manager_request, [ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK] = zread_srv6_manager_request, + [ZEBRA_SRV6_MANAGER_GET_LOCATOR] = zread_srv6_manager_request, [ZEBRA_CLIENT_CAPABILITIES] = zread_client_capabilities, [ZEBRA_NEIGH_DISCOVER] = zread_neigh_discover, [ZEBRA_NHG_ADD] = zread_nhg_add, diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 43f734d26e..c7123e2593 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -110,6 +110,9 @@ extern int zsend_zebra_srv6_locator_delete(struct zserv *client, extern int zsend_srv6_manager_get_locator_chunk_response(struct zserv *client, vrf_id_t vrf_id, struct srv6_locator *loc); +extern int zsend_srv6_manager_get_locator_response(struct zserv *client, + struct srv6_locator *locator); + #ifdef __cplusplus } #endif diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 6e72440274..0217be8c7f 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -61,6 +61,11 @@ DEFINE_HOOK(srv6_manager_release_chunk, vrf_id_t vrf_id), (client, locator_name, vrf_id)); +DEFINE_HOOK(srv6_manager_get_locator, + (struct srv6_locator **locator, struct zserv *client, + const char *locator_name), + (locator, client, locator_name)); + /* define wrappers to be called in zapi_msg.c (as hooks must be called in * source file where they were defined) */ @@ -91,6 +96,13 @@ int srv6_manager_client_disconnect_cb(struct zserv *client) return 0; } +void srv6_manager_get_locator_call(struct srv6_locator **locator, + struct zserv *client, + const char *locator_name) +{ + hook_call(srv6_manager_get_locator, locator, client, locator_name); +} + static int zebra_srv6_cleanup(struct zserv *client) { return 0; @@ -921,6 +933,28 @@ void zebra_srv6_encap_src_addr_unset(void) memset(&srv6->encap_src_addr, 0, sizeof(struct in6_addr)); } +/** + * Handle a get SRv6 Locator request received from a client. + * + * It looks up the requested locator and send it to the client. + * + * @param locator SRv6 locator returned by this function + * @param client The client that sent the Get SRv6 Locator request + * @param locator_name Name of the locator to look up + * + * @return 0 on success + */ +static int srv6_manager_get_srv6_locator_internal(struct srv6_locator **locator, + struct zserv *client, + const char *locator_name) +{ + *locator = zebra_srv6_locator_lookup(locator_name); + if (!*locator) + return -1; + + return zsend_zebra_srv6_locator_add(client, *locator); +} + void zebra_srv6_terminate(void) { struct srv6_locator *locator; @@ -983,6 +1017,9 @@ void zebra_srv6_init(void) zebra_srv6_manager_get_locator_chunk); hook_register(srv6_manager_release_chunk, zebra_srv6_manager_release_locator_chunk); + + hook_register(srv6_manager_get_locator, + srv6_manager_get_srv6_locator_internal); } bool zebra_srv6_is_enable(void) diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index ad10092575..681789e4ac 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -231,6 +231,10 @@ DECLARE_HOOK(srv6_manager_release_chunk, vrf_id_t vrf_id), (client, locator_name, vrf_id)); +DECLARE_HOOK(srv6_manager_get_locator, + (struct srv6_locator **locator, struct zserv *client, + const char *locator_name), + (locator, client, locator_name)); extern void zebra_srv6_locator_add(struct srv6_locator *locator); extern void zebra_srv6_locator_delete(struct srv6_locator *locator); @@ -286,6 +290,10 @@ zebra_srv6_sid_alloc(struct zebra_srv6_sid_ctx *ctx, struct in6_addr *sid_value, extern void zebra_srv6_sid_free(struct zebra_srv6_sid *sid); extern void delete_zebra_srv6_sid(void *val); +extern void srv6_manager_get_locator_call(struct srv6_locator **locator, + struct zserv *client, + const char *locator_name); + extern struct zebra_srv6_sid_ctx *zebra_srv6_sid_ctx_alloc(void); extern void zebra_srv6_sid_ctx_free(struct zebra_srv6_sid_ctx *ctx); extern void delete_zebra_srv6_sid_ctx(void *val); -- 2.39.5