From 74b0e8c3713a01f83758556672583880ce5c684a Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 4 Nov 2024 13:49:34 +0400 Subject: [PATCH] fix: make route normalization keep family When we normalize the route with e.g. IPv6 all addresses (`::/0`), we were wiping the family information. Keep the information, and also fix the scope for such routes. Fixes #9624 Signed-off-by: Andrey Smirnov --- .../pkg/controllers/network/route_config.go | 4 +- pkg/machinery/resources/network/route_spec.go | 38 ++++++++++++++++--- .../resources/network/route_spec_test.go | 24 +++++++++++- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/internal/app/machined/pkg/controllers/network/route_config.go b/internal/app/machined/pkg/controllers/network/route_config.go index b819a71dc1..b9d768dbff 100644 --- a/internal/app/machined/pkg/controllers/network/route_config.go +++ b/internal/app/machined/pkg/controllers/network/route_config.go @@ -257,7 +257,7 @@ func (ctrl *RouteConfigController) processDevicesConfiguration(logger *zap.Logge } } - route.Normalize() + normalizedFamily := route.Normalize() route.Priority = in.Metric() if route.Priority == 0 { @@ -271,6 +271,8 @@ func (ctrl *RouteConfigController) processDevicesConfiguration(logger *zap.Logge route.Family = nethelpers.FamilyInet6 case !value.IsZero(route.Destination) && route.Destination.Addr().Is6(): route.Family = nethelpers.FamilyInet6 + case normalizedFamily != 0: + route.Family = normalizedFamily default: route.Family = nethelpers.FamilyInet4 } diff --git a/pkg/machinery/resources/network/route_spec.go b/pkg/machinery/resources/network/route_spec.go index a1375c3986..dbb7d8189d 100644 --- a/pkg/machinery/resources/network/route_spec.go +++ b/pkg/machinery/resources/network/route_spec.go @@ -48,28 +48,54 @@ var ( ) // Normalize converts 0.0.0.0 to zero value. -func (route *RouteSpecSpec) Normalize() { - if route.Destination.Bits() == 0 && (route.Destination.Addr().Compare(zero4) == 0 || route.Destination.Addr().Compare(zero16) == 0) { +// +//nolint:gocyclo +func (route *RouteSpecSpec) Normalize() nethelpers.Family { + var family nethelpers.Family + + if route.Destination.Bits() == 0 { // clear destination to be zero value to support "0.0.0.0/0" routes - route.Destination = netip.Prefix{} + if route.Destination.Addr().Compare(zero4) == 0 { + family = nethelpers.FamilyInet4 + route.Destination = netip.Prefix{} + } + + if route.Destination.Addr().Compare(zero16) == 0 { + family = nethelpers.FamilyInet6 + route.Destination = netip.Prefix{} + } + } + + if route.Gateway.Compare(zero4) == 0 { + family = nethelpers.FamilyInet4 + route.Gateway = netip.Addr{} } - if route.Gateway.Compare(zero4) == 0 || route.Gateway.Compare(zero16) == 0 { + if route.Gateway.Compare(zero16) == 0 { + family = nethelpers.FamilyInet6 route.Gateway = netip.Addr{} } - if route.Source.Compare(zero4) == 0 || route.Source.Compare(zero16) == 0 { + if route.Source.Compare(zero4) == 0 { + family = nethelpers.FamilyInet4 + route.Source = netip.Addr{} + } + + if route.Source.Compare(zero16) == 0 { + family = nethelpers.FamilyInet6 route.Source = netip.Addr{} } switch { - case value.IsZero(route.Gateway): + case value.IsZero(route.Gateway) && !value.IsZero(route.Destination): route.Scope = nethelpers.ScopeLink case route.Destination.Addr().IsLoopback(): route.Scope = nethelpers.ScopeHost default: route.Scope = nethelpers.ScopeGlobal } + + return family } // NewRouteSpec initializes a RouteSpec resource. diff --git a/pkg/machinery/resources/network/route_spec_test.go b/pkg/machinery/resources/network/route_spec_test.go index 1818c5810d..4e85c8b9a9 100644 --- a/pkg/machinery/resources/network/route_spec_test.go +++ b/pkg/machinery/resources/network/route_spec_test.go @@ -73,9 +73,31 @@ func TestRoutSpecNormalize(t *testing.T) { MTU: 1400, } - spec.Normalize() + normalizedFamily := spec.Normalize() assert.Equal(t, netip.Prefix{}, spec.Destination) assert.Equal(t, netip.Addr{}, spec.Source) assert.Equal(t, netip.Addr{}, spec.Gateway) + assert.Equal(t, nethelpers.FamilyInet4, normalizedFamily) + assert.Equal(t, nethelpers.ScopeGlobal, spec.Scope) +} + +func TestRoutSpecNormalizeV6(t *testing.T) { + spec := network.RouteSpecSpec{ + Family: nethelpers.FamilyInet4, + Destination: netip.MustParsePrefix("::/0"), + OutLinkName: "eth0", + Table: nethelpers.TableLocal, + Priority: 1024, + ConfigLayer: network.ConfigPlatform, + MTU: 1400, + } + + normalizedFamily := spec.Normalize() + + assert.Equal(t, netip.Prefix{}, spec.Destination) + assert.Equal(t, netip.Addr{}, spec.Source) + assert.Equal(t, netip.Addr{}, spec.Gateway) + assert.Equal(t, nethelpers.FamilyInet6, normalizedFamily) + assert.Equal(t, nethelpers.ScopeGlobal, spec.Scope) }