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>
This commit is contained in:
Carmine Scarpitta 2025-02-13 11:01:11 +01:00
parent 646c4f95d9
commit ec5ff367b1
2 changed files with 61 additions and 1 deletions

View File

@ -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);
/*

View File

@ -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