From 45add4c5913f84e1485ac08c09afa95d9aa73682 Mon Sep 17 00:00:00 2001 From: Eric Li Date: Mon, 2 Nov 2026 18:03:09 -0500 Subject: [PATCH] fix(config): print the prefix in duplicate prefix errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously if 2 clients both get the same prefix, the error printed is mangled: router foo has duplicate prefix {%!s(*state.StaticPrefixHealth=&{{{{0 2814…} 33} 0})}. This fixes it to router foo has duplicate prefix 10.0.0.1/32 --- state/validation.go | 4 ++-- state/validation_test.go | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/state/validation.go b/state/validation.go index 3836fffd..9bb912da 100644 --- a/state/validation.go +++ b/state/validation.go @@ -120,7 +120,7 @@ func CentralConfigValidator(cfg *CentralCfg) error { routerPrefixes := make(map[netip.Prefix]struct{}) for _, p := range router.Prefixes { if _, ok := routerPrefixes[p.GetPrefix()]; ok { - return fmt.Errorf("router %s has duplicate prefix %s", router.Id, p) + return fmt.Errorf("router %s has duplicate prefix %s", router.Id, p.GetPrefix()) } routerPrefixes[p.GetPrefix()] = struct{}{} } @@ -129,7 +129,7 @@ func CentralConfigValidator(cfg *CentralCfg) error { client := cfg.GetClient(peer) for _, cp := range client.Prefixes { if _, ok := routerPrefixes[cp.GetPrefix()]; ok { - return fmt.Errorf("router %s has duplicate prefix %s (provided by client %s)", router.Id, cp, client.Id) + return fmt.Errorf("router %s has duplicate prefix %s (provided by client %s)", router.Id, cp.GetPrefix(), client.Id) } routerPrefixes[cp.GetPrefix()] = struct{}{} } diff --git a/state/validation_test.go b/state/validation_test.go index 41fea72f..fadcac48 100644 --- a/state/validation_test.go +++ b/state/validation_test.go @@ -244,3 +244,21 @@ func TestCentralConfigValidator_AnycastPrefix(t *testing.T) { } assert.NoError(t, CentralConfigValidator(cfg)) } + +func TestCentralConfigValidator_DuplicatePrefixMessage(t *testing.T) { + prefix := PrefixHealthWrapper{&StaticPrefixHealth{Prefix: netip.MustParsePrefix("10.5.0.0/24")}} + cfg := CentralCfg{Routers: []RouterCfg{{NodeCfg: NodeCfg{Id: "r1", Prefixes: []PrefixHealthWrapper{prefix, prefix}}}}} + assert.EqualError(t, CentralConfigValidator(&cfg), "router r1 has duplicate prefix 10.5.0.0/24") + + addr := []netip.Addr{netip.MustParseAddr("10.0.0.5")} + cfg = CentralCfg{ + Routers: []RouterCfg{{NodeCfg: NodeCfg{Id: "r1"}}}, + Clients: []ClientCfg{ + {NodeCfg: NodeCfg{Id: "phone", Addresses: addr}}, + {NodeCfg: NodeCfg{Id: "laptop", Addresses: addr}}, + }, + Graph: []string{"r1, phone, laptop"}, + } + ExpandCentralConfig(&cfg) + assert.ErrorContains(t, CentralConfigValidator(&cfg), "router r1 has duplicate prefix 10.0.0.5/32 (provided by client") +}