]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Notify daemons about SIDs
authorCarmine Scarpitta <cscarpit@cisco.com>
Thu, 2 May 2024 11:39:49 +0000 (13:39 +0200)
committerCarmine Scarpitta <cscarpit@cisco.com>
Thu, 13 Jun 2024 12:54:16 +0000 (14:54 +0200)
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 <cscarpit@cisco.com>
zebra/zapi_msg.c
zebra/zapi_msg.h
zebra/zebra_srv6.c

index bab4c4fa3d7489603d121e58b044d36c7fb8eef7..164c0dd6872398929fe473005166123c5702b5ba 100644 (file)
@@ -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, &note, 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,
index c7123e2593f2a78204852b2b8ef39e6b97ef9717..3505bc0dc4e3ca93b1e5e71a6d7393b518ee3e6c 100644 (file)
@@ -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);
index d93f09f1b4fd225bb8f9f5fa52fa8a38260f8c3c..663afa2f855d203af54aec1357a4473131b8e557 100644 (file)
@@ -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;
 }