@@ -1323,6 +1323,88 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
13231323 framework .ExpectNoError (err )
13241324 }
13251325 })
1326+
1327+ framework .ConformanceIt ("should create and delete keepSrcMac OpenFlow rules when u2oInterconnection is enabled" , func () {
1328+ f .SkipVersionPriorTo (1 , 14 , "keepSrcMac OpenFlow rules were introduced in v1.14" )
1329+
1330+ ginkgo .By ("Creating provider network " + providerNetworkName )
1331+ pn := makeProviderNetwork (providerNetworkName , false , linkMap )
1332+ _ = providerNetworkClient .CreateSync (pn )
1333+
1334+ ginkgo .By ("Getting docker network " + dockerNetworkName )
1335+ network , err := docker .NetworkInspect (dockerNetworkName )
1336+ framework .ExpectNoError (err , "getting docker network " + dockerNetworkName )
1337+
1338+ ginkgo .By ("Creating vlan " + vlanName )
1339+ vlan := framework .MakeVlan (vlanName , providerNetworkName , 0 )
1340+ _ = vlanClient .Create (vlan )
1341+
1342+ ginkgo .By ("Creating underlay subnet " + subnetName )
1343+ var cidrV4 , cidrV6 , gatewayV4 , gatewayV6 string
1344+ for _ , config := range dockerNetwork .IPAM .Config {
1345+ switch util .CheckProtocol (config .Subnet ) {
1346+ case apiv1 .ProtocolIPv4 :
1347+ if f .HasIPv4 () {
1348+ cidrV4 = config .Subnet
1349+ gatewayV4 = config .Gateway
1350+ }
1351+ case apiv1 .ProtocolIPv6 :
1352+ if f .HasIPv6 () {
1353+ cidrV6 = config .Subnet
1354+ gatewayV6 = config .Gateway
1355+ }
1356+ }
1357+ }
1358+ underlayCidr := make ([]string , 0 , 2 )
1359+ gateway := make ([]string , 0 , 2 )
1360+ if f .HasIPv4 () {
1361+ underlayCidr = append (underlayCidr , cidrV4 )
1362+ gateway = append (gateway , gatewayV4 )
1363+ }
1364+ if f .HasIPv6 () {
1365+ underlayCidr = append (underlayCidr , cidrV6 )
1366+ gateway = append (gateway , gatewayV6 )
1367+ }
1368+
1369+ excludeIPs := make ([]string , 0 , len (network .Containers )* 2 )
1370+ for _ , container := range network .Containers {
1371+ if container .IPv4Address != "" && f .HasIPv4 () {
1372+ excludeIPs = append (excludeIPs , strings .Split (container .IPv4Address , "/" )[0 ])
1373+ }
1374+ if container .IPv6Address != "" && f .HasIPv6 () {
1375+ excludeIPs = append (excludeIPs , strings .Split (container .IPv6Address , "/" )[0 ])
1376+ }
1377+ }
1378+
1379+ ginkgo .By ("Creating underlay subnet with u2oInterconnection enabled " + subnetName )
1380+ subnet := framework .MakeSubnet (subnetName , vlanName , strings .Join (underlayCidr , "," ), strings .Join (gateway , "," ), "" , "" , excludeIPs , nil , []string {namespaceName })
1381+ subnet .Spec .U2OInterconnection = true
1382+ _ = subnetClient .CreateSync (subnet )
1383+
1384+ ginkgo .By ("Waiting for U2OInterconnection status to be ready" )
1385+ waitSubnetU2OStatus (f , subnetName , subnetClient , true )
1386+
1387+ ginkgo .By ("Creating underlay pod " + u2oPodNameUnderlay )
1388+ annotations := map [string ]string {
1389+ util .LogicalSwitchAnnotation : subnetName ,
1390+ }
1391+ args := []string {"netexec" , "--http-port" , strconv .Itoa (curlListenPort )}
1392+ underlayPod := framework .MakePod (namespaceName , u2oPodNameUnderlay , nil , annotations , framework .AgnhostImage , nil , args )
1393+ underlayPod = podClient .CreateSync (underlayPod )
1394+ waitSubnetStatusUpdate (subnetName , subnetClient , 2 )
1395+
1396+ ginkgo .By ("Verifying keepSrcMac OpenFlow rules exist after pod creation" )
1397+ checkKeepSrcMacFlow (underlayPod , providerNetworkName , true )
1398+
1399+ ginkgo .By ("Deleting underlay pod " + u2oPodNameUnderlay )
1400+ podClient .DeleteSync (u2oPodNameUnderlay )
1401+ waitSubnetStatusUpdate (subnetName , subnetClient , 1 )
1402+
1403+ ginkgo .By ("Verifying keepSrcMac OpenFlow rules are deleted after pod deletion" )
1404+ // Wait a bit for the flow rules to be cleaned up
1405+ time .Sleep (2 * time .Second )
1406+ checkKeepSrcMacFlow (underlayPod , providerNetworkName , false )
1407+ })
13261408})
13271409
13281410func checkU2OItems (f * framework.Framework , subnet * apiv1.Subnet , underlayPod , overlayPod * corev1.Pod , isU2OCustomVpc bool , pnName string ) {
@@ -1503,25 +1585,26 @@ func checkReachable(podName, podNamespace, sourceIP, targetIP, targetPort string
15031585func checkKeepSrcMacFlow (pod * corev1.Pod , providerNetworkName string , expectRules bool ) {
15041586 ginkgo .GinkgoHelper ()
15051587
1506- cmd := fmt .Sprintf ("kubectl exec -n %s %s -- ip -o link show eth0 | awk '{print $16}'" , pod .Namespace , pod .Name )
1507- output , err := exec .Command ("bash" , "-c" , cmd ).CombinedOutput ()
1508- if err != nil {
1509- framework .Logf ("Error getting MAC address: %v, %s" , err , string (output ))
1510- return
1511- }
1512- podMac := strings .TrimSpace (string (output ))
1513-
15141588 podNodeName := pod .Spec .NodeName
1515- ginkgo .By (fmt .Sprintf ("Checking keepSrcMac OpenFlow rule on node %s for Pod %s with MAC %s (expect rules: %v)" ,
1516- podNodeName , pod .Name , podMac , expectRules ))
1589+ framework .Logf ("Checking keepSrcMac OpenFlow rule on node %s for Pod %s" , podNodeName , pod .Name )
1590+
1591+ podMac := pod .Annotations [util .MacAddressAnnotation ]
1592+ if podMac == "" {
1593+ if ! expectRules {
1594+ return
1595+ }
1596+ }
15171597
15181598 var ruleFound bool
15191599 framework .WaitUntil (1 * time .Second , 5 * time .Second , func (_ context.Context ) (bool , error ) {
15201600 nodeCmd := fmt .Sprintf ("kubectl ko ofctl %s dump-flows br-%s | grep actions=mod_dl_src:%s | wc -l" ,
15211601 podNodeName , providerNetworkName , podMac )
1522- output , _ := exec .Command ("bash" , "-c" , nodeCmd ).CombinedOutput ()
1523- outputStr := string (output )
1602+ output , err := exec .Command ("bash" , "-c" , nodeCmd ).CombinedOutput ()
1603+ if err != nil {
1604+ return false , nil
1605+ }
15241606
1607+ outputStr := string (output )
15251608 lines := strings .Split (outputStr , "\n " )
15261609 var countStr string
15271610 for i := len (lines ) - 1 ; i >= 0 ; i -- {
@@ -1538,18 +1621,12 @@ func checkKeepSrcMacFlow(pod *corev1.Pod, providerNetworkName string, expectRule
15381621 countNum , _ = strconv .Atoi (matches [0 ])
15391622 }
15401623
1541- framework .Logf ("Raw output: '%s', extracted count: %d" , outputStr , countNum )
15421624 ruleFound = countNum > 0
15431625
15441626 if (expectRules && ruleFound ) || (! expectRules && ! ruleFound ) {
15451627 return true , nil
15461628 }
15471629
1548- if expectRules {
1549- framework .Logf ("keepSrcMac flow rule not found but expected, retrying..." )
1550- } else {
1551- framework .Logf ("keepSrcMac flow rule found but not expected, retrying..." )
1552- }
15531630 return false , nil
15541631 }, "" )
15551632
0 commit comments