]> git.puffer.fish Git - mirror/frr.git/commitdiff
staticd: Avoid requesting SRv6 sid from zebra when loc and sid block dont match 18580/head
authorRajasekar Raja <rajasekarr@nvidia.com>
Fri, 4 Apr 2025 20:27:03 +0000 (13:27 -0700)
committerRajasekar Raja <rajasekarr@nvidia.com>
Mon, 7 Apr 2025 17:34:07 +0000 (10:34 -0700)
Currently, when the locator block and sid block differs, staticd would
still go ahead and request zebra to allocate the SID which it does if
there is atleast one match (from any locators).

Only when staticd tries to install the route, it sees that the locator
block and sid block are different and avoids installing the route.

Fix:
Check if the locator block and sid block match before even requesting
Zebra to allocate one.

Signed-off-by: Rajasekar Raja <rajasekarr@nvidia.com>
staticd/static_zebra.c
tests/topotests/static_srv6_sids/test_static_srv6_sids.py

index 3ed525f386fd6159407e5c47bbfd7d9a5ec38a35..e3b646a39290b3cdbcbcdc8797b40b66ae00d77c 100644 (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` */
index 1ea94c8c070c4c793deeeebbaa98a8637be1d76b..abf49df046b49306ca06f3fb3e1a18365ccf4c65 100755 (executable)
@@ -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