From 5b7f63470cb7a786206705dcbba1976e53a3732c Mon Sep 17 00:00:00 2001 From: Kabir Kwatra Date: Thu, 8 Jan 2026 16:00:14 -0800 Subject: [PATCH] Fix NLB IP version selection to respect service ipFamilies When ipFamilyPolicy is PreferDualStack, the getLbListenerBackendSetIpVersion function was incorrectly returning [IPv4, IPv6] based solely on subnet capabilities, ignoring the service's ipFamilies field. This caused issues when: - Service has ipFamilyPolicy: PreferDualStack - Service has ipFamilies: [IPv4] (explicitly IPv4-only) - Subnet supports dual-stack The CCM would create IPv6 listeners even though the service explicitly specifies IPv4-only via ipFamilies. The ipFamilies field is the authoritative specification of what IP families a service uses. The ipFamilyPolicy only influences how ipFamilies gets populated when not explicitly set. This fix ensures the CCM respects ipFamilies by only including IP versions that are both specified in ipFamilies AND supported by the subnet. --- .../providers/oci/load_balancer.go | 23 ++++++++++--------- .../providers/oci/load_balancer_test.go | 8 +++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pkg/cloudprovider/providers/oci/load_balancer.go b/pkg/cloudprovider/providers/oci/load_balancer.go index 4eba9aa4ae..a385afc9b7 100644 --- a/pkg/cloudprovider/providers/oci/load_balancer.go +++ b/pkg/cloudprovider/providers/oci/load_balancer.go @@ -2244,19 +2244,20 @@ func (cp *CloudProvider) getLbListenerBackendSetIpVersion(ipFamilies []string, i } return []string{IPv4, IPv6}, nil case string(v1.IPFamilyPolicyPreferDualStack): - if errIPv6Subnet != nil && errIPv4Subnet != nil { - // should never happen - return nil, errors.New("subnet does not have IPv4 or IPv6 cidr, can't create loadbalancer") + // ipFamilies is the authoritative source of what IP families the service uses. + // Only include IP versions that are in ipFamilies AND supported by the subnet. + var result []string + for _, ipFamily := range ipFamilies { + if ipFamily == IPv4 && errIPv4Subnet == nil { + result = append(result, IPv4) + } else if ipFamily == IPv6 && errIPv6Subnet == nil { + result = append(result, IPv6) + } } - if errIPv6Subnet != nil { - cp.logger.Warn("subnet provided does not have IPv6 subnet CIDR block, creating listeners and backends of ip-version IPv4") - return []string{IPv4}, nil + if len(result) == 0 { + return nil, errors.New("no compatible IP families between service spec and subnet capabilities") } - if errIPv4Subnet != nil { - cp.logger.Warn("subnet provided does not have IPV4 subnet CIDR block, creating listeners and backends of ip-version IPv6") - return []string{IPv6}, nil - } - return []string{IPv4, IPv6}, nil + return result, nil } return []string{IPv4}, nil } diff --git a/pkg/cloudprovider/providers/oci/load_balancer_test.go b/pkg/cloudprovider/providers/oci/load_balancer_test.go index a2879062ff..3ac29dee2d 100644 --- a/pkg/cloudprovider/providers/oci/load_balancer_test.go +++ b/pkg/cloudprovider/providers/oci/load_balancer_test.go @@ -1781,7 +1781,7 @@ func Test_getLbListenerBackendSetIpVersion(t *testing.T) { listenerBackendSetIpVersions: []string{IPv4}, wantErr: nil, }, - "PreferDualStack IPv4": { + "PreferDualStack IPv4 - ipFamilies takes precedence over subnet capabilities": { ipFamilies: []string{IPv4}, ipFamilyPolicy: string(v1.IPFamilyPolicyPreferDualStack), nodeSubnets: []*core.Subnet{ @@ -1791,10 +1791,10 @@ func Test_getLbListenerBackendSetIpVersion(t *testing.T) { Ipv6CidrBlocks: []string{"2001:0000:130F:0000:0000:09C0:876A:130B"}, }, }, - listenerBackendSetIpVersions: []string{IPv4, IPv6}, + listenerBackendSetIpVersions: []string{IPv4}, wantErr: nil, }, - "PreferDualStack IPv4 multiple subnets": { + "PreferDualStack IPv4 multiple subnets - ipFamilies takes precedence": { ipFamilies: []string{IPv4}, ipFamilyPolicy: string(v1.IPFamilyPolicyPreferDualStack), nodeSubnets: []*core.Subnet{ @@ -1806,7 +1806,7 @@ func Test_getLbListenerBackendSetIpVersion(t *testing.T) { Ipv6CidrBlocks: []string{"2001:0000:130F:0000:0000:09C0:876A:130B"}, }, }, - listenerBackendSetIpVersions: []string{IPv4, IPv6}, + listenerBackendSetIpVersions: []string{IPv4}, wantErr: nil, }, }