From b3c90ae2e860b2b1d3fae242cd699612f17d0328 Mon Sep 17 00:00:00 2001 From: Tim Rozet Date: Mon, 28 Oct 2024 16:24:06 -0400 Subject: [PATCH] Only configure IPv6 RAs when ipv6 mode enabled Without this fix, ovn-controller would spam: 2024-10-28T16:58:44.283Z|04438|pinctrl|WARN|Invalid IPv6 prefixes: Signed-off-by: Tim Rozet --- go-controller/pkg/ovn/gateway.go | 2 +- go-controller/pkg/ovn/multihoming_test.go | 2 +- ...econdary_layer2_network_controller_test.go | 50 ++++++++++++------- ...econdary_layer3_network_controller_test.go | 48 ++++++++++-------- 4 files changed, 62 insertions(+), 40 deletions(-) diff --git a/go-controller/pkg/ovn/gateway.go b/go-controller/pkg/ovn/gateway.go index ea244082d1..8a5615ac78 100644 --- a/go-controller/pkg/ovn/gateway.go +++ b/go-controller/pkg/ovn/gateway.go @@ -403,7 +403,7 @@ func (gw *GatewayManager) GatewayInit( types.NetworkExternalID: gw.netInfo.GetNetworkName(), types.TopologyExternalID: gw.netInfo.TopologyType(), } - if gw.netInfo.IsPrimaryNetwork() && gw.netInfo.TopologyType() == types.Layer2Topology { + if gw.netInfo.IsPrimaryNetwork() && gw.netInfo.TopologyType() == types.Layer2Topology && config.IPv6Mode { logicalRouterPort.Ipv6RaConfigs = map[string]string{ "address_mode": "dhcpv6_stateful", "send_periodic": "true", diff --git a/go-controller/pkg/ovn/multihoming_test.go b/go-controller/pkg/ovn/multihoming_test.go index a625e284ad..1637b55d8d 100644 --- a/go-controller/pkg/ovn/multihoming_test.go +++ b/go-controller/pkg/ovn/multihoming_test.go @@ -463,7 +463,7 @@ func dummyOVNPodNetworkAnnotationForNetwork(portInfo portInfo, netConfig seconda role = ovntypes.NetworkRolePrimary } var gateways []string - for _, subnetStr := range strings.Split(netConfig.clustersubnets, ",") { + for _, subnetStr := range strings.Split(netConfig.clustersubnet, ",") { subnet := testing.MustParseIPNet(subnetStr) gateways = append(gateways, util.GetNodeGatewayIfAddr(subnet).IP.String()) } diff --git a/go-controller/pkg/ovn/secondary_layer2_network_controller_test.go b/go-controller/pkg/ovn/secondary_layer2_network_controller_test.go index cd328b5de0..70f89bff35 100644 --- a/go-controller/pkg/ovn/secondary_layer2_network_controller_test.go +++ b/go-controller/pkg/ovn/secondary_layer2_network_controller_test.go @@ -15,6 +15,7 @@ import ( nadapi "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + net2 "k8s.io/utils/net" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/nbdb" @@ -64,6 +65,11 @@ var _ = Describe("OVN Multi-Homed pod operations for layer2 network", func() { } } config.Gateway.Mode = gatewayMode + if net2.IsIPv6CIDRString(netInfo.clustersubnet) { + config.IPv6Mode = true + // tests dont support dualstack yet + config.IPv4Mode = false + } app.Action = func(ctx *cli.Context) error { By(fmt.Sprintf("creating a network attachment definition for network: %s", netInfo.netName)) nad, err := newNetworkAttachmentDefinition( @@ -206,6 +212,13 @@ var _ = Describe("OVN Multi-Homed pod operations for layer2 network", func() { icClusterWithDisableSNATTestConfiguration(), config.GatewayModeShared, ), + /** FIXME: tests do not support ipv6 yet + Entry("pod on a IPv6 user defined primary network on an IC cluster with per-pod SNATs enabled", + dummyPrimaryLayer2UserDefinedNetwork("2001:db8:abcd:0012::/64"), + icClusterWithDisableSNATTestConfiguration(), + config.GatewayModeShared, + ), + */ ) DescribeTable( @@ -332,10 +345,10 @@ var _ = Describe("OVN Multi-Homed pod operations for layer2 network", func() { func dummySecondaryLayer2UserDefinedNetwork(subnets string) secondaryNetInfo { return secondaryNetInfo{ - netName: secondaryNetworkName, - nadName: namespacedName(ns, nadName), - topology: ovntypes.Layer2Topology, - clustersubnets: subnets, + netName: secondaryNetworkName, + nadName: namespacedName(ns, nadName), + topology: ovntypes.Layer2Topology, + clustersubnet: subnets, } } @@ -364,7 +377,7 @@ func dummyL2TestPod(nsName string, info secondaryNetInfo) testPod { pod.addNetwork( info.netName, info.nadName, - info.clustersubnets, + info.clustersubnet, "", "100.200.0.1", "100.200.0.3/16", @@ -388,7 +401,7 @@ func dummyL2TestPod(nsName string, info secondaryNetInfo) testPod { pod.addNetwork( info.netName, info.nadName, - info.clustersubnets, + info.clustersubnet, "", "", "100.200.0.1/16", @@ -478,13 +491,16 @@ func expectedLayer2EgressEntities(netInfo util.NetInfo, gwConfig util.L3GatewayC func expectedGWToNetworkSwitchRouterPort(name string, netInfo util.NetInfo, networks ...*net.IPNet) *nbdb.LogicalRouterPort { options := map[string]string{"gateway_mtu": fmt.Sprintf("%d", 1400)} lrp := expectedLogicalRouterPort(name, netInfo, options, networks...) - lrp.Ipv6RaConfigs = map[string]string{ - "address_mode": "dhcpv6_stateful", - "mtu": "1400", - "send_periodic": "true", - "max_interval": "900", - "min_interval": "300", - "router_preference": "LOW", + + if config.IPv6Mode { + lrp.Ipv6RaConfigs = map[string]string{ + "address_mode": "dhcpv6_stateful", + "mtu": "1400", + "send_periodic": "true", + "max_interval": "900", + "min_interval": "300", + "router_preference": "LOW", + } } return lrp } @@ -519,10 +535,10 @@ func ipv4DefaultRoute() *net.IPNet { func dummyLayer2SecondaryUserDefinedNetwork(subnets string) secondaryNetInfo { return secondaryNetInfo{ - netName: secondaryNetworkName, - nadName: namespacedName(ns, nadName), - topology: ovntypes.Layer2Topology, - clustersubnets: subnets, + netName: secondaryNetworkName, + nadName: namespacedName(ns, nadName), + topology: ovntypes.Layer2Topology, + clustersubnet: subnets, } } diff --git a/go-controller/pkg/ovn/secondary_layer3_network_controller_test.go b/go-controller/pkg/ovn/secondary_layer3_network_controller_test.go index 49aa22d396..f7538cd57b 100644 --- a/go-controller/pkg/ovn/secondary_layer3_network_controller_test.go +++ b/go-controller/pkg/ovn/secondary_layer3_network_controller_test.go @@ -16,6 +16,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + net2 "k8s.io/utils/net" "k8s.io/utils/ptr" nadapi "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" @@ -34,12 +35,12 @@ import ( ) type secondaryNetInfo struct { - netName string - nadName string - clustersubnets string - hostsubnets string // not used in layer2 tests - topology string - isPrimary bool + netName string + nadName string + clustersubnet string + hostsubnet string // not used in layer2 tests + topology string + isPrimary bool } const ( @@ -97,6 +98,11 @@ var _ = Describe("OVN Multi-Homed pod operations", func() { } } config.Gateway.Mode = gwMode + if net2.IsIPv6CIDRString(netInfo.clustersubnet) { + config.IPv6Mode = true + // tests dont support dualstack yet + config.IPv4Mode = false + } app.Action = func(ctx *cli.Context) error { nad, err := newNetworkAttachmentDefinition( ns, @@ -281,10 +287,10 @@ var _ = Describe("OVN Multi-Homed pod operations", func() { Expect(err).NotTo(HaveOccurred()) initialDB.NBData = append( initialDB.NBData, - expectedGWEntities(podInfo.nodeName, netInfo.hostsubnets, networkConfig, *gwConfig)...) + expectedGWEntities(podInfo.nodeName, netInfo.hostsubnet, networkConfig, *gwConfig)...) initialDB.NBData = append( initialDB.NBData, - expectedLayer3EgressEntities(networkConfig, *gwConfig, ovntest.MustParseIPNet(netInfo.hostsubnets))...) + expectedLayer3EgressEntities(networkConfig, *gwConfig, ovntest.MustParseIPNet(netInfo.hostsubnet))...) } initialDB.NBData = append(initialDB.NBData, nbZone) @@ -388,7 +394,7 @@ func newPodWithPrimaryUDN( pod.addNetwork( primaryUDNConfig.netName, primaryUDNConfig.nadName, - primaryUDNConfig.hostsubnets, + primaryUDNConfig.hostsubnet, "", nodeGWIP, "192.168.1.3/24", @@ -472,7 +478,7 @@ func (sni *secondaryNetInfo) netconf() *ovncnitypes.NetConf { }, Topology: sni.topology, NADName: sni.nadName, - Subnets: sni.clustersubnets, + Subnets: sni.clustersubnet, Role: role, } } @@ -496,7 +502,7 @@ func dummyTestPod(nsName string, info secondaryNetInfo) testPod { pod.addNetwork( info.netName, info.nadName, - info.hostsubnets, + info.hostsubnet, "", "", "192.168.1.3/24", @@ -505,7 +511,7 @@ func dummyTestPod(nsName string, info secondaryNetInfo) testPod { 0, []util.PodRoute{ { - Dest: testing.MustParseIPNet(info.clustersubnets), + Dest: testing.MustParseIPNet(info.clustersubnet), NextHop: testing.MustParseIP("192.168.1.1"), }, }, @@ -518,25 +524,25 @@ func dummyTestPodAdditionalNetworkIP() string { return dummyTestPod(ns, secNetInfo).getNetworkPortInfo(secNetInfo.netName, secNetInfo.nadName).podIP } -func dummySecondaryLayer3UserDefinedNetwork(clustersubnets, hostsubnets string) secondaryNetInfo { +func dummySecondaryLayer3UserDefinedNetwork(clustersubnet, hostsubnet string) secondaryNetInfo { return secondaryNetInfo{ - netName: secondaryNetworkName, - nadName: namespacedName(ns, nadName), - topology: ovntypes.Layer3Topology, - clustersubnets: clustersubnets, - hostsubnets: hostsubnets, + netName: secondaryNetworkName, + nadName: namespacedName(ns, nadName), + topology: ovntypes.Layer3Topology, + clustersubnet: clustersubnet, + hostsubnet: hostsubnet, } } -func dummyPrimaryLayer3UserDefinedNetwork(clustersubnets, hostsubnets string) secondaryNetInfo { - secondaryNet := dummySecondaryLayer3UserDefinedNetwork(clustersubnets, hostsubnets) +func dummyPrimaryLayer3UserDefinedNetwork(clustersubnet, hostsubnet string) secondaryNetInfo { + secondaryNet := dummySecondaryLayer3UserDefinedNetwork(clustersubnet, hostsubnet) secondaryNet.isPrimary = true return secondaryNet } // This util is returning a network-name/hostSubnet for the node's node-subnets annotation func (sni *secondaryNetInfo) String() string { - return fmt.Sprintf("%q: %q", sni.netName, sni.hostsubnets) + return fmt.Sprintf("%q: %q", sni.netName, sni.hostsubnet) } func newNodeWithSecondaryNets(nodeName string, nodeIPv4CIDR string, netInfos ...secondaryNetInfo) (*v1.Node, error) {