From efa830e89ca39c93eeddef40ed7c959ba36b1fc1 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 2 May 2024 13:39:49 +0200 Subject: [PATCH] zebra: Notify daemons about SIDs Send asynchronous notifications to zclients when an SRv6 SID is allocated/released and when a SID alloc/release operation fails. Signed-off-by: Carmine Scarpitta --- zebra/zapi_msg.c | 33 +++++++++++++++++++++++++++++++++ zebra/zapi_msg.h | 5 +++++ zebra/zebra_srv6.c | 22 ++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index bab4c4fa3d..164c0dd687 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -999,6 +999,39 @@ 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) +{ + struct stream *s; + uint16_t cmd = ZEBRA_SRV6_SID_NOTIFY; + char buf[256]; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: notifying %s ctx %s sid %pI6 note %s (proto=%u, instance=%u, sessionId=%u)", + __func__, zserv_command_string(cmd), + srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value, + zapi_srv6_sid_notify2str(note), client->proto, + client->instance, client->session_id); + + s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + zclient_create_header(s, cmd, VRF_DEFAULT); + /* Notification type (e.g. ZAPI_SRV6_SID_ALLOCATED, ZAPI_SRV6_SID_FAIL_ALLOC, ...) */ + stream_put(s, ¬e, sizeof(note)); + /* Context associated with the SRv6 SID */ + stream_put(s, ctx, sizeof(struct srv6_sid_ctx)); + /* SRv6 SID value (i.e. IPv6 address) */ + stream_put(s, sid_value, sizeof(struct in6_addr)); + /* SRv6 SID function */ + stream_putl(s, func); + /* SRv6 wide SID function */ + stream_putl(s, wide_func); + stream_putw_at(s, 0, stream_get_endp(s)); + + zserv_send_message(client, s); +} + /* Router-id is updated. Send ZEBRA_ROUTER_ID_UPDATE to client. */ int zsend_router_id_update(struct zserv *client, afi_t afi, struct prefix *p, diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index c7123e2593..3505bc0dc4 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -94,6 +94,11 @@ extern int zsend_sr_policy_notify_status(uint32_t color, extern void zsend_neighbor_notify(int cmd, struct interface *ifp, struct ipaddr *ipaddr, int ndm_state, union sockunion *link_layer_ipv4, int ip_len); +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, + enum zapi_srv6_sid_notify note); extern int zsend_client_close_notify(struct zserv *client, struct zserv *closed_client); diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index d93f09f1b4..663afa2f85 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -2279,6 +2279,8 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, const char *locator_name) { int ret = -1; + struct listnode *node; + struct zserv *c; char buf[256]; if (IS_ZEBRA_DEBUG_PACKET) @@ -2291,6 +2293,10 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, zlog_warn("%s: not got SRv6 SID for ctx %s, sid_value=%pI6, locator_name=%s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value, locator_name); + + /* Notify client about SID alloc failure */ + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + ZAPI_SRV6_SID_FAIL_ALLOC); } else if (ret == 0) { if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: got existing SRv6 SID for ctx %s: sid_value=%pI6 (func=%u) (proto=%u, instance=%u, sessionId=%u), notify client", @@ -2300,6 +2306,10 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, client->instance, client->session_id); if (!listnode_lookup((*sid)->client_list, client)) listnode_add((*sid)->client_list, client); + + zsend_srv6_sid_notify(client, ctx, &(*sid)->value, (*sid)->func, + (*sid)->wide_func, + ZAPI_SRV6_SID_ALLOCATED); } else { if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: got new SRv6 SID for ctx %s: sid_value=%pI6 (func=%u) (proto=%u, instance=%u, sessionId=%u), notifying all clients", @@ -2309,6 +2319,11 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, client->instance, client->session_id); if (!listnode_lookup((*sid)->client_list, client)) listnode_add((*sid)->client_list, client); + + for (ALL_LIST_ELEMENTS_RO((*sid)->client_list, node, c)) + zsend_srv6_sid_notify(c, ctx, &(*sid)->value, + (*sid)->func, (*sid)->wide_func, + ZAPI_SRV6_SID_ALLOCATED); } return ret; @@ -2382,6 +2397,13 @@ static int srv6_manager_release_sid_internal(struct zserv *client, zlog_debug("%s: no SID associated with ctx %s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + if (ret == 0) + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + ZAPI_SRV6_SID_RELEASED); + else + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + ZAPI_SRV6_SID_FAIL_RELEASE); + return ret; } -- 2.39.5