go.ligato.io/vpp-agent/v3@v3.5.0/tests/e2e/010_interfaces_test.go (about)

     1  //  Copyright (c) 2019 Cisco and/or its affiliates.
     2  //
     3  //  Licensed under the Apache License, Version 2.0 (the "License");
     4  //  you may not use this file except in compliance with the License.
     5  //  You may obtain a copy of the License at:
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  //  Unless required by applicable law or agreed to in writing, software
    10  //  distributed under the License is distributed on an "AS IS" BASIS,
    11  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //  See the License for the specific language governing permissions and
    13  //  limitations under the License.
    14  
    15  package e2e
    16  
    17  import (
    18  	"context"
    19  	"os"
    20  	"testing"
    21  	"time"
    22  
    23  	. "github.com/onsi/gomega"
    24  
    25  	"go.ligato.io/vpp-agent/v3/proto/ligato/kvscheduler"
    26  	linux_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces"
    27  	linux_namespace "go.ligato.io/vpp-agent/v3/proto/ligato/linux/namespace"
    28  	vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    29  	vpp_l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2"
    30  	. "go.ligato.io/vpp-agent/v3/tests/e2e/e2etest"
    31  )
    32  
    33  // connect VPP with a microservice via TAP interface
    34  func TestInterfaceConnTap(t *testing.T) {
    35  	ctx := Setup(t)
    36  	defer ctx.Teardown()
    37  
    38  	const (
    39  		vppTapName       = "vpp-tap"
    40  		linuxTapName     = "linux-tap"
    41  		linuxTapHostname = "tap"
    42  		vppTapIP         = "192.168.1.1"
    43  		linuxTapIP       = "192.168.1.2"
    44  		netMask          = "/30"
    45  		msName           = "microservice1"
    46  	)
    47  
    48  	vppTap := &vpp_interfaces.Interface{
    49  		Name:        vppTapName,
    50  		Type:        vpp_interfaces.Interface_TAP,
    51  		Enabled:     true,
    52  		IpAddresses: []string{vppTapIP + netMask},
    53  		Link: &vpp_interfaces.Interface_Tap{
    54  			Tap: &vpp_interfaces.TapLink{
    55  				Version:        2,
    56  				ToMicroservice: MsNamePrefix + msName,
    57  			},
    58  		},
    59  	}
    60  	linuxTap := &linux_interfaces.Interface{
    61  		Name:        linuxTapName,
    62  		Type:        linux_interfaces.Interface_TAP_TO_VPP,
    63  		Enabled:     true,
    64  		IpAddresses: []string{linuxTapIP + netMask},
    65  		HostIfName:  linuxTapHostname,
    66  		Link: &linux_interfaces.Interface_Tap{
    67  			Tap: &linux_interfaces.TapLink{
    68  				VppTapIfName: vppTapName,
    69  			},
    70  		},
    71  		Namespace: &linux_namespace.NetNamespace{
    72  			Type:      linux_namespace.NetNamespace_MICROSERVICE,
    73  			Reference: MsNamePrefix + msName,
    74  		},
    75  	}
    76  
    77  	ctx.StartMicroservice(msName)
    78  
    79  	// configure TAPs
    80  	err := ctx.GenericClient().ChangeRequest().Update(
    81  		vppTap,
    82  		linuxTap,
    83  	).Send(context.Background())
    84  	ctx.Expect(err).ToNot(HaveOccurred())
    85  
    86  	ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
    87  	ctx.Expect(ctx.GetValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED))
    88  	ctx.Expect(ctx.PingFromVPP(linuxTapIP)).To(Succeed())
    89  	ctx.Expect(ctx.PingFromMs(msName, vppTapIP)).To(Succeed())
    90  
    91  	// resync TAPs
    92  	err = ctx.GenericClient().ResyncConfig(
    93  		vppTap,
    94  		linuxTap,
    95  	)
    96  	ctx.Expect(err).ToNot(HaveOccurred())
    97  
    98  	ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
    99  	ctx.Expect(ctx.GetValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   100  	ctx.Expect(ctx.PingFromVPP(linuxTapIP)).To(Succeed())
   101  	ctx.Expect(ctx.PingFromMs(msName, vppTapIP)).To(Succeed())
   102  
   103  	// restart microservice twice
   104  	for i := 0; i < 2; i++ {
   105  		ctx.StopMicroservice(msName)
   106  		ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_PENDING))
   107  		ctx.Eventually(ctx.GetValueStateClb(linuxTap)).Should(Equal(kvscheduler.ValueState_PENDING))
   108  		ctx.Expect(ctx.PingFromVPP(linuxTapIP)).NotTo(Succeed())
   109  		ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   110  
   111  		ctx.StartMicroservice(msName)
   112  		ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   113  		ctx.Expect(ctx.GetValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   114  		ctx.Expect(ctx.PingFromVPP(linuxTapIP)).To(Succeed())
   115  		ctx.Expect(ctx.PingFromMs(msName, vppTapIP)).To(Succeed())
   116  		ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   117  	}
   118  
   119  	// re-create VPP TAP
   120  	err = ctx.GenericClient().ChangeRequest().
   121  		Delete(vppTap).Send(context.Background())
   122  	ctx.Expect(err).ToNot(HaveOccurred())
   123  
   124  	ctx.Expect(ctx.PingFromVPP(linuxTapIP)).NotTo(Succeed())
   125  	ctx.Expect(ctx.PingFromMs(msName, vppTapIP)).NotTo(Succeed())
   126  
   127  	err = ctx.GenericClient().ChangeRequest().Update(
   128  		vppTap,
   129  	).Send(context.Background())
   130  	ctx.Expect(err).ToNot(HaveOccurred())
   131  
   132  	ctx.Eventually(ctx.PingFromVPPClb(linuxTapIP)).Should(Succeed())
   133  	ctx.Expect(ctx.PingFromMs(msName, vppTapIP)).To(Succeed())
   134  	ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   135  
   136  	// re-create Linux TAP
   137  	err = ctx.GenericClient().ChangeRequest().Delete(
   138  		linuxTap,
   139  	).Send(context.Background())
   140  	ctx.Expect(err).ToNot(HaveOccurred())
   141  
   142  	ctx.Expect(ctx.PingFromVPP(linuxTapIP)).NotTo(Succeed())
   143  	ctx.Expect(ctx.PingFromMs(msName, vppTapIP)).NotTo(Succeed())
   144  
   145  	err = ctx.GenericClient().ChangeRequest().Update(
   146  		linuxTap,
   147  	).Send(context.Background())
   148  	ctx.Expect(err).ToNot(HaveOccurred())
   149  
   150  	ctx.Eventually(ctx.PingFromVPPClb(linuxTapIP)).Should(Succeed())
   151  	ctx.Expect(ctx.PingFromMs(msName, vppTapIP)).To(Succeed())
   152  	ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   153  }
   154  
   155  // +---------------------------------------------------+
   156  // | VPP                                               |
   157  // |                                                   |
   158  // |     +---------------+       +---------------+     |
   159  // |     |192.168.1.10/24|       |192.168.2.20/24|     |
   160  // |     +-------+-------+       +-------+-------+     |
   161  // |             | (SUBIF)               | (SUBIF)     |
   162  // |     +-------+-----------------------+-------+     |
   163  // |     |                                       |     |
   164  // |     +-------------------+-------------------+     |
   165  // +-------------------------|-------------------------+
   166  // -                         | (MEMIF)                 -
   167  // +-------------------------|-------------------------+
   168  // |     +-------------------+-------------------+     |
   169  // |     |                                       |     |
   170  // |     +-------+-----------------------+-------+     |
   171  // |             | (SUBIF)               | (SUBIF)     |
   172  // |     +-------+-------+       +-------+-------+     |
   173  // |     |192.168.1.10/24|       |192.168.2.20/24|     |
   174  // |     +-------+-------+       +-------+-------+     |
   175  // |             |                       |             |
   176  // | VPP         | (BD)                  | (BD)        |
   177  // |             |                       |             |
   178  // |     +-------+-------+       +-------+-------+     |
   179  // |     |192.168.1.11/24|       |192.168.2.22/24|     |
   180  // |     +-------+-------+       +-------+-------+     |
   181  // +-------------|-----------------------|-------------+
   182  // -             | (TAP)                 | (TAP)       -
   183  // +-------------|----------+ +----------|-------------+
   184  // |     +-------+-------+  | |  +-------+-------+     |
   185  // |     |192.168.1.11/24|  | |  |192.168.2.22/24|     |
   186  // |     +-------+-------+  | |  +-------+-------+     |
   187  // |                        | |                        |
   188  // | LINUX                  | |                  LINUX |
   189  // +------------------------+ +------------------------+
   190  //
   191  // This test tests the primarily the following pings:
   192  // from: 192.168.1.10 (left subif in top vpp) to: 192.168.1.11 (left linux microservice) - should pass (same vlan)
   193  // from: 192.168.2.20 (right subif in top vpp) to: 192.168.2.22 (right linux microservice) - should pass (same vlan)
   194  // from: 192.168.1.10 (left subif in top vpp) to: 192.168.2.22 (right linux microservice) - should fail (different vlans)
   195  // from: 192.168.2.20 (right subif in top vpp) to: 192.168.1.11 (left linux microservice) - should fail (different vlans)
   196  func TestMemifSubinterfaceVlanConn(t *testing.T) {
   197  	ctx := Setup(t)
   198  	defer ctx.Teardown()
   199  
   200  	const (
   201  		vpp1MemifName  = "vpp1-to-vpp2"
   202  		vpp2MemifName  = "vpp2-to-vpp1"
   203  		vpp1Subif1Name = "vpp1Subif1"
   204  		vpp1Subif2Name = "vpp1Subif2"
   205  		vpp1Subif1IP   = "192.168.1.10"
   206  		vpp1Subif2IP   = "192.168.2.20"
   207  		vpp2Subif1Name = "vpp2Subif1"
   208  		vpp2Subif2Name = "vpp2Subif2"
   209  		vpp2Tap1Name   = "vpp2-to-ms1"
   210  		vpp2Tap2Name   = "vpp2-to-ms2"
   211  		ms1TapName     = "ms1-to-vpp2"
   212  		ms2TapName     = "ms2-to-vpp2"
   213  		ms1TapIP       = "192.168.1.11"
   214  		ms2TapIP       = "192.168.2.22"
   215  		bd1Name        = "bd1"
   216  		bd2Name        = "bd2"
   217  		ms1Name        = "ms1"
   218  		ms2Name        = "ms2"
   219  		agent2Name     = "agent2"
   220  		netMask        = "/24"
   221  		msTapHostname  = "tap"
   222  		memifFilepath  = "/test-memif-subif-vlan-conn/memif/"
   223  		memifSockname  = "memif.sock"
   224  	)
   225  
   226  	// needed for creation of memif socket
   227  	if err := os.MkdirAll(ctx.ShareDir+memifFilepath, os.ModePerm); err != nil {
   228  		t.Fatal(err)
   229  	}
   230  
   231  	// agent1 configuration
   232  	vpp1Memif := &vpp_interfaces.Interface{
   233  		Name:    vpp1MemifName,
   234  		Type:    vpp_interfaces.Interface_MEMIF,
   235  		Enabled: true,
   236  		Link: &vpp_interfaces.Interface_Memif{
   237  			Memif: &vpp_interfaces.MemifLink{
   238  				Master:         true,
   239  				Id:             1,
   240  				SocketFilename: ctx.ShareDir + memifFilepath + memifSockname,
   241  			},
   242  		},
   243  	}
   244  	vpp1Subif1 := &vpp_interfaces.Interface{
   245  		Name:        vpp1Subif1Name,
   246  		Type:        vpp_interfaces.Interface_SUB_INTERFACE,
   247  		Enabled:     true,
   248  		IpAddresses: []string{vpp1Subif1IP + netMask},
   249  		Link: &vpp_interfaces.Interface_Sub{
   250  			Sub: &vpp_interfaces.SubInterface{
   251  				ParentName:  vpp1MemifName,
   252  				SubId:       10,
   253  				TagRwOption: vpp_interfaces.SubInterface_POP1,
   254  			},
   255  		},
   256  	}
   257  	vpp1Subif2 := &vpp_interfaces.Interface{
   258  		Name:        vpp1Subif2Name,
   259  		Type:        vpp_interfaces.Interface_SUB_INTERFACE,
   260  		Enabled:     true,
   261  		IpAddresses: []string{vpp1Subif2IP + netMask},
   262  		Link: &vpp_interfaces.Interface_Sub{
   263  			Sub: &vpp_interfaces.SubInterface{
   264  				ParentName:  vpp1MemifName,
   265  				SubId:       20,
   266  				TagRwOption: vpp_interfaces.SubInterface_POP1,
   267  			},
   268  		},
   269  	}
   270  
   271  	// agent2 configuration
   272  	vpp2Memif := &vpp_interfaces.Interface{
   273  		Name:    vpp2MemifName,
   274  		Type:    vpp_interfaces.Interface_MEMIF,
   275  		Enabled: true,
   276  		Link: &vpp_interfaces.Interface_Memif{
   277  			Memif: &vpp_interfaces.MemifLink{
   278  				Master:         false,
   279  				Id:             1,
   280  				SocketFilename: ctx.ShareDir + memifFilepath + memifSockname,
   281  			},
   282  		},
   283  	}
   284  	vpp2Subif1 := &vpp_interfaces.Interface{
   285  		Name:    vpp2Subif1Name,
   286  		Type:    vpp_interfaces.Interface_SUB_INTERFACE,
   287  		Enabled: true,
   288  		Link: &vpp_interfaces.Interface_Sub{
   289  			Sub: &vpp_interfaces.SubInterface{
   290  				ParentName:  vpp2MemifName,
   291  				SubId:       10,
   292  				TagRwOption: vpp_interfaces.SubInterface_POP1,
   293  			},
   294  		},
   295  	}
   296  	vpp2Subif2 := &vpp_interfaces.Interface{
   297  		Name:    vpp2Subif2Name,
   298  		Type:    vpp_interfaces.Interface_SUB_INTERFACE,
   299  		Enabled: true,
   300  		Link: &vpp_interfaces.Interface_Sub{
   301  			Sub: &vpp_interfaces.SubInterface{
   302  				ParentName:  vpp2MemifName,
   303  				SubId:       20,
   304  				TagRwOption: vpp_interfaces.SubInterface_POP1,
   305  			},
   306  		},
   307  	}
   308  
   309  	vpp2Tap1 := &vpp_interfaces.Interface{
   310  		Name:    vpp2Tap1Name,
   311  		Type:    vpp_interfaces.Interface_TAP,
   312  		Enabled: true,
   313  		Link: &vpp_interfaces.Interface_Tap{
   314  			Tap: &vpp_interfaces.TapLink{
   315  				Version:        2,
   316  				ToMicroservice: MsNamePrefix + ms1Name,
   317  			},
   318  		},
   319  	}
   320  	vpp2Tap2 := &vpp_interfaces.Interface{
   321  		Name:    vpp2Tap2Name,
   322  		Type:    vpp_interfaces.Interface_TAP,
   323  		Enabled: true,
   324  		Link: &vpp_interfaces.Interface_Tap{
   325  			Tap: &vpp_interfaces.TapLink{
   326  				Version:        2,
   327  				ToMicroservice: MsNamePrefix + ms2Name,
   328  			},
   329  		},
   330  	}
   331  
   332  	ms1Tap := &linux_interfaces.Interface{
   333  		Name:        ms1TapName,
   334  		Type:        linux_interfaces.Interface_TAP_TO_VPP,
   335  		Enabled:     true,
   336  		IpAddresses: []string{ms1TapIP + netMask},
   337  		HostIfName:  msTapHostname,
   338  		Link: &linux_interfaces.Interface_Tap{
   339  			Tap: &linux_interfaces.TapLink{
   340  				VppTapIfName: vpp2Tap1Name,
   341  			},
   342  		},
   343  		Namespace: &linux_namespace.NetNamespace{
   344  			Type:      linux_namespace.NetNamespace_MICROSERVICE,
   345  			Reference: MsNamePrefix + ms1Name,
   346  		},
   347  	}
   348  	ms2Tap := &linux_interfaces.Interface{
   349  		Name:        ms2TapName,
   350  		Type:        linux_interfaces.Interface_TAP_TO_VPP,
   351  		Enabled:     true,
   352  		IpAddresses: []string{ms2TapIP + netMask},
   353  		HostIfName:  msTapHostname,
   354  		Link: &linux_interfaces.Interface_Tap{
   355  			Tap: &linux_interfaces.TapLink{
   356  				VppTapIfName: vpp2Tap2Name,
   357  			},
   358  		},
   359  		Namespace: &linux_namespace.NetNamespace{
   360  			Type:      linux_namespace.NetNamespace_MICROSERVICE,
   361  			Reference: MsNamePrefix + ms2Name,
   362  		},
   363  	}
   364  
   365  	bd1 := &vpp_l2.BridgeDomain{
   366  		Name:    bd1Name,
   367  		Flood:   true,
   368  		Forward: true,
   369  		Learn:   true,
   370  		Interfaces: []*vpp_l2.BridgeDomain_Interface{
   371  			{
   372  				Name: vpp2Subif1Name,
   373  			},
   374  			{
   375  				Name: vpp2Tap1Name,
   376  			},
   377  		},
   378  	}
   379  	bd2 := &vpp_l2.BridgeDomain{
   380  		Name:    bd2Name,
   381  		Flood:   true,
   382  		Forward: true,
   383  		Learn:   true,
   384  		Interfaces: []*vpp_l2.BridgeDomain_Interface{
   385  			{
   386  				Name: vpp2Subif2Name,
   387  			},
   388  			{
   389  				Name: vpp2Tap2Name,
   390  			},
   391  		},
   392  	}
   393  
   394  	ctx.StartMicroservice(ms1Name)
   395  	ctx.StartMicroservice(ms2Name)
   396  	agent1 := ctx.Agent
   397  	agent2 := ctx.StartAgent(agent2Name)
   398  
   399  	err := agent1.GenericClient().ChangeRequest().Update(
   400  		vpp1Memif,
   401  		vpp1Subif1,
   402  		vpp1Subif2,
   403  	).Send(context.Background())
   404  	ctx.Expect(err).ToNot(HaveOccurred())
   405  	err = agent2.GenericClient().ChangeRequest().Update(
   406  		vpp2Memif,
   407  		vpp2Subif1,
   408  		vpp2Subif2,
   409  		vpp2Tap1,
   410  		vpp2Tap2,
   411  		ms1Tap,
   412  		ms2Tap,
   413  		bd1,
   414  		bd2,
   415  	).Send(context.Background())
   416  	ctx.Expect(err).ToNot(HaveOccurred())
   417  
   418  	if ctx.VppRelease() <= "21.01" {
   419  		time.Sleep(5 * time.Second)
   420  	}
   421  
   422  	// Check VPP1 value states
   423  	ctx.Eventually(agent1.GetValueStateClb(vpp1Memif)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   424  	ctx.Expect(agent1.GetValueState(vpp1Subif1)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   425  	ctx.Expect(agent1.GetValueState(vpp1Subif2)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   426  	// Check VPP2 value states
   427  	ctx.Eventually(agent2.GetValueStateClb(vpp2Memif)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   428  	ctx.Expect(agent2.GetValueState(vpp2Subif1)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   429  	ctx.Expect(agent2.GetValueState(vpp2Subif2)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   430  	ctx.Expect(agent2.GetValueState(ms1Tap)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   431  	ctx.Expect(agent2.GetValueState(ms2Tap)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   432  	ctx.Expect(agent2.GetValueState(vpp2Tap1)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   433  	ctx.Expect(agent2.GetValueState(vpp2Tap2)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   434  	// Pings from VPP should automatically go through correct vlan
   435  	ctx.Expect(agent1.PingFromVPP(ms1TapIP)).To(Succeed())
   436  	ctx.Expect(agent1.PingFromVPP(ms2TapIP)).To(Succeed())
   437  	// Pings from correct vlan should succeed
   438  	ctx.Expect(agent1.PingFromVPP(ms1TapIP, "source", "memif1/1.10")).To(Succeed())
   439  	ctx.Expect(agent1.PingFromVPP(ms2TapIP, "source", "memif1/1.20")).To(Succeed())
   440  	ctx.Expect(ctx.PingFromMs(ms1Name, vpp1Subif1IP)).To(Succeed())
   441  	ctx.Expect(ctx.PingFromMs(ms2Name, vpp1Subif2IP)).To(Succeed())
   442  	// Pings from incorrect vlan should fail
   443  	ctx.Expect(agent1.PingFromVPP(ms1TapIP, "source", "memif1/1.20")).NotTo(Succeed())
   444  	ctx.Expect(agent1.PingFromVPP(ms2TapIP, "source", "memif1/1.10")).NotTo(Succeed())
   445  	ctx.Expect(ctx.PingFromMs(ms1Name, vpp1Subif2IP)).NotTo(Succeed())
   446  	ctx.Expect(ctx.PingFromMs(ms2Name, vpp1Subif1IP)).NotTo(Succeed())
   447  }
   448  
   449  // connect VPP with a microservice via TAP tunnel interface
   450  // TODO: fix topology setup for a traffic (ping) test
   451  func TestInterfaceTapTunnel(t *testing.T) {
   452  	ctx := Setup(t)
   453  	defer ctx.Teardown()
   454  
   455  	const (
   456  		vppTapName       = "vpp-taptun"
   457  		linuxTapName     = "linux-taptun"
   458  		linuxTapHostname = "taptun"
   459  		vppTapIP         = "192.168.1.1"
   460  		linuxTapIP       = "192.168.1.2"
   461  		netMask          = "/30"
   462  		msName           = "microservice1"
   463  	)
   464  
   465  	vppTap := &vpp_interfaces.Interface{
   466  		Name:        vppTapName,
   467  		Type:        vpp_interfaces.Interface_TAP,
   468  		Enabled:     true,
   469  		IpAddresses: []string{vppTapIP + netMask},
   470  		Link: &vpp_interfaces.Interface_Tap{
   471  			Tap: &vpp_interfaces.TapLink{
   472  				Version:        2,
   473  				EnableTunnel:   true,
   474  				ToMicroservice: MsNamePrefix + msName,
   475  			},
   476  		},
   477  	}
   478  	linuxTap := &linux_interfaces.Interface{
   479  		Name:        linuxTapName,
   480  		Type:        linux_interfaces.Interface_TAP_TO_VPP,
   481  		Enabled:     true,
   482  		IpAddresses: []string{linuxTapIP + netMask},
   483  		HostIfName:  linuxTapHostname,
   484  		Link: &linux_interfaces.Interface_Tap{
   485  			Tap: &linux_interfaces.TapLink{
   486  				VppTapIfName: vppTapName,
   487  			},
   488  		},
   489  		Namespace: &linux_namespace.NetNamespace{
   490  			Type:      linux_namespace.NetNamespace_MICROSERVICE,
   491  			Reference: MsNamePrefix + msName,
   492  		},
   493  	}
   494  
   495  	ctx.StartMicroservice(msName)
   496  
   497  	// configure TAPs
   498  	req := ctx.GenericClient().ChangeRequest()
   499  	err := req.Update(
   500  		vppTap,
   501  		linuxTap,
   502  	).Send(context.Background())
   503  	ctx.Expect(err).ToNot(HaveOccurred())
   504  
   505  	ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   506  	ctx.Expect(ctx.GetValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   507  	//ctx.Expect(ctx.pingFromVPP(linuxTapIP)).To(Succeed())
   508  	//ctx.Expect(ctx.pingFromMs(msName, vppTapIP)).To(Succeed())
   509  
   510  	ctx.ExecVppctl("show", "int")
   511  	ctx.ExecVppctl("show", "int", "addr")
   512  	ctx.ExecCmd("ip", "link")
   513  	ctx.ExecCmd("ip", "addr")
   514  	ctx.PingFromVPP(linuxTapIP)
   515  
   516  	// resync TAPs
   517  	err = ctx.GenericClient().ResyncConfig(
   518  		vppTap,
   519  		linuxTap,
   520  	)
   521  	ctx.Expect(err).ToNot(HaveOccurred())
   522  
   523  	ctx.ExecVppctl("show", "int")
   524  	ctx.ExecVppctl("show", "int", "addr")
   525  	ctx.ExecCmd("ip", "link")
   526  	ctx.ExecCmd("ip", "addr")
   527  
   528  	ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   529  	ctx.Expect(ctx.GetValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   530  	//ctx.Expect(ctx.pingFromVPP(linuxTapIP)).To(Succeed())
   531  	//ctx.Expect(ctx.pingFromMs(msName, vppTapIP)).To(Succeed())
   532  
   533  	// restart microservice twice
   534  	/*for i := 0; i < 2; i++ {
   535  		ctx.stopMicroservice(msName)
   536  		ctx.Eventually(ctx.getValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_PENDING))
   537  		ctx.Eventually(ctx.getValueStateClb(linuxTap)).Should(Equal(kvscheduler.ValueState_PENDING))
   538  		ctx.Expect(ctx.pingFromVPP(linuxTapIP)).NotTo(Succeed())
   539  		ctx.Expect(ctx.agentInSync()).To(BeTrue())
   540  
   541  		ctx.startMicroservice(msName)
   542  		ctx.Eventually(ctx.getValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   543  		ctx.Expect(ctx.getValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   544  		ctx.Expect(ctx.pingFromVPP(linuxTapIP)).To(Succeed())
   545  		ctx.Expect(ctx.pingFromMs(msName, vppTapIP)).To(Succeed())
   546  		ctx.Expect(ctx.agentInSync()).To(BeTrue())
   547  	}
   548  
   549  	// re-create VPP TAP
   550  	req = ctx.GenericClient().ChangeRequest()
   551  	err = req.Delete(
   552  		vppTap,
   553  	).Send(context.Background())
   554  	ctx.Expect(err).ToNot(HaveOccurred())
   555  
   556  	ctx.Expect(ctx.pingFromVPP(linuxTapIP)).NotTo(Succeed())
   557  	ctx.Expect(ctx.pingFromMs(msName, vppTapIP)).NotTo(Succeed())
   558  
   559  	req = ctx.GenericClient().ChangeRequest()
   560  	err = req.Update(
   561  		vppTap,
   562  	).Send(context.Background())
   563  	ctx.Expect(err).ToNot(HaveOccurred())
   564  
   565  	ctx.Eventually(ctx.pingFromVPPClb(linuxTapIP)).Should(Succeed())
   566  	ctx.Expect(ctx.pingFromMs(msName, vppTapIP)).To(Succeed())
   567  	ctx.Expect(ctx.agentInSync()).To(BeTrue())
   568  
   569  	// re-create Linux TAP
   570  	req = ctx.GenericClient().ChangeRequest()
   571  	err = req.Delete(
   572  		linuxTap,
   573  	).Send(context.Background())
   574  	ctx.Expect(err).ToNot(HaveOccurred())
   575  
   576  	ctx.Expect(ctx.pingFromVPP(linuxTapIP)).NotTo(Succeed())
   577  	ctx.Expect(ctx.pingFromMs(msName, vppTapIP)).NotTo(Succeed())
   578  
   579  	req = ctx.GenericClient().ChangeRequest()
   580  	err = req.Update(
   581  		linuxTap,
   582  	).Send(context.Background())
   583  	ctx.Expect(err).ToNot(HaveOccurred())
   584  
   585  	ctx.Eventually(ctx.pingFromVPPClb(linuxTapIP)).Should(Succeed())
   586  	ctx.Expect(ctx.pingFromMs(msName, vppTapIP)).To(Succeed())
   587  	ctx.Expect(ctx.agentInSync()).To(BeTrue())*/
   588  }
   589  
   590  // connect VPP with a microservice via AF-PACKET + VETH interfaces
   591  func TestInterfaceConnAfPacket(t *testing.T) {
   592  	ctx := Setup(t)
   593  	defer ctx.Teardown()
   594  
   595  	const (
   596  		afPacketName  = "vpp-afpacket"
   597  		veth1Name     = "linux-veth1"
   598  		veth2Name     = "linux-veth2"
   599  		veth1Hostname = "veth1"
   600  		veth2Hostname = "veth2"
   601  		afPacketIP    = "192.168.1.1"
   602  		veth2IP       = "192.168.1.2"
   603  		netMask       = "/30"
   604  		msName        = "microservice1"
   605  	)
   606  
   607  	afPacket := &vpp_interfaces.Interface{
   608  		Name:        afPacketName,
   609  		Type:        vpp_interfaces.Interface_AF_PACKET,
   610  		Enabled:     true,
   611  		IpAddresses: []string{afPacketIP + netMask},
   612  		Link: &vpp_interfaces.Interface_Afpacket{
   613  			Afpacket: &vpp_interfaces.AfpacketLink{
   614  				HostIfName: veth1Hostname,
   615  			},
   616  		},
   617  	}
   618  	veth1 := &linux_interfaces.Interface{
   619  		Name:       veth1Name,
   620  		Type:       linux_interfaces.Interface_VETH,
   621  		Enabled:    true,
   622  		HostIfName: veth1Hostname,
   623  		Link: &linux_interfaces.Interface_Veth{
   624  			Veth: &linux_interfaces.VethLink{
   625  				PeerIfName: veth2Name,
   626  			},
   627  		},
   628  	}
   629  	veth2 := &linux_interfaces.Interface{
   630  		Name:        veth2Name,
   631  		Type:        linux_interfaces.Interface_VETH,
   632  		Enabled:     true,
   633  		HostIfName:  veth2Hostname,
   634  		IpAddresses: []string{veth2IP + netMask},
   635  		Link: &linux_interfaces.Interface_Veth{
   636  			Veth: &linux_interfaces.VethLink{
   637  				PeerIfName: veth1Name,
   638  			},
   639  		},
   640  		Namespace: &linux_namespace.NetNamespace{
   641  			Type:      linux_namespace.NetNamespace_MICROSERVICE,
   642  			Reference: MsNamePrefix + msName,
   643  		},
   644  	}
   645  
   646  	ctx.StartMicroservice(msName)
   647  	req := ctx.GenericClient().ChangeRequest()
   648  	err := req.Update(
   649  		afPacket,
   650  		veth1,
   651  		veth2,
   652  	).Send(context.Background())
   653  	ctx.Expect(err).ToNot(HaveOccurred())
   654  
   655  	ctx.Eventually(ctx.GetValueStateClb(afPacket)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   656  	ctx.Expect(ctx.GetValueState(veth1)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   657  	ctx.Expect(ctx.GetValueState(veth2)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   658  	ctx.Expect(ctx.PingFromVPP(veth2IP)).To(Succeed())
   659  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).To(Succeed())
   660  
   661  	// restart microservice twice
   662  	for i := 0; i < 2; i++ {
   663  		ctx.StopMicroservice(msName)
   664  		ctx.Eventually(ctx.GetValueStateClb(afPacket)).Should(Equal(kvscheduler.ValueState_PENDING))
   665  		ctx.Eventually(ctx.GetValueStateClb(veth1)).Should(Equal(kvscheduler.ValueState_PENDING))
   666  		ctx.Eventually(ctx.GetValueStateClb(veth2)).Should(Equal(kvscheduler.ValueState_PENDING))
   667  		ctx.Expect(ctx.PingFromVPP(veth2IP)).NotTo(Succeed())
   668  		ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   669  
   670  		ctx.StartMicroservice(msName)
   671  		ctx.Eventually(ctx.GetValueStateClb(afPacket)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   672  		ctx.Expect(ctx.GetValueState(veth1)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   673  		ctx.Expect(ctx.GetValueState(veth2)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   674  		ctx.Expect(ctx.PingFromVPP(veth2IP)).To(Succeed())
   675  		ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).To(Succeed())
   676  		ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   677  	}
   678  
   679  	// re-create AF-PACKET
   680  	req = ctx.GenericClient().ChangeRequest()
   681  	err = req.Delete(
   682  		afPacket,
   683  	).Send(context.Background())
   684  	ctx.Expect(err).ToNot(HaveOccurred())
   685  
   686  	ctx.Expect(ctx.PingFromVPP(veth2IP)).NotTo(Succeed())
   687  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).NotTo(Succeed())
   688  
   689  	req = ctx.GenericClient().ChangeRequest()
   690  	err = req.Update(
   691  		afPacket,
   692  	).Send(context.Background())
   693  	ctx.Expect(err).ToNot(HaveOccurred())
   694  
   695  	ctx.Eventually(ctx.PingFromVPPClb(veth2IP)).Should(Succeed())
   696  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).To(Succeed())
   697  	ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   698  
   699  	// re-create VETH
   700  	req = ctx.GenericClient().ChangeRequest()
   701  	err = req.Delete(
   702  		veth2,
   703  	).Send(context.Background())
   704  	ctx.Expect(err).ToNot(HaveOccurred())
   705  
   706  	ctx.Expect(ctx.PingFromVPP(veth2IP)).NotTo(Succeed())
   707  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).NotTo(Succeed())
   708  
   709  	req = ctx.GenericClient().ChangeRequest()
   710  	err = req.Update(
   711  		veth2,
   712  	).Send(context.Background())
   713  	ctx.Expect(err).ToNot(HaveOccurred())
   714  
   715  	ctx.Eventually(ctx.PingFromVPPClb(veth2IP)).Should(Succeed())
   716  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).To(Succeed())
   717  	ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   718  }
   719  
   720  // Connect VPP with a microservice via AF-PACKET + VETH interfaces.
   721  // Configure AF-PACKET with logical reference to the target VETH interface.
   722  func TestInterfaceAfPacketWithLogicalReference(t *testing.T) {
   723  	ctx := Setup(t)
   724  	defer ctx.Teardown()
   725  
   726  	const (
   727  		afPacketName  = "vpp-afpacket"
   728  		veth1Name     = "linux-veth1"
   729  		veth2Name     = "linux-veth2"
   730  		veth1Hostname = "veth1"
   731  		veth2Hostname = "veth2"
   732  		afPacketIP    = "192.168.1.1"
   733  		veth2IP       = "192.168.1.2"
   734  		netMask       = "/30"
   735  		msName        = "microservice1"
   736  	)
   737  
   738  	afPacket := &vpp_interfaces.Interface{
   739  		Name:        afPacketName,
   740  		Type:        vpp_interfaces.Interface_AF_PACKET,
   741  		Enabled:     true,
   742  		IpAddresses: []string{afPacketIP + netMask},
   743  		Link: &vpp_interfaces.Interface_Afpacket{
   744  			Afpacket: &vpp_interfaces.AfpacketLink{
   745  				LinuxInterface: veth1Name,
   746  			},
   747  		},
   748  	}
   749  	veth1 := &linux_interfaces.Interface{
   750  		Name:       veth1Name,
   751  		Type:       linux_interfaces.Interface_VETH,
   752  		Enabled:    true,
   753  		HostIfName: veth1Hostname,
   754  		Link: &linux_interfaces.Interface_Veth{
   755  			Veth: &linux_interfaces.VethLink{
   756  				PeerIfName: veth2Name,
   757  			},
   758  		},
   759  	}
   760  	veth2 := &linux_interfaces.Interface{
   761  		Name:        veth2Name,
   762  		Type:        linux_interfaces.Interface_VETH,
   763  		Enabled:     true,
   764  		HostIfName:  veth2Hostname,
   765  		IpAddresses: []string{veth2IP + netMask},
   766  		Link: &linux_interfaces.Interface_Veth{
   767  			Veth: &linux_interfaces.VethLink{
   768  				PeerIfName: veth1Name,
   769  			},
   770  		},
   771  		Namespace: &linux_namespace.NetNamespace{
   772  			Type:      linux_namespace.NetNamespace_MICROSERVICE,
   773  			Reference: MsNamePrefix + msName,
   774  		},
   775  	}
   776  
   777  	ctx.StartMicroservice(msName)
   778  	req := ctx.GenericClient().ChangeRequest()
   779  	err := req.Update(
   780  		afPacket,
   781  		veth1,
   782  		veth2,
   783  	).Send(context.Background())
   784  	ctx.Expect(err).ToNot(HaveOccurred())
   785  
   786  	ctx.Eventually(ctx.GetValueStateClb(afPacket)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   787  	ctx.Expect(ctx.GetValueState(veth1)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   788  	ctx.Expect(ctx.GetValueState(veth2)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   789  	ctx.Expect(ctx.PingFromVPP(veth2IP)).To(Succeed())
   790  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).To(Succeed())
   791  
   792  	// restart microservice twice
   793  	for i := 0; i < 2; i++ {
   794  		ctx.StopMicroservice(msName)
   795  		ctx.Eventually(ctx.GetValueStateClb(afPacket)).Should(Equal(kvscheduler.ValueState_PENDING))
   796  		ctx.Eventually(ctx.GetValueStateClb(veth1)).Should(Equal(kvscheduler.ValueState_PENDING))
   797  		ctx.Eventually(ctx.GetValueStateClb(veth2)).Should(Equal(kvscheduler.ValueState_PENDING))
   798  		ctx.Expect(ctx.PingFromVPP(veth2IP)).NotTo(Succeed())
   799  		ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   800  
   801  		ctx.StartMicroservice(msName)
   802  		ctx.Eventually(ctx.GetValueStateClb(afPacket)).Should(Equal(kvscheduler.ValueState_CONFIGURED))
   803  		ctx.Expect(ctx.GetValueState(veth1)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   804  		ctx.Expect(ctx.GetValueState(veth2)).To(Equal(kvscheduler.ValueState_CONFIGURED))
   805  		ctx.Expect(ctx.PingFromVPP(veth2IP)).To(Succeed())
   806  		ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).To(Succeed())
   807  		ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   808  	}
   809  
   810  	// re-create AF-PACKET
   811  	req = ctx.GenericClient().ChangeRequest()
   812  	err = req.Delete(
   813  		afPacket,
   814  	).Send(context.Background())
   815  	ctx.Expect(err).ToNot(HaveOccurred())
   816  
   817  	ctx.Expect(ctx.PingFromVPP(veth2IP)).NotTo(Succeed())
   818  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).NotTo(Succeed())
   819  
   820  	req = ctx.GenericClient().ChangeRequest()
   821  	err = req.Update(
   822  		afPacket,
   823  	).Send(context.Background())
   824  	ctx.Expect(err).ToNot(HaveOccurred())
   825  
   826  	ctx.Eventually(ctx.PingFromVPPClb(veth2IP)).Should(Succeed())
   827  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).To(Succeed())
   828  	ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   829  
   830  	// re-create VETH
   831  	req = ctx.GenericClient().ChangeRequest()
   832  	err = req.Delete(
   833  		veth2,
   834  	).Send(context.Background())
   835  	ctx.Expect(err).ToNot(HaveOccurred())
   836  
   837  	ctx.Expect(ctx.PingFromVPP(veth2IP)).NotTo(Succeed())
   838  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).NotTo(Succeed())
   839  
   840  	req = ctx.GenericClient().ChangeRequest()
   841  	err = req.Update(
   842  		veth2,
   843  	).Send(context.Background())
   844  	ctx.Expect(err).ToNot(HaveOccurred())
   845  
   846  	ctx.Eventually(ctx.PingFromVPPClb(veth2IP)).Should(Succeed())
   847  	ctx.Expect(ctx.PingFromMs(msName, afPacketIP)).To(Succeed())
   848  	ctx.Expect(ctx.AgentInSync()).To(BeTrue())
   849  }