aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_vm_vpp_interfaces.py
diff options
context:
space:
mode:
authorNaveen Joy <najoy@cisco.com>2023-07-28 16:33:30 -0700
committerDave Wallace <dwallacelf@gmail.com>2023-12-21 00:53:44 +0000
commit70335e8e50e004f0ab111a5607becf0438d806bc (patch)
treef1c87cf4b77530d1dd792d332d54fead3dd85b84 /test/test_vm_vpp_interfaces.py
parent00c59e4965c72d1d1ab77590fe57ee7f890546a8 (diff)
tests: memif interface tests using libmemif
Type: test Change-Id: I711dfe65ad542a45acd484f0b4e3e6ade9576f66 Signed-off-by: Naveen Joy <najoy@cisco.com>
Diffstat (limited to 'test/test_vm_vpp_interfaces.py')
-rw-r--r--test/test_vm_vpp_interfaces.py359
1 files changed, 220 insertions, 139 deletions
diff --git a/test/test_vm_vpp_interfaces.py b/test/test_vm_vpp_interfaces.py
index 917b95006c4..0c90325e35a 100644
--- a/test/test_vm_vpp_interfaces.py
+++ b/test/test_vm_vpp_interfaces.py
@@ -9,6 +9,7 @@ from vpp_qemu_utils import (
set_interface_mtu,
disable_interface_gso,
add_namespace_route,
+ libmemif_test_app,
)
from vpp_iperf import start_iperf, stop_iperf
from framework import VppTestCase
@@ -21,7 +22,7 @@ from vm_test_config import test_config
#
# Tests for:
-# - tapv2, tunv2 & af_packet_v2 & v3 interfaces.
+# - tapv2, tunv2, af_packet_v2/v3 & memif interfaces.
# - reads test config from the file vm_test_config.py
# - Uses iPerf to send TCP/IP streams to VPP
# - VPP ingress interface runs the iperf client
@@ -79,7 +80,11 @@ def create_test(test_name, test, ip_version, mtu):
vpp_interfaces=self.vpp_interfaces,
linux_interfaces=self.linux_interfaces,
)
- # Start the Iperf server in dual stack mode & run iperf client
+ if "memif" in self.if_types:
+ self.logger.debug("Starting libmemif test_app for memif test")
+ self.memif_process = libmemif_test_app(
+ memif_sock_path=self.get_memif_sock_path(), logger=self.logger
+ )
if result is True:
start_iperf(ip_version=6, server_only=True, logger=self.logger)
self.assertTrue(
@@ -156,8 +161,11 @@ class TestVPPInterfacesQemu(VppTestCase):
3. Cross-Connect interfaces in VPP using L2 or L3.
"""
super(TestVPPInterfacesQemu, self).setUp()
- client_if_type = test["client_if_type"]
- server_if_type = test["server_if_type"]
+ # Need to support multiple interface types as the memif interface
+ # in VPP is connected to the iPerf client & server by x-connecting
+ # to a tap interface in their respective namespaces.
+ client_if_types = test["client_if_type"].split(",")
+ server_if_types = test["server_if_type"].split(",")
client_if_version = test["client_if_version"]
server_if_version = test["server_if_version"]
x_connect_mode = test["x_connect_mode"]
@@ -188,6 +196,11 @@ class TestVPPInterfacesQemu(VppTestCase):
)
vpp_server_nexthop = str(ip_interface(vpp_server_prefix).ip)
create_namespace([client_namespace, server_namespace])
+ # IPerf client & server ingress/egress interface indexes in VPP
+ self.tap_interfaces = []
+ self.memif_interfaces = []
+ self.ingress_if_idxes = []
+ self.egress_if_idxes = []
self.vpp_interfaces = []
self.linux_interfaces = []
enable_client_if_gso = test.get("client_if_gso", 0)
@@ -197,155 +210,197 @@ class TestVPPInterfacesQemu(VppTestCase):
enable_client_if_checksum_offload = test.get("client_if_checksum_offload", 0)
enable_server_if_checksum_offload = test.get("server_if_checksum_offload", 0)
## Handle client interface types
- if client_if_type == "af_packet":
- create_host_interface(
- af_packet_config["iprf_client_interface_on_linux"],
- af_packet_config["iprf_client_interface_on_vpp"],
- client_namespace,
- layer2["client_ip4_prefix"]
- if x_connect_mode == "L2"
- else layer3["client_ip4_prefix"],
- layer2["client_ip6_prefix"]
- if x_connect_mode == "L2"
- else layer3["client_ip6_prefix"],
- )
- self.ingress_if_idx = self.create_af_packet(
- version=client_if_version,
- host_if_name=af_packet_config["iprf_client_interface_on_vpp"],
- enable_gso=enable_client_if_gso,
- )
- self.vpp_interfaces.append(self.ingress_if_idx)
- self.linux_interfaces.append(
- ["", af_packet_config["iprf_client_interface_on_vpp"]]
- )
- self.linux_interfaces.append(
- [client_namespace, af_packet_config["iprf_client_interface_on_linux"]]
- )
- if enable_client_if_gso == 0:
- disable_interface_gso(
- "", af_packet_config["iprf_client_interface_on_vpp"]
+ for client_if_type in client_if_types:
+ if client_if_type == "af_packet":
+ create_host_interface(
+ af_packet_config["iprf_client_interface_on_linux"],
+ af_packet_config["iprf_client_interface_on_vpp"],
+ client_namespace,
+ layer2["client_ip4_prefix"]
+ if x_connect_mode == "L2"
+ else layer3["client_ip4_prefix"],
+ layer2["client_ip6_prefix"]
+ if x_connect_mode == "L2"
+ else layer3["client_ip6_prefix"],
)
- disable_interface_gso(
- client_namespace, af_packet_config["iprf_client_interface_on_linux"]
+ self.ingress_if_idx = self.create_af_packet(
+ version=client_if_version,
+ host_if_name=af_packet_config["iprf_client_interface_on_vpp"],
+ enable_gso=enable_client_if_gso,
)
- elif client_if_type == "tap" or client_if_type == "tun":
- self.ingress_if_idx = self.create_tap_tun(
- id=101,
- host_namespace=client_namespace,
- ip_version=ip_version,
- host_ip4_prefix=layer2["client_ip4_prefix"]
- if x_connect_mode == "L2"
- else layer3["client_ip4_prefix"],
- host_ip6_prefix=layer2["client_ip6_prefix"]
- if x_connect_mode == "L2"
- else layer3["client_ip6_prefix"],
- host_ip4_gw=vpp_client_nexthop
- if x_connect_mode == "L3" and ip_version == 4
- else None,
- host_ip6_gw=vpp_client_nexthop
- if x_connect_mode == "L3" and ip_version == 6
- else None,
- int_type=client_if_type,
- host_if_name=f"{client_if_type}0",
- enable_gso=enable_client_if_gso,
- enable_gro=enable_client_if_gro,
- enable_checksum_offload=enable_client_if_checksum_offload,
- )
- self.vpp_interfaces.append(self.ingress_if_idx)
- self.linux_interfaces.append([client_namespace, f"{client_if_type}0"])
- # Seeing TCP timeouts if tx=on & rx=on Linux tap & tun interfaces
- disable_interface_gso(client_namespace, f"{client_if_type}0")
- else:
- print(
- f"Unsupported client interface type: {client_if_type} "
- f"for test - ID={test['id']}"
- )
- sys.exit(1)
-
- if server_if_type == "af_packet":
- create_host_interface(
- af_packet_config["iprf_server_interface_on_linux"],
- af_packet_config["iprf_server_interface_on_vpp"],
- server_namespace,
- server_ip4_prefix,
- server_ip6_prefix,
- )
- self.egress_if_idx = self.create_af_packet(
- version=server_if_version,
- host_if_name=af_packet_config["iprf_server_interface_on_vpp"],
- enable_gso=enable_server_if_gso,
- )
- self.vpp_interfaces.append(self.egress_if_idx)
- self.linux_interfaces.append(
- ["", af_packet_config["iprf_server_interface_on_vpp"]]
- )
- self.linux_interfaces.append(
- [server_namespace, af_packet_config["iprf_server_interface_on_linux"]]
- )
- if enable_server_if_gso == 0:
- disable_interface_gso(
- "", af_packet_config["iprf_server_interface_on_vpp"]
+ self.ingress_if_idxes.append(self.ingress_if_idx)
+ self.vpp_interfaces.append(self.ingress_if_idx)
+ self.linux_interfaces.append(
+ ["", af_packet_config["iprf_client_interface_on_vpp"]]
)
- disable_interface_gso(
- server_namespace, af_packet_config["iprf_server_interface_on_linux"]
+ self.linux_interfaces.append(
+ [
+ client_namespace,
+ af_packet_config["iprf_client_interface_on_linux"],
+ ]
)
- elif server_if_type == "tap" or server_if_type == "tun":
- self.egress_if_idx = self.create_tap_tun(
- id=102,
- host_namespace=server_namespace,
- ip_version=ip_version,
- host_ip4_prefix=layer2["server_ip4_prefix"]
- if x_connect_mode == "L2"
- else layer3["server_ip4_prefix"],
- host_ip6_prefix=layer2["server_ip6_prefix"]
- if x_connect_mode == "L2"
- else layer3["server_ip6_prefix"],
- int_type=server_if_type,
- host_if_name=f"{server_if_type}0",
- enable_gso=enable_server_if_gso,
- enable_gro=enable_server_if_gro,
- enable_checksum_offload=enable_server_if_checksum_offload,
- )
- self.vpp_interfaces.append(self.egress_if_idx)
- self.linux_interfaces.append([server_namespace, f"{server_if_type}0"])
- # Seeing TCP timeouts if tx=on & rx=on Linux tap & tun interfaces
- disable_interface_gso(server_namespace, f"{server_if_type}0")
- else:
- print(
- f"Unsupported server interface type: {server_if_type} "
- f"for test - ID={test['id']}"
- )
- sys.exit(1)
-
- if x_connect_mode == "L2":
- self.l2_connect_interfaces(1, self.ingress_if_idx, self.egress_if_idx)
- elif x_connect_mode == "L3":
- # L3 connect client & server side
- vrf_id = layer3["ip4_vrf"] if ip_version == 4 else layer3["ip6_vrf"]
- self.l3_connect_interfaces(
- ip_version,
- vrf_id,
- (self.ingress_if_idx, vpp_client_prefix),
- (self.egress_if_idx, vpp_server_prefix),
- )
- # Setup namespace routing
- if ip_version == 4:
- add_namespace_route(client_namespace, "0.0.0.0/0", vpp_client_nexthop)
- add_namespace_route(server_namespace, "0.0.0.0/0", vpp_server_nexthop)
+ if enable_client_if_gso == 0:
+ disable_interface_gso(
+ "", af_packet_config["iprf_client_interface_on_vpp"]
+ )
+ disable_interface_gso(
+ client_namespace,
+ af_packet_config["iprf_client_interface_on_linux"],
+ )
+ elif client_if_type == "tap" or client_if_type == "tun":
+ self.ingress_if_idx = self.create_tap_tun(
+ id=101,
+ host_namespace=client_namespace,
+ ip_version=ip_version,
+ host_ip4_prefix=layer2["client_ip4_prefix"]
+ if x_connect_mode == "L2"
+ else layer3["client_ip4_prefix"],
+ host_ip6_prefix=layer2["client_ip6_prefix"]
+ if x_connect_mode == "L2"
+ else layer3["client_ip6_prefix"],
+ host_ip4_gw=vpp_client_nexthop
+ if x_connect_mode == "L3" and ip_version == 4
+ else None,
+ host_ip6_gw=vpp_client_nexthop
+ if x_connect_mode == "L3" and ip_version == 6
+ else None,
+ int_type=client_if_type,
+ host_if_name=f"{client_if_type}0",
+ enable_gso=enable_client_if_gso,
+ enable_gro=enable_client_if_gro,
+ enable_checksum_offload=enable_client_if_checksum_offload,
+ )
+ self.tap_interfaces.append(self.ingress_if_idx)
+ self.ingress_if_idxes.append(self.ingress_if_idx)
+ self.vpp_interfaces.append(self.ingress_if_idx)
+ self.linux_interfaces.append([client_namespace, f"{client_if_type}0"])
+ # Seeing TCP timeouts if tx=on & rx=on Linux tap & tun interfaces
+ disable_interface_gso(client_namespace, f"{client_if_type}0")
+ elif client_if_type == "memif":
+ self.ingress_if_idx = self.create_memif(
+ memif_id=0, mode=0 if x_connect_mode == "L2" else 1
+ )
+ self.memif_interfaces.append(self.ingress_if_idx)
+ self.ingress_if_idxes.append(self.ingress_if_idx)
+ self.vpp_interfaces.append(self.ingress_if_idx)
+ else:
+ print(
+ f"Unsupported client interface type: {client_if_type} "
+ f"for test - ID={test['id']}"
+ )
+ sys.exit(1)
+ for server_if_type in server_if_types:
+ if server_if_type == "af_packet":
+ create_host_interface(
+ af_packet_config["iprf_server_interface_on_linux"],
+ af_packet_config["iprf_server_interface_on_vpp"],
+ server_namespace,
+ server_ip4_prefix,
+ server_ip6_prefix,
+ )
+ self.egress_if_idx = self.create_af_packet(
+ version=server_if_version,
+ host_if_name=af_packet_config["iprf_server_interface_on_vpp"],
+ enable_gso=enable_server_if_gso,
+ )
+ self.egress_if_idxes.append(self.egress_if_idx)
+ self.vpp_interfaces.append(self.egress_if_idx)
+ self.linux_interfaces.append(
+ ["", af_packet_config["iprf_server_interface_on_vpp"]]
+ )
+ self.linux_interfaces.append(
+ [
+ server_namespace,
+ af_packet_config["iprf_server_interface_on_linux"],
+ ]
+ )
+ if enable_server_if_gso == 0:
+ disable_interface_gso(
+ "", af_packet_config["iprf_server_interface_on_vpp"]
+ )
+ disable_interface_gso(
+ server_namespace,
+ af_packet_config["iprf_server_interface_on_linux"],
+ )
+ elif server_if_type == "tap" or server_if_type == "tun":
+ self.egress_if_idx = self.create_tap_tun(
+ id=102,
+ host_namespace=server_namespace,
+ ip_version=ip_version,
+ host_ip4_prefix=layer2["server_ip4_prefix"]
+ if x_connect_mode == "L2"
+ else layer3["server_ip4_prefix"],
+ host_ip6_prefix=layer2["server_ip6_prefix"]
+ if x_connect_mode == "L2"
+ else layer3["server_ip6_prefix"],
+ int_type=server_if_type,
+ host_if_name=f"{server_if_type}0",
+ enable_gso=enable_server_if_gso,
+ enable_gro=enable_server_if_gro,
+ enable_checksum_offload=enable_server_if_checksum_offload,
+ )
+ self.tap_interfaces.append(self.egress_if_idx)
+ self.egress_if_idxes.append(self.egress_if_idx)
+ self.vpp_interfaces.append(self.egress_if_idx)
+ self.linux_interfaces.append([server_namespace, f"{server_if_type}0"])
+ # Seeing TCP timeouts if tx=on & rx=on Linux tap & tun interfaces
+ disable_interface_gso(server_namespace, f"{server_if_type}0")
+ elif server_if_type == "memif":
+ self.egress_if_idx = self.create_memif(
+ memif_id=1, mode=0 if x_connect_mode == "L2" else 1
+ )
+ self.memif_interfaces.append(self.egress_if_idx)
+ self.egress_if_idxes.append(self.egress_if_idx)
+ self.vpp_interfaces.append(self.egress_if_idx)
else:
- add_namespace_route(client_namespace, "::/0", vpp_client_nexthop)
- add_namespace_route(server_namespace, "::/0", vpp_server_nexthop)
+ print(
+ f"Unsupported server interface type: {server_if_type} "
+ f"for test - ID={test['id']}"
+ )
+ sys.exit(1)
+ self.if_types = set(client_if_types).union(set(server_if_types))
+ # for memif testing: tapv2, memif & libmemif_app are connected
+ if "memif" not in self.if_types:
+ if x_connect_mode == "L2":
+ self.l2_connect_interfaces(1, self.ingress_if_idx, self.egress_if_idx)
+ elif x_connect_mode == "L3":
+ # L3 connect client & server side
+ vrf_id = layer3["ip4_vrf"] if ip_version == 4 else layer3["ip6_vrf"]
+ self.l3_connect_interfaces(
+ ip_version,
+ vrf_id,
+ (self.ingress_if_idx, vpp_client_prefix),
+ (self.egress_if_idx, vpp_server_prefix),
+ )
+ # Setup namespace routing
+ if ip_version == 4:
+ add_namespace_route(
+ client_namespace, "0.0.0.0/0", vpp_client_nexthop
+ )
+ add_namespace_route(
+ server_namespace, "0.0.0.0/0", vpp_server_nexthop
+ )
+ else:
+ add_namespace_route(client_namespace, "::/0", vpp_client_nexthop)
+ add_namespace_route(server_namespace, "::/0", vpp_server_nexthop)
+ else:
+ # connect: ingress tap & memif & egress tap and memif interfaces
+ if x_connect_mode == "L2":
+ self.l2_connect_interfaces(1, *self.ingress_if_idxes)
+ self.l2_connect_interfaces(2, *self.egress_if_idxes)
# Wait for Linux IPv6 stack to become ready
if ip_version == 6:
time.sleep(2)
def tearDown(self):
try:
- self.vapi.tap_delete_v2(self.ingress_if_idx)
+ for interface_if_idx in self.tap_interfaces:
+ self.vapi.tap_delete_v2(sw_if_index=interface_if_idx)
except Exception:
pass
try:
- self.vapi.tap_delete_v2(self.egress_if_idx)
+ for interface_if_idx in self.memif_interfaces:
+ self.vapi.memif_delete(sw_if_index=interface_if_idx)
except Exception:
pass
try:
@@ -384,6 +439,11 @@ class TestVPPInterfacesQemu(VppTestCase):
except Exception:
pass
try:
+ self.vapi.bridge_domain_add_del_v2(bd_id=1, is_add=0)
+ self.vapi.bridge_domain_add_del_v2(bd_id=2, is_add=0)
+ except Exception:
+ pass
+ try:
delete_namespace(
[
client_namespace,
@@ -396,6 +456,12 @@ class TestVPPInterfacesQemu(VppTestCase):
stop_iperf()
except Exception:
pass
+ try:
+ if self.memif_process:
+ self.memif_process.terminate()
+ self.memif_process.join()
+ except Exception:
+ pass
def create_af_packet(self, version, host_if_name, enable_gso=0):
"""Create an af_packetv3 interface in VPP.
@@ -535,6 +601,21 @@ class TestVPPInterfacesQemu(VppTestCase):
self.vapi.sw_interface_set_flags(sw_if_index=sw_if_index, flags=1)
return sw_if_index
+ def create_memif(self, memif_id, mode):
+ """Create memif interface in VPP.
+
+ Parameters:
+ memif_id: A unique ID for the memif interface
+ mode: 0 = ethernet, 1 = ip, 2 = punt/inject
+ """
+ # create memif interface with role=0 (i.e. master)
+ result = self.vapi.memif_create_v2(
+ role=0, mode=mode, id=memif_id, buffer_size=9216
+ )
+ sw_if_index = result.sw_if_index
+ self.vapi.sw_interface_set_flags(sw_if_index=sw_if_index, flags=1)
+ return sw_if_index
+
def dump_bridge_domain_details(self, bd_id):
return self.vapi.bridge_domain_dump(bd_id=bd_id)