Created
January 16, 2026 16:29
-
-
Save trozet/49aa57e90a997443cba61578271616b1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| trozet@fedora:~/go/src/github.com/ovn-org/ovn-kubernetes/go-controller$ git diff | |
| diff --git a/go-controller/pkg/clustermanager/pod/allocator.go b/go-controller/pkg/clustermanager/pod/allocator.go | |
| index b1919afd1c..1832ebf0d7 100644 | |
| --- a/go-controller/pkg/clustermanager/pod/allocator.go | |
| +++ b/go-controller/pkg/clustermanager/pod/allocator.go | |
| @@ -217,7 +217,12 @@ func (a *PodAllocator) reconcile(old, new *corev1.Pod, releaseFromAllocator bool | |
| } | |
| } | |
| - onNetwork, networkMap, err := util.GetPodNADToNetworkMappingWithActiveNetwork(pod, a.netInfo, activeNetwork) | |
| + onNetwork, networkMap, err := util.GetPodNADToNetworkMappingWithActiveNetworkAndResolver( | |
| + pod, | |
| + a.netInfo, | |
| + activeNetwork, | |
| + a.networkManager.GetNetworkNameForNADKey, | |
| + ) | |
| if err != nil { | |
| a.recordPodErrorEvent(pod, err) | |
| return fmt.Errorf("failed to get NAD to network mapping: %w", err) | |
| diff --git a/go-controller/pkg/node/base_node_network_controller_dpu.go b/go-controller/pkg/node/base_node_network_controller_dpu.go | |
| index 22fdb5cd94..2b61a93507 100644 | |
| --- a/go-controller/pkg/node/base_node_network_controller_dpu.go | |
| +++ b/go-controller/pkg/node/base_node_network_controller_dpu.go | |
| @@ -136,7 +136,12 @@ func (bnnc *BaseNodeNetworkController) watchPodsDPU() (*factory.Handler, error) | |
| } | |
| } | |
| - on, networkMap, err := util.GetPodNADToNetworkMappingWithActiveNetwork(pod, bnnc.GetNetInfo(), activeNetwork) | |
| + on, networkMap, err := util.GetPodNADToNetworkMappingWithActiveNetworkAndResolver( | |
| + pod, | |
| + bnnc.GetNetInfo(), | |
| + activeNetwork, | |
| + bnnc.networkManager.GetNetworkNameForNADKey, | |
| + ) | |
| if err != nil || !on { | |
| if err != nil { | |
| // configuration error, no need to retry, do not return error | |
| diff --git a/go-controller/pkg/ovn/base_network_controller.go b/go-controller/pkg/ovn/base_network_controller.go | |
| index 9df5b8c6bb..2137684d69 100644 | |
| --- a/go-controller/pkg/ovn/base_network_controller.go | |
| +++ b/go-controller/pkg/ovn/base_network_controller.go | |
| @@ -950,8 +950,8 @@ func (bnc *BaseNetworkController) getPodNADKeys(pod *corev1.Pod) []string { | |
| if !bnc.IsUserDefinedNetwork() { | |
| return []string{types.DefaultNetworkName} | |
| } | |
| - podNadKeys, _ := util.PodNadKeys(pod, bnc.GetNetInfo()) | |
| - return podNadKeys | |
| + podNADKeys, _ := util.PodNADKeys(pod, bnc.GetNetInfo(), bnc.networkManager.GetNetworkNameForNADKey) | |
| + return podNADKeys | |
| } | |
| func (bnc *BaseNetworkController) getClusterPortGroupDbIDs(base string) *libovsdbops.DbObjectIDs { | |
| diff --git a/go-controller/pkg/ovn/base_network_controller_user_defined.go b/go-controller/pkg/ovn/base_network_controller_user_defined.go | |
| index f752555177..35b075bf7f 100644 | |
| --- a/go-controller/pkg/ovn/base_network_controller_user_defined.go | |
| +++ b/go-controller/pkg/ovn/base_network_controller_user_defined.go | |
| @@ -278,7 +278,12 @@ func (bsnc *BaseUserDefinedNetworkController) ensurePodForUserDefinedNetwork(pod | |
| } | |
| } | |
| - on, networkMap, err := bsnc.getPodNADToNetworkMapping(pod, activeNetwork) | |
| + on, networkMap, err := util.GetPodNADToNetworkMappingWithActiveNetworkAndResolver( | |
| + pod, | |
| + bsnc.GetNetInfo(), | |
| + activeNetwork, | |
| + bsnc.networkManager.GetNetworkNameForNADKey, | |
| + ) | |
| if err != nil { | |
| bsnc.recordPodErrorEvent(pod, err) | |
| // configuration error, no need to retry, do not return error | |
| @@ -312,53 +317,6 @@ func (bsnc *BaseUserDefinedNetworkController) ensurePodForUserDefinedNetwork(pod | |
| return nil | |
| } | |
| -func (bsnc *BaseUserDefinedNetworkController) getPodNADToNetworkMapping(pod *corev1.Pod, activeNetwork util.NetInfo) (bool, map[string]*nadapi.NetworkSelectionElement, error) { | |
| - if bsnc.IsPrimaryNetwork() { | |
| - return util.GetPodNADToNetworkMappingWithActiveNetwork(pod, bsnc.GetNetInfo(), activeNetwork) | |
| - } | |
| - if pod.Spec.HostNetwork { | |
| - return false, nil, nil | |
| - } | |
| - | |
| - networkSelections := map[string]*nadapi.NetworkSelectionElement{} | |
| - allNetworks, err := util.GetK8sPodAllNetworkSelections(pod) | |
| - if err != nil { | |
| - return false, nil, err | |
| - } | |
| - | |
| - nNADs := map[string]int{} | |
| - for _, network := range allNetworks { | |
| - nadNamespace := network.Namespace | |
| - if nadNamespace == "" { | |
| - nadNamespace = pod.Namespace | |
| - } | |
| - nadName := util.GetNADName(nadNamespace, network.Name) | |
| - networkName := bsnc.networkManager.GetNetworkNameForNADKey(nadName) | |
| - if networkName == "" { | |
| - // fallback to checking NADs if for some reason the cache was empty | |
| - if !bsnc.GetNetInfo().HasNAD(nadName) { | |
| - continue | |
| - } | |
| - } else if networkName != bsnc.GetNetworkName() { | |
| - continue | |
| - } | |
| - | |
| - cnt := nNADs[nadName] | |
| - if cnt > 0 && bsnc.GetNetInfo().TopologyType() == types.LocalnetTopology { | |
| - return false, nil, fmt.Errorf("pod %s/%s cannot have same networkSelectionElement %s of type %s multiple times", | |
| - pod.Namespace, pod.Name, nadName, types.LocalnetTopology) | |
| - } | |
| - nNADs[nadName] = cnt + 1 | |
| - networkSelections[util.GetIndexedNADKey(nadName, cnt)] = network | |
| - } | |
| - | |
| - if len(networkSelections) == 0 { | |
| - return false, nil, nil | |
| - } | |
| - | |
| - return true, networkSelections, nil | |
| -} | |
| - | |
| func (bsnc *BaseUserDefinedNetworkController) addLogicalPortToNetworkForNAD(pod *corev1.Pod, nadKey, switchName string, | |
| network *nadapi.NetworkSelectionElement, kubevirtLiveMigrationStatus *kubevirt.LiveMigrationStatus, | |
| ) error { | |
| @@ -609,7 +567,12 @@ func (bsnc *BaseUserDefinedNetworkController) hasIPAMClaim(pod *corev1.Pod, nadK | |
| } | |
| } else { | |
| // secondary network the IPAM claim reference is on the network selection element | |
| - on, networkMap, err := bsnc.getPodNADToNetworkMapping(pod, nil) | |
| + on, networkMap, err := util.GetPodNADToNetworkMappingWithActiveNetworkAndResolver( | |
| + pod, | |
| + bsnc.GetNetInfo(), | |
| + nil, | |
| + bsnc.networkManager.GetNetworkNameForNADKey, | |
| + ) | |
| if err != nil { | |
| return false, fmt.Errorf("failed to get network mapping for pod %s/%s on network %s: %v", | |
| pod.Namespace, pod.Name, bsnc.GetNetworkName(), err) | |
| @@ -685,7 +648,12 @@ func (bsnc *BaseUserDefinedNetworkController) syncPodsForUserDefinedNetwork(pods | |
| } | |
| } | |
| - on, networkMap, err := bsnc.getPodNADToNetworkMapping(pod, activeNetwork) | |
| + on, networkMap, err := util.GetPodNADToNetworkMappingWithActiveNetworkAndResolver( | |
| + pod, | |
| + bsnc.GetNetInfo(), | |
| + activeNetwork, | |
| + bsnc.networkManager.GetNetworkNameForNADKey, | |
| + ) | |
| if err != nil || !on { | |
| if err != nil { | |
| bsnc.recordPodErrorEvent(pod, err) | |
| diff --git a/go-controller/pkg/util/multi_network.go b/go-controller/pkg/util/multi_network.go | |
| index 0c51994d42..4ba9310618 100644 | |
| --- a/go-controller/pkg/util/multi_network.go | |
| +++ b/go-controller/pkg/util/multi_network.go | |
| @@ -1547,6 +1547,14 @@ func GetPodNADToNetworkMapping(pod *corev1.Pod, nInfo NetInfo) (bool, map[string | |
| return true, networkSelections, nil | |
| } | |
| + return getPodNADToNetworkMappingWithPredicate(pod, nInfo, nInfo.HasNAD) | |
| +} | |
| + | |
| +func getPodNADToNetworkMappingWithPredicate( | |
| + pod *corev1.Pod, | |
| + nInfo NetInfo, | |
| + nadMatches func(nadKey string) bool, | |
| +) (bool, map[string]*nettypes.NetworkSelectionElement, error) { | |
| // For non-default network controller, try to see if its name exists in the Pod's k8s.v1.cni.cncf.io/networks, if no, | |
| // return false; | |
| allNetworks, err := GetK8sPodAllNetworkSelections(pod) | |
| @@ -1554,25 +1562,31 @@ func GetPodNADToNetworkMapping(pod *corev1.Pod, nInfo NetInfo) (bool, map[string | |
| return false, nil, err | |
| } | |
| + networkSelections := map[string]*nettypes.NetworkSelectionElement{} | |
| // Get map of per-NAD NetworkSelectionElement, if there are multiple NetworkSelectionElements of the same NAD, | |
| // calculate numbers of network elements of that same NAD. | |
| nNADs := map[string]int{} | |
| for _, network := range allNetworks { | |
| - nadName := GetNADName(network.Namespace, network.Name) | |
| - if nInfo.HasNAD(nadName) { | |
| - if nInfo.IsPrimaryNetwork() { | |
| - return false, nil, fmt.Errorf("unexpected primary network %q specified with a NetworkSelectionElement %+v", nInfo.GetNetworkName(), network) | |
| - } | |
| + nadNamespace := network.Namespace | |
| + if nadNamespace == "" { | |
| + nadNamespace = pod.Namespace | |
| + } | |
| + nadName := GetNADName(nadNamespace, network.Name) | |
| + if !nadMatches(nadName) { | |
| + continue | |
| + } | |
| + if nInfo.IsPrimaryNetwork() { | |
| + return false, nil, fmt.Errorf("unexpected primary network %q specified with a NetworkSelectionElement %+v", nInfo.GetNetworkName(), network) | |
| + } | |
| - // for multiple NetworkSelectionElements of the same NAD, set its nadName to indexed nadName | |
| - cnt := nNADs[nadName] | |
| - if cnt > 0 && nInfo.TopologyType() == types.LocalnetTopology { | |
| - return false, nil, fmt.Errorf("pod %s/%s cannot have same networkSelectionElement %s of type %s multiple times", | |
| - pod.Namespace, pod.Name, nadName, types.LocalnetTopology) | |
| - } | |
| - nNADs[nadName] = cnt + 1 | |
| - networkSelections[GetIndexedNADKey(nadName, cnt)] = network | |
| + // for multiple NetworkSelectionElements of the same NAD, set its nadName to indexed nadName | |
| + cnt := nNADs[nadName] | |
| + if cnt > 0 && nInfo.TopologyType() == types.LocalnetTopology { | |
| + return false, nil, fmt.Errorf("pod %s/%s cannot have same networkSelectionElement %s of type %s multiple times", | |
| + pod.Namespace, pod.Name, nadName, types.LocalnetTopology) | |
| } | |
| + nNADs[nadName] = cnt + 1 | |
| + networkSelections[GetIndexedNADKey(nadName, cnt)] = network | |
| } | |
| if len(networkSelections) == 0 { | |
| @@ -1582,6 +1596,32 @@ func GetPodNADToNetworkMapping(pod *corev1.Pod, nInfo NetInfo) (bool, map[string | |
| return true, networkSelections, nil | |
| } | |
| +// GetSecondaryPodNADToNetworkMappingWithResolver is a variant that uses a resolver to map NAD keys to network names. | |
| +// It is intended for secondary user-defined networks where the controller may not have all NADs cached. | |
| +func GetSecondaryPodNADToNetworkMappingWithResolver( | |
| + pod *corev1.Pod, | |
| + nInfo NetInfo, | |
| + getNetworkNameForNADKey func(nadKey string) string, | |
| +) (bool, map[string]*nettypes.NetworkSelectionElement, error) { | |
| + if nInfo.IsPrimaryNetwork() { | |
| + return false, nil, fmt.Errorf("resolver-based mapping is not supported for primary networks %q", nInfo.GetNetworkName()) | |
| + } | |
| + if getNetworkNameForNADKey == nil || !nInfo.IsUserDefinedNetwork() { | |
| + return GetPodNADToNetworkMapping(pod, nInfo) | |
| + } | |
| + if pod.Spec.HostNetwork { | |
| + return false, nil, nil | |
| + } | |
| + | |
| + return getPodNADToNetworkMappingWithPredicate(pod, nInfo, func(nadName string) bool { | |
| + networkName := getNetworkNameForNADKey(nadName) | |
| + if networkName == "" { | |
| + return nInfo.HasNAD(nadName) | |
| + } | |
| + return networkName == nInfo.GetNetworkName() | |
| + }) | |
| +} | |
| + | |
| // overrideActiveNSEWithDefaultNSE overrides the provided active NetworkSelectionElement with the IP and MAC requests from | |
| // the default NetworkSelectionElement after validating its namespace and name. | |
| func overrideActiveNSEWithDefaultNSE(defaultNSE, activeNSE *nettypes.NetworkSelectionElement) error { | |
| @@ -1674,6 +1714,20 @@ func GetPodNADToNetworkMappingWithActiveNetwork(pod *corev1.Pod, nInfo NetInfo, | |
| return true, networkSelections, nil | |
| } | |
| +// GetPodNADToNetworkMappingWithActiveNetworkAndResolver uses a resolver when available for secondary networks, | |
| +// and otherwise falls back to the active-network aware default behavior. | |
| +func GetPodNADToNetworkMappingWithActiveNetworkAndResolver( | |
| + pod *corev1.Pod, | |
| + nInfo NetInfo, | |
| + activeNetwork NetInfo, | |
| + getNetworkNameForNADKey func(nadKey string) string, | |
| +) (bool, map[string]*nettypes.NetworkSelectionElement, error) { | |
| + if getNetworkNameForNADKey == nil || !nInfo.IsUserDefinedNetwork() || nInfo.IsPrimaryNetwork() { | |
| + return GetPodNADToNetworkMappingWithActiveNetwork(pod, nInfo, activeNetwork) | |
| + } | |
| + return GetSecondaryPodNADToNetworkMappingWithResolver(pod, nInfo, getNetworkNameForNADKey) | |
| +} | |
| + | |
| // getNADWithNamespace returns the first occurrence of NAD key with the given namespace name. | |
| func getNADWithNamespace(nads []string, targetNamespace string) *k8sapitypes.NamespacedName { | |
| for _, nad := range nads { | |
| @@ -1827,6 +1881,9 @@ func GetNetworkRole( | |
| getNetworkNameForNADKey func(nadKey string) string, | |
| pod *corev1.Pod, | |
| ) (string, error) { | |
| + if getNetworkNameForNADKey == nil { | |
| + return "", fmt.Errorf("getNetworkNameForNADKey is required") | |
| + } | |
| // no network segmentation enabled, and is default controller, must be default network | |
| if !IsNetworkSegmentationSupportEnabled() && controllerNetInfo.IsDefault() { | |
| @@ -1848,13 +1905,11 @@ func GetNetworkRole( | |
| return types.NetworkRoleInfrastructure, nil | |
| } | |
| - if getNetworkNameForNADKey != nil { | |
| - if networkName := getNetworkNameForNADKey(primaryNAD); networkName != "" { | |
| - if networkName == controllerNetInfo.GetNetworkName() { | |
| - return types.NetworkRolePrimary, nil | |
| - } | |
| - return types.NetworkRoleNone, nil | |
| + if networkName := getNetworkNameForNADKey(primaryNAD); networkName != "" { | |
| + if networkName == controllerNetInfo.GetNetworkName() { | |
| + return types.NetworkRolePrimary, nil | |
| } | |
| + return types.NetworkRoleNone, nil | |
| } | |
| if controllerNetInfo.HasNAD(primaryNAD) { | |
| return types.NetworkRolePrimary, nil | |
| @@ -1865,40 +1920,29 @@ func GetNetworkRole( | |
| } | |
| // at this point the controller must be a secondary network | |
| - if getNetworkNameForNADKey != nil { | |
| - allNetworks, err := GetK8sPodAllNetworkSelections(pod) | |
| - if err != nil { | |
| - return "", fmt.Errorf("failed to get pod network mapping: %w", err) | |
| + allNetworks, err := GetK8sPodAllNetworkSelections(pod) | |
| + if err != nil { | |
| + return "", fmt.Errorf("failed to get pod network mapping: %w", err) | |
| + } | |
| + for _, network := range allNetworks { | |
| + nadNamespace := network.Namespace | |
| + if nadNamespace == "" { | |
| + nadNamespace = pod.Namespace | |
| } | |
| - for _, network := range allNetworks { | |
| - nadNamespace := network.Namespace | |
| - if nadNamespace == "" { | |
| - nadNamespace = pod.Namespace | |
| - } | |
| - nadKey := GetNADName(nadNamespace, network.Name) | |
| - networkName := getNetworkNameForNADKey(nadKey) | |
| - if networkName == "" { | |
| - // fallback if cache miss | |
| - if controllerNetInfo.HasNAD(nadKey) { | |
| - return types.NetworkRoleSecondary, nil | |
| - } | |
| - continue | |
| - } | |
| - if networkName == controllerNetInfo.GetNetworkName() { | |
| + nadKey := GetNADName(nadNamespace, network.Name) | |
| + networkName := getNetworkNameForNADKey(nadKey) | |
| + if networkName == "" { | |
| + // fallback if cache miss | |
| + if controllerNetInfo.HasNAD(nadKey) { | |
| return types.NetworkRoleSecondary, nil | |
| } | |
| + continue | |
| + } | |
| + if networkName == controllerNetInfo.GetNetworkName() { | |
| + return types.NetworkRoleSecondary, nil | |
| } | |
| - return types.NetworkRoleNone, nil | |
| - } | |
| - | |
| - on, _, err := GetPodNADToNetworkMapping(pod, controllerNetInfo.GetNetInfo()) | |
| - if err != nil { | |
| - return "", fmt.Errorf("failed to get pod network mapping: %w", err) | |
| - } | |
| - if !on { | |
| - return types.NetworkRoleNone, nil | |
| } | |
| - return types.NetworkRoleSecondary, nil | |
| + return types.NetworkRoleNone, nil | |
| } | |
| // (C)UDN network name generation functions must ensure the absence of name conflicts between all (C)UDNs. | |
| diff --git a/go-controller/pkg/util/pod_annotation.go b/go-controller/pkg/util/pod_annotation.go | |
| index fb969cc110..76d8bf5d64 100644 | |
| --- a/go-controller/pkg/util/pod_annotation.go | |
| +++ b/go-controller/pkg/util/pod_annotation.go | |
| @@ -394,25 +394,25 @@ func DefaultNetworkPodIPs(pod *corev1.Pod) ([]net.IP, error) { | |
| func SecondaryNetworkPodIPs(pod *corev1.Pod, networkInfo NetInfo) ([]net.IP, error) { | |
| ips := []net.IP{} | |
| - podNadKeys, err := PodNadKeys(pod, networkInfo) | |
| + podNADKeys, err := PodNADKeys(pod, networkInfo, nil) | |
| if err != nil { | |
| return nil, err | |
| } | |
| - for _, nadKey := range podNadKeys { | |
| + for _, nadKey := range podNADKeys { | |
| ips = append(ips, getAnnotatedPodIPs(pod, nadKey)...) | |
| } | |
| return ips, nil | |
| } | |
| -// PodNadKeys returns pod's NAD keys associated with given network specified by netconf. | |
| +// PodNADKeys returns pod's NAD keys associated with given network specified by netconf. | |
| // If netinfo belongs to user defined primary network, then retrieve NAD names from | |
| // netinfo.GetNADs() which is serving pod's namespace. | |
| // For all other cases, retrieve NAD names for the pod based on NetworkSelectionElement. | |
| -func PodNadKeys(pod *corev1.Pod, netinfo NetInfo) ([]string, error) { | |
| +func PodNADKeys(pod *corev1.Pod, netinfo NetInfo, getNetworkNameForNADKey func(nadKey string) string) ([]string, error) { | |
| if netinfo.IsPrimaryNetwork() { | |
| return GetPrimaryNetworkNADNamesForNamespaceFromNetInfo(pod.Namespace, netinfo) | |
| } | |
| - on, networkMap, err := GetPodNADToNetworkMapping(pod, netinfo) | |
| + on, networkMap, err := GetSecondaryPodNADToNetworkMappingWithResolver(pod, netinfo, getNetworkNameForNADKey) | |
| // skip pods that are not on this network | |
| if err != nil { | |
| return nil, err |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment