Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 13 additions & 20 deletions go-controller/pkg/node/controllers/egressip/egressip.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import (
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/syncmap"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util/egressip"
utilerrors "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util/errors"
)

Expand Down Expand Up @@ -539,15 +540,15 @@ func (c *Controller) processEIP(eip *eipv1.EgressIP) (*eIPConfig, sets.Set[strin
if isValid := isEIPStatusItemValid(status, c.nodeName); !isValid {
continue
}
eIPNet, err := util.GetIPNetFullMask(status.EgressIP)
if err != nil {
ip := net.ParseIP(status.EgressIP)
if ip == nil {
return nil, selectedNamespaces, selectedPods, selectedNamespacesPodIPs,
fmt.Errorf("failed to generate mask for EgressIP %s IP %s: %v", eip.Name, status.EgressIP, err)
fmt.Errorf("failed to parse EgressIP %s IP %s", eip.Name, status.EgressIP)
}
if util.IsOVNNetwork(parsedNodeEIPConfig, eIPNet.IP) {
if util.IsOVNNetwork(parsedNodeEIPConfig, ip) {
continue
}
found, link, err := findLinkOnSameNetworkAsIP(eIPNet.IP, c.v4, c.v6)
found, link, err := findLinkOnSameNetworkAsIP(ip, c.v4, c.v6)
if err != nil {
return nil, selectedNamespaces, selectedPods, selectedNamespacesPodIPs,
fmt.Errorf("failed to find a network to host EgressIP %s IP %s: %v", eip.Name, status.EgressIP, err)
Expand All @@ -560,7 +561,7 @@ func (c *Controller) processEIP(eip *eipv1.EgressIP) (*eIPConfig, sets.Set[strin
if err != nil {
return nil, selectedNamespaces, selectedPods, selectedNamespacesPodIPs, fmt.Errorf("failed to list namespaces: %w", err)
}
isEIPV6 := utilnet.IsIPv6(eIPNet.IP)
isEIPV6 := utilnet.IsIPv6(ip)
for _, namespace := range namespaces {
netInfo, err := c.getActiveNetworkForNamespace(namespace.Name)
if err != nil {
Expand Down Expand Up @@ -593,13 +594,13 @@ func (c *Controller) processEIP(eip *eipv1.EgressIP) (*eIPConfig, sets.Set[strin
if selectedNamespacesPodIPs[namespace.Name] == nil {
selectedNamespacesPodIPs[namespace.Name] = make(map[ktypes.NamespacedName]*podIPConfigList)
}
selectedNamespacesPodIPs[namespace.Name][podNamespaceName] = generatePodConfig(ips, link, eIPNet, isEIPV6)
selectedNamespacesPodIPs[namespace.Name][podNamespaceName] = generatePodConfig(ips, link, ip, isEIPV6)
selectedPods.Insert(podNamespaceName)
}
}
// ensure at least one pod is selected before generating config
if len(selectedNamespacesPodIPs) > 0 {
eipSpecificConfig, err = generateEIPConfig(link, eIPNet, isEIPV6)
eipSpecificConfig, err = generateEIPConfig(link, ip, isEIPV6)
if err != nil {
return nil, selectedNamespaces, selectedPods, selectedNamespacesPodIPs,
fmt.Errorf("failed to generate EIP configuration for EgressIP %s IP %s: %v", eip.Name, status.EgressIP, err)
Expand All @@ -611,15 +612,15 @@ func (c *Controller) processEIP(eip *eipv1.EgressIP) (*eIPConfig, sets.Set[strin
return eipSpecificConfig, selectedNamespaces, selectedPods, selectedNamespacesPodIPs, nil
}

func generatePodConfig(podIPs []net.IP, link netlink.Link, eIPNet *net.IPNet, isEIPV6 bool) *podIPConfigList {
func generatePodConfig(podIPs []net.IP, link netlink.Link, eIP net.IP, isEIPV6 bool) *podIPConfigList {
newPodIPConfigs := newPodIPConfigList()
for _, podIP := range podIPs {
isPodIPv6 := utilnet.IsIPv6(podIP)
if isPodIPv6 != isEIPV6 {
continue
}
ipConfig := newPodIPConfig()
ipConfig.ipTableRule = generateIPTablesSNATRuleArg(podIP, isPodIPv6, link.Attrs().Name, eIPNet.IP.String())
ipConfig.ipTableRule = generateIPTablesSNATRuleArg(podIP, isPodIPv6, link.Attrs().Name, eIP.String())
ipConfig.ipRule = generateIPRule(podIP, isPodIPv6, link.Attrs().Index)
ipConfig.v6 = isPodIPv6
newPodIPConfigs.elems = append(newPodIPConfigs.elems, ipConfig)
Expand All @@ -628,14 +629,14 @@ func generatePodConfig(podIPs []net.IP, link netlink.Link, eIPNet *net.IPNet, is
}

// generateEIPConfig generates configuration that isn't related to any pod EIPs to support config of a single EIP
func generateEIPConfig(link netlink.Link, eIPNet *net.IPNet, isEIPV6 bool) (*eIPConfig, error) {
func generateEIPConfig(link netlink.Link, eIP net.IP, isEIPV6 bool) (*eIPConfig, error) {
eipConfig := newEIPConfig()
linkRoutes, err := generateRoutesForLink(link, isEIPV6)
if err != nil {
return nil, err
}
eipConfig.routes = linkRoutes
eipConfig.addr = getNetlinkAddress(eIPNet, link.Attrs().Index)
eipConfig.addr = egressip.GetNetlinkAddress(eIP, link.Attrs().Index)
return eipConfig, nil
}

Expand Down Expand Up @@ -1482,14 +1483,6 @@ func isLinkUp(flags string) bool {
return strings.Contains(flags, "up")
}

func getNetlinkAddress(addr *net.IPNet, ifindex int) *netlink.Addr {
return &netlink.Addr{
IPNet: addr,
Scope: int(netlink.SCOPE_UNIVERSE),
LinkIndex: ifindex,
}
}

// generateIPRules generates IP rules at a predefined priority for each pod IP with a custom routing table based
// from the links 'ifindex'
func generateIPRule(srcIP net.IP, isIPv6 bool, ifIndex int) netlink.Rule {
Expand Down
35 changes: 3 additions & 32 deletions go-controller/pkg/node/egressip/gateway_egressip.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ package egressip
import (
"encoding/json"
"fmt"
"math"
"net"
"sync"

"github.com/vishvananda/netlink"
"golang.org/x/sys/unix"

"k8s.io/apimachinery/pkg/util/sets"
corev1informers "k8s.io/client-go/informers/core/v1"
corev1listers "k8s.io/client-go/listers/core/v1"
Expand All @@ -23,6 +19,7 @@ import (
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/kube"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/node/linkmanager"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util/egressip"
)

// markIPs contains packet mark and associated EgressIP IP for IPv4 / IPv6. Key is packet mark, value egress IP
Expand Down Expand Up @@ -451,15 +448,15 @@ func (g *BridgeEIPAddrManager) addIPBridge(ip net.IP) error {
if err != nil {
return fmt.Errorf("failed to get link obj by name %s: %v", g.bridgeName, err)
}
return g.addrManager.AddAddress(getEIPBridgeNetlinkAddress(ip, link.Attrs().Index))
return g.addrManager.AddAddress(*egressip.GetNetlinkAddress(ip, link.Attrs().Index))
}

func (g *BridgeEIPAddrManager) deleteIPBridge(ip net.IP) error {
link, err := util.GetNetLinkOps().LinkByName(g.bridgeName)
if err != nil {
return fmt.Errorf("failed to get link obj by name %s: %v", g.bridgeName, err)
}
return g.addrManager.DelAddress(getEIPBridgeNetlinkAddress(ip, link.Attrs().Index))
return g.addrManager.DelAddress(*egressip.GetNetlinkAddress(ip, link.Attrs().Index))
}

// getAnnotationIPs retrieves the egress IP annotation from the current node Nodes object. If multiple users, callers must synchronise.
Expand Down Expand Up @@ -514,29 +511,3 @@ func getIPsStr(ips ...net.IP) []string {
}
return ipsStr
}

func getEIPBridgeNetlinkAddress(ip net.IP, ifindex int) netlink.Addr {
return netlink.Addr{
IPNet: &net.IPNet{IP: ip, Mask: util.GetIPFullMask(ip)},
Flags: getEIPNetlinkAddressFlag(ip),
Scope: int(netlink.SCOPE_UNIVERSE),
ValidLft: getEIPNetlinkAddressValidLft(ip),
LinkIndex: ifindex,
}
}

func getEIPNetlinkAddressFlag(ip net.IP) int {
// isV6?
if ip.To4() == nil && ip.To16() != nil {
return unix.IFA_F_NODAD
}
return 0
}

func getEIPNetlinkAddressValidLft(ip net.IP) int {
// isV6?
if ip.To4() == nil && ip.To16() != nil {
return math.MaxUint32
}
return 0
}
Loading