@@ -34,7 +34,9 @@ const (
3434 // tcpdumpGeneveFilter can be used to filter out Geneve encapsulated packets destined to target node.
3535 tcpdumpGeneveFilter = "udp port 6081 and src %s and dst %s"
3636 // tcpdumpICMPFilter can be used to filter out icmp packets destined to target node.
37- tcpdumpICMPFilter = "icmp and src %s and dst %s"
37+ tcpdumpICMPFilter = "icmp and src %s and dst %s"
38+ // tcpdumpNATTFilter can be used to filter out NAT-T encapsulated packets destined to target node.
39+ tcpdumpNATTFilter = "udp port 4500 and src %s and dst %s"
3840 masterIPsecMachineConfigName = "80-ipsec-master-extensions"
3941 workerIPSecMachineConfigName = "80-ipsec-worker-extensions"
4042 ipsecRolloutWaitDuration = 40 * time .Minute
@@ -95,27 +97,50 @@ var (
9597
9698type trafficType string
9799
100+ type ipsecConfig struct {
101+ mode v1.IPsecMode
102+ encap v1.Encapsulation
103+ }
104+
98105const (
99106 esp trafficType = "esp"
100107 geneve trafficType = "geneve"
101108 icmp trafficType = "icmp"
109+ natt trafficType = "natt"
102110)
103111
104- func getIPsecMode (oc * exutil.CLI ) (v1. IPsecMode , error ) {
112+ func getIPsecConfig (oc * exutil.CLI ) (* ipsecConfig , error ) {
105113 network , err := oc .AdminOperatorClient ().OperatorV1 ().Networks ().Get (context .Background (), "cluster" , metav1.GetOptions {})
106114 if err != nil {
107- return v1 . IPsecModeDisabled , err
115+ return nil , err
108116 }
109117 conf := network .Spec .DefaultNetwork .OVNKubernetesConfig
118+ mode := getIPsecMode (conf )
119+ encap := getIPsecEncap (conf )
120+ return & ipsecConfig {mode : mode ,
121+ encap : encap }, nil
122+ }
123+
124+ func getIPsecMode (ovnkCfg * v1.OVNKubernetesConfig ) v1.IPsecMode {
110125 mode := v1 .IPsecModeDisabled
111- if conf .IPsecConfig != nil {
112- if conf .IPsecConfig .Mode != "" {
113- mode = conf .IPsecConfig .Mode
126+ if ovnkCfg .IPsecConfig != nil {
127+ if ovnkCfg .IPsecConfig .Mode != "" {
128+ mode = ovnkCfg .IPsecConfig .Mode
114129 } else {
115130 mode = v1 .IPsecModeFull // Backward compatibility with existing configs
116131 }
117132 }
118- return mode , nil
133+ return mode
134+ }
135+
136+ func getIPsecEncap (ovnkCfg * v1.OVNKubernetesConfig ) v1.Encapsulation {
137+ encapType := v1 .Encapsulation (v1 .EncapsulationAuto )
138+ if ovnkCfg .IPsecConfig != nil &&
139+ ovnkCfg .IPsecConfig .Mode == v1 .IPsecModeFull &&
140+ ovnkCfg .IPsecConfig .Full != nil {
141+ encapType = ovnkCfg .IPsecConfig .Full .Encapsulation
142+ }
143+ return encapType
119144}
120145
121146// ensureIPsecFullEnabled this function ensure IPsec is enabled by making sure ovn-ipsec-host daemonset
@@ -237,7 +262,7 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
237262 nodeIP string
238263 }
239264 type testConfig struct {
240- ipsecMode v1. IPsecMode
265+ ipsecCfg * ipsecConfig
241266 srcNodeConfig * testNodeConfig
242267 dstNodeConfig * testNodeConfig
243268 }
@@ -261,6 +286,9 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
261286 case icmp :
262287 srcNodeTrafficFilter = fmt .Sprintf (tcpdumpICMPFilter , src .tcpdumpPod .Status .PodIP , dst .tcpdumpPod .Status .PodIP )
263288 dstNodeTrafficFilter = fmt .Sprintf (tcpdumpICMPFilter , dst .tcpdumpPod .Status .PodIP , src .tcpdumpPod .Status .PodIP )
289+ case natt :
290+ srcNodeTrafficFilter = fmt .Sprintf (tcpdumpNATTFilter , src .tcpdumpPod .Status .PodIP , dst .tcpdumpPod .Status .PodIP )
291+ dstNodeTrafficFilter = fmt .Sprintf (tcpdumpNATTFilter , dst .tcpdumpPod .Status .PodIP , src .tcpdumpPod .Status .PodIP )
264292 }
265293 checkSrcNodeTraffic := func (src * testNodeConfig ) error {
266294 _ , err := oc .AsAdmin ().Run ("exec" ).Args (src .tcpdumpPod .Name , "-n" , src .tcpdumpPod .Namespace , "--" ,
@@ -370,6 +398,8 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
370398 o .Expect (err ).To (o .HaveOccurred ())
371399 err = pingAndCheckNodeTraffic (config .srcNodeConfig , config .dstNodeConfig , icmp )
372400 o .Expect (err ).To (o .HaveOccurred ())
401+ err = pingAndCheckNodeTraffic (config .srcNodeConfig , config .dstNodeConfig , natt )
402+ o .Expect (err ).To (o .HaveOccurred ())
373403 err = nil
374404 }
375405
@@ -388,13 +418,37 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
388418 o .Expect (err ).NotTo (o .HaveOccurred ())
389419 err = pingAndCheckNodeTraffic (config .srcNodeConfig , config .dstNodeConfig , geneve )
390420 o .Expect (err ).To (o .HaveOccurred ())
421+ err = pingAndCheckNodeTraffic (config .srcNodeConfig , config .dstNodeConfig , natt )
422+ o .Expect (err ).To (o .HaveOccurred ())
423+ err = nil
424+ }
425+
426+ checkForNATTOnlyPodTraffic := func (config * testConfig ) {
427+ g .GinkgoHelper ()
428+ err := setupTestPods (config , false )
429+ o .Expect (err ).NotTo (o .HaveOccurred ())
430+ defer func () {
431+ // Don't cleanup test pods in error scenario.
432+ if err != nil && ! framework .TestContext .DeleteNamespaceOnFailure {
433+ return
434+ }
435+ cleanupTestPods (config )
436+ }()
437+ err = pingAndCheckNodeTraffic (config .srcNodeConfig , config .dstNodeConfig , natt )
438+ o .Expect (err ).NotTo (o .HaveOccurred ())
439+ err = pingAndCheckNodeTraffic (config .srcNodeConfig , config .dstNodeConfig , geneve )
440+ o .Expect (err ).To (o .HaveOccurred ())
441+ err = pingAndCheckNodeTraffic (config .srcNodeConfig , config .dstNodeConfig , esp )
442+ o .Expect (err ).To (o .HaveOccurred ())
391443 err = nil
392444 }
393445
394- checkPodTraffic := func (mode v1. IPsecMode ) {
446+ checkPodTraffic := func (ipsecCfg * ipsecConfig ) {
395447 g .GinkgoHelper ()
396- if mode == v1 .IPsecModeFull {
448+ if ipsecCfg . mode == v1 .IPsecModeFull && ipsecCfg . encap == v1 . EncapsulationAuto {
397449 checkForESPOnlyPodTraffic (config )
450+ } else if ipsecCfg .mode == v1 .IPsecModeFull && ipsecCfg .encap == v1 .EncapsulationAlways {
451+ checkForNATTOnlyPodTraffic (config )
398452 } else {
399453 checkForGeneveOnlyPodTraffic (config )
400454 }
@@ -427,12 +481,12 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
427481 g .BeforeAll (func () {
428482 // Set up the config object with existing IPsecConfig, setup testing config on
429483 // the selected nodes.
430- ipsecMode , err := getIPsecMode (oc )
484+ ipsecConfig , err := getIPsecConfig (oc )
431485 o .Expect (err ).NotTo (o .HaveOccurred ())
432- o .Expect (ipsecMode ).NotTo (o .Equal (v1 .IPsecModeDisabled ))
486+ o .Expect (ipsecConfig . mode ).NotTo (o .Equal (v1 .IPsecModeDisabled ))
433487
434488 srcNode , dstNode := & testNodeConfig {}, & testNodeConfig {}
435- config = & testConfig {ipsecMode : ipsecMode , srcNodeConfig : srcNode ,
489+ config = & testConfig {ipsecCfg : ipsecConfig , srcNodeConfig : srcNode ,
436490 dstNodeConfig : dstNode }
437491
438492 // Deploy nmstate handler which is used for rolling out IPsec config
@@ -463,7 +517,7 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
463517 return areMachineConfigPoolsReadyWithMachineConfig (pools , nsCertMachineConfigName )
464518 }, ipsecRolloutWaitDuration , ipsecRolloutWaitInterval ).Should (o .BeTrue ())
465519 // Ensure IPsec mode is still correctly configured.
466- waitForIPsecConfigToComplete (oc , config . ipsecMode )
520+ waitForIPsecConfigToComplete (oc , ipsecConfig . mode )
467521 })
468522
469523 g .BeforeEach (func () {
@@ -494,10 +548,10 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
494548 })
495549
496550 g .AfterEach (func () {
497- ipsecMode , err := getIPsecMode (oc )
551+ ipsecConfig , err := getIPsecConfig (oc )
498552 o .Expect (err ).NotTo (o .HaveOccurred ())
499553 if g .CurrentSpecReport ().Failed () {
500- if ipsecMode == v1 .IPsecModeFull {
554+ if ipsecConfig . mode == v1 .IPsecModeFull {
501555 var ipsecPods []string
502556 srcIPsecPod , err := findIPsecPodonNode (oc , config .srcNodeConfig .nodeName )
503557 o .Expect (err ).NotTo (o .HaveOccurred ())
@@ -545,15 +599,16 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
545599
546600 g .It ("check traffic with IPsec [apigroup:config.openshift.io] [Suite:openshift/network/ipsec]" , func () {
547601 o .Expect (config ).NotTo (o .BeNil ())
602+ o .Expect (config .ipsecCfg ).NotTo (o .BeNil ())
548603
549604 g .By ("validate traffic before changing IPsec configuration" )
550- checkPodTraffic (config .ipsecMode )
605+ checkPodTraffic (config .ipsecCfg )
551606 // N/S ipsec config is not in effect yet, so node traffic behaves as it were disabled
552607 checkNodeTraffic (v1 .IPsecModeDisabled )
553608
554609 // TODO: remove this block when https://issues.redhat.com/browse/RHEL-67307 is fixed.
555- if config .ipsecMode == v1 .IPsecModeFull {
556- g .By (fmt .Sprintf ("skip testing IPsec NS configuration with %s mode due to nmstate bug RHEL-67307" , config .ipsecMode ))
610+ if config .ipsecCfg . mode == v1 .IPsecModeFull {
611+ g .By (fmt .Sprintf ("skip testing IPsec NS configuration with %s mode due to nmstate bug RHEL-67307" , config .ipsecCfg . mode ))
557612 return
558613 }
559614
@@ -581,7 +636,8 @@ var _ = g.Describe("[sig-network][Feature:IPsec]", g.Ordered, func() {
581636
582637 g .By ("validate IPsec traffic between nodes" )
583638 // Pod traffic will be encrypted as a result N/S encryption being enabled between this two nodes
584- checkPodTraffic (v1 .IPsecModeFull )
639+ checkPodTraffic (& ipsecConfig {mode : v1 .IPsecModeFull ,
640+ encap : v1 .Encapsulation (v1 .EncapsulationAuto )})
585641 checkNodeTraffic (v1 .IPsecModeExternal )
586642 })
587643 })
0 commit comments