Merge pull request #18580 from raja-rajasekar/rajasekarr/check_sid_loc_block_beforehand

staticd: Avoid requesting SRv6 sid from zebra when loc and sid block dont match
This commit is contained in:
Carmine Scarpitta 2025-04-08 14:53:26 +02:00 committed by GitHub
commit 46a526568f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 56 additions and 19 deletions

View file

@ -625,8 +625,6 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid)
struct seg6local_context ctx = {};
struct interface *ifp = NULL;
struct vrf *vrf;
struct prefix_ipv6 sid_block = {};
struct prefix_ipv6 locator_block = {};
struct prefix_ipv6 sid_locator = {};
if (!sid)
@ -738,22 +736,7 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid)
break;
}
sid_block = sid->addr;
sid_block.prefixlen = sid->locator->block_bits_length;
apply_mask(&sid_block);
locator_block = sid->locator->prefix;
locator_block.prefixlen = sid->locator->block_bits_length;
apply_mask(&locator_block);
if (prefix_same(&sid_block, &locator_block))
ctx.block_len = sid->locator->block_bits_length;
else {
zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block,
&locator_block);
return;
}
ctx.block_len = sid->locator->block_bits_length;
sid_locator = sid->addr;
sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length;
apply_mask(&sid_locator);
@ -915,6 +898,30 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA);
}
/* Validate if the sid block and locator block are the same */
static bool static_zebra_sid_locator_block_check(struct static_srv6_sid *sid)
{
struct prefix_ipv6 sid_block = {};
struct prefix_ipv6 locator_block = {};
sid_block = sid->addr;
sid_block.prefixlen = sid->locator->block_bits_length;
apply_mask(&sid_block);
locator_block = sid->locator->prefix;
locator_block.prefixlen = sid->locator->block_bits_length;
apply_mask(&locator_block);
if (!prefix_same(&sid_block, &locator_block)) {
zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block,
&locator_block);
return false;
}
return true;
}
extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid)
{
struct srv6_sid_ctx ctx = {};
@ -922,7 +929,7 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid)
struct vrf *vrf;
struct interface *ifp;
if (!sid)
if (!sid || !static_zebra_sid_locator_block_check(sid))
return;
/* convert `srv6_endpoint_behavior_codepoint` to `seg6local_action_t` */

View file

@ -210,6 +210,36 @@ def test_srv6_static_sids_sid_modify():
check_srv6_static_sids(router, "expected_srv6_sids_sid_modify.json")
def test_srv6_static_sids_wrong_sid_block():
"""
The purpose of this test is to verify how FRR behaves when the user
provides an invalid configuration.
Add a new static Sid with a mismatch in locator and sid block
to make sure no Sid is allocated by zebra (TBD: Strict verify once show cmd
commit is merged (#16836))
"""
router = get_topogen().gears["r1"]
router.vtysh_cmd(
"""
configure terminal
segment-routing
srv6
locators
locator MAIN1
prefix fcbb:1234:1::/48 block-len 32 node-len 16 func-bits 16
srv6
static-sids
sid fcbb:bbbb:1:fe50::/64 locator MAIN1 behavior uA interface sr0 nexthop 2001::3
"""
)
output = json.loads(router.vtysh_cmd("show ipv6 route static json"))
if "fcbb:bbbb:1:fe50::/64" in output:
assert (
False
), "Failed. Expected no entry for fcbb:bbbb:1:fe50::/64 since loc and node block dont match"
def test_srv6_static_sids_sid_delete_all():
"""
Remove all static SIDs and verify they get removed