Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-4.15] OCPBUGS-46403: Add static route to the hairpin masquerade IPs to pod #2396

Merged
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
Add static route to the hairpin masquerade IPs to pod
When users attach pod to a secondary network and override the default
route pod. It will cause the assymetric routing for service haripin
traffic.

We add static routes to ensure the traffic to the hairpin masquerade
IP always goes to OVN.

Signed-off-by: Peng Liu <[email protected]>
pliurh authored and openshift-cherrypick-robot committed Dec 13, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 1cd6dfd7f433e291fb9749c51741fbde90382807
35 changes: 35 additions & 0 deletions go-controller/pkg/allocator/pod/pod_annotation_test.go
Original file line number Diff line number Diff line change
@@ -183,6 +183,13 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) {
MAC: util.IPAddrToHWAddr(ovntest.MustParseIPNets("192.168.0.3/24")[0].IP),
Gateways: []net.IP{ovntest.MustParseIP("192.168.0.1").To4()},
Routes: []util.PodRoute{
{
Dest: &net.IPNet{
IP: ovntest.MustParseIP("169.254.169.5"),
Mask: net.CIDRMask(32, 32),
},
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
},
{
Dest: ovntest.MustParseIPNet("100.64.0.0/16"),
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
@@ -264,6 +271,13 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) {
MAC: util.IPAddrToHWAddr(ovntest.MustParseIPNets("192.168.0.4/24")[0].IP),
Gateways: []net.IP{ovntest.MustParseIP("192.168.0.1").To4()},
Routes: []util.PodRoute{
{
Dest: &net.IPNet{
IP: ovntest.MustParseIP("169.254.169.5"),
Mask: net.CIDRMask(32, 32),
},
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
},
{
Dest: ovntest.MustParseIPNet("100.64.0.0/16"),
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
@@ -293,6 +307,13 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) {
MAC: util.IPAddrToHWAddr(ovntest.MustParseIPNets("192.168.0.4/24")[0].IP),
Gateways: []net.IP{ovntest.MustParseIP("192.168.0.1").To4()},
Routes: []util.PodRoute{
{
Dest: &net.IPNet{
IP: ovntest.MustParseIP("169.254.169.5"),
Mask: net.CIDRMask(32, 32),
},
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
},
{
Dest: ovntest.MustParseIPNet("100.64.0.0/16"),
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
@@ -321,6 +342,13 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) {
MAC: util.IPAddrToHWAddr(ovntest.MustParseIPNets("192.168.0.3/24")[0].IP),
Gateways: []net.IP{ovntest.MustParseIP("192.168.0.1").To4()},
Routes: []util.PodRoute{
{
Dest: &net.IPNet{
IP: ovntest.MustParseIP("169.254.169.5"),
Mask: net.CIDRMask(32, 32),
},
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
},
{
Dest: ovntest.MustParseIPNet("100.64.0.0/16"),
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
@@ -377,6 +405,13 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) {
MAC: requestedMACParsed,
Gateways: []net.IP{ovntest.MustParseIP("192.168.0.1").To4()},
Routes: []util.PodRoute{
{
Dest: &net.IPNet{
IP: ovntest.MustParseIP("169.254.169.5"),
Mask: net.CIDRMask(32, 32),
},
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
},
{
Dest: ovntest.MustParseIPNet("100.64.0.0/16"),
NextHop: ovntest.MustParseIP("192.168.0.1").To4(),
7 changes: 7 additions & 0 deletions go-controller/pkg/ovn/pods_test.go
Original file line number Diff line number Diff line change
@@ -250,6 +250,13 @@ func newTPod(nodeName, nodeSubnet, nodeMgtIP, nodeGWIP, podName, podIPs, podMAC,
routeSources = append(routeSources, sc)
}
}
hairpinMasqueradeIP := config.Gateway.MasqueradeIPs.V4OVNServiceHairpinMasqueradeIP.String()
mask := 32
if isIPv6 {
hairpinMasqueradeIP = config.Gateway.MasqueradeIPs.V6OVNServiceHairpinMasqueradeIP.String()
mask = 128
}
routeSources = append(routeSources, ovntest.MustParseIPNet(fmt.Sprintf("%s/%d", hairpinMasqueradeIP, mask)))
joinNet := config.Gateway.V4JoinSubnet
if isIPv6 {
joinNet = config.Gateway.V6JoinSubnet
39 changes: 30 additions & 9 deletions go-controller/pkg/util/pod_annotation.go
Original file line number Diff line number Diff line change
@@ -441,6 +441,33 @@ func joinSubnetToRoute(isIPv6 bool, gatewayIP net.IP) PodRoute {
}
}

func serviceCIDRToRoute(isIPv6 bool, gatewayIP net.IP) []PodRoute {
var podRoutes []PodRoute
for _, serviceSubnet := range config.Kubernetes.ServiceCIDRs {
if isIPv6 == utilnet.IsIPv6CIDR(serviceSubnet) {
podRoutes = append(podRoutes, PodRoute{
Dest: serviceSubnet,
NextHop: gatewayIP,
})
}
}
return podRoutes
}

func hairpinMasqueradeIPToRoute(isIPv6 bool, gatewayIP net.IP) PodRoute {
ip := config.Gateway.MasqueradeIPs.V4OVNServiceHairpinMasqueradeIP
if isIPv6 {
ip = config.Gateway.MasqueradeIPs.V6OVNServiceHairpinMasqueradeIP
}
return PodRoute{
Dest: &net.IPNet{
IP: ip,
Mask: GetIPFullMask(ip),
},
NextHop: gatewayIP,
}
}

// addRoutesGatewayIP updates the provided pod annotation for the provided pod
// with the gateways derived from the allocated IPs
func AddRoutesGatewayIP(
@@ -523,15 +550,9 @@ func AddRoutesGatewayIP(
}

// Ensure default service network traffic always goes to OVN
for _, serviceSubnet := range config.Kubernetes.ServiceCIDRs {
if isIPv6 == utilnet.IsIPv6CIDR(serviceSubnet) {
podAnnotation.Routes = append(podAnnotation.Routes, PodRoute{
Dest: serviceSubnet,
NextHop: gatewayIPnet.IP,
})
}
}

podAnnotation.Routes = append(podAnnotation.Routes, serviceCIDRToRoute(isIPv6, gatewayIPnet.IP)...)
// Ensure service hairpin masquerade traffic always goes to OVN
podAnnotation.Routes = append(podAnnotation.Routes, hairpinMasqueradeIPToRoute(isIPv6, gatewayIPnet.IP))
otherDefaultRoute := otherDefaultRouteV4
if isIPv6 {
otherDefaultRoute = otherDefaultRouteV6