From 79698eb9c32ee0ff1294533941044e9411a316fc Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Sat, 8 Jun 2024 07:15:47 +0200 Subject: [PATCH] zebra, lib: add locator name in sid notify messages In the near future, some daemons may only register SIDs. This may be the case for the pathd daemon when creating SRv6 binding SIDs. When a locator is getting deleted at ZEBRA level, the daemon may have an easy way to find out the SIds to unregister to. This commit proposes to add the locator name to the SID_SRV6_NOTIFY message whenever possible. Only case when an allocation failure happens, the locator will not be present. In all other places, the notify API at procol levels has the locator name extra-parameter. Signed-off-by: Philippe Guibert Signed-off-by: Carmine Scarpitta --- lib/zclient.c | 18 +++++++++++++++++- lib/zclient.h | 3 ++- zebra/zapi_msg.c | 11 ++++++++++- zebra/zapi_msg.h | 2 +- zebra/zebra_srv6.c | 15 ++++++++++++--- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index a1386e501a72..8bfbd45850e9 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2136,9 +2136,12 @@ bool zapi_iptable_notify_decode(struct stream *s, bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, uint32_t *func, uint32_t *wide_func, - enum zapi_srv6_sid_notify *note) + enum zapi_srv6_sid_notify *note, + char **p_locator_name) { uint32_t f, wf; + uint16_t len; + static char locator_name[SRV6_LOCNAME_SIZE] = {}; STREAM_GET(note, s, sizeof(*note)); STREAM_GET(ctx, s, sizeof(struct srv6_sid_ctx)); @@ -2151,6 +2154,19 @@ bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, if (wide_func) *wide_func = wf; + STREAM_GETW(s, len); + if (len > SRV6_LOCNAME_SIZE) { + *p_locator_name = NULL; + return false; + } + if (p_locator_name) { + if (len == 0) + *p_locator_name = NULL; + else { + STREAM_GET(locator_name, s, len); + *p_locator_name = locator_name; + } + } return true; stream_failure: diff --git a/lib/zclient.h b/lib/zclient.h index bfe955b7acc7..2877b347d8d0 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -1177,7 +1177,8 @@ bool zapi_ipset_notify_decode(struct stream *s, bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, uint32_t *func, uint32_t *wide_func, - enum zapi_srv6_sid_notify *note); + enum zapi_srv6_sid_notify *note, + char **locator_name); /* Nexthop-group message apis */ extern enum zclient_send_status diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 164c0dd68723..2a1eea9594ee 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1001,7 +1001,9 @@ void zsend_neighbor_notify(int cmd, struct interface *ifp, void zsend_srv6_sid_notify(struct zserv *client, const struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, uint32_t func, - uint32_t wide_func, enum zapi_srv6_sid_notify note) + uint32_t wide_func, const char *locator_name, + enum zapi_srv6_sid_notify note) + { struct stream *s; uint16_t cmd = ZEBRA_SRV6_SID_NOTIFY; @@ -1027,6 +1029,13 @@ void zsend_srv6_sid_notify(struct zserv *client, const struct srv6_sid_ctx *ctx, stream_putl(s, func); /* SRv6 wide SID function */ stream_putl(s, wide_func); + /* SRv6 locator name optional */ + if (locator_name) { + stream_putw(s, strlen(locator_name)); + stream_put(s, locator_name, strlen(locator_name)); + } else + stream_putw(s, 0); + stream_putw_at(s, 0, stream_get_endp(s)); zserv_send_message(client, s); diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 3505bc0dc4e3..9e3ea6fb6ecd 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -97,7 +97,7 @@ extern void zsend_neighbor_notify(int cmd, struct interface *ifp, extern void zsend_srv6_sid_notify(struct zserv *client, const struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, uint32_t func, - uint32_t wide_func, + uint32_t wide_func, const char *locator_name, enum zapi_srv6_sid_notify note); extern int zsend_client_close_notify(struct zserv *client, diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index a6db66bbccea..0ca77a49740c 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -2280,7 +2280,7 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, sid_value ? sid_value : &in6addr_any, locator_name); /* Notify client about SID alloc failure */ - zsend_srv6_sid_notify(client, ctx, sid_value, 0, 0, + zsend_srv6_sid_notify(client, ctx, sid_value, 0, 0, NULL, ZAPI_SRV6_SID_FAIL_ALLOC); } else if (ret == 0) { if (IS_ZEBRA_DEBUG_PACKET) @@ -2294,6 +2294,8 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, zsend_srv6_sid_notify(client, ctx, &(*sid)->value, (*sid)->func, (*sid)->wide_func, + (*sid)->locator ? (*sid)->locator->name + : NULL, ZAPI_SRV6_SID_ALLOCATED); } else { if (IS_ZEBRA_DEBUG_PACKET) @@ -2308,6 +2310,9 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, for (ALL_LIST_ELEMENTS_RO((*sid)->client_list, node, c)) zsend_srv6_sid_notify(c, ctx, &(*sid)->value, (*sid)->func, (*sid)->wide_func, + (*sid)->locator + ? (*sid)->locator->name + : NULL, ZAPI_SRV6_SID_ALLOCATED); } @@ -2366,6 +2371,7 @@ static int srv6_manager_release_sid_internal(struct zserv *client, struct zebra_srv6_sid_ctx *zctx; struct listnode *node, *nnode; char buf[256]; + const char *locator_name = NULL; if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: releasing SRv6 SID associated with ctx %s", @@ -2374,6 +2380,9 @@ static int srv6_manager_release_sid_internal(struct zserv *client, /* Lookup Zebra SID context and release it */ for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, zctx)) if (memcmp(&zctx->ctx, ctx, sizeof(struct srv6_sid_ctx)) == 0) { + if (zctx->sid && zctx->sid->locator) + locator_name = + (const char *)zctx->sid->locator->name; ret = release_srv6_sid(client, zctx); break; } @@ -2383,10 +2392,10 @@ static int srv6_manager_release_sid_internal(struct zserv *client, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); if (ret == 0) - zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, locator_name, ZAPI_SRV6_SID_RELEASED); else - zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, locator_name, ZAPI_SRV6_SID_FAIL_RELEASE); return ret;