Commit db6e6da526 for frr
commit db6e6da526e810c8fc76a3fdcda8a0a7c0025a44
Author: Andreas Karis <ak.karis@gmail.com>
Date: Thu Sep 17 00:31:58 2026 +0200
zebra: skip writing empty SRv6 locator prefix in config output
The config writer unconditionally outputs the prefix line for every
locator in srv6->locators. When a prefix is removed via "no prefix",
no_locator_prefix zeroes the prefix but leaves the locator in the
list, causing the config to display:
prefix ::/0 block-len 0 node-len 0 func-bits 0
This was a pre-existing issue, but the previous commit (adding the
locator to srv6->locators immediately on allocation) exacerbates it:
locators now appear in the list before a prefix is ever configured,
so the zeroed prefix is also output for newly created locators that
have not yet had their prefix set.
Fix by guarding the prefix output with a check against in6addr_any.
Reported-at: https://github.com/FRRouting/frr/issues/23387
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Andreas Karis <ak.karis@gmail.com>
diff --git a/lib/srv6.h b/lib/srv6.h
index d906d78e16..dedee8e394 100644
--- a/lib/srv6.h
+++ b/lib/srv6.h
@@ -166,6 +166,10 @@ struct srv6_locator {
};
DECLARE_QOBJ_TYPE(srv6_locator);
+#define SRV6_LOCATOR_PREFIX_IS_SET(loc) \
+ (!IPV6_ADDR_SAME(&(loc)->prefix.prefix, &in6addr_any) || (loc)->prefix.prefixlen || \
+ (loc)->block_bits_length || (loc)->node_bits_length || (loc)->function_bits_length)
+
struct srv6_locator_chunk {
char locator_name[SRV6_LOCNAME_SIZE];
struct prefix_ipv6 prefix;
diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c
index da2af776f3..f9ad786b66 100644
--- a/zebra/zebra_srv6_vty.c
+++ b/zebra/zebra_srv6_vty.c
@@ -1652,22 +1652,22 @@ static int zebra_sr_config(struct vty *vty)
vty_out(vty, " locators\n");
for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
vty_out(vty, " locator %s\n", locator->name);
- vty_out(vty, " prefix %pFX", &locator->prefix);
- if (locator->block_bits_length !=
- locator->prefix.prefixlen - ZEBRA_SRV6_LOCATOR_NODE_LENGTH)
- vty_out(vty, " block-len %u",
- locator->block_bits_length);
- if (locator->node_bits_length != ZEBRA_SRV6_LOCATOR_NODE_LENGTH)
- vty_out(vty, " node-len %u",
- locator->node_bits_length);
-
- if (locator->function_bits_length != ZEBRA_SRV6_FUNCTION_LENGTH)
- vty_out(vty, " func-bits %u", locator->function_bits_length);
-
- if (locator->argument_bits_length)
- vty_out(vty, " arg-len %u",
- locator->argument_bits_length);
- vty_out(vty, "\n");
+ if (SRV6_LOCATOR_PREFIX_IS_SET(locator)) {
+ vty_out(vty, " prefix %pFX", &locator->prefix);
+ if (locator->block_bits_length !=
+ locator->prefix.prefixlen - ZEBRA_SRV6_LOCATOR_NODE_LENGTH)
+ vty_out(vty, " block-len %u", locator->block_bits_length);
+ if (locator->node_bits_length != ZEBRA_SRV6_LOCATOR_NODE_LENGTH)
+ vty_out(vty, " node-len %u", locator->node_bits_length);
+
+ if (locator->function_bits_length != ZEBRA_SRV6_FUNCTION_LENGTH)
+ vty_out(vty, " func-bits %u",
+ locator->function_bits_length);
+
+ if (locator->argument_bits_length)
+ vty_out(vty, " arg-len %u", locator->argument_bits_length);
+ vty_out(vty, "\n");
+ }
if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID))
vty_out(vty, " behavior usid\n");
if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_PSP))