From ec5ff367b120e67c9e7bd87ffa8baa2334e75628 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 13 Feb 2025 11:01:11 +0100 Subject: [PATCH] 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 --- staticd/static_zebra.c | 16 ++++++++++++++- zebra/zebra_srv6.c | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 552dd3ee1f..d3ff5ee45f 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -890,6 +890,7 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) struct srv6_sid_ctx ctx = {}; int ret = 0; struct vrf *vrf; + struct interface *ifp; if (!sid) return; @@ -940,13 +941,23 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid) ctx.vrf_id = vrf->vrf_id; } + break; + case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID: + ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END_X; + ctx.nh6 = sid->attributes.nh6; + ifp = if_lookup_by_name(sid->attributes.ifname, VRF_DEFAULT); + if (!ifp) { + zlog_warn("Failed to request SRv6 SID %pFX: interface %s does not exist", + &sid->addr, sid->attributes.ifname); + return; + } + ctx.ifindex = ifp->ifindex; break; case SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_END_X: case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD: - case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP: case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD: case SRV6_ENDPOINT_BEHAVIOR_OPAQUE: @@ -1240,6 +1251,9 @@ static int static_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS) return 0; } + if (!IPV6_ADDR_SAME(&ctx.nh6, &in6addr_any)) + sid->attributes.nh6 = ctx.nh6; + SET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID); /* 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 #include @@ -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 -- 2.39.5