Skip to content

Commit 4a06d4b

Browse files
authored
Merge pull request #5396 from npinaeva/remove-joinip-anno
Remove OVNNodeGRLRPAddrs annotation
2 parents da01d12 + e4d2b28 commit 4a06d4b

39 files changed

+758
-1069
lines changed

go-controller/hybrid-overlay/pkg/controller/ovn_node_linux.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
hotypes "github.com/ovn-org/ovn-kubernetes/go-controller/hybrid-overlay/pkg/types"
2323
houtil "github.com/ovn-org/ovn-kubernetes/go-controller/hybrid-overlay/pkg/util"
2424
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config"
25+
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/generator/udn"
2526
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/kube"
2627
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types"
2728
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util"
@@ -499,7 +500,7 @@ func (n *NodeController) EnsureHybridOverlayBridge(node *corev1.Node) error {
499500
return nil
500501
}
501502
if n.gwLRPIP == nil {
502-
gwLRPIP, err := util.ParseNodeGatewayRouterJoinIPv4(node, types.DefaultNetworkName)
503+
gwLRPIP, err := udn.GetGWRouterIPv4(node, &util.DefaultNetInfo{})
503504
if err != nil {
504505
return fmt.Errorf("invalid Gateway Router LRP IP: %v", err)
505506
}

go-controller/hybrid-overlay/pkg/controller/ovn_node_linux_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ var _ = Describe("Hybrid Overlay Node Linux Operations", func() {
395395
app.Action = func(ctx *cli.Context) error {
396396
annotations := createNodeAnnotationsForSubnet(thisNodeSubnet)
397397
annotations[hotypes.HybridOverlayDRMAC] = thisNodeDRMAC
398-
annotations[util.OVNNodeGRLRPAddrs] = "{\"default\":{\"ipv4\":\"100.64.0.3/16\"}}"
398+
annotations[util.OvnNodeID] = "3"
399399
annotations[hotypes.HybridOverlayDRIP] = thisNodeDRIP
400400
node := createNode(thisNode, "linux", thisNodeIP, annotations)
401401
fakeClient := fake.NewSimpleClientset(&corev1.NodeList{
@@ -461,13 +461,13 @@ var _ = Describe("Hybrid Overlay Node Linux Operations", func() {
461461

462462
annotations := createNodeAnnotationsForSubnet(thisNodeSubnet)
463463
annotations[hotypes.HybridOverlayDRMAC] = thisNodeDRMAC
464-
annotations[util.OVNNodeGRLRPAddrs] = "{\"default\":{\"ipv4\":\"100.64.0.3/16\"}}"
464+
annotations[util.OvnNodeID] = "3"
465465
annotations[hotypes.HybridOverlayDRIP] = thisNodeDRIP
466466
node := createNode(thisNode, "linux", thisNodeIP, annotations)
467467

468468
remoteNodeAnnotations := createNodeAnnotationsForSubnet(remoteNodeSubnet)
469469
remoteNodeAnnotations[hotypes.HybridOverlayDRMAC] = remoteNodeDRMAC
470-
remoteNodeAnnotations[util.OVNNodeGRLRPAddrs] = "{\"default\":{\"ipv4\":\"100.65.0.3/16\"}}"
470+
remoteNodeAnnotations[util.OvnNodeID] = "3"
471471
remoteNodeAnnotations[hotypes.HybridOverlayDRIP] = "1.2.4.3"
472472
remoteNode := createNode(remoteNodeName, "linux", "10.20.20.1", remoteNodeAnnotations)
473473

@@ -564,7 +564,7 @@ var _ = Describe("Hybrid Overlay Node Linux Operations", func() {
564564

565565
annotations := createNodeAnnotationsForSubnet(thisNodeSubnet)
566566
annotations[hotypes.HybridOverlayDRMAC] = thisNodeDRMAC
567-
annotations[util.OVNNodeGRLRPAddrs] = "{\"default\":{\"ipv4\":\"100.64.0.3/16\"}}"
567+
annotations[util.OvnNodeID] = "3"
568568
annotations[hotypes.HybridOverlayDRIP] = thisNodeDRIP
569569
node := createNode(thisNode, "linux", thisNodeIP, annotations)
570570
testPod := createPod("test", "pod1", thisNode, pod1CIDR, pod1MAC)
@@ -648,7 +648,7 @@ var _ = Describe("Hybrid Overlay Node Linux Operations", func() {
648648

649649
annotations := createNodeAnnotationsForSubnet(thisNodeSubnet)
650650
annotations[hotypes.HybridOverlayDRMAC] = thisNodeDRMAC
651-
annotations[util.OVNNodeGRLRPAddrs] = "{\"default\":{\"ipv4\":\"100.64.0.3/16\"}}"
651+
annotations[util.OvnNodeID] = "3"
652652
annotations[hotypes.HybridOverlayDRIP] = thisNodeDRIP
653653
node := createNode(thisNode, "linux", thisNodeIP, annotations)
654654
fakeClient := fake.NewSimpleClientset(&corev1.NodeList{
@@ -748,7 +748,7 @@ var _ = Describe("Hybrid Overlay Node Linux Operations", func() {
748748

749749
annotations := createNodeAnnotationsForSubnet(thisNodeSubnet)
750750
annotations[hotypes.HybridOverlayDRMAC] = thisNodeDRMAC
751-
annotations[util.OVNNodeGRLRPAddrs] = "{\"default\":{\"ipv4\":\"100.64.0.3/16\"}}"
751+
annotations[util.OvnNodeID] = "3"
752752
annotations[hotypes.HybridOverlayDRIP] = thisNodeDRIP
753753
node := createNode(thisNode, "linux", thisNodeIP, annotations)
754754
fakeClient := fake.NewSimpleClientset(&corev1.NodeList{
@@ -888,7 +888,7 @@ var _ = Describe("Hybrid Overlay Node Linux Operations", func() {
888888

889889
annotations := createNodeAnnotationsForSubnet(thisNodeSubnet)
890890
annotations[hotypes.HybridOverlayDRMAC] = thisNodeDRMAC
891-
annotations[util.OVNNodeGRLRPAddrs] = "{\"default\":{\"ipv4\":\"100.64.0.3/16\"}}"
891+
annotations[util.OvnNodeID] = "3"
892892
annotations[hotypes.HybridOverlayDRIP] = thisNodeDRIP
893893
node := createNode(thisNode, "linux", thisNodeIP, annotations)
894894
fakeClient := fake.NewSimpleClientset(&corev1.NodeList{
@@ -1017,7 +1017,7 @@ var _ = Describe("Hybrid Overlay Node Linux Operations", func() {
10171017

10181018
annotations := createNodeAnnotationsForSubnet(thisNodeSubnet)
10191019
annotations[hotypes.HybridOverlayDRMAC] = thisNodeDRMAC
1020-
annotations[util.OVNNodeGRLRPAddrs] = "{\"default\":{\"ipv4\":\"100.64.0.3/16\"}}"
1020+
annotations[util.OvnNodeID] = "3"
10211021
annotations[hotypes.HybridOverlayDRIP] = thisNodeDRIP
10221022
node := createNode(thisNode, "linux", thisNodeIP, annotations)
10231023
fakeClient := fake.NewSimpleClientset(&corev1.NodeList{

go-controller/pkg/allocator/pod/pod_annotation.go

Lines changed: 188 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ import (
1010
corev1 "k8s.io/api/core/v1"
1111
listers "k8s.io/client-go/listers/core/v1"
1212
"k8s.io/klog/v2"
13+
utilnet "k8s.io/utils/net"
1314

1415
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/allocator/id"
1516
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/allocator/ip"
1617
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/allocator/ip/subnet"
18+
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config"
19+
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/generator/udn"
1720
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/kube"
1821
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/persistentips"
1922
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types"
@@ -434,7 +437,7 @@ func allocatePodAnnotationWithRollback(
434437
}
435438

436439
// handle routes & gateways
437-
err = util.AddRoutesGatewayIP(netInfo, node, pod, tentative, network)
440+
err = AddRoutesGatewayIP(netInfo, node, pod, tentative, network)
438441
if err != nil {
439442
return
440443
}
@@ -456,3 +459,187 @@ func allocatePodAnnotationWithRollback(
456459

457460
return
458461
}
462+
463+
func joinSubnetToRoute(netinfo util.NetInfo, isIPv6 bool, gatewayIP net.IP) util.PodRoute {
464+
joinSubnet := netinfo.JoinSubnetV4()
465+
if isIPv6 {
466+
joinSubnet = netinfo.JoinSubnetV6()
467+
}
468+
return util.PodRoute{
469+
Dest: joinSubnet,
470+
NextHop: gatewayIP,
471+
}
472+
}
473+
474+
func serviceCIDRToRoute(isIPv6 bool, gatewayIP net.IP) []util.PodRoute {
475+
var podRoutes []util.PodRoute
476+
for _, serviceSubnet := range config.Kubernetes.ServiceCIDRs {
477+
if isIPv6 == utilnet.IsIPv6CIDR(serviceSubnet) {
478+
podRoutes = append(podRoutes, util.PodRoute{
479+
Dest: serviceSubnet,
480+
NextHop: gatewayIP,
481+
})
482+
}
483+
}
484+
return podRoutes
485+
}
486+
487+
func hairpinMasqueradeIPToRoute(isIPv6 bool, gatewayIP net.IP) util.PodRoute {
488+
ip := config.Gateway.MasqueradeIPs.V4OVNServiceHairpinMasqueradeIP
489+
if isIPv6 {
490+
ip = config.Gateway.MasqueradeIPs.V6OVNServiceHairpinMasqueradeIP
491+
}
492+
return util.PodRoute{
493+
Dest: &net.IPNet{
494+
IP: ip,
495+
Mask: util.GetIPFullMask(ip),
496+
},
497+
NextHop: gatewayIP,
498+
}
499+
}
500+
501+
// addRoutesGatewayIP updates the provided pod annotation for the provided pod
502+
// with the gateways derived from the allocated IPs
503+
func AddRoutesGatewayIP(
504+
netinfo util.NetInfo,
505+
node *corev1.Node,
506+
pod *corev1.Pod,
507+
podAnnotation *util.PodAnnotation,
508+
network *nadapi.NetworkSelectionElement) error {
509+
510+
// generate the nodeSubnets from the allocated IPs
511+
nodeSubnets := util.IPsToNetworkIPs(podAnnotation.IPs...)
512+
513+
if netinfo.IsSecondary() {
514+
// for secondary network, see if its network-attachment's annotation has default-route key.
515+
// If present, then we need to add default route for it
516+
podAnnotation.Gateways = append(podAnnotation.Gateways, network.GatewayRequest...)
517+
topoType := netinfo.TopologyType()
518+
switch topoType {
519+
case types.LocalnetTopology:
520+
// no route needed for directly connected subnets
521+
return nil
522+
case types.Layer2Topology:
523+
if !util.IsNetworkSegmentationSupportEnabled() || !netinfo.IsPrimaryNetwork() {
524+
return nil
525+
}
526+
for _, podIfAddr := range podAnnotation.IPs {
527+
isIPv6 := utilnet.IsIPv6CIDR(podIfAddr)
528+
nodeSubnet, err := util.MatchFirstIPNetFamily(isIPv6, nodeSubnets)
529+
if err != nil {
530+
return err
531+
}
532+
gatewayIPnet := util.GetNodeGatewayIfAddr(nodeSubnet)
533+
// Ensure default service network traffic always goes to OVN
534+
podAnnotation.Routes = append(podAnnotation.Routes, serviceCIDRToRoute(isIPv6, gatewayIPnet.IP)...)
535+
// Ensure UDN join subnet traffic always goes to UDN LSP
536+
podAnnotation.Routes = append(podAnnotation.Routes, joinSubnetToRoute(netinfo, isIPv6, gatewayIPnet.IP))
537+
if network != nil && len(network.GatewayRequest) == 0 { // if specific default route for pod was not requested then add gatewayIP
538+
podAnnotation.Gateways = append(podAnnotation.Gateways, gatewayIPnet.IP)
539+
}
540+
}
541+
// Until https://github.com/ovn-kubernetes/ovn-kubernetes/issues/4876 is fixed, it is limited to IC only
542+
if config.OVNKubernetesFeature.EnableInterconnect {
543+
if _, isIPv6Mode := netinfo.IPMode(); isIPv6Mode {
544+
joinAddrs, err := udn.GetGWRouterIPs(node, netinfo.GetNetInfo())
545+
if err != nil {
546+
if util.IsAnnotationNotSetError(err) {
547+
return types.NewSuppressedError(err)
548+
}
549+
return fmt.Errorf("failed parsing node gateway router join addresses, network %q, %w", netinfo.GetNetworkName(), err)
550+
}
551+
podAnnotation.GatewayIPv6LLA = util.HWAddrToIPv6LLA(util.IPAddrToHWAddr(joinAddrs[0].IP))
552+
}
553+
}
554+
return nil
555+
case types.Layer3Topology:
556+
for _, podIfAddr := range podAnnotation.IPs {
557+
isIPv6 := utilnet.IsIPv6CIDR(podIfAddr)
558+
nodeSubnet, err := util.MatchFirstIPNetFamily(isIPv6, nodeSubnets)
559+
if err != nil {
560+
return err
561+
}
562+
gatewayIPnet := util.GetNodeGatewayIfAddr(nodeSubnet)
563+
for _, clusterSubnet := range netinfo.Subnets() {
564+
if isIPv6 == utilnet.IsIPv6CIDR(clusterSubnet.CIDR) {
565+
podAnnotation.Routes = append(podAnnotation.Routes, util.PodRoute{
566+
Dest: clusterSubnet.CIDR,
567+
NextHop: gatewayIPnet.IP,
568+
})
569+
}
570+
}
571+
if !util.IsNetworkSegmentationSupportEnabled() || !netinfo.IsPrimaryNetwork() {
572+
continue
573+
}
574+
// Ensure default service network traffic always goes to OVN
575+
podAnnotation.Routes = append(podAnnotation.Routes, serviceCIDRToRoute(isIPv6, gatewayIPnet.IP)...)
576+
// Ensure UDN join subnet traffic always goes to UDN LSP
577+
podAnnotation.Routes = append(podAnnotation.Routes, joinSubnetToRoute(netinfo, isIPv6, gatewayIPnet.IP))
578+
if network != nil && len(network.GatewayRequest) == 0 { // if specific default route for pod was not requested then add gatewayIP
579+
podAnnotation.Gateways = append(podAnnotation.Gateways, gatewayIPnet.IP)
580+
}
581+
}
582+
return nil
583+
}
584+
return fmt.Errorf("topology type %s not supported", topoType)
585+
}
586+
587+
// if there are other network attachments for the pod, then check if those network-attachment's
588+
// annotation has default-route key. If present, then we need to skip adding default route for
589+
// OVN interface
590+
networks, err := util.GetK8sPodAllNetworkSelections(pod)
591+
if err != nil {
592+
return fmt.Errorf("error while getting network attachment definition for [%s/%s]: %v",
593+
pod.Namespace, pod.Name, err)
594+
}
595+
otherDefaultRouteV4 := false
596+
otherDefaultRouteV6 := false
597+
for _, network := range networks {
598+
for _, gatewayRequest := range network.GatewayRequest {
599+
if utilnet.IsIPv6(gatewayRequest) {
600+
otherDefaultRouteV6 = true
601+
} else {
602+
otherDefaultRouteV4 = true
603+
}
604+
}
605+
}
606+
607+
for _, podIfAddr := range podAnnotation.IPs {
608+
isIPv6 := utilnet.IsIPv6CIDR(podIfAddr)
609+
nodeSubnet, err := util.MatchFirstIPNetFamily(isIPv6, nodeSubnets)
610+
if err != nil {
611+
return err
612+
}
613+
614+
gatewayIPnet := util.GetNodeGatewayIfAddr(nodeSubnet)
615+
616+
// Ensure default pod network traffic always goes to OVN
617+
for _, clusterSubnet := range config.Default.ClusterSubnets {
618+
if isIPv6 == utilnet.IsIPv6CIDR(clusterSubnet.CIDR) {
619+
podAnnotation.Routes = append(podAnnotation.Routes, util.PodRoute{
620+
Dest: clusterSubnet.CIDR,
621+
NextHop: gatewayIPnet.IP,
622+
})
623+
}
624+
}
625+
626+
if podAnnotation.Role == types.NetworkRolePrimary {
627+
// Ensure default service network traffic always goes to OVN
628+
podAnnotation.Routes = append(podAnnotation.Routes, serviceCIDRToRoute(isIPv6, gatewayIPnet.IP)...)
629+
// Ensure service hairpin masquerade traffic always goes to OVN
630+
podAnnotation.Routes = append(podAnnotation.Routes, hairpinMasqueradeIPToRoute(isIPv6, gatewayIPnet.IP))
631+
otherDefaultRoute := otherDefaultRouteV4
632+
if isIPv6 {
633+
otherDefaultRoute = otherDefaultRouteV6
634+
}
635+
if !otherDefaultRoute {
636+
podAnnotation.Gateways = append(podAnnotation.Gateways, gatewayIPnet.IP)
637+
}
638+
}
639+
640+
// Ensure default join subnet traffic always goes to OVN
641+
podAnnotation.Routes = append(podAnnotation.Routes, joinSubnetToRoute(netinfo, isIPv6, gatewayIPnet.IP))
642+
}
643+
644+
return nil
645+
}

go-controller/pkg/allocator/pod/pod_annotation_test.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -936,17 +936,10 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) {
936936
}
937937
}
938938

939-
ifaddrs := `{"network":{"ipv4":"100.65.0.4/16","ipv6":"fd99::4/64"}}`
940-
if tt.isSingleStackIPv4 {
941-
ifaddrs = `{"network":{"ipv4":"100.65.0.4/16"}}`
942-
} else if tt.isSingleStackIPv6 {
943-
ifaddrs = `{"network":{"ipv6":"fd99::4/64"}}`
944-
}
945-
946939
node := &corev1.Node{
947940
ObjectMeta: metav1.ObjectMeta{
948941
Annotations: map[string]string{
949-
"k8s.ovn.org/node-gateway-router-lrp-ifaddrs": ifaddrs,
942+
"k8s.ovn.org/node-id": "4",
950943
},
951944
},
952945
}

0 commit comments

Comments
 (0)