Commit 464b7a9ca4 for frr
commit 464b7a9ca4fef47e57a2504c80b4645e82c36464
Author: Carmine Scarpitta <cscarpit@cisco.com>
Date: Mon Oct 19 11:13:38 2026 +0200
staticd: Release uDT SIDs when VRFs go down
Create a Linux VRF and bring it up:
ip link add Vrf30 type vrf table 30
ip link set dev Vrf30 up
Configure a uDT46 SID for Vrf30:
configure terminal
segment-routing
srv6
static-sids
sid fcbb:bbbb:1:fe30::/64 locator MAIN behavior uDT46 vrf Vrf30
staticd allocates the SID for Vrf30. The `show segment-routing srv6 sid`
command shows the SID with `VRF 'Vrf30'` as its context:
r1# show segment-routing srv6 sid
SID Behavior Context Daemon/Instance Locator AllocationType
------------------------------ --------------- ----------------- --------- ---------------
fcbb:bbbb:1:fe30:: End.DT46 VRF 'Vrf30' static(0) MAIN explicit
Delete the VRF:
ip link del Vrf30
The SID is not deallocated. It remains allocated against the old Vrf30, which
no longer exists. The command still lists the SID, but its context is now
`VRF '<unknown>'`:
r1# show segment-routing srv6 sid
SID Behavior Context Daemon/Instance Locator AllocationType
------------------------------ ----------------- ----------------- --------- ---------------
fcbb:bbbb:1:fe30:: End.DT46 VRF '<unknown>' static(0) MAIN explicit
Fix this by releasing the SID when staticd receives the Vrf30 down event.
When the VRF is recreated, existing staticd logic requests and installs the
SID again for the new VRF.
Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
diff --git a/staticd/static_srv6.c b/staticd/static_srv6.c
index 377802d1ec..f70d680e60 100644
--- a/staticd/static_srv6.c
+++ b/staticd/static_srv6.c
@@ -39,6 +39,19 @@ DECLARE_HASH(static_srv6_neigh_table, struct static_srv6_if_neigh, item,
/* Global neighbor cache instance */
struct static_srv6_neigh_cache *neigh_cache;
+static bool is_udt_sid(const struct static_srv6_sid *sid)
+{
+ if (sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT6 ||
+ sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID ||
+ sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT4 ||
+ sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID ||
+ sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT46 ||
+ sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID)
+ return true;
+ else
+ return false;
+}
+
/*
* Determines if the specified SID needs to be installed or removed
* due to a state change (up/down) on the provided interface.
@@ -50,14 +63,6 @@ struct static_srv6_neigh_cache *neigh_cache;
*/
static bool is_sid_update_required(struct interface *ifp, struct static_srv6_sid *sid)
{
- /* Check if the SID's behavior is one of the uDT* variants. */
- bool is_udt = (sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT6 ||
- sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID ||
- sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT4 ||
- sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID ||
- sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT46 ||
- sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID);
-
/* Check if the SID's behavior is one of the uDT4/uDT46 variants. */
bool is_udt4_or_udt46 = (sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT4 ||
sid->behavior == SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID ||
@@ -92,7 +97,7 @@ static bool is_sid_update_required(struct interface *ifp, struct static_srv6_sid
return true;
}
- if (is_udt) {
+ if (is_udt_sid(sid)) {
/*
* 3a. SID is uDT*. uDT* SIDs are associated with a VRF interface defined in their attributes.
* Therefore, an update is needed if the provided interface 'ifp' matches the SID's associated VRF.
@@ -166,6 +171,12 @@ void static_ifp_srv6_sids_update(struct interface *ifp, bool is_up)
if (needs_install)
static_zebra_srv6_sid_install(sid);
} else {
+ if (is_udt_sid(sid) && strmatch(sid->attributes.vrf_name, ifp->name) &&
+ CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID)) {
+ static_zebra_release_srv6_sid(sid);
+ UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID);
+ }
+
static_zebra_srv6_sid_uninstall(sid);
}
}