Skip to content

Commit

Permalink
Add static route to the hairpin masquerade IPs to pod
Browse files Browse the repository at this point in the history
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 <pliu@redhat.com>
  • Loading branch information
pliurh authored and jcaamano committed Sep 10, 2024
1 parent 96f94fc commit 6cdf7ec
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
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
Expand Up @@ -218,6 +218,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(),
Expand Down Expand Up @@ -301,6 +308,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(),
Expand Down Expand Up @@ -332,6 +346,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(),
Expand Down Expand Up @@ -362,6 +383,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(),
Expand Down Expand Up @@ -420,6 +448,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(),
Expand Down
7 changes: 7 additions & 0 deletions go-controller/pkg/ovn/pods_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 16 additions & 1 deletion go-controller/pkg/util/pod_annotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,20 @@ func serviceCIDRToRoute(isIPv6 bool, gatewayIP net.IP) []PodRoute {
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(
Expand Down Expand Up @@ -581,7 +595,8 @@ func AddRoutesGatewayIP(
if podAnnotation.Role == types.NetworkRolePrimary {
// Ensure default service network traffic always goes to OVN
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
Expand Down

0 comments on commit 6cdf7ec

Please sign in to comment.