diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 3ed525f386..e3b646a392 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -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` */ diff --git a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py index 1ea94c8c07..abf49df046 100755 --- a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py +++ b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py @@ -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