Skip to content

Commit 5308cbf

Browse files
committed
CreateDefaultRouteToExternal should use node GR IP annotations
This function is called from many different threads. Relying on nbdb for the GR IP is not safe here, as the GR IP could be changing due to a k8s event, and the route will be wrongly configured with an old IP still in OVN NBDB. Signed-off-by: Tim Rozet <[email protected]>
1 parent a008345 commit 5308cbf

14 files changed

+63
-24
lines changed

go-controller/pkg/kubevirt/router.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,16 @@ func EnsureLocalZonePodAddressesToNodeRoute(watchFactory *factory.WatchFactory,
9595
if config.OVNKubernetesFeature.EnableInterconnect {
9696
// NOTE: EIP & ESVC use same route and if this is already present thanks to those features,
9797
// this will be a no-op
98-
if err := libovsdbutil.CreateDefaultRouteToExternal(nbClient, types.OVNClusterRouter, types.GWRouterPrefix+pod.Spec.NodeName, clusterSubnets); err != nil {
98+
node, err := watchFactory.GetNode(pod.Spec.NodeName)
99+
if err != nil {
100+
return fmt.Errorf("failed getting to list node %q for pod %s/%s: %w", pod.Spec.NodeName, pod.Namespace, pod.Name, err)
101+
}
102+
gatewayIPs, err := util.ParseNodeGatewayRouterJoinAddrs(node, types.DefaultNetworkName)
103+
if err != nil {
104+
return fmt.Errorf("failed to get default network gateway router join IPs for node %q: %w", node.Name, err)
105+
}
106+
if err := libovsdbutil.CreateDefaultRouteToExternal(nbClient, types.OVNClusterRouter,
107+
types.GWRouterPrefix+pod.Spec.NodeName, clusterSubnets, gatewayIPs); err != nil {
99108
return err
100109
}
101110
}

go-controller/pkg/libovsdb/util/router.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config"
1414
libovsdbops "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/libovsdb/ops"
1515
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/nbdb"
16-
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types"
1716
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util"
1817
)
1918

@@ -34,11 +33,7 @@ import (
3433
// (TODO: FIXME): With this route, we are officially breaking support for IC with zones that have multiple-nodes
3534
// NOTE: This route is exactly the same as what is added by pod-live-migration feature and we keep the route exactly
3635
// same across the 3 features so that if the route already exists on the node, this is just a no-op
37-
func CreateDefaultRouteToExternal(nbClient libovsdbclient.Client, clusterRouter, gwRouterName string, clusterSubnets []config.CIDRNetworkEntry) error {
38-
gatewayIPs, err := GetLRPAddrs(nbClient, types.GWRouterToJoinSwitchPrefix+gwRouterName)
39-
if err != nil {
40-
return fmt.Errorf("attempt at finding node gateway router %s network information failed, err: %w", gwRouterName, err)
41-
}
36+
func CreateDefaultRouteToExternal(nbClient libovsdbclient.Client, clusterRouter, gwRouterName string, clusterSubnets []config.CIDRNetworkEntry, gatewayIPs []*net.IPNet) error {
4237
for _, clusterSubnet := range clusterSubnets {
4338
isClusterSubnetIPV6 := utilnet.IsIPv6String(clusterSubnet.CIDR.IP.String())
4439
gatewayIP, err := util.MatchFirstIPNetFamily(isClusterSubnetIPV6, gatewayIPs)

go-controller/pkg/libovsdb/util/router_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ func TestCreateDefaultRouteToExternal(t *testing.T) {
3131
gwRouterPortName := types.GWRouterToJoinSwitchPrefix + gwRouterName
3232
gwRouterIPAddressV4 := "100.64.0.3"
3333
gwRouterIPAddressV6 := "fd98::3"
34+
gwRouterIPAddressV4CIDR := fmt.Sprintf("%s/32", gwRouterIPAddressV4)
35+
gwRouterIPAddressV6CIDR := fmt.Sprintf("%s/128", gwRouterIPAddressV6)
36+
gatewayIPs := []*net.IPNet{ovntest.MustParseIPNet(gwRouterIPAddressV4CIDR), ovntest.MustParseIPNet(gwRouterIPAddressV6CIDR)}
3437
gwRouterPort := &nbdb.LogicalRouterPort{
3538
UUID: gwRouterPortName + "-uuid",
3639
Name: gwRouterPortName,
@@ -228,7 +231,7 @@ func TestCreateDefaultRouteToExternal(t *testing.T) {
228231
tc.preTestAction()
229232
}
230233

231-
if err = CreateDefaultRouteToExternal(nbClient, ovnClusterRouterName, gwRouterName, config.Default.ClusterSubnets); err != nil {
234+
if err = CreateDefaultRouteToExternal(nbClient, ovnClusterRouterName, gwRouterName, config.Default.ClusterSubnets, gatewayIPs); err != nil {
232235
t.Fatal(fmt.Errorf("failed to run CreateDefaultRouteToExternal: %v", err))
233236
}
234237

go-controller/pkg/ovn/controller/egressservice/egressservice_zone.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ type InitClusterEgressPoliciesFunc func(client libovsdbclient.Client, addressSet
5050
type EnsureNoRerouteNodePoliciesFunc func(client libovsdbclient.Client, addressSetFactory addressset.AddressSetFactory,
5151
networkName, controllerName, clusterRouter string, nodeLister corelisters.NodeLister, v4, v6 bool) error
5252
type DeleteLegacyDefaultNoRerouteNodePoliciesFunc func(nbClient libovsdbclient.Client, clusterRouter, nodeName string) error
53-
type CreateDefaultRouteToExternalFunc func(nbClient libovsdbclient.Client, clusterRouter, gwRouterName string, clusterSubnets []config.CIDRNetworkEntry) error
53+
type CreateDefaultRouteToExternalFunc func(nbClient libovsdbclient.Client, clusterRouter, gwRouterName string, clusterSubnets []config.CIDRNetworkEntry, gatewayIPs []*net.IPNet) error
5454

5555
type Controller struct {
5656
// network information

go-controller/pkg/ovn/controller/egressservice/egressservice_zone_node.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,15 @@ func (c *Controller) syncNode(key string) error {
151151
return nil
152152
}
153153

154+
gatewayIPs, err := util.ParseNodeGatewayRouterJoinAddrs(n, types.DefaultNetworkName)
155+
if err != nil {
156+
return fmt.Errorf("failed to get default network gateway router join IPs for node %q: %w", n.Name, err)
157+
}
158+
154159
// At this point the node exists and is ready
155160
if config.OVNKubernetesFeature.EnableInterconnect && c.zone != types.OvnDefaultZone && c.isNodeInLocalZone(n) {
156-
if err := c.createDefaultRouteToExternalForIC(c.nbClient, c.GetNetworkScopedClusterRouterName(), c.GetNetworkScopedGWRouterName(nodeName), c.Subnets()); err != nil {
161+
if err := c.createDefaultRouteToExternalForIC(c.nbClient, c.GetNetworkScopedClusterRouterName(),
162+
c.GetNetworkScopedGWRouterName(nodeName), c.Subnets(), gatewayIPs); err != nil {
157163
return err
158164
}
159165
}

go-controller/pkg/ovn/egressip.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,8 +2051,12 @@ func (e *EgressIPController) addEgressNode(node *corev1.Node) error {
20512051
// on IC if the node is gone, then the ovn_cluster_router is also gone along with all
20522052
// the routes on it.
20532053
ni := e.networkManager.GetNetwork(types.DefaultNetworkName)
2054+
gatewayIPs, err := util.ParseNodeGatewayRouterJoinAddrs(node, types.DefaultNetworkName)
2055+
if err != nil {
2056+
return fmt.Errorf("failed to get default network gateway router join IPs for node %q: %w", node.Name, err)
2057+
}
20542058
if err := libovsdbutil.CreateDefaultRouteToExternal(e.nbClient, ni.GetNetworkScopedClusterRouterName(),
2055-
ni.GetNetworkScopedGWRouterName(node.Name), ni.Subnets()); err != nil {
2059+
ni.GetNetworkScopedGWRouterName(node.Name), ni.Subnets(), gatewayIPs); err != nil {
20562060
return fmt.Errorf("failed to create route to external for network %s: %v", ni.GetNetworkName(), err)
20572061
}
20582062
}
@@ -3121,7 +3125,7 @@ func createDefaultNoRerouteServicePolicies(nbClient libovsdbclient.Client, netwo
31213125
return nil
31223126
}
31233127

3124-
func (e *EgressIPController) ensureRouterPoliciesForNetwork(ni util.NetInfo) error {
3128+
func (e *EgressIPController) ensureRouterPoliciesForNetwork(ni util.NetInfo, node *corev1.Node) error {
31253129
e.nodeUpdateMutex.Lock()
31263130
defer e.nodeUpdateMutex.Unlock()
31273131
subnetEntries := ni.Subnets()
@@ -3146,8 +3150,12 @@ func (e *EgressIPController) ensureRouterPoliciesForNetwork(ni util.NetInfo) err
31463150
return fmt.Errorf("failed to ensure no reroute node policies for network %s: %v", ni.GetNetworkName(), err)
31473151
}
31483152
if config.OVNKubernetesFeature.EnableInterconnect && ni.TopologyType() == types.Layer3Topology {
3153+
gatewayIPs, err := util.ParseNodeGatewayRouterJoinAddrs(node, ni.GetNetworkName())
3154+
if err != nil {
3155+
return fmt.Errorf("failed to get %q network gateway router join IPs for node %q, err: %w", ni.GetNetworkName(), node.Name, err)
3156+
}
31493157
if err := libovsdbutil.CreateDefaultRouteToExternal(e.nbClient, routerName,
3150-
ni.GetNetworkScopedGWRouterName(localNode), subnetEntries); err != nil {
3158+
ni.GetNetworkScopedGWRouterName(localNode), subnetEntries, gatewayIPs); err != nil {
31513159
return fmt.Errorf("failed to create route to external for network %s: %v", ni.GetNetworkName(), err)
31523160
}
31533161
}

go-controller/pkg/ovn/egressip_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5418,6 +5418,7 @@ var _ = ginkgo.Describe("OVN master EgressIP Operations cluster default network"
54185418
"k8s.ovn.org/node-transit-switch-port-ifaddr": "{\"ipv4\":\"100.88.0.2/16\"}", // used only for ic=true test
54195419
"k8s.ovn.org/zone-name": node1Zone, // used only for ic=true test
54205420
util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", node1IPv4CIDR),
5421+
util.OVNNodeGRLRPAddrs: fmt.Sprintf(`{"default":{"ipv4":"%s/16"}}`, nodeLogicalRouterIPv4[0]),
54215422
}
54225423
if node1Zone != "global" {
54235424
annotations["k8s.ovn.org/remote-zone-migrated"] = node1Zone // used only for ic=true test
@@ -5432,6 +5433,7 @@ var _ = ginkgo.Describe("OVN master EgressIP Operations cluster default network"
54325433
"k8s.ovn.org/node-transit-switch-port-ifaddr": "{\"ipv4\":\"100.88.0.3/16\"}", // used only for ic=true test
54335434
"k8s.ovn.org/zone-name": node2Zone, // used only for ic=true test
54345435
util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", node2IPv4CIDR),
5436+
util.OVNNodeGRLRPAddrs: fmt.Sprintf(`{"default":{"ipv4":"%s/16"}}`, node2LogicalRouterIPv4[0]),
54355437
}
54365438
if node2Zone != "global" {
54375439
annotations["k8s.ovn.org/remote-zone-migrated"] = node2Zone // used only for ic=true test

go-controller/pkg/ovn/egressip_udn_l2_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ var _ = ginkgo.Describe("EgressIP Operations for user defined network with topol
304304
fakeOvn.controller.eIPC.nodeZoneState.Store(node2Name, false)
305305
fakeOvn.controller.eIPC.zone = node1.Name
306306
fakeOvn.controller.zone = node1.Name
307-
err = fakeOvn.eIPController.ensureRouterPoliciesForNetwork(netInfo)
307+
err = fakeOvn.eIPController.ensureRouterPoliciesForNetwork(netInfo, &node1)
308308
gomega.Expect(err).NotTo(gomega.HaveOccurred())
309309
err = fakeOvn.eIPController.ensureSwitchPoliciesForNode(netInfo, node1Name)
310310
gomega.Expect(err).NotTo(gomega.HaveOccurred())
@@ -670,7 +670,7 @@ var _ = ginkgo.Describe("EgressIP Operations for user defined network with topol
670670
gomega.Expect(err).NotTo(gomega.HaveOccurred())
671671
defer fakeOvn.networkManager.Stop()
672672
// simulate Start() of secondary network controller
673-
err = fakeOvn.eIPController.ensureRouterPoliciesForNetwork(secConInfo.bnc.GetNetInfo())
673+
err = fakeOvn.eIPController.ensureRouterPoliciesForNetwork(secConInfo.bnc.GetNetInfo(), &node1)
674674
gomega.Expect(err).NotTo(gomega.HaveOccurred())
675675
err = fakeOvn.eIPController.ensureSwitchPoliciesForNode(secConInfo.bnc.GetNetInfo(), node1Name)
676676
gomega.Expect(err).NotTo(gomega.HaveOccurred())
@@ -1662,7 +1662,7 @@ var _ = ginkgo.Describe("EgressIP Operations for user defined network with topol
16621662
defer fakeOvn.networkManager.Stop()
16631663
err = fakeOvn.controller.WatchEgressNodes()
16641664
gomega.Expect(err).NotTo(gomega.HaveOccurred())
1665-
err = fakeOvn.eIPController.ensureRouterPoliciesForNetwork(netInfo)
1665+
err = fakeOvn.eIPController.ensureRouterPoliciesForNetwork(netInfo, &node1)
16661666
gomega.Expect(err).NotTo(gomega.HaveOccurred())
16671667
err = fakeOvn.eIPController.ensureSwitchPoliciesForNode(netInfo, node1Name)
16681668
gomega.Expect(err).NotTo(gomega.HaveOccurred())
@@ -2026,7 +2026,7 @@ var _ = ginkgo.Describe("EgressIP Operations for user defined network with topol
20262026
err = fakeOvn.networkManager.Start()
20272027
gomega.Expect(err).NotTo(gomega.HaveOccurred())
20282028
defer fakeOvn.networkManager.Stop()
2029-
err = fakeOvn.eIPController.ensureRouterPoliciesForNetwork(netInfo)
2029+
err = fakeOvn.eIPController.ensureRouterPoliciesForNetwork(netInfo, &node1)
20302030
gomega.Expect(err).NotTo(gomega.HaveOccurred())
20312031
err = fakeOvn.eIPController.ensureSwitchPoliciesForNode(netInfo, node1Name)
20322032
gomega.Expect(err).NotTo(gomega.HaveOccurred())

0 commit comments

Comments
 (0)