]> git.puffer.fish Git - mirror/frr.git/commitdiff
staticd: Fix SRv6 SID installation and deletion
authorCarmine Scarpitta <cscarpit@cisco.com>
Fri, 7 Feb 2025 16:47:45 +0000 (17:47 +0100)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Thu, 13 Feb 2025 18:38:16 +0000 (18:38 +0000)
The SRv6 support in staticd (PR #16894) does not set the correct SID
parameters (block length, node length, function length).

This commit fixes the issue and computes the correct parameters.

Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
(cherry picked from commit e1654ba5548625981d2b9ff580b2fb6e2ae9d5dc)

staticd/static_zebra.c

index 6da2dfec90853ea30d85ea7f2931c4f1349077bf..9a794d4d02cc54f587eab0277307fd1d6b160547 100644 (file)
@@ -615,6 +615,9 @@ 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)
                return;
@@ -696,10 +699,30 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid)
                break;
        }
 
-       ctx.block_len = sid->locator->block_bits_length;
-       ctx.node_len = sid->locator->node_bits_length;
-       ctx.function_len = sid->locator->function_bits_length;
-       ctx.argument_len = sid->locator->argument_bits_length;
+       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;
+       }
+
+       sid_locator = sid->addr;
+       sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length;
+       apply_mask(&sid_locator);
+
+       if (prefix_same(&sid_locator, &sid->locator->prefix))
+               ctx.node_len = sid->locator->node_bits_length;
+
+       ctx.function_len = sid->addr.prefixlen - (ctx.block_len + ctx.node_len);
 
        /* Attach the SID to the SRv6 interface */
        if (!ifp) {
@@ -724,6 +747,9 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)
        struct interface *ifp = NULL;
        struct seg6local_context ctx = {};
        struct vrf *vrf;
+       struct prefix_ipv6 sid_block = {};
+       struct prefix_ipv6 locator_block = {};
+       struct prefix_ipv6 sid_locator = {};
 
        if (!sid)
                return;
@@ -803,10 +829,30 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)
                }
        }
 
-       ctx.block_len = sid->locator->block_bits_length;
-       ctx.node_len = sid->locator->node_bits_length;
-       ctx.function_len = sid->locator->function_bits_length;
-       ctx.argument_len = sid->locator->argument_bits_length;
+       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;
+       }
+
+       sid_locator = sid->addr;
+       sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length;
+       apply_mask(&sid_locator);
+
+       if (prefix_same(&sid_locator, &sid->locator->prefix))
+               ctx.node_len = sid->locator->node_bits_length;
+
+       ctx.function_len = sid->addr.prefixlen - (ctx.block_len + ctx.node_len);
 
        static_zebra_send_localsid(ZEBRA_ROUTE_DELETE, &sid->addr.prefix, sid->addr.prefixlen,
                                   ifp->ifindex, action, &ctx);