summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
authorCarmine Scarpitta <cscarpit@cisco.com>2025-02-13 11:01:11 +0100
committerCarmine Scarpitta <cscarpit@cisco.com>2025-02-26 07:19:51 +0100
commitec5ff367b120e67c9e7bd87ffa8baa2334e75628 (patch)
tree5ffc3ba9960fba1c33ffbeb44cc61743c41154b3 /zebra
parent646c4f95d9aa978558757df58d013e78f0c50363 (diff)
staticd: Extend `static_zebra_request_srv6_sid` to request SRv6 uA SIDs
In order to configure an SRv6 uA SID in staticd, staticd should request SRv6 SID Manager to allocate a SID bound to the uA behavior. Currently, `static_zebra_request_srv6_sid` does not support requesting SIDs bound to the uA behavior. This commit extends the `static_zebra_request_srv6_sid` function to enable staticd to request SIDs bound to the uA behavior. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Diffstat (limited to 'zebra')
-rw-r--r--zebra/zebra_srv6.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c
index 6d228c5e24..51efcceb75 100644
--- a/zebra/zebra_srv6.c
+++ b/zebra/zebra_srv6.c
@@ -18,6 +18,7 @@
#include "zebra/zebra_srv6.h"
#include "zebra/zebra_errors.h"
#include "zebra/ge_netlink.h"
+#include "zebra/interface.h"
#include <stdio.h>
#include <string.h>
@@ -1745,6 +1746,13 @@ int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx,
int ret = -1;
struct srv6_locator *locator;
char buf[256];
+ struct nhg_connected *rb_node_dep = NULL;
+ struct listnode *node;
+ struct nexthop *nexthop;
+ struct nbr_connected *nc;
+ bool found = false;
+ struct interface *ifp;
+ struct zebra_if *zebra_if;
enum srv6_sid_alloc_mode alloc_mode =
(sid_value) ? SRV6_SID_ALLOC_MODE_EXPLICIT
@@ -1755,6 +1763,44 @@ int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx,
__func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx),
sid_value, srv6_sid_alloc_mode2str(alloc_mode));
+ if (ctx->ifindex != 0 && IPV6_ADDR_SAME(&ctx->nh6, &in6addr_any)) {
+ ifp = if_lookup_by_index(ctx->ifindex, VRF_DEFAULT);
+ if (!ifp) {
+ zlog_err("%s: interface %u does not exist", __func__, ctx->ifindex);
+ return -1;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nc))
+ if (nc->address && nc->address->family == AF_INET6 &&
+ IN6_IS_ADDR_LINKLOCAL(&nc->address->u.prefix6)) {
+ ctx->nh6 = nc->address->u.prefix6;
+ found = true;
+ break;
+ }
+
+ if (!found) {
+ zebra_if = ifp->info;
+
+ frr_each (nhg_connected_tree, &zebra_if->nhg_dependents, rb_node_dep) {
+ for (ALL_NEXTHOPS(rb_node_dep->nhe->nhg, nexthop)) {
+ /* skip non link-local addresses */
+ if (!IPV6_ADDR_SAME(&nexthop->gate.ipv6, &in6addr_any)) {
+ ctx->nh6 = nexthop->gate.ipv6;
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (!found) {
+ zlog_err("%s: cannot get SID, interface (ifindex %u) not found",
+ __func__, ctx->ifindex);
+ return -1;
+ }
+ }
+ }
+
if (alloc_mode == SRV6_SID_ALLOC_MODE_EXPLICIT) {
/*
* Explicit SID allocation: allocate a specific SID value