aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile82
-rw-r--r--test/asf/asfframework.py72
-rw-r--r--test/asf/test_adl.py2
-rw-r--r--test/asf/test_api_trace.py2
-rw-r--r--test/asf/test_http_static.py2
-rw-r--r--test/asf/test_lb_api.py6
-rw-r--r--test/asf/test_prom.py1
-rw-r--r--test/asf/test_quic.py12
-rw-r--r--test/asf/test_session.py12
-rw-r--r--test/asf/test_session_sdl.py297
-rw-r--r--test/asf/test_tcp.py10
-rw-r--r--test/asf/test_tls.py6
-rw-r--r--test/asf/test_vcl.py107
-rw-r--r--test/asf/test_vhost.py2
-rw-r--r--test/asf/vpp_session_sdl.py75
-rw-r--r--test/config.py5
-rw-r--r--test/framework.py3
-rw-r--r--test/patches/scapy-2.4.5/cdp.patch14
-rw-r--r--test/patches/scapy-2.4.5/ikev2.patch22
-rw-r--r--test/patches/scapy-2.4.5/ipsec.patch230
-rw-r--r--test/patches/scapy-2.4.5/ppp.patch45
-rw-r--r--test/patches/scapy-2.4.5/scapy-python312.patch590
-rw-r--r--test/requirements-3.txt463
-rw-r--r--test/requirements.txt4
-rw-r--r--test/template_ipsec.py36
-rw-r--r--test/test_arping.py4
-rw-r--r--test/test_bond.py7
-rw-r--r--test/test_cdp.py2
-rw-r--r--test/test_cnat.py4
-rw-r--r--test/test_det44.py2
-rw-r--r--test/test_dhcp.py18
-rw-r--r--test/test_dhcp6.py9
-rw-r--r--test/test_dns.py2
-rw-r--r--test/test_dslite.py4
-rw-r--r--test/test_dvr.py2
-rw-r--r--test/test_flowprobe.py26
-rw-r--r--test/test_geneve.py3
-rw-r--r--test/test_gre.py3
-rw-r--r--test/test_gso.py4
-rw-r--r--test/test_gtpu.py3
-rw-r--r--test/test_igmp.py2
-rw-r--r--test/test_ikev2.py71
-rw-r--r--test/test_interface_crud.py4
-rw-r--r--test/test_ip4.py66
-rw-r--r--test/test_ip4_vrf_multi_instance.py4
-rw-r--r--test/test_ip6.py13
-rw-r--r--test/test_ip6_nd_mirror_proxy.py6
-rw-r--r--test/test_ip6_vrf_multi_instance.py4
-rw-r--r--test/test_ip_mcast.py10
-rw-r--r--test/test_ip_session_redirect.py5
-rw-r--r--test/test_ipip.py4
-rw-r--r--test/test_ipsec_ah.py4
-rw-r--r--test/test_ipsec_esp.py5
-rw-r--r--test/test_ipsec_spd_flow_cache_input.py8
-rw-r--r--test/test_ipsec_spd_fp_input.py7
-rw-r--r--test/test_ipsec_tun_if_esp.py36
-rw-r--r--test/test_l2tp.py4
-rw-r--r--test/test_l3xc.py2
-rw-r--r--test/test_lacp.py3
-rw-r--r--test/test_lb.py3
-rw-r--r--test/test_linux_cp.py14
-rw-r--r--test/test_lisp.py3
-rw-r--r--test/test_lldp.py1
-rw-r--r--test/test_map.py2
-rw-r--r--test/test_map_br.py2
-rw-r--r--test/test_memif.py2
-rw-r--r--test/test_mpls.py4
-rw-r--r--test/test_mtu.py6
-rw-r--r--test/test_nat44_ed.py15
-rw-r--r--test/test_nat44_ed_output.py4
-rw-r--r--test/test_nat44_ei.py24
-rw-r--r--test/test_nat64.py6
-rw-r--r--test/test_nat66.py2
-rw-r--r--test/test_npt66.py2
-rw-r--r--test/test_pcap.py4
-rw-r--r--test/test_pg.py4
-rw-r--r--test/test_ping.py4
-rw-r--r--test/test_pipe.py2
-rw-r--r--test/test_pnat.py4
-rw-r--r--test/test_pppoe.py3
-rw-r--r--test/test_pvti.py1153
-rw-r--r--test/test_reassembly.py22
-rw-r--r--test/test_span.py7
-rw-r--r--test/test_srv6_ad.py2
-rw-r--r--test/test_srv6_ad_flow.py4
-rw-r--r--test/test_srv6_as.py2
-rw-r--r--test/test_srv6_mobile.py15
-rw-r--r--test/test_svs.py2
-rw-r--r--test/test_trace_filter.py4
-rw-r--r--test/test_udp.py26
-rw-r--r--test/test_urpf.py2
-rw-r--r--test/test_vlib.py7
-rw-r--r--test/test_vrrp.py2
-rw-r--r--test/test_vxlan.py4
-rw-r--r--test/test_vxlan6.py4
-rw-r--r--test/test_wireguard.py14
-rw-r--r--test/vm_vpp_interfaces.py10
-rw-r--r--test/vpp_ip_route.py10
-rw-r--r--test/vpp_pg_interface.py2
99 files changed, 3445 insertions, 409 deletions
diff --git a/test/Makefile b/test/Makefile
index 9b9cc178cf6..bc5bc0cf129 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -74,12 +74,13 @@ V=0
endif
PYTHON_VERSION=$(shell $(PYTHON_INTERP) -c 'import sys; print(sys.version_info.major)')
-PIP_VERSION=24.0
+PIP_VERSION=24.2
# Keep in sync with requirements.txt
PIP_TOOLS_VERSION=7.4.1
-PIP_SETUPTOOLS_VERSION=69.2.0
+PIP_SETUPTOOLS_VERSION=71.1.0
PYTHON_DEPENDS=requirements-$(PYTHON_VERSION).txt
SCAPY_SOURCE=$(shell find $(VENV_PATH)/lib/python* -name site-packages)
+SCAPY_VERSION=$(shell grep scapy $(TEST_DIR)/requirements.txt | cut -d'=' -f3 | cut -d';' -f1)
BUILD_COV_DIR=$(BR)/test-coverage
PIP_TOOLS_INSTALL_DONE=$(VENV_RUN_DIR)/pip-tools-install-$(PYTHON_VERSION)-$(PIP_TOOLS_VERSION).done
@@ -118,7 +119,7 @@ $(PIP_INSTALL_DONE): $(PIP_TOOLS_INSTALL_DONE) $(PYTHON_DEPENDS)
$(PIP_PATCH_DONE): $(PIP_INSTALL_DONE)
@echo --- patching ---
@sleep 1 # Ensure python recompiles patched *.py files -> *.pyc
- for f in $(CURDIR)/patches/scapy-2.4.3/*.patch ; do \
+ for f in $(CURDIR)/patches/scapy-$(SCAPY_VERSION)/*.patch ; do \
echo Applying patch: $$(basename $$f) ; \
patch --forward -p1 -d $(SCAPY_SOURCE) < $$f ; \
retCode=$$?; \
@@ -255,8 +256,8 @@ ARG17=--extern-apidir=$(EXTERN_APIDIR)
endif
ARG18=
-ifneq ($(findstring $(DECODE_PCAPS),1 y yes),)
-ARG18=--decode-pcaps
+ifneq ($(DECODE_PCAPS),)
+ARG18=--decode-pcaps=$(DECODE_PCAPS)
endif
ifneq ($(findstring $(API_PRELOAD),1 y yes),)
@@ -350,32 +351,72 @@ cov-prep: test-dep
@lcov --zerocounters --directory $(VPP_BUILD_DIR)
@test -z "$(EXTERN_COV_DIR)" || lcov --zerocounters --directory $(EXTERN_COV_DIR)
+COV_REM_NOT_CODE="/usr/include/*" "*/build-root/*" "/opt/*" "/usr/lib/*" \
+ "*_test.*" "*test_*" "*vat*" "*/vnet/unix/gdb_funcs.c" \
+ "*pg.c"
+
+COV_REM_DRIVERS="*rdma*" "*/plugins/af_packet/*" "*/plugins/af_xdp/*" \
+ "*/plugins/avf/*" "*/plugins/dma_intel/*" "*/vlib/pci/*" \
+ "*/vnet/devices/*" "*/vlib/dma/*" "*/plugins/vmxnet3/*" \
+ "*/vnet/devices/virtio/*" "*/plugins/perfmon/arm*" \
+ "*/plugins/perfmon/intel/*" "*/vlib/vmbus/*" \
+ "*/vnet/dev/*" "*/plugins/dev_ena/*" "*/plugins/dev_iavf/*"
+
+COV_REM_UNUSED_FEAT="*/plugins/ioam/analyse/*" "*/plugins/ioam/lib-*/*" \
+ "*/plugins/ioam/export-common/*" "*/vnet/srp/*" \
+ "*/lawful-intercept/*" "*/lisp/*" "*/vnet/osi/*" \
+ "*/plugins/nsh/*"
+
+COV_REM_TODO_NO_TEST="*/vpp-api/client/*" "*/plugins/prom/*" \
+ "*/plugins/tlspicotls/*" "*/plugins/tlsmbedtls/*" \
+ "*/vppinfra/perfmon/*" "*/plugins/ila/*" \
+ "*/vlib/linux/*" "*/vnet/util/radix.c" "*/vapi/vapi.hpp" \
+ "*/vpp/api/types.c" "*/vpp/api/json_format.c" \
+ "*/plugins/ioam/*/*.h" "*/linux/netns.c" "*/vnet/flow/*" \
+ "*/vppinfra/random.c" "*/vppinfra/ring.h" \
+ "*/vppinfra/bihash_vec8_8.h" "*/vppinfra/maplog.c" \
+ "*/vppinfra/format_table.c" "*/vppinfra/timing_wheel.c" \
+ "*/vppinfra/macros.c" "*/vppinfra/valloc.c" \
+ "*/vppinfra/jsonformat.c" "*/vppinfra/vector/array_mask.h" \
+ "*/vppinfra/vector/toeplitz.c" "*/plugins/vrrp/vrrp_packet.h" \
+ "*/vnet/srv6/sr.h" "*/vlibapi/api_format.c" \
+ "*/vlibapi/node_serialize.c" "*/plugins/quic/error.c" \
+ "*/vnet/ipfix-export/flow_report_classify.h" \
+ "*/vnet/ip/ip6_ll_types.c" "*/vnet/ip/ip_psh_cksum.h" \
+ "*/vnet/ip/ip6_hop_by_hop.h" "*/vnet/ip/ip_format_fns.h" \
+ "*/vnet/dpo/classify_dpo.h" "*/vnet/dpo/l3_proxy_dpo.h" \
+ "*/vnet/ipsec/esp_format.c" "*/vnet/ethernet/sfp.c" \
+ "*/vnet/ethernet/ethernet_format_fns.h" \
+ "*/plugins/ikev2/ikev2_format.c" "*/vnet/bier/bier_types.c"
+
+COV_REM_ALT_TEST="*/plugins/hs_apps/*" "*/plugins/http/*.h"
+
.PHONY: cov-post
cov-post: wipe-cov $(BUILD_COV_DIR)
@lcov --capture \
--directory $(VPP_BUILD_DIR) \
- --output-file $(BUILD_COV_DIR)/coverage.info
+ --output-file $(BUILD_COV_DIR)/coverage$(HS_TEST).info
@test -z "$(EXTERN_COV_DIR)" || \
lcov --capture \
--directory $(EXTERN_COV_DIR) \
- --output-file $(BUILD_COV_DIR)/extern-coverage.info
- @lcov --remove $(BUILD_COV_DIR)/coverage.info \
- "/usr/include/*" "*/build-root/*" "/opt/*" "/usr/lib/*" \
- "*_test.*" "*vat*" "*rdma*" "*/vpp-api/client/*" "*/plugins/af_packet/*" \
- "*/plugins/af_xdp/*" "*/plugins/avf/*" "*/plugins/dma_intel/*" \
- "*/plugins/hs_apps/*" "*/plugins/vmxnet3/*" "*/vnet/devices/virtio/*" \
- "*/plugins/perfmon/arm*" "*/plugins/perfmon/intel/*" "*/vlib/vmbus/*" \
- "*/vnet/dev/*" "*/plugins/dev_ena/*" "*/plugins/builtinurl/*" "*/vnet/flow/*" \
- "*/plugins/http_static/builtinurl/*" "*/plugins/dev_iavf/*" \
- -o $(BUILD_COV_DIR)/coverage-filtered.info
- @genhtml $(BUILD_COV_DIR)/coverage-filtered.info \
+ --output-file $(BUILD_COV_DIR)/extern-coverage$(HS_TEST).info
+ @lcov --remove $(BUILD_COV_DIR)/coverage$(HS_TEST).info \
+ $(COV_REM_NOT_CODE) \
+ $(COV_REM_DRIVERS) \
+ $(COV_REM_TODO_NO_TEST) \
+ $(COV_REM_UNUSED_FEAT) \
+ $(COV_REM_ALT_TEST) \
+ -o $(BUILD_COV_DIR)/coverage-filtered$(HS_TEST).info
+ @genhtml $(BUILD_COV_DIR)/coverage-filtered$(HS_TEST).info \
--output-directory $(BUILD_COV_DIR)/html
@test -z "$(EXTERN_COV_DIR)" || \
- genhtml $(BUILD_COV_DIR)/extern-coverage.info \
+ genhtml $(BUILD_COV_DIR)/extern-coverage$(HS_TEST).info \
--output-directory $(BUILD_COV_DIR)/extern-html
@echo
@echo "Build finished. Code coverage report is in $(BUILD_COV_DIR)/html/index.html"
@test -z "$(EXTERN_COV_DIR)" || echo "Code coverage report for out-of-tree objects is in $(BUILD_COV_DIR)/extern-html/index.html"
+ @mkdir -p $(BR)/test-coverage-merged
+ @cp -f $(BUILD_COV_DIR)/coverage-filtered$(HS_TEST).info $(BR)/test-coverage-merged
.PHONY: cov
cov:
@@ -434,6 +475,7 @@ help:
@echo " test-cov-prep - coverage phase #1 : prepare lcov"
@echo " test-cov-build - coverage phase #2 : build gcov image & run tests against it (use TEST=)"
@echo " test-cov-post - coverage phase #3 : generate lcov html report"
+ @echo " test-cov-both - generate and merge code coverage report for Python and Golang tests"
@echo " test-all - build and run functional and extended tests"
@echo " test-all-debug - build and run functional and extended tests (debug build)"
@echo " test-all-cov - generate code coverage report for functional and extended tests"
@@ -613,6 +655,10 @@ help:
@echo " random seed used by test framework"
@echo " (default: time.time())"
@echo ""
+ @echo " DECODE_PCAPS=[all|failed|none]"
+ @echo " decode pcap files using tshark - all, only failed or none"
+ @echo " (default: failed)"
+ @echo ""
@echo "Starting VPP in GDB for use with DEBUG=attach:"
@echo ""
@echo " test-start-vpp-in-gdb - start VPP in gdb (release)"
diff --git a/test/asf/asfframework.py b/test/asf/asfframework.py
index 24880044cec..bd1b45c6476 100644
--- a/test/asf/asfframework.py
+++ b/test/asf/asfframework.py
@@ -166,25 +166,28 @@ def _is_distro_ubuntu2204():
is_distro_ubuntu2204 = _is_distro_ubuntu2204()
-def _is_distro_debian11():
+def _is_distro_ubuntu2404():
with open("/etc/os-release") as f:
for line in f.readlines():
- if "bullseye" in line:
+ if "noble" in line:
return True
return False
-is_distro_debian11 = _is_distro_debian11()
+is_distro_ubuntu2404 = _is_distro_ubuntu2404()
-def _is_distro_ubuntu2204():
+def _is_distro_debian11():
with open("/etc/os-release") as f:
for line in f.readlines():
- if "jammy" in line:
+ if "bullseye" in line:
return True
return False
+is_distro_debian11 = _is_distro_debian11()
+
+
class KeepAliveReporter(object):
"""
Singleton object which reports test start to parent process
@@ -236,6 +239,8 @@ class TestCaseTag(Enum):
FIXME_DEBIAN11 = 5
# marks suites broken on debug vpp image
FIXME_VPP_DEBUG = 6
+ # marks suites broken on Ubuntu-24.04
+ FIXME_UBUNTU2404 = 7
def create_tag_decorator(e):
@@ -255,6 +260,7 @@ tag_fixme_asan = create_tag_decorator(TestCaseTag.FIXME_ASAN)
tag_fixme_ubuntu2204 = create_tag_decorator(TestCaseTag.FIXME_UBUNTU2204)
tag_fixme_debian11 = create_tag_decorator(TestCaseTag.FIXME_DEBIAN11)
tag_fixme_vpp_debug = create_tag_decorator(TestCaseTag.FIXME_VPP_DEBUG)
+tag_fixme_ubuntu2404 = create_tag_decorator(TestCaseTag.FIXME_UBUNTU2404)
class DummyVpp:
@@ -317,6 +323,18 @@ class VppAsfTestCase(CPUInterface, unittest.TestCase):
cls = unittest.skip("Skipping @tag_fixme_asan tests")(cls)
@classmethod
+ def skip_fixme_ubuntu2204(cls):
+ """if @tag_fixme_ubuntu2204 & is Ubuntu22.04 - mark for skip"""
+ if cls.has_tag(TestCaseTag.FIXME_UBUNTU2204) and is_distro_ubuntu2204 == True:
+ cls = unittest.skip("Skipping @tag_fixme_ubuntu2204 tests")(cls)
+
+ @classmethod
+ def skip_fixme_ubuntu2404(cls):
+ """if @tag_fixme_ubuntu2404 & is Ubuntu24.04 - mark for skip"""
+ if cls.has_tag(TestCaseTag.FIXME_UBUNTU2404) and is_distro_ubuntu2404 == True:
+ cls = unittest.skip("Skipping @tag_fixme_ubuntu2404 tests")(cls)
+
+ @classmethod
def instance(cls):
"""Return the instance of this testcase"""
return cls.test_instance
@@ -1155,16 +1173,13 @@ class VppTestResult(unittest.TestResult):
self.runner = runner
self.printed = []
- def decodePcapFiles(self, test, when_configured=False):
- if when_configured == False or config.decode_pcaps == True:
- if hasattr(test, "pg_interfaces") and len(test.pg_interfaces) > 0:
- testcase_dir = os.path.dirname(test.pg_interfaces[0].out_path)
- test.pg_interfaces[0].decode_pcap_files(
- testcase_dir, f"suite{test.__class__.__name__}"
- )
- test.pg_interfaces[0].decode_pcap_files(
- testcase_dir, test._testMethodName
- )
+ def decodePcapFiles(self, test):
+ if hasattr(test, "pg_interfaces") and len(test.pg_interfaces) > 0:
+ testcase_dir = os.path.dirname(test.pg_interfaces[0].out_path)
+ test.pg_interfaces[0].decode_pcap_files(
+ testcase_dir, f"suite{test.__class__.__name__}"
+ )
+ test.pg_interfaces[0].decode_pcap_files(testcase_dir, test._testMethodName)
def addSuccess(self, test):
"""
@@ -1174,7 +1189,8 @@ class VppTestResult(unittest.TestResult):
"""
self.log_result("addSuccess", test)
- self.decodePcapFiles(test, when_configured=True)
+ if "all" == config.decode_pcaps:
+ self.decodePcapFiles(test)
unittest.TestResult.addSuccess(self, test)
self.result_string = colorize("OK", GREEN)
self.result_code = TestResultCode.PASS
@@ -1182,7 +1198,8 @@ class VppTestResult(unittest.TestResult):
def addExpectedFailure(self, test, err):
self.log_result("addExpectedFailure", test, err)
- self.decodePcapFiles(test)
+ if "none" != config.decode_pcaps:
+ self.decodePcapFiles(test)
super().addExpectedFailure(test, err)
self.result_string = colorize("FAIL", GREEN)
self.result_code = TestResultCode.EXPECTED_FAIL
@@ -1190,7 +1207,8 @@ class VppTestResult(unittest.TestResult):
def addUnexpectedSuccess(self, test):
self.log_result("addUnexpectedSuccess", test)
- self.decodePcapFiles(test, when_configured=True)
+ if "none" != config.decode_pcaps:
+ self.decodePcapFiles(test)
super().addUnexpectedSuccess(test)
self.result_string = colorize("OK", RED)
self.result_code = TestResultCode.UNEXPECTED_PASS
@@ -1276,7 +1294,9 @@ class VppTestResult(unittest.TestResult):
error_type_str = colorize("ERROR", RED)
else:
raise Exception(f"Unexpected result code {result_code}")
- self.decodePcapFiles(test)
+
+ if "none" != config.decode_pcaps:
+ self.decodePcapFiles(test)
unittest_fn(self, test, err)
if self.current_test_case_info:
@@ -1361,6 +1381,20 @@ class VppTestResult(unittest.TestResult):
test_title = colorize(f"FIXME with ASAN: {test_title}", RED)
test.skip_fixme_asan()
+ if (
+ test.has_tag(TestCaseTag.FIXME_UBUNTU2204)
+ and is_distro_ubuntu2204 == True
+ ):
+ test_title = colorize(f"FIXME with Ubuntu 22.04: {test_title}", RED)
+ test.skip_fixme_ubuntu2204()
+
+ if (
+ test.has_tag(TestCaseTag.FIXME_UBUNTU2404)
+ and is_distro_ubuntu2404 == True
+ ):
+ test_title = colorize(f"FIXME with Ubuntu 24.04: {test_title}", RED)
+ test.skip_fixme_ubuntu2404()
+
if hasattr(test, "vpp_worker_count"):
if test.vpp_worker_count == 0:
test_title += " [main thread only]"
diff --git a/test/asf/test_adl.py b/test/asf/test_adl.py
index 7e5ca8dcbe3..70d32bce9da 100644
--- a/test/asf/test_adl.py
+++ b/test/asf/test_adl.py
@@ -3,8 +3,10 @@
import unittest
from asfframework import VppAsfTestCase, VppTestRunner
+from config import config
+@unittest.skipIf("adl" in config.excluded_plugins, "Exclude ADL plugin tests")
class TestAdl(VppAsfTestCase):
"""Allow/Deny Plugin Unit Test Cases"""
diff --git a/test/asf/test_api_trace.py b/test/asf/test_api_trace.py
index 8776a79f0ac..04fcf63ca41 100644
--- a/test/asf/test_api_trace.py
+++ b/test/asf/test_api_trace.py
@@ -37,7 +37,7 @@ class TestJsonApiTrace(VppAsfTestCase):
found = True
break
self.assertTrue(found)
- self.assertEquals(o["_msgname"], "show_version")
+ self.assertEqual(o["_msgname"], "show_version")
def test_json_api_trace_replay(self):
fname = "/tmp/create_loop.json"
diff --git a/test/asf/test_http_static.py b/test/asf/test_http_static.py
index 18e8ba56a1e..73a95e992da 100644
--- a/test/asf/test_http_static.py
+++ b/test/asf/test_http_static.py
@@ -63,11 +63,13 @@ class TestHttpStaticVapi(VppAsfTestCase):
"exec",
"HttpStatic",
"curl",
+ "-v",
f"10.10.1.2/{self.temp.name[5:]}",
],
capture_output=True,
)
self.assertIn(b"Hello world", process.stdout)
+ self.assertIn(b"max-age=600", process.stderr)
self.temp2.seek(0)
process = subprocess.run(
diff --git a/test/asf/test_lb_api.py b/test/asf/test_lb_api.py
index 9608d0473a6..031479eb7f4 100644
--- a/test/asf/test_lb_api.py
+++ b/test/asf/test_lb_api.py
@@ -13,10 +13,14 @@
# limitations under the License.
from asfframework import VppAsfTestCase
+from config import config
+
+import unittest
DEFAULT_VIP = "lb_vip_details(_0=978, context=12, vip=vl_api_lb_ip_addr_t(pfx=IPv6Network(u'::/0'), protocol=<vl_api_ip_proto_t.IP_API_PROTO_RESERVED: 255>, port=0), encap=<vl_api_lb_encap_type_t.LB_API_ENCAP_TYPE_GRE4: 0>, dscp=<vl_api_ip_dscp_t.IP_API_DSCP_CS0: 0>, srv_type=<vl_api_lb_srv_type_t.LB_API_SRV_TYPE_CLUSTERIP: 0>, target_port=0, flow_table_length=0)" # noqa
+@unittest.skipIf("lb" in config.excluded_plugins, "Exclude LB plugin tests")
class TestLbEmptyApi(VppAsfTestCase):
"""TestLbEmptyApi"""
@@ -34,6 +38,7 @@ class TestLbEmptyApi(VppAsfTestCase):
self.assertEqual(rv, [], "Expected: [] Received: %r." % rv)
+@unittest.skipIf("lb" in config.excluded_plugins, "Exclude LB plugin tests")
class TestLbApi(VppAsfTestCase):
"""TestLbApi"""
@@ -55,6 +60,7 @@ class TestLbApi(VppAsfTestCase):
self.vapi.cli("lb vip 2001::/16 del")
+@unittest.skipIf("lb" in config.excluded_plugins, "Exclude LB plugin tests")
class TestLbAsApi(VppAsfTestCase):
"""TestLbAsApi"""
diff --git a/test/asf/test_prom.py b/test/asf/test_prom.py
index 3f8fb4c7a44..f536fd19d34 100644
--- a/test/asf/test_prom.py
+++ b/test/asf/test_prom.py
@@ -39,6 +39,7 @@ class TestProm(VppAsfTestCase):
"""Enable HTTP Static server and prometheus exporter, get stats"""
self.vapi.cli("http static server uri tcp://0.0.0.0/80 url-handlers")
self.vapi.cli("prom enable")
+ self.sleep(1, "wait for min-scrape-interval to expire")
process = subprocess.run(
[
diff --git a/test/asf/test_quic.py b/test/asf/test_quic.py
index e453bd5b3e5..c4fa6912114 100644
--- a/test/asf/test_quic.py
+++ b/test/asf/test_quic.py
@@ -117,6 +117,18 @@ class QUICTestCase(VppAsfTestCase):
self.logger.debug(self.vapi.cli("show ip fib"))
def tearDown(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0,
+ namespace_id=self.server_appns,
+ secret=self.server_appns_secret,
+ sw_if_index=self.loop0.sw_if_index,
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0,
+ namespace_id=self.client_appns,
+ secret=self.client_appns_secret,
+ sw_if_index=self.loop1.sw_if_index,
+ )
# Delete inter-table routes
self.ip_t01.remove_vpp_config()
self.ip_t10.remove_vpp_config()
diff --git a/test/asf/test_session.py b/test/asf/test_session.py
index 64f59df5758..184ec4fba54 100644
--- a/test/asf/test_session.py
+++ b/test/asf/test_session.py
@@ -9,9 +9,13 @@ from asfframework import (
tag_run_solo,
)
from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
+from config import config
@tag_fixme_vpp_workers
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class TestSession(VppAsfTestCase):
"""Session Test Case"""
@@ -56,6 +60,14 @@ class TestSession(VppAsfTestCase):
i.set_table_ip4(0)
i.admin_down()
+ # Unconfigure namespaces - remove our locks to the vrf tables
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+
super(TestSession, self).tearDown()
self.vapi.session_enable_disable(is_enable=1)
diff --git a/test/asf/test_session_sdl.py b/test/asf/test_session_sdl.py
new file mode 100644
index 00000000000..15d696350bc
--- /dev/null
+++ b/test/asf/test_session_sdl.py
@@ -0,0 +1,297 @@
+#!/usr/bin/env python3
+
+import unittest
+
+from framework import VppTestCase
+from asfframework import VppTestRunner, tag_fixme_vpp_workers
+from ipaddress import IPv4Network, IPv6Network
+
+from vpp_ip_route import (
+ VppIpRoute,
+ VppRoutePath,
+ VppIpTable,
+)
+
+from vpp_papi import VppEnum
+
+
+from vpp_session_sdl import VppSessionSdl
+from vpp_session_sdl import SessionSdl
+
+
+@tag_fixme_vpp_workers
+class TestSessionSDL(VppTestCase):
+ """Session SDL Test Case"""
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestSessionSDL, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestSessionSDL, cls).tearDownClass()
+
+ def setUp(self):
+ super(TestSessionSDL, self).setUp()
+ self.create_loopback_interfaces(2)
+
+ table_id = 0
+
+ for i in self.lo_interfaces:
+ i.admin_up()
+
+ if table_id != 0:
+ tbl = VppIpTable(self, table_id)
+ tbl.add_vpp_config()
+ tbl = VppIpTable(self, table_id, is_ip6=1)
+ tbl.add_vpp_config()
+
+ i.set_table_ip4(table_id)
+ i.set_table_ip6(table_id)
+ i.config_ip4()
+ i.config_ip6()
+ table_id += 1
+
+ def tearDown(self):
+ for i in self.lo_interfaces:
+ i.unconfig_ip4()
+ i.set_table_ip4(0)
+ i.unconfig_ip6()
+ i.set_table_ip6(0)
+ i.admin_down()
+ self.loop0.remove_vpp_config()
+ self.loop1.remove_vpp_config()
+ super(TestSessionSDL, self).tearDown()
+
+ def create_rule(self, lcl, action_index, tag):
+ return SessionSdl(lcl=lcl, action_index=action_index, tag=tag)
+
+ def apply_rules(self, rules, is_add, appns_index):
+ r = VppSessionSdl(self, rules, is_add=is_add, appns_index=appns_index)
+ r.add_vpp_config()
+
+ def test_session_sdl_ip4(self):
+ """Session SDL IP4 test"""
+
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL
+ )
+
+ # Configure namespaces
+ self.vapi.app_namespace_add_del_v4(
+ namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+
+ # Add inter-table routes
+ uri = "tcp://" + self.loop0.local_ip4 + "/1234"
+ server_cmd = "test echo server appns 0 fifo-size 4k " + "uri " + uri
+ client_cmd = (
+ "test echo client bytes 100000 appns 1 "
+ + "fifo-size 4k "
+ + "syn-timeout 2 uri "
+ + uri
+ )
+ ip_t01 = VppIpRoute(
+ self,
+ self.loop1.local_ip4,
+ 32,
+ [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=1)],
+ )
+ ip_t10 = VppIpRoute(
+ self,
+ self.loop0.local_ip4,
+ 32,
+ [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=0)],
+ table_id=1,
+ )
+ ip_t01.add_vpp_config()
+ ip_t10.add_vpp_config()
+
+ # Start builtin server for ip4
+ self.logger.info(self.vapi.cli(server_cmd))
+
+ # Add session filter to block loop0
+ rules = []
+ rules.append(
+ self.create_rule(lcl=self.loop0.local_ip4 + "/32", action_index=0, tag="")
+ )
+ self.apply_rules(rules, is_add=1, appns_index=0)
+
+ filter = self.vapi.session_sdl_dump()
+ self.assertEqual(filter[0].lcl, IPv4Network(self.loop0.local_ip4 + "/32"))
+
+ # irrelevant rules - add 64k entries in one API call
+ rules = []
+ for i in range(255):
+ for j in range(255):
+ prefix = "10.1.{0}.{1}/32".format(i, j)
+ rules.append(self.create_rule(lcl=prefix, action_index=0, tag=""))
+ self.apply_rules(rules, is_add=1, appns_index=0)
+
+ error = self.vapi.cli_return_response(server_cmd)
+ # Expecting an error because loop0 is blocked
+ self.assertEqual(-1, error.retval)
+
+ # Remove the session filter
+ rules = []
+ rules.append(
+ self.create_rule(lcl=self.loop0.local_ip4 + "/32", action_index=0, tag="")
+ )
+ self.apply_rules(rules, is_add=0, appns_index=0)
+
+ # Not expecting an error
+ self.logger.info(self.vapi.cli(client_cmd))
+
+ # Add a session filter not matching loop0
+ rules = []
+ rules.append(self.create_rule(lcl="172.100.1.0/24", action_index=0, tag=""))
+ self.apply_rules(rules, is_add=1, appns_index=0)
+
+ # Not expecting an error
+ self.logger.info(self.vapi.cli(client_cmd))
+
+ self.logger.info(self.vapi.cli(server_cmd + " stop"))
+
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+ # Delete inter-table routes
+ ip_t01.remove_vpp_config()
+ ip_t10.remove_vpp_config()
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+ def test_session_sdl_ip6(self):
+ """Session SDL IP6 test"""
+
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL
+ )
+
+ # Configure namespaces
+ self.vapi.app_namespace_add_del_v4(
+ namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+
+ # IP6 Test
+ # Add inter-table routes
+ uri = "tcp://" + self.loop0.local_ip6 + "/1235"
+ client_cmd = (
+ "test echo client bytes 100000 appns 1 "
+ + "fifo-size 4k "
+ + "syn-timeout 2 uri "
+ + uri
+ )
+ server_cmd = "test echo server appns 0 fifo-size 4k " + "uri " + uri
+
+ ip_t01 = VppIpRoute(
+ self,
+ self.loop1.local_ip6,
+ 128,
+ [VppRoutePath("0::0", 0xFFFFFFFF, nh_table_id=1)],
+ )
+ ip_t10 = VppIpRoute(
+ self,
+ self.loop0.local_ip6,
+ 128,
+ [VppRoutePath("0::0", 0xFFFFFFFF, nh_table_id=0)],
+ table_id=1,
+ )
+ ip_t01.add_vpp_config()
+ ip_t10.add_vpp_config()
+
+ # Start builtin server for ip6
+ self.logger.info(self.vapi.cli(server_cmd))
+
+ # case 1: No filter
+
+ # Not expecting an error
+ self.logger.info(self.vapi.cli(client_cmd))
+
+ # case 2: filter to block
+ # Add session filter to block loop0
+ rules = []
+ rules.append(
+ self.create_rule(lcl=self.loop0.local_ip6 + "/128", action_index=0, tag="")
+ )
+ self.apply_rules(rules, is_add=1, appns_index=0)
+ filter = self.vapi.session_sdl_dump()
+ self.assertEqual(filter[0].lcl, IPv6Network(self.loop0.local_ip6 + "/128"))
+
+ error = self.vapi.cli_return_response(client_cmd)
+ # Expecting an error because loop0 is blocked
+ self.assertEqual(-1, error.retval)
+
+ # case 3: remove to block
+ # Add session filter to block loop0
+ rules = []
+ rules.append(
+ self.create_rule(lcl=self.loop0.local_ip6 + "/128", action_index=0, tag="")
+ )
+ self.apply_rules(rules, is_add=0, appns_index=0)
+ # Not expecting an error
+ self.logger.info(self.vapi.cli(client_cmd))
+
+ # stop the server
+ self.logger.info(self.vapi.cli(server_cmd + " stop"))
+
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+ # Delete inter-table routes
+ ip_t01.remove_vpp_config()
+ ip_t10.remove_vpp_config()
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+ def test_session_enable_disable(self):
+ """Session SDL enable/disable test"""
+
+ for i in range(10):
+ # Enable sdl
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL
+ )
+
+ # Disable
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+ # Enable rule-table
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_RULE_TABLE
+ )
+
+ # Disable
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+ # Enable sdl
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL
+ )
+
+ # Disable
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+
+if __name__ == "__main__":
+ unittest.main(testRunner=VppTestRunner)
diff --git a/test/asf/test_tcp.py b/test/asf/test_tcp.py
index 69fc5c472a5..23772d34c76 100644
--- a/test/asf/test_tcp.py
+++ b/test/asf/test_tcp.py
@@ -4,8 +4,12 @@ import unittest
from asfframework import VppAsfTestCase, VppTestRunner
from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
+from config import config
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class TestTCP(VppAsfTestCase):
"""TCP Test Case"""
@@ -44,6 +48,12 @@ class TestTCP(VppAsfTestCase):
)
def tearDown(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
for i in self.lo_interfaces:
i.unconfig_ip4()
i.set_table_ip4(0)
diff --git a/test/asf/test_tls.py b/test/asf/test_tls.py
index d2d1d9a4747..2ce87143339 100644
--- a/test/asf/test_tls.py
+++ b/test/asf/test_tls.py
@@ -91,6 +91,12 @@ class TestTLS(VppAsfTestCase):
)
def tearDown(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
for i in self.lo_interfaces:
i.unconfig_ip4()
i.set_table_ip4(0)
diff --git a/test/asf/test_vcl.py b/test/asf/test_vcl.py
index a1113b863e8..124ea14089b 100644
--- a/test/asf/test_vcl.py
+++ b/test/asf/test_vcl.py
@@ -7,7 +7,7 @@ import subprocess
import signal
import glob
from config import config
-from asfframework import VppAsfTestCase, VppTestRunner, Worker
+from asfframework import VppAsfTestCase, VppTestRunner, Worker, tag_fixme_ubuntu2404
from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
iperf3 = "/usr/bin/iperf3"
@@ -189,6 +189,12 @@ class VCLTestCase(VppAsfTestCase):
self.logger.debug(self.vapi.cli("show ip fib"))
def thru_host_stack_tear_down(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index
+ )
for i in self.lo_interfaces:
i.unconfig_ip4()
i.set_table_ip4(0)
@@ -240,6 +246,12 @@ class VCLTestCase(VppAsfTestCase):
self.logger.debug(self.vapi.cli("show ip6 fib"))
def thru_host_stack_ipv6_tear_down(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index
+ )
for i in self.lo_interfaces:
i.unconfig_ip6()
i.set_table_ip6(0)
@@ -299,6 +311,7 @@ class VCLTestCase(VppAsfTestCase):
self.assert_equal(worker_client.result, 0, "Binary test return code")
+@tag_fixme_ubuntu2404
class LDPCutThruTestCase(VCLTestCase):
"""LDP Cut Thru Tests"""
@@ -403,6 +416,9 @@ class LDPCutThruTestCase(VCLTestCase):
)
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLCutThruTestCase(VCLTestCase):
"""VCL Cut Thru Tests"""
@@ -489,6 +505,9 @@ class VCLCutThruTestCase(VCLTestCase):
)
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLThruHostStackEcho(VCLTestCase):
"""VCL Thru Host Stack Echo"""
@@ -543,6 +562,9 @@ class VCLThruHostStackEcho(VCLTestCase):
self.logger.debug(self.vapi.cli("show app mq"))
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLThruHostStackTLS(VCLTestCase):
"""VCL Thru Host Stack TLS"""
@@ -594,6 +616,9 @@ class VCLThruHostStackTLS(VCLTestCase):
self.logger.debug(self.vapi.cli("show app mq"))
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLThruHostStackEchoInterruptMode(VCLThruHostStackEcho):
"""VCL Thru Host Stack Echo interrupt mode"""
@@ -625,6 +650,9 @@ class VCLThruHostStackTLSInterruptMode(VCLThruHostStackTLS):
super(VCLThruHostStackTLS, cls).setUpClass()
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLThruHostStackDTLS(VCLTestCase):
"""VCL Thru Host Stack DTLS"""
@@ -675,6 +703,9 @@ class VCLThruHostStackDTLS(VCLTestCase):
self.logger.debug(self.vapi.cli("show app mq"))
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLThruHostStackQUIC(VCLTestCase):
"""VCL Thru Host Stack QUIC"""
@@ -726,6 +757,62 @@ class VCLThruHostStackQUIC(VCLTestCase):
self.logger.debug(self.vapi.cli("show app mq"))
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
+class VCLThruHostStackHTTPPost(VCLTestCase):
+ """VCL Thru Host Stack HTTP Post"""
+
+ @classmethod
+ def setUpClass(cls):
+ cls.extra_vpp_plugin_config.append("plugin http_plugin.so { enable }")
+ super(VCLThruHostStackHTTPPost, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(VCLThruHostStackHTTPPost, cls).tearDownClass()
+
+ def setUp(self):
+ super(VCLThruHostStackHTTPPost, self).setUp()
+
+ self.thru_host_stack_setup()
+ self.client_uni_dir_http_post_timeout = 20
+ self.server_http_post_args = ["-p", "http", self.server_port]
+ self.client_uni_dir_http_post_test_args = [
+ "-N",
+ "10000",
+ "-U",
+ "-X",
+ "-p",
+ "http",
+ self.loop0.local_ip4,
+ self.server_port,
+ ]
+
+ def test_vcl_thru_host_stack_http_post_uni_dir(self):
+ """run VCL thru host stack uni-directional HTTP POST test"""
+
+ self.timeout = self.client_uni_dir_http_post_timeout
+ self.thru_host_stack_test(
+ "vcl_test_server",
+ self.server_http_post_args,
+ "vcl_test_client",
+ self.client_uni_dir_http_post_test_args,
+ )
+
+ def tearDown(self):
+ self.thru_host_stack_tear_down()
+ super(VCLThruHostStackHTTPPost, self).tearDown()
+
+ def show_commands_at_teardown(self):
+ self.logger.debug(self.vapi.cli("show app server"))
+ self.logger.debug(self.vapi.cli("show session verbose 2"))
+ self.logger.debug(self.vapi.cli("show app mq"))
+
+
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLThruHostStackBidirNsock(VCLTestCase):
"""VCL Thru Host Stack Bidir Nsock"""
@@ -780,6 +867,9 @@ class VCLThruHostStackBidirNsock(VCLTestCase):
)
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class LDPThruHostStackBidirNsock(VCLTestCase):
"""LDP Thru Host Stack Bidir Nsock"""
@@ -830,6 +920,9 @@ class LDPThruHostStackBidirNsock(VCLTestCase):
)
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class LDPThruHostStackNsock(VCLTestCase):
"""LDP Thru Host Stack Nsock"""
@@ -879,6 +972,9 @@ class LDPThruHostStackNsock(VCLTestCase):
)
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLThruHostStackNsock(VCLTestCase):
"""VCL Thru Host Stack Nsock"""
@@ -928,6 +1024,7 @@ class VCLThruHostStackNsock(VCLTestCase):
)
+@tag_fixme_ubuntu2404
class LDPThruHostStackIperf(VCLTestCase):
"""LDP Thru Host Stack Iperf"""
@@ -975,6 +1072,7 @@ class LDPThruHostStackIperf(VCLTestCase):
)
+@tag_fixme_ubuntu2404
class LDPThruHostStackIperfUdp(VCLTestCase):
"""LDP Thru Host Stack Iperf UDP"""
@@ -1020,6 +1118,7 @@ class LDPThruHostStackIperfUdp(VCLTestCase):
)
+@tag_fixme_ubuntu2404
class LDPIpv6CutThruTestCase(VCLTestCase):
"""LDP IPv6 Cut Thru Tests"""
@@ -1125,6 +1224,9 @@ class LDPIpv6CutThruTestCase(VCLTestCase):
)
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLIpv6CutThruTestCase(VCLTestCase):
"""VCL IPv6 Cut Thru Tests"""
@@ -1220,6 +1322,9 @@ class VCLIpv6CutThruTestCase(VCLTestCase):
)
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class VCLIpv6ThruHostStackEcho(VCLTestCase):
"""VCL IPv6 Thru Host Stack Echo"""
diff --git a/test/asf/test_vhost.py b/test/asf/test_vhost.py
index 622716cafe3..f7cdecfa6de 100644
--- a/test/asf/test_vhost.py
+++ b/test/asf/test_vhost.py
@@ -5,8 +5,10 @@ import unittest
from asfframework import VppAsfTestCase, VppTestRunner
from vpp_vhost_interface import VppVhostInterface
+from config import config
+@unittest.skipIf("vhost" in config.excluded_plugins, "Exclude Vhost plugin tests")
class TesVhostInterface(VppAsfTestCase):
"""Vhost User Test Case"""
diff --git a/test/asf/vpp_session_sdl.py b/test/asf/vpp_session_sdl.py
new file mode 100644
index 00000000000..b10c11d1e15
--- /dev/null
+++ b/test/asf/vpp_session_sdl.py
@@ -0,0 +1,75 @@
+from ipaddress import IPv4Network
+
+from vpp_object import VppObject
+from vpp_papi import VppEnum
+from vpp_ip import INVALID_INDEX
+from vpp_papi_provider import UnexpectedApiReturnValueError
+
+
+class SessionSdl:
+ """Session SDL"""
+
+ def __init__(
+ self,
+ lcl,
+ action_index,
+ tag,
+ ):
+
+ self.action_index = action_index
+ self.lcl = lcl
+ self.tag = tag
+
+ def encode(self):
+ return {
+ "lcl": self.lcl,
+ "action_index": self.action_index,
+ "tag": self.tag,
+ }
+
+
+class VppSessionSdl(VppObject):
+ """VPP Session SDL"""
+
+ def __init__(self, test, rules, is_add, appns_index):
+ self._test = test
+ self._rules = rules
+ self.is_add = is_add
+ self.appns_index = appns_index
+
+ @property
+ def rules(self):
+ return self._rules
+
+ @property
+ def count(self):
+ return len(self._rules)
+
+ def encode_rules(self):
+ rules = []
+ for rule in self._rules:
+ rules.append(rule.encode())
+ return rules
+
+ def add_vpp_config(self, expect_error=False):
+ try:
+ reply = self._test.vapi.session_sdl_add_del(
+ is_add=self.is_add,
+ appns_index=self.appns_index,
+ count=self.count,
+ r=self.encode_rules(),
+ )
+ self._test.registry.register(self, self._test.logger)
+ if expect_error:
+ self._test.fail("Unexpected api reply")
+ return self
+ except UnexpectedApiReturnValueError:
+ if not expect_error:
+ self._test.fail("Unexpected api reply")
+ return None
+
+ def query_vpp_config(self):
+ pass
+
+ def remove_vpp_config(self, expect_error=False):
+ pass
diff --git a/test/config.py b/test/config.py
index 32cc4cac5fa..e939f188c6c 100644
--- a/test/config.py
+++ b/test/config.py
@@ -409,10 +409,11 @@ parser.add_argument(
"/var/run/user/${uid}/vpp.",
)
-default_decode_pcaps = False
+default_decode_pcaps = "failed"
parser.add_argument(
"--decode-pcaps",
- action="store_true",
+ action="store",
+ choices=["none", "failed", "all"],
default=default_decode_pcaps,
help=f"if set, decode all pcap files from a test run (default: {default_decode_pcaps})",
)
diff --git a/test/framework.py b/test/framework.py
index 6ff03d8b073..fc22ad6483c 100644
--- a/test/framework.py
+++ b/test/framework.py
@@ -71,6 +71,9 @@ class _PacketInfo(object):
#: Store the copy of the former packet.
data = None
+ def __repr__(self):
+ return f"_PacketInfo index:{self.index} src:{self.src} dst:{self.dst} ip:{self.ip} proto:{self.proto} data:{self.data}"
+
def __eq__(self, other):
index = self.index == other.index
src = self.src == other.src
diff --git a/test/patches/scapy-2.4.5/cdp.patch b/test/patches/scapy-2.4.5/cdp.patch
new file mode 100644
index 00000000000..8fa9f69cc80
--- /dev/null
+++ b/test/patches/scapy-2.4.5/cdp.patch
@@ -0,0 +1,14 @@
+diff --git a/scapy/contrib/cdp.py b/scapy/contrib/cdp.py
+index a1532b78..83963ff4 100644
+--- a/scapy/contrib/cdp.py
++++ b/scapy/contrib/cdp.py
+@@ -392,7 +392,7 @@ class _CDPChecksum:
+ This padding is only used for checksum computation. The original
+ packet should not be altered."""
+ if len(pkt) % 2:
+- last_chr = orb(pkt[-1])
++ last_chr = orb(pkt[len(pkt)-1:])
+ if last_chr <= 0x80:
+ return pkt[:-1] + b'\x00' + chb(last_chr)
+ else:
+
diff --git a/test/patches/scapy-2.4.5/ikev2.patch b/test/patches/scapy-2.4.5/ikev2.patch
new file mode 100644
index 00000000000..a1dd45ad661
--- /dev/null
+++ b/test/patches/scapy-2.4.5/ikev2.patch
@@ -0,0 +1,22 @@
+diff --git a/scapy/contrib/ikev2.py b/scapy/contrib/ikev2.py
+index 7799fd1e..f81af7ac 100644
+--- a/scapy/contrib/ikev2.py
++++ b/scapy/contrib/ikev2.py
+@@ -607,12 +607,16 @@ class IKEv2_payload_TSr(IKEv2_class):
+
+ class IKEv2_payload_Delete(IKEv2_class):
+ name = "IKEv2 Vendor ID"
++ name = "IKEv2 delete payload"
+ overload_fields = {IKEv2: {"next_payload": 42}}
+ fields_desc = [
+ ByteEnumField("next_payload", None, IKEv2_payload_type),
+ ByteField("res", 0),
+- FieldLenField("length", None, "vendorID", "H", adjust=lambda pkt, x:x + 4), # noqa: E501
+- StrLenField("vendorID", "", length_from=lambda x:x.length - 4),
++ FieldLenField("length", None, "SPIs", "H", adjust=lambda pkt, x:x + 8), # noqa: E501
++ ByteEnumField("proto", 1, {1: "IKEv2", 2: "AH", 3: "ESP"}),
++ ByteField("SPIsize", 0),
++ ShortField("SPInum", 0),
++ StrLenField("SPIs", "", length_from=lambda x: x.length - 8),
+ ]
+
diff --git a/test/patches/scapy-2.4.5/ipsec.patch b/test/patches/scapy-2.4.5/ipsec.patch
new file mode 100644
index 00000000000..46280ce23c4
--- /dev/null
+++ b/test/patches/scapy-2.4.5/ipsec.patch
@@ -0,0 +1,230 @@
+diff --git a/scapy/layers/ipsec.py b/scapy/layers/ipsec.py
+index 8251dc14..bbb71102 100644
+--- a/scapy/layers/ipsec.py
++++ b/scapy/layers/ipsec.py
+@@ -60,7 +60,7 @@ import scapy.modules.six as six
+ from scapy.modules.six.moves import range
+ from scapy.layers.inet6 import IPv6, IPv6ExtHdrHopByHop, IPv6ExtHdrDestOpt, \
+ IPv6ExtHdrRouting
+-
++from scapy.contrib.mpls import MPLS
+
+ ###############################################################################
+ class AH(Packet):
+@@ -360,13 +360,16 @@ class CryptAlgo(object):
+ encryptor = cipher.encryptor()
+
+ if self.is_aead:
+- if esn_en:
+- aad = struct.pack('!LLL', esp.spi, esn, esp.seq)
+- else:
+- aad = struct.pack('!LL', esp.spi, esp.seq)
++ aad = sa.build_aead(esp)
++ if self.name == 'AES-NULL-GMAC':
++ aad = aad + esp.iv + data
++ aes_null_gmac_data = data
++ data = b''
+ encryptor.authenticate_additional_data(aad)
+ data = encryptor.update(data) + encryptor.finalize()
+ data += encryptor.tag[:self.icv_size]
++ if self.name == 'AES-NULL-GMAC':
++ data = aes_null_gmac_data + data
+ else:
+ data = encryptor.update(data) + encryptor.finalize()
+
+@@ -402,16 +405,18 @@ class CryptAlgo(object):
+
+ if self.is_aead:
+ # Tag value check is done during the finalize method
+- if esn_en:
+- decryptor.authenticate_additional_data(
+- struct.pack('!LLL', esp.spi, esn, esp.seq))
+- else:
+- decryptor.authenticate_additional_data(
+- struct.pack('!LL', esp.spi, esp.seq))
++ aad = sa.build_aead(esp)
++ if self.name == 'AES-NULL-GMAC':
++ aad = aad + iv + data
++ aes_null_gmac_data = data
++ data = b''
++ decryptor.authenticate_additional_data(aad)
+ try:
+ data = decryptor.update(data) + decryptor.finalize()
+ except InvalidTag as err:
+ raise IPSecIntegrityError(err)
++ if self.name == 'AES-NULL-GMAC':
++ data = aes_null_gmac_data + data
+
+ # extract padlen and nh
+ padlen = orb(data[-2])
+@@ -458,6 +463,13 @@ if algorithms:
+ iv_size=8,
+ icv_size=16,
+ format_mode_iv=_salt_format_mode_iv)
++ CRYPT_ALGOS['AES-NULL-GMAC'] = CryptAlgo('AES-NULL-GMAC',
++ cipher=algorithms.AES,
++ mode=modes.GCM,
++ salt_size=4,
++ iv_size=8,
++ icv_size=16,
++ format_mode_iv=_salt_format_mode_iv)
+ if hasattr(modes, 'CCM'):
+ CRYPT_ALGOS['AES-CCM'] = CryptAlgo('AES-CCM',
+ cipher=algorithms.AES,
+@@ -546,7 +558,7 @@ class AuthAlgo(object):
+ else:
+ return self.mac(key, self.digestmod(), default_backend())
+
+- def sign(self, pkt, key, esn_en=False, esn=0):
++ def sign(self, pkt, key, trailer=None, esn_en=False, esn=0):
+ """
+ Sign an IPsec (ESP or AH) packet with this algo.
+
+@@ -565,20 +577,20 @@ class AuthAlgo(object):
+
+ if pkt.haslayer(ESP):
+ mac.update(raw(pkt[ESP]))
++ if trailer:
++ mac.update(trailer)
+ pkt[ESP].data += mac.finalize()[:self.icv_size]
+
+ elif pkt.haslayer(AH):
+ clone = zero_mutable_fields(pkt.copy(), sending=True)
+- if esn_en:
+- temp = raw(clone) + struct.pack('!L', esn)
+- else:
+- temp = raw(clone)
+- mac.update(temp)
++ mac.update(raw(clone))
++ if trailer:
++ mac.update(trailer)
+ pkt[AH].icv = mac.finalize()[:self.icv_size]
+
+ return pkt
+
+- def verify(self, pkt, key, esn_en=False, esn=0):
++ def verify(self, pkt, key, trailer, esn_en=False, esn=0):
+ """
+ Check that the integrity check value (icv) of a packet is valid.
+
+@@ -602,7 +614,6 @@ class AuthAlgo(object):
+ pkt_icv = pkt.data[len(pkt.data) - self.icv_size:]
+ clone = pkt.copy()
+ clone.data = clone.data[:len(clone.data) - self.icv_size]
+- temp = raw(clone)
+
+ elif pkt.haslayer(AH):
+ if len(pkt[AH].icv) != self.icv_size:
+@@ -611,12 +622,10 @@ class AuthAlgo(object):
+ pkt[AH].icv = pkt[AH].icv[:self.icv_size]
+ pkt_icv = pkt[AH].icv
+ clone = zero_mutable_fields(pkt.copy(), sending=False)
+- if esn_en:
+- temp = raw(clone) + struct.pack('!L', esn)
+- else:
+- temp = raw(clone)
+
+- mac.update(temp)
++ mac.update(raw(clone))
++ if trailer:
++ mac.update(trailer) # bytearray(4)) #raw(trailer))
+ computed_icv = mac.finalize()[:self.icv_size]
+
+ # XXX: Cannot use mac.verify because the ICV can be truncated
+@@ -805,7 +814,7 @@ class SecurityAssociation(object):
+ This class is responsible of "encryption" and "decryption" of IPsec packets. # noqa: E501
+ """
+
+- SUPPORTED_PROTOS = (IP, IPv6)
++ SUPPORTED_PROTOS = (IP, IPv6, MPLS)
+
+ def __init__(self, proto, spi, seq_num=1, crypt_algo=None, crypt_key=None,
+ auth_algo=None, auth_key=None, tunnel_header=None, nat_t_header=None, esn_en=False, esn=0): # noqa: E501
+@@ -880,6 +889,23 @@ class SecurityAssociation(object):
+ raise TypeError('nat_t_header must be %s' % UDP.name)
+ self.nat_t_header = nat_t_header
+
++ def build_aead(self, esp):
++ if self.esn_en:
++ return (struct.pack('!LLL', esp.spi, self.seq_num >> 32, esp.seq))
++ else:
++ return (struct.pack('!LL', esp.spi, esp.seq))
++
++ def build_seq_num(self, num):
++ # only lower order bits are transmitted
++ # higher order bits are used in the ICV
++ lower = num & 0xffffffff
++ upper = num >> 32
++
++ if self.esn_en:
++ return lower, struct.pack("!I", upper)
++ else:
++ return lower, None
++
+ def check_spi(self, pkt):
+ if pkt.spi != self.spi:
+ raise TypeError('packet spi=0x%x does not match the SA spi=0x%x' %
+@@ -893,7 +919,8 @@ class SecurityAssociation(object):
+ if len(iv) != self.crypt_algo.iv_size:
+ raise TypeError('iv length must be %s' % self.crypt_algo.iv_size) # noqa: E501
+
+- esp = _ESPPlain(spi=self.spi, seq=seq_num or self.seq_num, iv=iv)
++ low_seq_num, high_seq_num = self.build_seq_num(seq_num or self.seq_num)
++ esp = _ESPPlain(spi=self.spi, seq=low_seq_num, iv=iv)
+
+ if self.tunnel_header:
+ tunnel = self.tunnel_header.copy()
+@@ -917,7 +944,7 @@ class SecurityAssociation(object):
+ esn_en=esn_en or self.esn_en,
+ esn=esn or self.esn)
+
+- self.auth_algo.sign(esp, self.auth_key)
++ self.auth_algo.sign(esp, self.auth_key, high_seq_num)
+
+ if self.nat_t_header:
+ nat_t_header = self.nat_t_header.copy()
+@@ -944,7 +971,8 @@ class SecurityAssociation(object):
+
+ def _encrypt_ah(self, pkt, seq_num=None, esn_en=False, esn=0):
+
+- ah = AH(spi=self.spi, seq=seq_num or self.seq_num,
++ low_seq_num, high_seq_num = self.build_seq_num(seq_num or self.seq_num)
++ ah = AH(spi=self.spi, seq=low_seq_num,
+ icv=b"\x00" * self.auth_algo.icv_size)
+
+ if self.tunnel_header:
+@@ -985,7 +1013,7 @@ class SecurityAssociation(object):
+ ip_header.plen = len(ip_header.payload) + len(ah) + len(payload)
+
+ signed_pkt = self.auth_algo.sign(ip_header / ah / payload,
+- self.auth_key,
++ self.auth_key, high_seq_num,
+ esn_en=esn_en or self.esn_en,
+ esn=esn or self.esn)
+
+@@ -1025,11 +1053,12 @@ class SecurityAssociation(object):
+
+ def _decrypt_esp(self, pkt, verify=True, esn_en=None, esn=None):
+
++ low_seq_num, high_seq_num = self.build_seq_num(self.seq_num)
+ encrypted = pkt[ESP]
+
+ if verify:
+ self.check_spi(pkt)
+- self.auth_algo.verify(encrypted, self.auth_key)
++ self.auth_algo.verify(encrypted, self.auth_key, high_seq_num)
+
+ esp = self.crypt_algo.decrypt(self, encrypted, self.crypt_key,
+ self.crypt_algo.icv_size or
+@@ -1070,9 +1099,10 @@ class SecurityAssociation(object):
+
+ def _decrypt_ah(self, pkt, verify=True, esn_en=None, esn=None):
+
++ low_seq_num, high_seq_num = self.build_seq_num(self.seq_num)
+ if verify:
+ self.check_spi(pkt)
+- self.auth_algo.verify(pkt, self.auth_key,
++ self.auth_algo.verify(pkt, self.auth_key, high_seq_num,
+ esn_en=esn_en or self.esn_en,
+ esn=esn or self.esn)
+
diff --git a/test/patches/scapy-2.4.5/ppp.patch b/test/patches/scapy-2.4.5/ppp.patch
new file mode 100644
index 00000000000..a3680bfee08
--- /dev/null
+++ b/test/patches/scapy-2.4.5/ppp.patch
@@ -0,0 +1,45 @@
+# NOTE: This patch copied from https://github.com/secdev/scapy
+# commit 3e6900776698cd5472c5405294414d5b672a3f18
+#
+diff --git a/scapy/layers/ppp.py b/scapy/layers/ppp.py
+index b5cd42b4..e0f4c593 100644
+--- a/scapy/layers/ppp.py
++++ b/scapy/layers/ppp.py
+@@ -292,6 +292,14 @@ class _PPPProtoField(EnumField):
+
+ See RFC 1661 section 2
+ <https://tools.ietf.org/html/rfc1661#section-2>
++
++ The generated proto field is two bytes when not specified, or when specified
++ as an integer or a string:
++ PPP()
++ PPP(proto=0x21)
++ PPP(proto="Internet Protocol version 4")
++ To explicitly forge a one byte proto field, use the bytes representation:
++ PPP(proto=b'\x21')
+ """
+ def getfield(self, pkt, s):
+ if ord(s[:1]) & 0x01:
+@@ -304,12 +312,18 @@ class _PPPProtoField(EnumField):
+ return super(_PPPProtoField, self).getfield(pkt, s)
+
+ def addfield(self, pkt, s, val):
+- if val < 0x100:
+- self.fmt = "!B"
+- self.sz = 1
++ if isinstance(val, bytes):
++ if len(val) == 1:
++ fmt, sz = "!B", 1
++ elif len(val) == 2:
++ fmt, sz = "!H", 2
++ else:
++ raise TypeError('Invalid length for PPP proto')
++ val = struct.Struct(fmt).unpack(val)[0]
+ else:
+- self.fmt = "!H"
+- self.sz = 2
++ fmt, sz = "!H", 2
++ self.fmt = fmt
++ self.sz = sz
+ self.struct = struct.Struct(self.fmt)
+ return super(_PPPProtoField, self).addfield(pkt, s, val)
diff --git a/test/patches/scapy-2.4.5/scapy-python312.patch b/test/patches/scapy-2.4.5/scapy-python312.patch
new file mode 100644
index 00000000000..f0638ff4dd6
--- /dev/null
+++ b/test/patches/scapy-2.4.5/scapy-python312.patch
@@ -0,0 +1,590 @@
+diff --git a/scapy/arch/bpf/core.py b/scapy/arch/bpf/core.py
+index d49267cd..13b7cff7 100644
+--- a/scapy/arch/bpf/core.py
++++ b/scapy/arch/bpf/core.py
+@@ -27,7 +27,7 @@ from scapy.error import Scapy_Exception, warning
+ from scapy.interfaces import InterfaceProvider, IFACES, NetworkInterface, \
+ network_name
+ from scapy.pton_ntop import inet_ntop
+-from scapy.modules.six.moves import range
++from six.moves import range
+
+
+ # ctypes definitions
+diff --git a/scapy/arch/linux.py b/scapy/arch/linux.py
+index 88f0de80..8870320f 100644
+--- a/scapy/arch/linux.py
++++ b/scapy/arch/linux.py
+@@ -49,8 +49,8 @@ from scapy.packet import Packet, Padding
+ from scapy.pton_ntop import inet_ntop
+ from scapy.supersocket import SuperSocket
+
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+
+ # Typing imports
+ from scapy.compat import (
+diff --git a/scapy/arch/windows/__init__.py b/scapy/arch/windows/__init__.py
+index 3e640f48..8a01681c 100755
+--- a/scapy/arch/windows/__init__.py
++++ b/scapy/arch/windows/__init__.py
+@@ -36,8 +36,8 @@ from scapy.pton_ntop import inet_ntop, inet_pton
+ from scapy.utils import atol, itom, mac2str, str2mac
+ from scapy.utils6 import construct_source_candidate_set, in6_getscope
+ from scapy.data import ARPHDR_ETHER, load_manuf
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import input, winreg
++import six
++from six.moves import input, winreg
+ from scapy.compat import plain_str
+ from scapy.supersocket import SuperSocket
+
+diff --git a/scapy/asn1/asn1.py b/scapy/asn1/asn1.py
+index 45eea565..a694de0d 100644
+--- a/scapy/asn1/asn1.py
++++ b/scapy/asn1/asn1.py
+@@ -18,8 +18,8 @@ from scapy.error import Scapy_Exception, warning
+ from scapy.volatile import RandField, RandIP, GeneralizedTime
+ from scapy.utils import Enum_metaclass, EnumElement, binrepr
+ from scapy.compat import plain_str, chb, orb
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+
+
+ class RandASN1Object(RandField):
+diff --git a/scapy/asn1fields.py b/scapy/asn1fields.py
+index 87679b55..887dd42e 100644
+--- a/scapy/asn1fields.py
++++ b/scapy/asn1fields.py
+@@ -20,8 +20,8 @@ from scapy.base_classes import BasePacket
+ from scapy.utils import binrepr
+ from scapy import packet
+ from functools import reduce
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+
+
+ class ASN1F_badsequence(Exception):
+diff --git a/scapy/base_classes.py b/scapy/base_classes.py
+index ec532110..51897d05 100644
+--- a/scapy/base_classes.py
++++ b/scapy/base_classes.py
+@@ -27,9 +27,9 @@ import warnings
+ import scapy
+ from scapy.error import Scapy_Exception
+ from scapy.consts import WINDOWS
+-import scapy.modules.six as six
++import six
+
+-from scapy.modules.six.moves import range
++from six.moves import range
+
+ from scapy.compat import (
+ Any,
+diff --git a/scapy/contrib/automotive/someip.py b/scapy/contrib/automotive/someip.py
+index a19e008d..136ab64c 100644
+--- a/scapy/contrib/automotive/someip.py
++++ b/scapy/contrib/automotive/someip.py
+@@ -36,7 +36,7 @@ from scapy.layers.inet import TCP, UDP
+ from scapy.layers.inet6 import IP6Field
+ from scapy.compat import raw, orb
+ from scapy.config import conf
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.packet import Packet, Raw, bind_top_down, bind_bottom_up
+ from scapy.fields import XShortField, BitEnumField, ConditionalField, \
+ BitField, XBitField, IntField, XByteField, ByteEnumField, \
+diff --git a/scapy/contrib/cansocket_python_can.py b/scapy/contrib/cansocket_python_can.py
+index 936d39cf..1a1b717d 100644
+--- a/scapy/contrib/cansocket_python_can.py
++++ b/scapy/contrib/cansocket_python_can.py
+@@ -21,7 +21,7 @@ from scapy.config import conf
+ from scapy.supersocket import SuperSocket
+ from scapy.layers.can import CAN
+ from scapy.error import warning
+-from scapy.modules.six.moves import queue
++from six.moves import queue
+ from scapy.compat import Any, List
+ from can import Message as can_Message
+ from can import CanError as can_CanError
+diff --git a/scapy/contrib/cdp.py b/scapy/contrib/cdp.py
+index fa116538..9700deba 100644
+--- a/scapy/contrib/cdp.py
++++ b/scapy/contrib/cdp.py
+@@ -43,7 +43,7 @@ from scapy.fields import (
+ from scapy.layers.inet import checksum
+ from scapy.layers.l2 import SNAP
+ from scapy.compat import orb, chb
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.config import conf
+
+
+diff --git a/scapy/contrib/diameter.py b/scapy/contrib/diameter.py
+index e99cb424..9fedca3d 100644
+--- a/scapy/contrib/diameter.py
++++ b/scapy/contrib/diameter.py
+@@ -32,8 +32,8 @@ from scapy.fields import ConditionalField, EnumField, Field, FieldLenField, \
+ XByteField, XIntField
+ from scapy.layers.inet import TCP
+ from scapy.layers.sctp import SCTPChunkData
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+ from scapy.compat import chb, orb, raw, bytes_hex, plain_str
+ from scapy.error import warning
+ from scapy.utils import inet_ntoa, inet_aton
+diff --git a/scapy/contrib/gtp.py b/scapy/contrib/gtp.py
+index bf369847..de3b8961 100644
+--- a/scapy/contrib/gtp.py
++++ b/scapy/contrib/gtp.py
+@@ -30,7 +30,7 @@ from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \
+ from scapy.layers.inet import IP, UDP
+ from scapy.layers.inet6 import IPv6, IP6Field
+ from scapy.layers.ppp import PPP
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.packet import bind_layers, bind_bottom_up, bind_top_down, \
+ Packet, Raw
+ from scapy.volatile import RandInt, RandIP, RandNum, RandString
+diff --git a/scapy/contrib/homeplugav.py b/scapy/contrib/homeplugav.py
+index 171eb7d0..92b22d16 100644
+--- a/scapy/contrib/homeplugav.py
++++ b/scapy/contrib/homeplugav.py
+@@ -44,7 +44,7 @@ from scapy.fields import (
+ XShortField,
+ )
+ from scapy.layers.l2 import Ether
+-from scapy.modules.six.moves import range
++from six.moves import range
+
+ """
+ Copyright (C) HomePlugAV Layer for Scapy by FlUxIuS (Sebastien Dudek)
+diff --git a/scapy/contrib/isis.py b/scapy/contrib/isis.py
+index b7fc222e..f68bb37d 100644
+--- a/scapy/contrib/isis.py
++++ b/scapy/contrib/isis.py
+@@ -80,7 +80,7 @@ from scapy.layers.clns import network_layer_protocol_ids, register_cln_protocol
+ from scapy.layers.inet6 import IP6ListField, IP6Field
+ from scapy.utils import fletcher16_checkbytes
+ from scapy.volatile import RandString, RandByte
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.compat import orb, hex_bytes
+
+ EXT_VERSION = "v0.0.3"
+diff --git a/scapy/contrib/isotp.py b/scapy/contrib/isotp.py
+index 845d566d..225c6b86 100644
+--- a/scapy/contrib/isotp.py
++++ b/scapy/contrib/isotp.py
+@@ -29,9 +29,9 @@ from scapy.fields import BitField, FlagsField, StrLenField, \
+ BitEnumField, ByteField, XByteField, BitFieldLenField, StrField
+ from scapy.compat import chb, orb
+ from scapy.layers.can import CAN, CAN_MAX_IDENTIFIER, CAN_MTU, CAN_MAX_DLEN
+-import scapy.modules.six as six
++import six
+ import scapy.automaton as automaton
+-from scapy.modules.six.moves import queue
++from six.moves import queue
+ from scapy.error import Scapy_Exception, warning, log_loading, log_runtime
+ from scapy.supersocket import SuperSocket, SO_TIMESTAMPNS
+ from scapy.config import conf
+diff --git a/scapy/contrib/ldp.py b/scapy/contrib/ldp.py
+index 25152ab7..ea8a6b83 100644
+--- a/scapy/contrib/ldp.py
++++ b/scapy/contrib/ldp.py
+@@ -27,7 +27,7 @@ from scapy.fields import BitField, IPField, IntField, ShortField, StrField, \
+ XBitField
+ from scapy.layers.inet import UDP
+ from scapy.layers.inet import TCP
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.config import conf
+ from scapy.utils import inet_aton, inet_ntoa
+
+diff --git a/scapy/contrib/lldp.py b/scapy/contrib/lldp.py
+index 04d37192..91b64439 100644
+--- a/scapy/contrib/lldp.py
++++ b/scapy/contrib/lldp.py
+@@ -51,7 +51,7 @@ from scapy.fields import MACField, IPField, BitField, \
+ ShortField, XStrLenField, ByteField, ConditionalField, \
+ MultipleTypeField
+ from scapy.packet import Packet, bind_layers
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.data import ETHER_TYPES
+ from scapy.compat import orb
+
+diff --git a/scapy/contrib/nfs.py b/scapy/contrib/nfs.py
+index 79259e39..6d6f47a1 100644
+--- a/scapy/contrib/nfs.py
++++ b/scapy/contrib/nfs.py
+@@ -12,7 +12,7 @@ from scapy.packet import Packet, bind_layers
+ from scapy.fields import IntField, IntEnumField, FieldListField, LongField, \
+ XIntField, XLongField, ConditionalField, PacketListField, StrLenField, \
+ PacketField
+-from scapy.modules.six import integer_types
++from six import integer_types
+
+ nfsstat3 = {
+ 0: 'NFS3_OK',
+diff --git a/scapy/contrib/ppi_geotag.py b/scapy/contrib/ppi_geotag.py
+index a7cc6345..bf16ae2b 100644
+--- a/scapy/contrib/ppi_geotag.py
++++ b/scapy/contrib/ppi_geotag.py
+@@ -34,8 +34,8 @@ from scapy.fields import ByteField, ConditionalField, Field, FlagsField, \
+ UTCTimeField, XLEIntField, SignedByteField, XLEShortField
+ from scapy.layers.ppi import PPI_Hdr, PPI_Element
+ from scapy.error import warning
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+
+ CURR_GEOTAG_VER = 2 # Major revision of specification
+
+diff --git a/scapy/contrib/skinny.py b/scapy/contrib/skinny.py
+index c12cb94e..f8a8be06 100644
+--- a/scapy/contrib/skinny.py
++++ b/scapy/contrib/skinny.py
+@@ -29,7 +29,7 @@ from scapy.packet import Packet, bind_layers
+ from scapy.fields import FlagsField, IPField, LEIntEnumField, LEIntField, \
+ StrFixedLenField
+ from scapy.layers.inet import TCP
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.volatile import RandShort
+ from scapy.config import conf
+
+diff --git a/scapy/contrib/tacacs.py b/scapy/contrib/tacacs.py
+index ed933f10..7b31f4c0 100755
+--- a/scapy/contrib/tacacs.py
++++ b/scapy/contrib/tacacs.py
+@@ -29,7 +29,7 @@ from scapy.fields import FieldLenField, ConditionalField, StrLenField
+ from scapy.layers.inet import TCP
+ from scapy.compat import chb, orb
+ from scapy.config import conf
+-from scapy.modules.six.moves import range
++from six.moves import range
+
+ SECRET = 'test'
+
+diff --git a/scapy/fields.py b/scapy/fields.py
+index 7448400c..5db02244 100644
+--- a/scapy/fields.py
++++ b/scapy/fields.py
+@@ -37,9 +37,9 @@ from scapy.utils6 import in6_6to4ExtractAddr, in6_isaddr6to4, \
+ in6_isaddrTeredo, in6_ptop, Net6, teredoAddrExtractInfo
+ from scapy.base_classes import Gen, Net, BasePacket, Field_metaclass
+ from scapy.error import warning
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
+-from scapy.modules.six import integer_types
++import six
++from six.moves import range
++from six import integer_types
+
+ # Typing imports
+ from scapy.compat import (
+diff --git a/scapy/interfaces.py b/scapy/interfaces.py
+index aae0c55a..75919bd2 100644
+--- a/scapy/interfaces.py
++++ b/scapy/interfaces.py
+@@ -17,8 +17,8 @@ from scapy.consts import WINDOWS
+ from scapy.utils import pretty_list
+ from scapy.utils6 import in6_isvalid
+
+-from scapy.modules.six.moves import UserDict
+-import scapy.modules.six as six
++from six.moves import UserDict
++import six
+
+ # Typing imports
+ import scapy
+diff --git a/scapy/layers/bluetooth4LE.py b/scapy/layers/bluetooth4LE.py
+index 40f8b0bb..d461b808 100644
+--- a/scapy/layers/bluetooth4LE.py
++++ b/scapy/layers/bluetooth4LE.py
+@@ -23,7 +23,7 @@ from scapy.contrib.ethercat import LEBitEnumField, LEBitField
+ from scapy.layers.bluetooth import EIR_Hdr, L2CAP_Hdr
+ from scapy.layers.ppi import PPI_Element, PPI_Hdr
+
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.utils import mac2str, str2mac
+
+ ####################
+diff --git a/scapy/layers/dhcp.py b/scapy/layers/dhcp.py
+index 4164d88e..ccb42e93 100644
+--- a/scapy/layers/dhcp.py
++++ b/scapy/layers/dhcp.py
+@@ -31,8 +31,8 @@ from scapy.volatile import RandBin, RandField, RandNum, RandNumExpo
+ from scapy.arch import get_if_raw_hwaddr
+ from scapy.sendrecv import srp1, sendp
+ from scapy.error import warning
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+ from scapy.config import conf
+
+ dhcpmagic = b"c\x82Sc"
+diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py
+index b1c9f456..5e87ef5e 100755
+--- a/scapy/layers/dns.py
++++ b/scapy/layers/dns.py
+@@ -24,8 +24,8 @@ from scapy.sendrecv import sr1
+ from scapy.layers.inet import IP, DestIPField, IPField, UDP, TCP
+ from scapy.layers.inet6 import DestIP6Field, IP6Field
+ from scapy.error import log_runtime, warning, Scapy_Exception
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+
+
+ def dns_get_str(s, pointer=0, pkt=None, _fullpacket=False):
+diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
+index 5222df51..2c411b81 100644
+--- a/scapy/layers/inet.py
++++ b/scapy/layers/inet.py
+@@ -64,8 +64,8 @@ from scapy.pton_ntop import inet_pton
+
+ import scapy.as_resolvers
+
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+
+ ####################
+ # IP Tools class #
+diff --git a/scapy/layers/ipsec.py b/scapy/layers/ipsec.py
+index 8251dc14..852b3dfb 100644
+--- a/scapy/layers/ipsec.py
++++ b/scapy/layers/ipsec.py
+@@ -56,8 +56,8 @@ from scapy.fields import ByteEnumField, ByteField, IntField, PacketField, \
+ ShortField, StrField, XIntField, XStrField, XStrLenField
+ from scapy.packet import Packet, bind_layers, Raw
+ from scapy.layers.inet import IP, UDP
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+ from scapy.layers.inet6 import IPv6, IPv6ExtHdrHopByHop, IPv6ExtHdrDestOpt, \
+ IPv6ExtHdrRouting
+
+diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py
+index b1224208..85377b37 100644
+--- a/scapy/layers/l2.py
++++ b/scapy/layers/l2.py
+@@ -51,7 +51,7 @@ from scapy.fields import (
+ XShortEnumField,
+ XShortField,
+ )
+-from scapy.modules.six import viewitems
++from six import viewitems
+ from scapy.packet import bind_layers, Packet
+ from scapy.plist import (
+ PacketList,
+diff --git a/scapy/layers/ntp.py b/scapy/layers/ntp.py
+index 21da95c8..c705c96a 100644
+--- a/scapy/layers/ntp.py
++++ b/scapy/layers/ntp.py
+@@ -25,8 +25,8 @@ from scapy.layers.inet import UDP
+ from scapy.utils import lhex
+ from scapy.compat import orb
+ from scapy.config import conf
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+
+
+ #############################################################################
+diff --git a/scapy/layers/tftp.py b/scapy/layers/tftp.py
+index 2e3077d9..11f1ed94 100644
+--- a/scapy/layers/tftp.py
++++ b/scapy/layers/tftp.py
+@@ -16,7 +16,7 @@ from scapy.fields import PacketListField, ShortEnumField, ShortField, \
+ StrNullField
+ from scapy.automaton import ATMT, Automaton
+ from scapy.layers.inet import UDP, IP
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.config import conf
+ from scapy.volatile import RandShort
+
+diff --git a/scapy/layers/tls/cert.py b/scapy/layers/tls/cert.py
+index b6eb0af2..293ef971 100644
+--- a/scapy/layers/tls/cert.py
++++ b/scapy/layers/tls/cert.py
+@@ -33,8 +33,8 @@ import os
+ import time
+
+ from scapy.config import conf, crypto_validator
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+ from scapy.error import warning
+ from scapy.utils import binrepr
+ from scapy.asn1.asn1 import ASN1_BIT_STRING
+diff --git a/scapy/layers/tls/crypto/prf.py b/scapy/layers/tls/crypto/prf.py
+index 210f9108..cb56f247 100644
+--- a/scapy/layers/tls/crypto/prf.py
++++ b/scapy/layers/tls/crypto/prf.py
+@@ -13,7 +13,7 @@ from scapy.utils import strxor
+
+ from scapy.layers.tls.crypto.hash import _tls_hash_algs
+ from scapy.layers.tls.crypto.h_mac import _tls_hmac_algs
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.compat import bytes_encode
+
+
+diff --git a/scapy/modules/krack/crypto.py b/scapy/modules/krack/crypto.py
+index a4803def..69cc678a 100644
+--- a/scapy/modules/krack/crypto.py
++++ b/scapy/modules/krack/crypto.py
+@@ -6,8 +6,8 @@ from zlib import crc32
+ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms
+ from cryptography.hazmat.backends import default_backend
+
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+ from scapy.compat import orb, chb
+ from scapy.layers.dot11 import Dot11TKIP
+ from scapy.utils import mac2str
+diff --git a/scapy/modules/p0f.py b/scapy/modules/p0f.py
+index 74ee9f16..5bca0bec 100644
+--- a/scapy/modules/p0f.py
++++ b/scapy/modules/p0f.py
+@@ -24,7 +24,7 @@ from scapy.error import warning, Scapy_Exception, log_runtime
+ from scapy.volatile import RandInt, RandByte, RandNum, RandShort, RandString
+ from scapy.sendrecv import sniff
+ from scapy.modules import six
+-from scapy.modules.six.moves import map, range
++from six.moves import map, range
+ if conf.route is None:
+ # unused import, only to initialize conf.route
+ import scapy.route # noqa: F401
+diff --git a/scapy/modules/voip.py b/scapy/modules/voip.py
+index 420ed641..9aa3cceb 100644
+--- a/scapy/modules/voip.py
++++ b/scapy/modules/voip.py
+@@ -18,7 +18,7 @@ from scapy.layers.inet import IP, UDP
+ from scapy.layers.rtp import RTP
+ from scapy.consts import WINDOWS
+ from scapy.config import conf
+-from scapy.modules.six.moves import range
++from six.moves import range
+
+
+ sox_base = (["sox", "-t", ".ul"], ["-", "-t", "ossdsp", "/dev/dsp"])
+diff --git a/scapy/plist.py b/scapy/plist.py
+index 6e959f9b..b9ba2d47 100644
+--- a/scapy/plist.py
++++ b/scapy/plist.py
+@@ -27,8 +27,8 @@ from scapy.utils import do_graph, hexdump, make_table, make_lined_table, \
+ from scapy.extlib import plt, Line2D, \
+ MATPLOTLIB_INLINED, MATPLOTLIB_DEFAULT_PLOT_KARGS
+ from functools import reduce
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range, zip
++import six
++from six.moves import range, zip
+
+ # typings
+ from scapy.compat import (
+diff --git a/scapy/pton_ntop.py b/scapy/pton_ntop.py
+index ba023a77..fd3e2522 100644
+--- a/scapy/pton_ntop.py
++++ b/scapy/pton_ntop.py
+@@ -14,7 +14,7 @@ from __future__ import absolute_import
+ import socket
+ import re
+ import binascii
+-from scapy.modules.six.moves import range
++from six.moves import range
+ from scapy.compat import plain_str, hex_bytes, bytes_encode, bytes_hex
+
+ from scapy.compat import (
+diff --git a/scapy/scapypipes.py b/scapy/scapypipes.py
+index 1cbd43cb..e8553493 100644
+--- a/scapy/scapypipes.py
++++ b/scapy/scapypipes.py
+@@ -7,7 +7,7 @@ from __future__ import print_function
+ import socket
+ import subprocess
+
+-from scapy.modules.six.moves.queue import Queue, Empty
++from six.moves.queue import Queue, Empty
+ from scapy.pipetool import Source, Drain, Sink
+ from scapy.config import conf
+ from scapy.compat import raw
+diff --git a/scapy/sendrecv.py b/scapy/sendrecv.py
+index 503c6a3b..372668de 100644
+--- a/scapy/sendrecv.py
++++ b/scapy/sendrecv.py
+@@ -36,7 +36,7 @@ from scapy.plist import (
+ from scapy.error import log_runtime, log_interactive, Scapy_Exception
+ from scapy.base_classes import Gen, SetGen
+ from scapy.modules import six
+-from scapy.modules.six.moves import map
++from six.moves import map
+ from scapy.sessions import DefaultSession
+ from scapy.supersocket import SuperSocket, IterSocket
+
+diff --git a/scapy/tools/UTscapy.py b/scapy/tools/UTscapy.py
+index 18e01659..a045bd49 100644
+--- a/scapy/tools/UTscapy.py
++++ b/scapy/tools/UTscapy.py
+@@ -27,8 +27,8 @@ import warnings
+ import zlib
+
+ from scapy.consts import WINDOWS
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range
++import six
++from six.moves import range
+ from scapy.config import conf
+ from scapy.compat import base64_bytes, bytes_hex, plain_str
+ from scapy.themes import DefaultTheme, BlackAndWhite
+diff --git a/scapy/utils.py b/scapy/utils.py
+index 12747fa6..09002915 100644
+--- a/scapy/utils.py
++++ b/scapy/utils.py
+@@ -28,8 +28,8 @@ import time
+ import threading
+ import warnings
+
+-import scapy.modules.six as six
+-from scapy.modules.six.moves import range, input, zip_longest
++import six
++from six.moves import range, input, zip_longest
+
+ from scapy.config import conf
+ from scapy.consts import DARWIN, OPENBSD, WINDOWS
+diff --git a/scapy/volatile.py b/scapy/volatile.py
+index 5587c7ce..f7e1b326 100644
+--- a/scapy/volatile.py
++++ b/scapy/volatile.py
+@@ -21,7 +21,7 @@ import struct
+ from scapy.base_classes import Net
+ from scapy.compat import bytes_encode, chb, plain_str
+ from scapy.utils import corrupt_bits, corrupt_bytes
+-from scapy.modules.six.moves import range
++from six.moves import range
+
+ ####################
+ # Random numbers #
diff --git a/test/requirements-3.txt b/test/requirements-3.txt
index 101f9d880c7..2284a67e5a9 100644
--- a/test/requirements-3.txt
+++ b/test/requirements-3.txt
@@ -14,41 +14,41 @@ attrs==23.2.0 \
# via
# jsonschema
# referencing
-babel==2.14.0 \
- --hash=sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363 \
- --hash=sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287
+babel==2.15.0 \
+ --hash=sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb \
+ --hash=sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413
# via sphinx
-black==24.3.0 \
- --hash=sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f \
- --hash=sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93 \
- --hash=sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11 \
- --hash=sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0 \
- --hash=sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9 \
- --hash=sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5 \
- --hash=sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213 \
- --hash=sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d \
- --hash=sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7 \
- --hash=sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837 \
- --hash=sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f \
- --hash=sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395 \
- --hash=sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995 \
- --hash=sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f \
- --hash=sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597 \
- --hash=sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959 \
- --hash=sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5 \
- --hash=sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb \
- --hash=sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4 \
- --hash=sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7 \
- --hash=sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd \
- --hash=sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7
+black==24.4.2 \
+ --hash=sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474 \
+ --hash=sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1 \
+ --hash=sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0 \
+ --hash=sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8 \
+ --hash=sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96 \
+ --hash=sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1 \
+ --hash=sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04 \
+ --hash=sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021 \
+ --hash=sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94 \
+ --hash=sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d \
+ --hash=sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c \
+ --hash=sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7 \
+ --hash=sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c \
+ --hash=sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc \
+ --hash=sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7 \
+ --hash=sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d \
+ --hash=sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c \
+ --hash=sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741 \
+ --hash=sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce \
+ --hash=sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb \
+ --hash=sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063 \
+ --hash=sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e
# via -r requirements.txt
build==1.2.1 \
--hash=sha256:526263f4870c26f26c433545579475377b2b7588b6f1eac76a001e873ae3e19d \
--hash=sha256:75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4
# via pip-tools
-certifi==2024.2.2 \
- --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \
- --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1
+certifi==2024.7.4 \
+ --hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \
+ --hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90
# via requests
cffi==1.16.0 \
--hash=sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc \
@@ -206,39 +206,34 @@ commonmark==0.9.1 \
--hash=sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60 \
--hash=sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9
# via recommonmark
-cryptography==42.0.5 \
- --hash=sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee \
- --hash=sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576 \
- --hash=sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d \
- --hash=sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30 \
- --hash=sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413 \
- --hash=sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb \
- --hash=sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da \
- --hash=sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4 \
- --hash=sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd \
- --hash=sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc \
- --hash=sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8 \
- --hash=sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1 \
- --hash=sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc \
- --hash=sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e \
- --hash=sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8 \
- --hash=sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940 \
- --hash=sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400 \
- --hash=sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7 \
- --hash=sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16 \
- --hash=sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278 \
- --hash=sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74 \
- --hash=sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec \
- --hash=sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1 \
- --hash=sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2 \
- --hash=sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c \
- --hash=sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922 \
- --hash=sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a \
- --hash=sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6 \
- --hash=sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1 \
- --hash=sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e \
- --hash=sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac \
- --hash=sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7
+cryptography==43.0.0 \
+ --hash=sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709 \
+ --hash=sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069 \
+ --hash=sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2 \
+ --hash=sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b \
+ --hash=sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e \
+ --hash=sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70 \
+ --hash=sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778 \
+ --hash=sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22 \
+ --hash=sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895 \
+ --hash=sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf \
+ --hash=sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431 \
+ --hash=sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f \
+ --hash=sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947 \
+ --hash=sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74 \
+ --hash=sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc \
+ --hash=sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66 \
+ --hash=sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66 \
+ --hash=sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf \
+ --hash=sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f \
+ --hash=sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5 \
+ --hash=sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e \
+ --hash=sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f \
+ --hash=sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55 \
+ --hash=sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1 \
+ --hash=sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47 \
+ --hash=sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5 \
+ --hash=sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0
# via
# -r requirements.txt
# noiseprotocol
@@ -253,17 +248,17 @@ docutils==0.20.1 \
# recommonmark
# sphinx
# sphinx-rtd-theme
-idna==3.6 \
- --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
- --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
+idna==3.7 \
+ --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \
+ --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0
# via requests
imagesize==1.4.1 \
--hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \
--hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a
# via sphinx
-importlib-metadata==7.1.0 \
- --hash=sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570 \
- --hash=sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2
+importlib-metadata==8.2.0 \
+ --hash=sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369 \
+ --hash=sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d
# via
# build
# sphinx
@@ -273,13 +268,13 @@ importlib-resources==6.4.0 \
# via
# jsonschema
# jsonschema-specifications
-jinja2==3.1.3 \
- --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \
- --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90
+jinja2==3.1.4 \
+ --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \
+ --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d
# via sphinx
-jsonschema==4.21.1 ; python_version >= "3.7" \
- --hash=sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f \
- --hash=sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5
+jsonschema==4.23.0 ; python_version >= "3.7" \
+ --hash=sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4 \
+ --hash=sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566
# via -r requirements.txt
jsonschema-specifications==2023.12.1 \
--hash=sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc \
@@ -362,9 +357,9 @@ objgraph==3.6.1 \
--hash=sha256:21c6bc62df0e7b77cc0a31d96feec04c965f09ec2e3d78b816b516a604f0defd \
--hash=sha256:fe96c74147bbcaae8665b396e5388bdcc3197deebba4e6381f05202ee5b453a7
# via -r requirements.txt
-packaging==24.0 \
- --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \
- --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9
+packaging==24.1 \
+ --hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \
+ --hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124
# via
# black
# build
@@ -382,35 +377,36 @@ pexpect==4.9.0 \
--hash=sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 \
--hash=sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f
# via -r requirements.txt
-pip-tools==7.3.0 \
- --hash=sha256:8717693288720a8c6ebd07149c93ab0be1fced0b5191df9e9decd3263e20d85e \
- --hash=sha256:8e9c99127fe024c025b46a0b2d15c7bd47f18f33226cf7330d35493663fc1d1d
+pip-tools==7.4.1 \
+ --hash=sha256:4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9 \
+ --hash=sha256:864826f5073864450e24dbeeb85ce3920cdfb09848a3d69ebf537b521f14bcc9
# via -r requirements.txt
pkgutil-resolve-name==1.3.10 \
--hash=sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174 \
--hash=sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e
# via jsonschema
-platformdirs==4.2.0 \
- --hash=sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068 \
- --hash=sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768
+platformdirs==4.2.2 \
+ --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \
+ --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3
# via black
-psutil==5.9.8 \
- --hash=sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d \
- --hash=sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73 \
- --hash=sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8 \
- --hash=sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2 \
- --hash=sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e \
- --hash=sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36 \
- --hash=sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7 \
- --hash=sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c \
- --hash=sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee \
- --hash=sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421 \
- --hash=sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf \
- --hash=sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81 \
- --hash=sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0 \
- --hash=sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631 \
- --hash=sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4 \
- --hash=sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8
+psutil==6.0.0 \
+ --hash=sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35 \
+ --hash=sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0 \
+ --hash=sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c \
+ --hash=sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1 \
+ --hash=sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3 \
+ --hash=sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c \
+ --hash=sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd \
+ --hash=sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3 \
+ --hash=sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0 \
+ --hash=sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2 \
+ --hash=sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6 \
+ --hash=sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d \
+ --hash=sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c \
+ --hash=sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0 \
+ --hash=sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132 \
+ --hash=sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14 \
+ --hash=sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0
# via -r requirements.txt
ptyprocess==0.7.0 \
--hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \
@@ -460,22 +456,24 @@ pyenchant==3.2.2 \
--hash=sha256:5facc821ece957208a81423af7d6ec7810dad29697cb0d77aae81e4e11c8e5a6 \
--hash=sha256:6153f521852e23a5add923dbacfbf4bebbb8d70c4e4bad609a8e0f9faeb915d1
# via sphinxcontrib-spelling
-pygments==2.17.2 \
- --hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \
- --hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367
+pygments==2.18.0 \
+ --hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \
+ --hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a
# via sphinx
-pympler==1.0.1 \
- --hash=sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa \
- --hash=sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d
+pympler==1.1 \
+ --hash=sha256:1eaa867cb8992c218430f1708fdaccda53df064144d1c5656b1e6f1ee6000424 \
+ --hash=sha256:5b223d6027d0619584116a0cbc28e8d2e378f7a79c1e5e024f9ff3b673c58506
# via -r requirements.txt
pyparsing==3.1.2 \
--hash=sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad \
--hash=sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742
# via -r requirements.txt
-pyproject-hooks==1.0.0 \
- --hash=sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 \
- --hash=sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5
- # via build
+pyproject-hooks==1.1.0 \
+ --hash=sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965 \
+ --hash=sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2
+ # via
+ # build
+ # pip-tools
pytz==2024.1 \
--hash=sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812 \
--hash=sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319
@@ -537,125 +535,129 @@ recommonmark==0.7.1 \
--hash=sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f \
--hash=sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67
# via -r requirements.txt
-referencing==0.34.0 \
- --hash=sha256:5773bd84ef41799a5a8ca72dc34590c041eb01bf9aa02632b4a973fb0181a844 \
- --hash=sha256:d53ae300ceddd3169f1ffa9caf2cb7b769e92657e4fafb23d34b93679116dfd4
+referencing==0.35.1 \
+ --hash=sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c \
+ --hash=sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de
# via
# jsonschema
# jsonschema-specifications
-requests==2.31.0 \
- --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
- --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
+requests==2.32.3 \
+ --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \
+ --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6
# via sphinx
-rpds-py==0.18.0 \
- --hash=sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f \
- --hash=sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c \
- --hash=sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76 \
- --hash=sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e \
- --hash=sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157 \
- --hash=sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f \
- --hash=sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5 \
- --hash=sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05 \
- --hash=sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24 \
- --hash=sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1 \
- --hash=sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8 \
- --hash=sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b \
- --hash=sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb \
- --hash=sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07 \
- --hash=sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1 \
- --hash=sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6 \
- --hash=sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e \
- --hash=sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e \
- --hash=sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1 \
- --hash=sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab \
- --hash=sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4 \
- --hash=sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17 \
- --hash=sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594 \
- --hash=sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d \
- --hash=sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d \
- --hash=sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3 \
- --hash=sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c \
- --hash=sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66 \
- --hash=sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f \
- --hash=sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80 \
- --hash=sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33 \
- --hash=sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f \
- --hash=sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c \
- --hash=sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022 \
- --hash=sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e \
- --hash=sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f \
- --hash=sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da \
- --hash=sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1 \
- --hash=sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688 \
- --hash=sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795 \
- --hash=sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c \
- --hash=sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98 \
- --hash=sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1 \
- --hash=sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20 \
- --hash=sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307 \
- --hash=sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4 \
- --hash=sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18 \
- --hash=sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294 \
- --hash=sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66 \
- --hash=sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467 \
- --hash=sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948 \
- --hash=sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e \
- --hash=sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1 \
- --hash=sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0 \
- --hash=sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7 \
- --hash=sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd \
- --hash=sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641 \
- --hash=sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d \
- --hash=sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9 \
- --hash=sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1 \
- --hash=sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da \
- --hash=sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3 \
- --hash=sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa \
- --hash=sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7 \
- --hash=sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40 \
- --hash=sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496 \
- --hash=sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124 \
- --hash=sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836 \
- --hash=sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434 \
- --hash=sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984 \
- --hash=sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f \
- --hash=sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6 \
- --hash=sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e \
- --hash=sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461 \
- --hash=sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c \
- --hash=sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432 \
- --hash=sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73 \
- --hash=sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58 \
- --hash=sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88 \
- --hash=sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337 \
- --hash=sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7 \
- --hash=sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863 \
- --hash=sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475 \
- --hash=sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3 \
- --hash=sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51 \
- --hash=sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf \
- --hash=sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024 \
- --hash=sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40 \
- --hash=sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9 \
- --hash=sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec \
- --hash=sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb \
- --hash=sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7 \
- --hash=sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861 \
- --hash=sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880 \
- --hash=sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f \
- --hash=sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd \
- --hash=sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca \
- --hash=sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58 \
- --hash=sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e
+rpds-py==0.19.1 \
+ --hash=sha256:01227f8b3e6c8961490d869aa65c99653df80d2f0a7fde8c64ebddab2b9b02fd \
+ --hash=sha256:08ce9c95a0b093b7aec75676b356a27879901488abc27e9d029273d280438505 \
+ --hash=sha256:0b02dd77a2de6e49078c8937aadabe933ceac04b41c5dde5eca13a69f3cf144e \
+ --hash=sha256:0d4b52811dcbc1aba08fd88d475f75b4f6db0984ba12275d9bed1a04b2cae9b5 \
+ --hash=sha256:13e6d4840897d4e4e6b2aa1443e3a8eca92b0402182aafc5f4ca1f5e24f9270a \
+ --hash=sha256:1a129c02b42d46758c87faeea21a9f574e1c858b9f358b6dd0bbd71d17713175 \
+ --hash=sha256:1a8dfa125b60ec00c7c9baef945bb04abf8ac772d8ebefd79dae2a5f316d7850 \
+ --hash=sha256:1c32e41de995f39b6b315d66c27dea3ef7f7c937c06caab4c6a79a5e09e2c415 \
+ --hash=sha256:1d494887d40dc4dd0d5a71e9d07324e5c09c4383d93942d391727e7a40ff810b \
+ --hash=sha256:1d4af2eb520d759f48f1073ad3caef997d1bfd910dc34e41261a595d3f038a94 \
+ --hash=sha256:1fb93d3486f793d54a094e2bfd9cd97031f63fcb5bc18faeb3dd4b49a1c06523 \
+ --hash=sha256:24f8ae92c7fae7c28d0fae9b52829235df83f34847aa8160a47eb229d9666c7b \
+ --hash=sha256:24fc5a84777cb61692d17988989690d6f34f7f95968ac81398d67c0d0994a897 \
+ --hash=sha256:26ab43b6d65d25b1a333c8d1b1c2f8399385ff683a35ab5e274ba7b8bb7dc61c \
+ --hash=sha256:271accf41b02687cef26367c775ab220372ee0f4925591c6796e7c148c50cab5 \
+ --hash=sha256:2ddd50f18ebc05ec29a0d9271e9dbe93997536da3546677f8ca00b76d477680c \
+ --hash=sha256:31dd5794837f00b46f4096aa8ccaa5972f73a938982e32ed817bb520c465e520 \
+ --hash=sha256:31e450840f2f27699d014cfc8865cc747184286b26d945bcea6042bb6aa4d26e \
+ --hash=sha256:32e0db3d6e4f45601b58e4ac75c6f24afbf99818c647cc2066f3e4b192dabb1f \
+ --hash=sha256:346557f5b1d8fd9966059b7a748fd79ac59f5752cd0e9498d6a40e3ac1c1875f \
+ --hash=sha256:34bca66e2e3eabc8a19e9afe0d3e77789733c702c7c43cd008e953d5d1463fde \
+ --hash=sha256:3511f6baf8438326e351097cecd137eb45c5f019944fe0fd0ae2fea2fd26be39 \
+ --hash=sha256:35af5e4d5448fa179fd7fff0bba0fba51f876cd55212f96c8bbcecc5c684ae5c \
+ --hash=sha256:3837c63dd6918a24de6c526277910e3766d8c2b1627c500b155f3eecad8fad65 \
+ --hash=sha256:39d67896f7235b2c886fb1ee77b1491b77049dcef6fbf0f401e7b4cbed86bbd4 \
+ --hash=sha256:3b823be829407393d84ee56dc849dbe3b31b6a326f388e171555b262e8456cc1 \
+ --hash=sha256:3c73254c256081704dba0a333457e2fb815364018788f9b501efe7c5e0ada401 \
+ --hash=sha256:3ddab996807c6b4227967fe1587febade4e48ac47bb0e2d3e7858bc621b1cace \
+ --hash=sha256:3e1dc59a5e7bc7f44bd0c048681f5e05356e479c50be4f2c1a7089103f1621d5 \
+ --hash=sha256:4383beb4a29935b8fa28aca8fa84c956bf545cb0c46307b091b8d312a9150e6a \
+ --hash=sha256:4cc4bc73e53af8e7a42c8fd7923bbe35babacfa7394ae9240b3430b5dcf16b2a \
+ --hash=sha256:4dd02e29c8cbed21a1875330b07246b71121a1c08e29f0ee3db5b4cfe16980c4 \
+ --hash=sha256:4f580ae79d0b861dfd912494ab9d477bea535bfb4756a2269130b6607a21802e \
+ --hash=sha256:53dbc35808c6faa2ce3e48571f8f74ef70802218554884787b86a30947842a14 \
+ --hash=sha256:56313be667a837ff1ea3508cebb1ef6681d418fa2913a0635386cf29cff35165 \
+ --hash=sha256:57863d16187995c10fe9cf911b897ed443ac68189179541734502353af33e693 \
+ --hash=sha256:5953391af1405f968eb5701ebbb577ebc5ced8d0041406f9052638bafe52209d \
+ --hash=sha256:5beffdbe766cfe4fb04f30644d822a1080b5359df7db3a63d30fa928375b2720 \
+ --hash=sha256:5e360188b72f8080fefa3adfdcf3618604cc8173651c9754f189fece068d2a45 \
+ --hash=sha256:5e58b61dcbb483a442c6239c3836696b79f2cd8e7eec11e12155d3f6f2d886d1 \
+ --hash=sha256:69084fd29bfeff14816666c93a466e85414fe6b7d236cfc108a9c11afa6f7301 \
+ --hash=sha256:6d1d7539043b2b31307f2c6c72957a97c839a88b2629a348ebabe5aa8b626d6b \
+ --hash=sha256:6d8b735c4d162dc7d86a9cf3d717f14b6c73637a1f9cd57fe7e61002d9cb1972 \
+ --hash=sha256:6ea961a674172ed2235d990d7edf85d15d8dfa23ab8575e48306371c070cda67 \
+ --hash=sha256:71157f9db7f6bc6599a852852f3389343bea34315b4e6f109e5cbc97c1fb2963 \
+ --hash=sha256:720f3108fb1bfa32e51db58b832898372eb5891e8472a8093008010911e324c5 \
+ --hash=sha256:74129d5ffc4cde992d89d345f7f7d6758320e5d44a369d74d83493429dad2de5 \
+ --hash=sha256:747251e428406b05fc86fee3904ee19550c4d2d19258cef274e2151f31ae9d38 \
+ --hash=sha256:75130df05aae7a7ac171b3b5b24714cffeabd054ad2ebc18870b3aa4526eba23 \
+ --hash=sha256:7b3661e6d4ba63a094138032c1356d557de5b3ea6fd3cca62a195f623e381c76 \
+ --hash=sha256:7d5c7e32f3ee42f77d8ff1a10384b5cdcc2d37035e2e3320ded909aa192d32c3 \
+ --hash=sha256:8124101e92c56827bebef084ff106e8ea11c743256149a95b9fd860d3a4f331f \
+ --hash=sha256:81db2e7282cc0487f500d4db203edc57da81acde9e35f061d69ed983228ffe3b \
+ --hash=sha256:840e18c38098221ea6201f091fc5d4de6128961d2930fbbc96806fb43f69aec1 \
+ --hash=sha256:89cc8921a4a5028d6dd388c399fcd2eef232e7040345af3d5b16c04b91cf3c7e \
+ --hash=sha256:8b32cd4ab6db50c875001ba4f5a6b30c0f42151aa1fbf9c2e7e3674893fb1dc4 \
+ --hash=sha256:8df1c283e57c9cb4d271fdc1875f4a58a143a2d1698eb0d6b7c0d7d5f49c53a1 \
+ --hash=sha256:902cf4739458852fe917104365ec0efbea7d29a15e4276c96a8d33e6ed8ec137 \
+ --hash=sha256:97fbb77eaeb97591efdc654b8b5f3ccc066406ccfb3175b41382f221ecc216e8 \
+ --hash=sha256:9c7042488165f7251dc7894cd533a875d2875af6d3b0e09eda9c4b334627ad1c \
+ --hash=sha256:9e318e6786b1e750a62f90c6f7fa8b542102bdcf97c7c4de2a48b50b61bd36ec \
+ --hash=sha256:a9421b23c85f361a133aa7c5e8ec757668f70343f4ed8fdb5a4a14abd5437244 \
+ --hash=sha256:aaf71f95b21f9dc708123335df22e5a2fef6307e3e6f9ed773b2e0938cc4d491 \
+ --hash=sha256:afedc35fe4b9e30ab240b208bb9dc8938cb4afe9187589e8d8d085e1aacb8309 \
+ --hash=sha256:b5e28e56143750808c1c79c70a16519e9bc0a68b623197b96292b21b62d6055c \
+ --hash=sha256:b82c9514c6d74b89a370c4060bdb80d2299bc6857e462e4a215b4ef7aa7b090e \
+ --hash=sha256:b8f78398e67a7227aefa95f876481485403eb974b29e9dc38b307bb6eb2315ea \
+ --hash=sha256:bbda75f245caecff8faa7e32ee94dfaa8312a3367397975527f29654cd17a6ed \
+ --hash=sha256:bca34e913d27401bda2a6f390d0614049f5a95b3b11cd8eff80fe4ec340a1208 \
+ --hash=sha256:bd04d8cab16cab5b0a9ffc7d10f0779cf1120ab16c3925404428f74a0a43205a \
+ --hash=sha256:c149a652aeac4902ecff2dd93c3b2681c608bd5208c793c4a99404b3e1afc87c \
+ --hash=sha256:c2087dbb76a87ec2c619253e021e4fb20d1a72580feeaa6892b0b3d955175a71 \
+ --hash=sha256:c34f751bf67cab69638564eee34023909380ba3e0d8ee7f6fe473079bf93f09b \
+ --hash=sha256:c6d20c8896c00775e6f62d8373aba32956aa0b850d02b5ec493f486c88e12859 \
+ --hash=sha256:c7af6f7b80f687b33a4cdb0a785a5d4de1fb027a44c9a049d8eb67d5bfe8a687 \
+ --hash=sha256:c7b07959866a6afb019abb9564d8a55046feb7a84506c74a6f197cbcdf8a208e \
+ --hash=sha256:ca0dda0c5715efe2ab35bb83f813f681ebcd2840d8b1b92bfc6fe3ab382fae4a \
+ --hash=sha256:cdb7eb3cf3deb3dd9e7b8749323b5d970052711f9e1e9f36364163627f96da58 \
+ --hash=sha256:ce757c7c90d35719b38fa3d4ca55654a76a40716ee299b0865f2de21c146801c \
+ --hash=sha256:d1fa67ef839bad3815124f5f57e48cd50ff392f4911a9f3cf449d66fa3df62a5 \
+ --hash=sha256:d2dbd8f4990d4788cb122f63bf000357533f34860d269c1a8e90ae362090ff3a \
+ --hash=sha256:d4ec0046facab83012d821b33cead742a35b54575c4edfb7ed7445f63441835f \
+ --hash=sha256:dbceedcf4a9329cc665452db1aaf0845b85c666e4885b92ee0cddb1dbf7e052a \
+ --hash=sha256:dc733d35f861f8d78abfaf54035461e10423422999b360966bf1c443cbc42705 \
+ --hash=sha256:dd635c2c4043222d80d80ca1ac4530a633102a9f2ad12252183bcf338c1b9474 \
+ --hash=sha256:de1f7cd5b6b351e1afd7568bdab94934d656abe273d66cda0ceea43bbc02a0c2 \
+ --hash=sha256:df7c841813f6265e636fe548a49664c77af31ddfa0085515326342a751a6ba51 \
+ --hash=sha256:e0f9d268b19e8f61bf42a1da48276bcd05f7ab5560311f541d22557f8227b866 \
+ --hash=sha256:e2d66eb41ffca6cc3c91d8387509d27ba73ad28371ef90255c50cb51f8953301 \
+ --hash=sha256:e429fc517a1c5e2a70d576077231538a98d59a45dfc552d1ac45a132844e6dfb \
+ --hash=sha256:e4d2b88efe65544a7d5121b0c3b003ebba92bfede2ea3577ce548b69c5235185 \
+ --hash=sha256:e76c902d229a3aa9d5ceb813e1cbcc69bf5bda44c80d574ff1ac1fa3136dea71 \
+ --hash=sha256:ef07a0a1d254eeb16455d839cef6e8c2ed127f47f014bbda64a58b5482b6c836 \
+ --hash=sha256:f09529d2332264a902688031a83c19de8fda5eb5881e44233286b9c9ec91856d \
+ --hash=sha256:f0a6d4a93d2a05daec7cb885157c97bbb0be4da739d6f9dfb02e101eb40921cd \
+ --hash=sha256:f0cf2a0dbb5987da4bd92a7ca727eadb225581dd9681365beba9accbe5308f7d \
+ --hash=sha256:f2671cb47e50a97f419a02cd1e0c339b31de017b033186358db92f4d8e2e17d8 \
+ --hash=sha256:f35b34a5184d5e0cc360b61664c1c06e866aab077b5a7c538a3e20c8fcdbf90b \
+ --hash=sha256:f3d73022990ab0c8b172cce57c69fd9a89c24fd473a5e79cbce92df87e3d9c48 \
+ --hash=sha256:f5b8353ea1a4d7dfb59a7f45c04df66ecfd363bb5b35f33b11ea579111d4655f \
+ --hash=sha256:f809a17cc78bd331e137caa25262b507225854073fd319e987bd216bed911b7c \
+ --hash=sha256:f9bc4161bd3b970cd6a6fcda70583ad4afd10f2750609fb1f3ca9505050d4ef3 \
+ --hash=sha256:fdf4890cda3b59170009d012fca3294c00140e7f2abe1910e6a730809d0f3f9b
# via
# jsonschema
# referencing
-scapy==2.4.3 ; python_version >= "2.7" or python_version >= "3.4" \
- --hash=sha256:e2f8d11f6a941c14a789ae8b236b27bd634681f1b29b5e893861e284d234f6b0
+scapy==2.4.5 ; python_version >= "3.4" \
+ --hash=sha256:bc707e3604784496b6665a9e5b2a69c36cc9fb032af4864b29051531b24c8593
# via -r requirements.txt
-sh==2.0.6 \
- --hash=sha256:9b2998f313f201c777e2c0061f0b1367497097ef13388595be147e2a00bf7ba1 \
- --hash=sha256:ced8f2e081a858b66a46ace3703dec243779abbd5a1887ba7e3c34f34da70cd2
+sh==2.0.7 \
+ --hash=sha256:029d45198902bfb967391eccfd13a88d92f7cebd200411e93f99ebacc6afbb35 \
+ --hash=sha256:2f2f79a65abd00696cf2e9ad26508cf8abb6dba5745f40255f1c0ded2876926d
# via -r requirements.txt
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
@@ -721,22 +723,21 @@ tomli==2.0.1 \
# black
# build
# pip-tools
- # pyproject-hooks
-typing-extensions==4.10.0 \
- --hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \
- --hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb
+typing-extensions==4.12.2 \
+ --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \
+ --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8
# via black
-urllib3==2.2.1 \
- --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
- --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
+urllib3==2.2.2 \
+ --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
+ --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168
# via requests
wheel==0.43.0 \
--hash=sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85 \
--hash=sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81
# via pip-tools
-zipp==3.18.1 \
- --hash=sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b \
- --hash=sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715
+zipp==3.19.2 \
+ --hash=sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19 \
+ --hash=sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c
# via
# importlib-metadata
# importlib-resources
diff --git a/test/requirements.txt b/test/requirements.txt
index c01d31161f7..d1ab9492ae8 100644
--- a/test/requirements.txt
+++ b/test/requirements.txt
@@ -1,4 +1,4 @@
-pip-tools==7.3.0 # BSD Keep this in sync with Makefile's PIP_TOOLS_VERSION
+pip-tools==7.4.1 # BSD Keep this in sync with Makefile's PIP_TOOLS_VERSION
cryptography!=2.0 # BSD/Apache-2.0
deprecation>=2.0.6 # Apache-2.0
faulthandler; python_version < '3.3' # # BSD License (2 clause)
@@ -6,7 +6,7 @@ ipaddress; python_version < '3.3' # PSF
parameterized>=0.6.1 # BSD
pexpect # ISC
psutil # BSD
-scapy==2.4.3; python_version >= '2.7' or python_version >= '3.4' # GPL2 https://github.com/secdev/scapy/blob/master/LICENSE
+scapy==2.4.5; python_version >= '3.4' # GPL2 https://github.com/secdev/scapy/blob/master/LICENSE
six # MIT
syslog_rfc5424_parser>=0.3.1 # ISC
objgraph # MIT
diff --git a/test/template_ipsec.py b/test/template_ipsec.py
index b5cd922f127..4e68d44013f 100644
--- a/test/template_ipsec.py
+++ b/test/template_ipsec.py
@@ -1,11 +1,13 @@
import unittest
import socket
import struct
+import re
+import os
from scapy.layers.inet import IP, ICMP, TCP, UDP
from scapy.layers.ipsec import SecurityAssociation, ESP
from scapy.layers.l2 import Ether
-from scapy.packet import raw, Raw
+from scapy.packet import raw, Raw, Padding
from scapy.layers.inet6 import (
IPv6,
ICMPv6EchoRequest,
@@ -22,8 +24,7 @@ from vpp_papi import VppEnum
from vpp_ipsec import VppIpsecSpd, VppIpsecSpdEntry, VppIpsecSpdItfBinding
from ipaddress import ip_address
-from re import search
-from os import popen
+from config import config
class IPsecIPv4Params:
@@ -323,6 +324,9 @@ class IpsecTcp(object):
self.assert_packet_checksums_valid(decrypted)
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class IpsecTcpTests(IpsecTcp):
def test_tcp_checksum(self):
"""verify checksum correctness for vpp generated packets"""
@@ -1849,6 +1853,9 @@ class IpsecTra4(object):
self._verify_tra_anti_replay_algorithm_no_esn()
+@unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+)
class IpsecTra4Tests(IpsecTra4):
"""UT test methods for Transport v4"""
@@ -1931,7 +1938,7 @@ class IpsecTra6(object):
Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac)
/ IPv6(src=src, dst=dst)
/ IPv6ExtHdrHopByHop()
- / IPv6ExtHdrFragment(id=2, offset=200)
+ / IPv6ExtHdrFragment(id=2, offset=0)
/ Raw(b"\xff" * 200)
for i in range(count)
]
@@ -1978,7 +1985,7 @@ class IpsecTra6(object):
tx = (
Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
/ IPv6(src=self.tra_if.local_ip6, dst=self.tra_if.remote_ip6)
- / IPv6ExtHdrFragment(id=2, offset=200)
+ / IPv6ExtHdrFragment(id=2, offset=0)
/ Raw(b"\xff" * 200)
)
@@ -1997,7 +2004,7 @@ class IpsecTra6(object):
Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
/ IPv6(src=self.tra_if.local_ip6, dst=self.tra_if.remote_ip6)
/ IPv6ExtHdrHopByHop()
- / IPv6ExtHdrFragment(id=2, offset=200)
+ / IPv6ExtHdrFragment(id=2, offset=0)
/ Raw(b"\xff" * 200)
)
@@ -2014,7 +2021,7 @@ class IpsecTra6(object):
Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
/ IPv6(src=self.tra_if.local_ip6, dst=self.tra_if.remote_ip6)
/ IPv6ExtHdrHopByHop()
- / IPv6ExtHdrFragment(id=2, offset=200)
+ / IPv6ExtHdrFragment(id=2, offset=0)
/ IPv6ExtHdrDestOpt()
/ Raw(b"\xff" * 200)
)
@@ -2029,6 +2036,9 @@ class IpsecTra6(object):
self.assert_equal(dc[IPv6ExtHdrFragment].id, 2)
+@unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+)
class IpsecTra6Tests(IpsecTra6):
"""UT test methods for Transport v6"""
@@ -3022,7 +3032,7 @@ class SpdFlowCacheTemplate(IPSecIPv4Fwd):
return False
def create_stream(
- cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=5678, proto="UDP-ESP"
+ cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=4500, proto="UDP-ESP"
):
packets = []
packets = super(SpdFlowCacheTemplate, cls).create_stream(
@@ -3031,7 +3041,7 @@ class SpdFlowCacheTemplate(IPSecIPv4Fwd):
return packets
def verify_capture(
- self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=5678
+ self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=4500
):
super(SpdFlowCacheTemplate, self).verify_l3_l4_capture(
src_if, dst_if, capture, tcp_port_in, udp_port_in
@@ -3056,7 +3066,7 @@ class SpdFastPathTemplate(IPSecIPv4Fwd):
super(SpdFastPathTemplate, self).tearDown()
def create_stream(
- cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=5678, proto="UDP-ESP"
+ cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=4500, proto="UDP-ESP"
):
packets = []
packets = super(SpdFastPathTemplate, cls).create_stream(
@@ -3065,7 +3075,7 @@ class SpdFastPathTemplate(IPSecIPv4Fwd):
return packets
def verify_capture(
- self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=5678
+ self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=4500
):
super(SpdFastPathTemplate, self).verify_l3_l4_capture(
src_if, dst_if, capture, tcp_port_in, udp_port_in
@@ -3084,7 +3094,7 @@ class IpsecDefaultTemplate(IPSecIPv4Fwd):
super(IpsecDefaultTemplate, self).tearDown()
def create_stream(
- cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=5678, proto="UDP-ESP"
+ cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=4500, proto="UDP-ESP"
):
packets = []
packets = super(IpsecDefaultTemplate, cls).create_stream(
@@ -3093,7 +3103,7 @@ class IpsecDefaultTemplate(IPSecIPv4Fwd):
return packets
def verify_capture(
- self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=5678
+ self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=4500
):
super(IpsecDefaultTemplate, self).verify_l3_l4_capture(
src_if, dst_if, capture, tcp_port_in, udp_port_in
diff --git a/test/test_arping.py b/test/test_arping.py
index a3e7e041ba1..435b15ee121 100644
--- a/test/test_arping.py
+++ b/test/test_arping.py
@@ -2,6 +2,9 @@ from scapy.layers.l2 import ARP
from scapy.layers.inet6 import ICMPv6ND_NS, ICMPv6ND_NA, IPv6
from framework import VppTestCase
+from config import config
+
+import unittest
""" TestArping is a subclass of VPPTestCase classes.
@@ -10,6 +13,7 @@ Basic test for sanity check of arping.
"""
+@unittest.skipIf("arping" in config.excluded_plugins, "Exclude Arping plugin tests")
class TestArping(VppTestCase):
"""Arping Test Case"""
diff --git a/test/test_bond.py b/test/test_bond.py
index ccd6246bed8..3c0df628470 100644
--- a/test/test_bond.py
+++ b/test/test_bond.py
@@ -10,6 +10,7 @@ from framework import VppTestCase
from asfframework import VppTestRunner
from vpp_bond_interface import VppBondInterface
from vpp_papi import MACAddress, VppEnum
+from config import config
class TestBondInterface(VppTestCase):
@@ -174,6 +175,9 @@ class TestBondInterface(VppTestCase):
bond0.remove_vpp_config()
+ @unittest.skipIf(
+ "lacp" in config.excluded_plugins, "Exclude tests requiring LACP plugin"
+ )
def test_bond_add_member(self):
"""Bond add_member/detach member test"""
@@ -227,6 +231,9 @@ class TestBondInterface(VppTestCase):
bond0.remove_vpp_config()
+ @unittest.skipIf(
+ "lacp" in config.excluded_plugins, "Exclude tests requiring LACP plugin"
+ )
def test_bond(self):
"""Bond add/delete interface test"""
self.logger.info("Bond add interfaces")
diff --git a/test/test_cdp.py b/test/test_cdp.py
index da378dbebe3..8d72e88aa24 100644
--- a/test/test_cdp.py
+++ b/test/test_cdp.py
@@ -17,6 +17,7 @@ from scapy.all import raw
from re import compile
from time import sleep
from util import ppp
+from config import config
import platform
import sys
import unittest
@@ -39,6 +40,7 @@ class CustomTLV(Packet):
]
+@unittest.skipIf("cdp" in config.excluded_plugins, "Exclude CDP plugin tests")
class TestCDP(VppTestCase):
"""CDP Test Case"""
diff --git a/test/test_cnat.py b/test/test_cnat.py
index ff8e1ebbbbb..9e979a4e09e 100644
--- a/test/test_cnat.py
+++ b/test/test_cnat.py
@@ -6,6 +6,7 @@ from framework import VppTestCase
from asfframework import VppTestRunner
from vpp_ip import INVALID_INDEX
from itertools import product
+from config import config
from scapy.packet import Raw
from scapy.layers.l2 import Ether
@@ -335,6 +336,7 @@ class CnatTestContext(object):
# -------------------------------------------------------------------
+@unittest.skipIf("cnat" in config.excluded_plugins, "Exclude CNAT plugin tests")
class TestCNatTranslation(CnatCommonTestCase):
"""CNat Translation"""
@@ -679,6 +681,7 @@ class TestCNatTranslation(CnatCommonTestCase):
self.cnat_fhc_translation()
+@unittest.skipIf("cnat" in config.excluded_plugins, "Exclude CNAT plugin tests")
class TestCNatSourceNAT(CnatCommonTestCase):
"""CNat Source NAT"""
@@ -818,6 +821,7 @@ class TestCNatSourceNAT(CnatCommonTestCase):
self.vapi.cnat_session_purge()
+@unittest.skipIf("cnat" in config.excluded_plugins, "Exclude CNAT plugin tests")
class TestCNatDHCP(CnatCommonTestCase):
"""CNat Translation"""
diff --git a/test/test_det44.py b/test/test_det44.py
index ede80981349..11d33ef0acd 100644
--- a/test/test_det44.py
+++ b/test/test_det44.py
@@ -12,8 +12,10 @@ from scapy.layers.inet import IP, TCP, UDP, ICMP
from scapy.layers.inet import IPerror, UDPerror
from scapy.layers.l2 import Ether
from util import ppp
+from config import config
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestDET44(VppTestCase):
"""Deterministic NAT Test Cases"""
diff --git a/test/test_dhcp.py b/test/test_dhcp.py
index 3924ebc840d..e668b7bd1c0 100644
--- a/test/test_dhcp.py
+++ b/test/test_dhcp.py
@@ -32,6 +32,7 @@ from vpp_papi import mac_pton, VppEnum
from vpp_sub_interface import VppDot1QSubint
from vpp_qos import VppQosEgressMap, VppQosMark
from vpp_dhcp import VppDHCPClient, VppDHCPProxy
+from config import config
DHCP4_CLIENT_PORT = 68
@@ -41,6 +42,7 @@ DHCP6_SERVER_PORT = 546
@tag_run_solo
+@unittest.skipIf("dhcp" in config.excluded_plugins, "Exclude DHCP plugin tests")
class TestDHCP(VppTestCase):
"""DHCP Test Case"""
@@ -119,7 +121,7 @@ class TestDHCP(VppTestCase):
for i in dhcp.options:
if isinstance(i, tuple):
- if i[0] == "relay_agent_Information":
+ if i[0] == "relay_agent_information":
#
# There are two sb-options present - each of length 6.
#
@@ -530,7 +532,7 @@ class TestDHCP(VppTestCase):
/ DHCP(
options=[
("message-type", "offer"),
- ("relay_agent_Information", option_82),
+ ("relay_agent_information", option_82),
("end"),
]
)
@@ -541,7 +543,7 @@ class TestDHCP(VppTestCase):
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
- rx = self.pg3.get_capture(1)
+ rx = self.pg3.get_capture(1, timeout=5)
rx = rx[0]
self.verify_dhcp_offer(rx, self.pg3)
@@ -561,7 +563,7 @@ class TestDHCP(VppTestCase):
/ DHCP(
options=[
("message-type", "offer"),
- ("relay_agent_Information", bad_ip),
+ ("relay_agent_information", bad_ip),
("end"),
]
)
@@ -582,7 +584,7 @@ class TestDHCP(VppTestCase):
/ DHCP(
options=[
("message-type", "offer"),
- ("relay_agent_Information", bad_if_index),
+ ("relay_agent_information", bad_if_index),
("end"),
]
)
@@ -746,7 +748,7 @@ class TestDHCP(VppTestCase):
/ DHCP(
options=[
("message-type", "offer"),
- ("relay_agent_Information", option_82),
+ ("relay_agent_information", option_82),
("end"),
]
)
@@ -759,7 +761,7 @@ class TestDHCP(VppTestCase):
/ DHCP(
options=[
("message-type", "offer"),
- ("relay_agent_Information", option_82),
+ ("relay_agent_information", option_82),
("end"),
]
)
@@ -786,7 +788,7 @@ class TestDHCP(VppTestCase):
/ DHCP(
options=[
("message-type", "offer"),
- ("relay_agent_Information", option_82),
+ ("relay_agent_information", option_82),
("end"),
]
)
diff --git a/test/test_dhcp6.py b/test/test_dhcp6.py
index 5c8e4354ab0..1328a62e1d3 100644
--- a/test/test_dhcp6.py
+++ b/test/test_dhcp6.py
@@ -24,14 +24,17 @@ from scapy.layers.inet6 import IPv6, Ether, UDP
from framework import VppTestCase
from asfframework import tag_fixme_vpp_workers, tag_run_solo
from vpp_papi import VppEnum
+from config import config
import util
import os
+import unittest
def ip6_normalize(ip6):
return inet_ntop(AF_INET6, inet_pton(AF_INET6, ip6))
+@unittest.skipIf("dhcp" in config.excluded_plugins, "Exclude DHCP plugin tests")
class TestDHCPv6DataPlane(VppTestCase):
"""DHCPv6 Data Plane Test Case"""
@@ -243,6 +246,7 @@ class TestDHCPv6DataPlane(VppTestCase):
@tag_run_solo
+@unittest.skipIf("dhcp" in config.excluded_plugins, "Exclude DHCP plugin tests")
class TestDHCPv6IANAControlPlane(VppTestCase):
"""DHCPv6 IA NA Control Plane Test Case"""
@@ -303,7 +307,7 @@ class TestDHCPv6IANAControlPlane(VppTestCase):
return addresses.difference(self.initial_addresses)
def validate_duid_ll(self, duid):
- DUID_LL(duid)
+ DUID_LL(bytes(duid))
def validate_packet(self, packet, msg_type, is_resend=False):
try:
@@ -497,6 +501,7 @@ class TestDHCPv6IANAControlPlane(VppTestCase):
@tag_fixme_vpp_workers
+@unittest.skipIf("dhcp" in config.excluded_plugins, "Exclude DHCP plugin tests")
class TestDHCPv6PDControlPlane(VppTestCase):
"""DHCPv6 PD Control Plane Test Case"""
@@ -557,7 +562,7 @@ class TestDHCPv6PDControlPlane(VppTestCase):
return addresses.difference(self.initial_addresses)
def validate_duid_ll(self, duid):
- DUID_LL(duid)
+ DUID_LL(bytes(duid))
def validate_packet(self, packet, msg_type, is_resend=False):
try:
diff --git a/test/test_dns.py b/test/test_dns.py
index edd1415bb01..77f26d71eaa 100644
--- a/test/test_dns.py
+++ b/test/test_dns.py
@@ -5,12 +5,14 @@ import unittest
from framework import VppTestCase
from asfframework import VppTestRunner
from ipaddress import *
+from config import config
from scapy.layers.inet import IP, UDP
from scapy.layers.l2 import Ether
from scapy.layers.dns import DNS, DNSQR
+@unittest.skipIf("dns" in config.excluded_plugins, "Exclude DNS plugin tests")
class TestDns(VppTestCase):
"""Dns Test Cases"""
diff --git a/test/test_dslite.py b/test/test_dslite.py
index ca481bc2d6b..b88605b3a2f 100644
--- a/test/test_dslite.py
+++ b/test/test_dslite.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import socket
+import unittest
from asfframework import tag_fixme_vpp_workers
from framework import VppTestCase
@@ -17,9 +18,11 @@ from scapy.packet import Raw
from syslog_rfc5424_parser import SyslogMessage, ParseError
from syslog_rfc5424_parser.constants import SyslogSeverity
from vpp_ip_route import VppIpRoute, VppRoutePath
+from config import config
@tag_fixme_vpp_workers
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestDSlite(VppTestCase):
"""DS-Lite Test Cases"""
@@ -233,6 +236,7 @@ class TestDSlite(VppTestCase):
self.logger.info(self.vapi.cli("show dslite sessions"))
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestDSliteCE(VppTestCase):
"""DS-Lite CE Test Cases"""
diff --git a/test/test_dvr.py b/test/test_dvr.py
index e616408e8c7..dcc17f040eb 100644
--- a/test/test_dvr.py
+++ b/test/test_dvr.py
@@ -13,10 +13,12 @@ from scapy.layers.l2 import Ether, Dot1Q
from scapy.layers.inet import IP, UDP
from socket import AF_INET
from ipaddress import IPv4Network
+from config import config
NUM_PKTS = 67
+@unittest.skipIf("acl" in config.excluded_plugins, "Exclude tests requiring ACL plugin")
class TestDVR(VppTestCase):
"""Distributed Virtual Router"""
diff --git a/test/test_flowprobe.py b/test/test_flowprobe.py
index 8e3fecfd7b4..9622e6158b5 100644
--- a/test/test_flowprobe.py
+++ b/test/test_flowprobe.py
@@ -31,6 +31,7 @@ from vpp_papi.macaddress import mac_ntop
from socket import inet_ntop
from vpp_papi import VppEnum
from vpp_sub_interface import VppDot1ADSubint
+from config import config
TMPL_COMMON_FIELD_COUNT = 6
@@ -183,9 +184,7 @@ class MethodHolder(VppTestCase):
variables and configure VPP.
"""
super(MethodHolder, cls).setUpClass()
- if (is_distro_ubuntu2204 == True or is_distro_debian11 == True) and not hasattr(
- cls, "vpp"
- ):
+ if (is_distro_debian11 == True) and not hasattr(cls, "vpp"):
return
try:
# Create pg interfaces
@@ -386,6 +385,9 @@ class MethodHolder(VppTestCase):
@tag_fixme_vpp_workers
@tag_fixme_ubuntu2204
@tag_fixme_debian11
+@unittest.skipIf(
+ "flowprobe" in config.excluded_plugins, "Exclude Flowprobe plugin tests"
+)
class Flowprobe(MethodHolder):
"""Template verification, timer tests"""
@@ -1228,6 +1230,9 @@ class DatapathTestsHolder(object):
self.logger.info("FFP_TEST_FINISH_0002")
+@unittest.skipIf(
+ "flowprobe" in config.excluded_plugins, "Exclude Flowprobe plugin tests"
+)
class DatapathTx(MethodHolder, DatapathTestsHolder):
"""Collect info on Ethernet, IP4 and IP6 datapath (TX) (no timers)"""
@@ -1308,6 +1313,9 @@ class DatapathTx(MethodHolder, DatapathTestsHolder):
ipfix.remove_vpp_config()
+@unittest.skipIf(
+ "flowprobe" in config.excluded_plugins, "Exclude Flowprobe plugin tests"
+)
class DatapathRx(MethodHolder, DatapathTestsHolder):
"""Collect info on Ethernet, IP4 and IP6 datapath (RX) (no timers)"""
@@ -1318,6 +1326,9 @@ class DatapathRx(MethodHolder, DatapathTestsHolder):
@unittest.skipUnless(config.extended, "part of extended tests")
+@unittest.skipIf(
+ "flowprobe" in config.excluded_plugins, "Exclude Flowprobe plugin tests"
+)
class DisableIPFIX(MethodHolder):
"""Disable IPFIX"""
@@ -1366,6 +1377,9 @@ class DisableIPFIX(MethodHolder):
@unittest.skipUnless(config.extended, "part of extended tests")
+@unittest.skipIf(
+ "flowprobe" in config.excluded_plugins, "Exclude Flowprobe plugin tests"
+)
class ReenableIPFIX(MethodHolder):
"""Re-enable IPFIX"""
@@ -1433,6 +1447,9 @@ class ReenableIPFIX(MethodHolder):
@unittest.skipUnless(config.extended, "part of extended tests")
+@unittest.skipIf(
+ "flowprobe" in config.excluded_plugins, "Exclude Flowprobe plugin tests"
+)
class DisableFP(MethodHolder):
"""Disable Flowprobe feature"""
@@ -1541,6 +1558,9 @@ class DisableFP(MethodHolder):
@unittest.skipUnless(config.extended, "part of extended tests")
+@unittest.skipIf(
+ "flowprobe" in config.excluded_plugins, "Exclude Flowprobe plugin tests"
+)
class ReenableFP(MethodHolder):
"""Re-enable Flowprobe feature"""
diff --git a/test/test_geneve.py b/test/test_geneve.py
index 2b87303e710..f8c135bed10 100644
--- a/test/test_geneve.py
+++ b/test/test_geneve.py
@@ -5,6 +5,7 @@ import unittest
from framework import VppTestCase
from asfframework import VppTestRunner
from template_bd import BridgeDomain
+from config import config
from scapy.layers.l2 import Ether, ARP
from scapy.layers.inet import IP, UDP, ICMP
@@ -15,6 +16,7 @@ from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_ip import INVALID_INDEX
+@unittest.skipIf("geneve" in config.excluded_plugins, "Exclude GENEVE plugin tests")
class TestGeneve(BridgeDomain, VppTestCase):
"""GENEVE Test Case"""
@@ -250,6 +252,7 @@ class TestGeneve(BridgeDomain, VppTestCase):
self.logger.info(self.vapi.cli("show geneve tunnel"))
+@unittest.skipIf("geneve" in config.excluded_plugins, "Exclude GENEVE plugin tests")
class TestGeneveL3(VppTestCase):
"""GENEVE L3 Test Case"""
diff --git a/test/test_gre.py b/test/test_gre.py
index 763fb9d9b99..8b2851baea2 100644
--- a/test/test_gre.py
+++ b/test/test_gre.py
@@ -24,9 +24,11 @@ from vpp_ip_route import (
from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
from util import ppp, ppc
from vpp_papi import VppEnum
+from config import config
@tag_fixme_vpp_workers
+@unittest.skipIf("gre" in config.excluded_plugins, "Exclude GRE plugin tests")
class TestGREInputNodes(VppTestCase):
"""GRE Input Nodes Test Case"""
@@ -73,6 +75,7 @@ class TestGREInputNodes(VppTestCase):
self.assertEqual(err, err_count)
+@unittest.skipIf("gre" in config.excluded_plugins, "Exclude GRE plugin tests")
class TestGRE(VppTestCase):
"""GRE Test Case"""
diff --git a/test/test_gso.py b/test/test_gso.py
index 3d9ce5fb4ee..c3822b01faa 100644
--- a/test/test_gso.py
+++ b/test/test_gso.py
@@ -25,6 +25,7 @@ from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathProto
from vpp_ipip_tun_interface import VppIpIpTunInterface
from vpp_vxlan_tunnel import VppVxlanTunnel
from vpp_gre_interface import VppGreInterface
+from config import config
from vpp_ipsec import VppIpsecSA, VppIpsecTunProtect
from template_ipsec import (
@@ -378,6 +379,9 @@ class TestGSO(VppTestCase):
sw_if_index=self.pg1.sw_if_index, enable_disable=0
)
+ @unittest.skipIf(
+ "vxlan" in config.excluded_plugins, "Exclude tests requiring VXLAN plugin"
+ )
def test_gso_vxlan(self):
"""GSO VXLAN test"""
self.logger.info(self.vapi.cli("sh int addr"))
diff --git a/test/test_gtpu.py b/test/test_gtpu.py
index 5fe4f36ccb3..d05a1ff89e8 100644
--- a/test/test_gtpu.py
+++ b/test/test_gtpu.py
@@ -5,6 +5,7 @@ import unittest
from framework import VppTestCase
from asfframework import VppTestRunner, tag_fixme_vpp_workers
from template_bd import BridgeDomain
+from config import config
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
@@ -17,6 +18,7 @@ from vpp_ip import INVALID_INDEX
@tag_fixme_vpp_workers
+@unittest.skipIf("gtpu" in config.excluded_plugins, "Exclude GTPU plugin tests")
class TestGtpuUDP(VppTestCase):
"""GTPU UDP ports Test Case"""
@@ -119,6 +121,7 @@ class TestGtpuUDP(VppTestCase):
)
+@unittest.skipIf("gtpu" in config.excluded_plugins, "Exclude GTPU plugin tests")
class TestGtpu(BridgeDomain, VppTestCase):
"""GTPU Test Case"""
diff --git a/test/test_igmp.py b/test/test_igmp.py
index 037f108b897..e0da2b82079 100644
--- a/test/test_igmp.py
+++ b/test/test_igmp.py
@@ -19,6 +19,7 @@ from vpp_igmp import (
wait_for_igmp_event,
)
from vpp_ip_route import find_mroute, VppIpTable
+from config import config
class IgmpMode:
@@ -27,6 +28,7 @@ class IgmpMode:
@tag_fixme_vpp_workers
+@unittest.skipIf("igmp" in config.excluded_plugins, "Exclude IGMP plugin tests")
class TestIgmp(VppTestCase):
"""IGMP Test Case"""
diff --git a/test/test_ikev2.py b/test/test_ikev2.py
index fd065b47c98..4bff829c51b 100644
--- a/test/test_ikev2.py
+++ b/test/test_ikev2.py
@@ -23,10 +23,7 @@ from scapy.utils import long_converter
from framework import VppTestCase
from asfframework import (
tag_fixme_vpp_workers,
- tag_fixme_ubuntu2204,
- tag_fixme_debian11,
- is_distro_ubuntu2204,
- is_distro_debian11,
+ tag_fixme_ubuntu2404,
VppTestRunner,
)
from vpp_ikev2 import Profile, IDType, AuthMethod
@@ -677,7 +674,7 @@ class IkePeer(VppTestCase):
self.assertIsNotNone(self.p.query_vpp_config())
if self.sa.is_initiator:
self.sa.generate_dh_data()
- self.vapi.cli("ikev2 set logging level 4")
+ self.vapi.cli("ikev2 set logging level 5")
self.vapi.cli("event-lo clear")
def assert_counter(self, count, name, version="ip4"):
@@ -1215,7 +1212,7 @@ class TemplateInitiator(IkePeer):
if self.no_idr_auth:
self.assertEqual(idi.next_payload, 39) # AUTH
else:
- idr = ikev2.IKEv2_payload_IDr(idi.payload)
+ idr = ikev2.IKEv2_payload_IDr(bytes(idi.payload))
self.assertEqual(idr.load, self.sa.r_id)
prop = idi[ikev2.IKEv2_payload_Proposal]
c = self.sa.child_sas[0]
@@ -2025,20 +2022,21 @@ class TestApi(VppTestCase):
self.assertEqual(ap.tun_itf, 0xFFFFFFFF)
-@tag_fixme_vpp_workers
class TestResponderBehindNAT(TemplateResponder, Ikev2Params):
"""test responder - responder behind NAT"""
IKE_NODE_SUFFIX = "ip4-natt"
+ vpp_worker_count = 2
def config_tc(self):
self.config_params({"r_natt": True})
-@tag_fixme_vpp_workers
class TestInitiatorNATT(TemplateInitiator, Ikev2Params):
"""test ikev2 initiator - NAT traversal (intitiator behind NAT)"""
+ vpp_worker_count = 2
+
def config_tc(self):
self.config_params(
{
@@ -2067,10 +2065,11 @@ class TestInitiatorNATT(TemplateInitiator, Ikev2Params):
)
-@tag_fixme_vpp_workers
class TestInitiatorPsk(TemplateInitiator, Ikev2Params):
"""test ikev2 initiator - pre shared key auth"""
+ vpp_worker_count = 2
+
def config_tc(self):
self.config_params(
{
@@ -2098,10 +2097,11 @@ class TestInitiatorPsk(TemplateInitiator, Ikev2Params):
)
-@tag_fixme_vpp_workers
class TestInitiatorRequestWindowSize(TestInitiatorPsk):
"""test initiator - request window size (1)"""
+ vpp_worker_count = 2
+
def rekey_respond(self, req, update_child_sa_data):
ih = self.get_ike_header(req)
plain = self.sa.hmac_and_decrypt(ih)
@@ -2147,10 +2147,11 @@ class TestInitiatorRequestWindowSize(TestInitiatorPsk):
self.verify_ipsec_sas(is_rekey=True)
-@tag_fixme_vpp_workers
class TestInitiatorRekey(TestInitiatorPsk):
"""test ikev2 initiator - rekey"""
+ vpp_worker_count = 2
+
def rekey_from_initiator(self):
ispi = int.from_bytes(self.sa.child_sas[0].ispi, "little")
self.pg0.enable_capture()
@@ -2192,10 +2193,11 @@ class TestInitiatorRekey(TestInitiatorPsk):
self.verify_ipsec_sas(is_rekey=True)
-@tag_fixme_vpp_workers
class TestInitiatorDelSAFromResponder(TemplateInitiator, Ikev2Params):
"""test ikev2 initiator - delete IKE SA from responder"""
+ vpp_worker_count = 2
+
def config_tc(self):
self.config_params(
{
@@ -2225,30 +2227,32 @@ class TestInitiatorDelSAFromResponder(TemplateInitiator, Ikev2Params):
)
-@tag_fixme_vpp_workers
class TestResponderInitBehindNATT(TemplateResponder, Ikev2Params):
"""test ikev2 responder - initiator behind NAT"""
IKE_NODE_SUFFIX = "ip4-natt"
+ vpp_worker_count = 2
def config_tc(self):
self.config_params({"i_natt": True})
-@tag_fixme_vpp_workers
class TestResponderPsk(TemplateResponder, Ikev2Params):
"""test ikev2 responder - pre shared key auth"""
+ vpp_worker_count = 2
+
def config_tc(self):
self.config_params()
-@tag_fixme_vpp_workers
class TestResponderDpd(TestResponderPsk):
"""
Dead peer detection test
"""
+ vpp_worker_count = 2
+
def config_tc(self):
self.config_params({"dpd_disabled": False})
@@ -2276,11 +2280,11 @@ class TestResponderDpd(TestResponderPsk):
self.assertEqual(len(ipsec_sas), 0)
-@tag_fixme_vpp_workers
class TestResponderRekey(TestResponderPsk):
"""test ikev2 responder - rekey"""
WITH_KEX = False
+ vpp_worker_count = 2
def send_rekey_from_initiator(self):
if self.WITH_KEX:
@@ -2318,10 +2322,12 @@ class TestResponderRekey(TestResponderPsk):
self.assertEqual(r[0].sa.stats.n_rekey_req, 1)
-@tag_fixme_vpp_workers
+@tag_fixme_ubuntu2404
class TestResponderRekeyRepeat(TestResponderRekey):
"""test ikev2 responder - rekey repeat"""
+ vpp_worker_count = 2
+
def test_responder(self):
super(TestResponderRekeyRepeat, self).test_responder()
# rekey request is not accepted until old IPsec SA is expired
@@ -2344,24 +2350,26 @@ class TestResponderRekeyRepeat(TestResponderRekey):
self.verify_ipsec_sas(sa_count=3)
-@tag_fixme_vpp_workers
class TestResponderRekeyKEX(TestResponderRekey):
"""test ikev2 responder - rekey with key exchange"""
WITH_KEX = True
+ vpp_worker_count = 2
-@tag_fixme_vpp_workers
+@tag_fixme_ubuntu2404
class TestResponderRekeyRepeatKEX(TestResponderRekeyRepeat):
"""test ikev2 responder - rekey repeat with key exchange"""
WITH_KEX = True
+ vpp_worker_count = 2
-@tag_fixme_vpp_workers
class TestResponderRekeySA(TestResponderPsk):
"""test ikev2 responder - rekey IKE SA"""
+ vpp_worker_count = 2
+
def send_rekey_from_initiator(self, newsa):
packet = self.create_sa_rekey_request(
spi=newsa.ispi,
@@ -2402,8 +2410,6 @@ class TestResponderRekeySA(TestResponderPsk):
self.verify_ike_sas()
-@tag_fixme_ubuntu2204
-@tag_fixme_debian11
class TestResponderVrf(TestResponderPsk, Ikev2Params):
"""test ikev2 responder - non-default table id"""
@@ -2413,10 +2419,7 @@ class TestResponderVrf(TestResponderPsk, Ikev2Params):
globals()["ikev2"] = _ikev2
super(IkePeer, cls).setUpClass()
- if (is_distro_ubuntu2204 == True or is_distro_debian11 == True) and not hasattr(
- cls, "vpp"
- ):
- return
+
cls.create_pg_interfaces(range(1))
cls.vapi.cli("ip table add 1")
cls.vapi.cli("set interface ip table pg0 1")
@@ -2431,7 +2434,7 @@ class TestResponderVrf(TestResponderPsk, Ikev2Params):
self.config_params({"dpd_disabled": False})
def test_responder(self):
- self.vapi.ikev2_profile_set_liveness(period=2, max_retries=1)
+ self.vapi.ikev2_profile_set_liveness(period=2, max_retries=3)
super(TestResponderVrf, self).test_responder()
self.pg0.enable_capture()
self.pg_start()
@@ -2442,10 +2445,11 @@ class TestResponderVrf(TestResponderPsk, Ikev2Params):
self.assertEqual(plain, b"")
-@tag_fixme_vpp_workers
class TestResponderRsaSign(TemplateResponder, Ikev2Params):
"""test ikev2 responder - cert based auth"""
+ vpp_worker_count = 2
+
def config_tc(self):
self.config_params(
{
@@ -2459,7 +2463,6 @@ class TestResponderRsaSign(TemplateResponder, Ikev2Params):
)
-@tag_fixme_vpp_workers
class Test_IKE_AES_CBC_128_SHA256_128_MODP2048_ESP_AES_CBC_192_SHA_384_192(
TemplateResponder, Ikev2Params
):
@@ -2467,6 +2470,8 @@ class Test_IKE_AES_CBC_128_SHA256_128_MODP2048_ESP_AES_CBC_192_SHA_384_192(
IKE:AES_CBC_128_SHA256_128,DH=modp2048 ESP:AES_CBC_192_SHA_384_192
"""
+ vpp_worker_count = 2
+
def config_tc(self):
self.config_params(
{
@@ -2481,7 +2486,6 @@ class Test_IKE_AES_CBC_128_SHA256_128_MODP2048_ESP_AES_CBC_192_SHA_384_192(
)
-@tag_fixme_vpp_workers
class TestAES_CBC_128_SHA256_128_MODP3072_ESP_AES_GCM_16(
TemplateResponder, Ikev2Params
):
@@ -2489,6 +2493,8 @@ class TestAES_CBC_128_SHA256_128_MODP3072_ESP_AES_GCM_16(
IKE:AES_CBC_128_SHA256_128,DH=modp3072 ESP:AES_GCM_16
"""
+ vpp_worker_count = 2
+
def config_tc(self):
self.config_params(
{
@@ -2501,13 +2507,13 @@ class TestAES_CBC_128_SHA256_128_MODP3072_ESP_AES_GCM_16(
)
-@tag_fixme_vpp_workers
class Test_IKE_AES_GCM_16_256(TemplateResponder, Ikev2Params):
"""
IKE:AES_GCM_16_256
"""
IKE_NODE_SUFFIX = "ip6"
+ vpp_worker_count = 2
def config_tc(self):
self.config_params(
@@ -2524,12 +2530,13 @@ class Test_IKE_AES_GCM_16_256(TemplateResponder, Ikev2Params):
)
-@tag_fixme_vpp_workers
class TestInitiatorKeepaliveMsg(TestInitiatorPsk):
"""
Test for keep alive messages
"""
+ vpp_worker_count = 2
+
def send_empty_req_from_responder(self):
packet = self.create_empty_request()
self.pg0.add_stream(packet)
diff --git a/test/test_interface_crud.py b/test/test_interface_crud.py
index c88759d9b59..6565d23a8b6 100644
--- a/test/test_interface_crud.py
+++ b/test/test_interface_crud.py
@@ -18,6 +18,7 @@ from scapy.layers.l2 import Ether
from framework import VppTestCase
from asfframework import VppTestRunner
+from config import config
class TestLoopbackInterfaceCRUD(VppTestCase):
@@ -81,6 +82,9 @@ class TestLoopbackInterfaceCRUD(VppTestCase):
info = (i.local_ip4, request_src_if.remote_ip4, 0, i.sw_if_index)
self.assertIn(info, rcvd_icmp_pkts)
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_crud(self):
# create
loopbacks = self.create_loopback_interfaces(20)
diff --git a/test/test_ip4.py b/test/test_ip4.py
index 926ca77a5f8..150ea629308 100644
--- a/test/test_ip4.py
+++ b/test/test_ip4.py
@@ -34,6 +34,7 @@ from vpp_papi import vpp_papi, VppEnum
from vpp_neighbor import VppNeighbor
from vpp_lo_interface import VppLoInterface
from vpp_policer import VppPolicer, PolicerAction
+from config import config
NUM_PKTS = 67
@@ -244,12 +245,13 @@ class TestIPv4RouteLookup(VppTestCase):
"""IPv4 Route Lookup Test Case"""
routes = []
+ tables = []
- def route_lookup(self, prefix, exact):
+ def route_lookup(self, prefix, exact, table_id=0):
return self.vapi.api(
self.vapi.papi.ip_route_lookup,
{
- "table_id": 0,
+ "table_id": table_id,
"exact": exact,
"prefix": prefix,
},
@@ -283,11 +285,30 @@ class TestIPv4RouteLookup(VppTestCase):
r.add_vpp_config()
self.routes.append(r)
+ custom_vrf = VppIpTable(self, 200)
+ custom_vrf.add_vpp_config()
+ self.tables.append(custom_vrf)
+
+ r = VppIpRoute(self, "2.2.0.0", 16, [drop_nh], 200)
+ r.add_vpp_config()
+ self.routes.append(r)
+
+ r = VppIpRoute(self, "2.2.2.0", 24, [drop_nh], 200)
+ r.add_vpp_config()
+ self.routes.append(r)
+
+ r = VppIpRoute(self, "2.2.2.2", 32, [drop_nh], 200)
+ r.add_vpp_config()
+ self.routes.append(r)
+
def tearDown(self):
# Remove the routes we added
for r in self.routes:
r.remove_vpp_config()
+ for vrf in self.tables:
+ vrf.remove_vpp_config()
+
super(TestIPv4RouteLookup, self).tearDown()
def test_exact_match(self):
@@ -305,6 +326,20 @@ class TestIPv4RouteLookup(VppTestCase):
with self.vapi.assert_negative_api_retval():
self.route_lookup("1.1.1.2/32", True)
+ # Verify we find the host route
+ prefix = "2.2.2.2/32"
+ result = self.route_lookup(prefix, True, 200)
+ assert prefix == str(result.route.prefix)
+
+ # Verify we find a middle prefix route
+ prefix = "2.2.2.0/24"
+ result = self.route_lookup(prefix, True, 200)
+ assert prefix == str(result.route.prefix)
+
+ # Verify we do not find an available LPM.
+ with self.vapi.assert_negative_api_retval():
+ self.route_lookup("2.2.2.1/32", True, 200)
+
def test_longest_prefix_match(self):
# verify we find lpm
lpm_prefix = "1.1.1.0/24"
@@ -315,6 +350,15 @@ class TestIPv4RouteLookup(VppTestCase):
result = self.route_lookup(lpm_prefix, False)
assert lpm_prefix == str(result.route.prefix)
+ # verify we find lpm
+ lpm_prefix = "2.2.2.0/24"
+ result = self.route_lookup("2.2.2.1/32", False, 200)
+ assert lpm_prefix == str(result.route.prefix)
+
+ # Verify we find the exact when not requested
+ result = self.route_lookup(lpm_prefix, False, 200)
+ assert lpm_prefix == str(result.route.prefix)
+
# Can't seem to delete the default route so no negative LPM test.
@@ -459,6 +503,9 @@ class TestIPv4IfAddrRoute(VppTestCase):
)
+@unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+)
class TestICMPEcho(VppTestCase):
"""ICMP Echo Test Case"""
@@ -929,6 +976,19 @@ class TestIPNull(VppTestCase):
r2.remove_vpp_config()
rx = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1)
+ t = VppIpTable(self, 2, False)
+ t.add_vpp_config()
+ r3 = VppIpRoute(
+ self,
+ "1.1.1.0",
+ 31,
+ [VppRoutePath("0.0.0.0", 0xFFFFFFFF, type=FibPathType.FIB_PATH_TYPE_DROP)],
+ table_id=2,
+ )
+ r3.add_vpp_config()
+ r3.remove_vpp_config()
+ t.remove_vpp_config()
+
class TestIPDisabled(VppTestCase):
"""IPv4 disabled"""
@@ -1396,7 +1456,7 @@ class TestIPLoadBalance(VppTestCase):
src_pkts.append(
(
Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
- / IP(dst="1.1.1.1", src="20.0.0.%d" % ii)
+ / IP(dst="1.1.1.1", src="20.0.0.%d" % (ii % 256))
/ UDP(sport=1234, dport=1234)
/ Raw(b"\xa5" * 100)
)
diff --git a/test/test_ip4_vrf_multi_instance.py b/test/test_ip4_vrf_multi_instance.py
index cbda790637b..318a4a81f44 100644
--- a/test/test_ip4_vrf_multi_instance.py
+++ b/test/test_ip4_vrf_multi_instance.py
@@ -195,7 +195,7 @@ class TestIp4VrfMultiInst(VppTestCase):
for i in range(count):
vrf_id = i + start
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id})
self.logger.info("IPv4 VRF ID %d created" % vrf_id)
if vrf_id not in self.vrf_list:
self.vrf_list.append(vrf_id)
@@ -249,7 +249,7 @@ class TestIp4VrfMultiInst(VppTestCase):
self.logger.info("IPv4 VRF ID %d reset finished" % vrf_id)
self.logger.debug(self.vapi.ppcli("show ip fib"))
self.logger.debug(self.vapi.ppcli("show ip neighbors"))
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id})
def create_stream(self, src_if, packet_sizes):
"""
diff --git a/test/test_ip6.py b/test/test_ip6.py
index 84b060aa7a3..25f2c623a0b 100644
--- a/test/test_ip6.py
+++ b/test/test_ip6.py
@@ -67,6 +67,7 @@ from vpp_policer import VppPolicer, PolicerAction
from ipaddress import IPv6Network, IPv6Address
from vpp_gre_interface import VppGreInterface
from vpp_teib import VppTeib
+from config import config
AF_INET6 = socket.AF_INET6
@@ -1368,6 +1369,9 @@ class TestIPv6IfAddrRoute(VppTestCase):
)
+@unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+)
class TestICMPv6Echo(VppTestCase):
"""ICMPv6 Echo Test Case"""
@@ -3324,6 +3328,9 @@ class TestIP6AddrReplace(VppTestCase):
self.assertTrue(pfx.query_vpp_config())
+@unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+)
class TestIP6LinkLocal(VppTestCase):
"""IPv6 Link Local"""
@@ -3416,6 +3423,9 @@ class TestIP6LinkLocal(VppTestCase):
p_echo_request_3.dst = self.pg1.local_mac
self.send_and_expect(self.pg1, [p_echo_request_3], self.pg1)
+ @unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests requiring GRE plugin"
+ )
def test_ip6_ll_p2p(self):
"""IPv6 Link Local P2P (GRE)"""
@@ -3445,6 +3455,9 @@ class TestIP6LinkLocal(VppTestCase):
self.pg0.unconfig_ip4()
gre_if.remove_vpp_config()
+ @unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests requiring GRE plugin"
+ )
def test_ip6_ll_p2mp(self):
"""IPv6 Link Local P2MP (GRE)"""
diff --git a/test/test_ip6_nd_mirror_proxy.py b/test/test_ip6_nd_mirror_proxy.py
index 10dc77e1a86..e94309e8b50 100644
--- a/test/test_ip6_nd_mirror_proxy.py
+++ b/test/test_ip6_nd_mirror_proxy.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
import unittest
-from socket import inet_pton, inet_ntop
+from socket import inet_pton, inet_ntop, AF_INET6
from framework import VppTestCase
from asfframework import VppTestRunner
@@ -59,8 +59,8 @@ class TestNDPROXY(VppTestCase):
# will come from the VPP's own address.
#
addr = self.pg0.remote_ip6
- nsma = in6_getnsma(inet_pton(socket.AF_INET6, addr))
- d = inet_ntop(socket.AF_INET6, nsma)
+ nsma = in6_getnsma(inet_pton(AF_INET6, addr))
+ d = inet_ntop(AF_INET6, nsma)
# Make pg1 un-numbered to pg0
#
diff --git a/test/test_ip6_vrf_multi_instance.py b/test/test_ip6_vrf_multi_instance.py
index da3de8e6100..26519b129cf 100644
--- a/test/test_ip6_vrf_multi_instance.py
+++ b/test/test_ip6_vrf_multi_instance.py
@@ -213,7 +213,7 @@ class TestIP6VrfMultiInst(VppTestCase):
"""
for i in range(count):
vrf_id = i + start
- self.vapi.ip_table_add_del(
+ self.vapi.ip_table_add_del_v2(
is_add=1, table={"table_id": vrf_id, "is_ip6": 1}
)
self.logger.info("IPv6 VRF ID %d created" % vrf_id)
@@ -276,7 +276,7 @@ class TestIP6VrfMultiInst(VppTestCase):
self.vrf_list.remove(vrf_id)
if vrf_id in self.vrf_reset_list:
self.vrf_reset_list.remove(vrf_id)
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id, "is_ip6": 1})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id, "is_ip6": 1})
def create_stream(self, src_if, packet_sizes):
"""
diff --git a/test/test_ip_mcast.py b/test/test_ip_mcast.py
index 564b4231da9..682e7699210 100644
--- a/test/test_ip_mcast.py
+++ b/test/test_ip_mcast.py
@@ -14,6 +14,7 @@ from vpp_ip_route import (
)
from vpp_gre_interface import VppGreInterface
from vpp_papi import VppEnum
+from config import config
from scapy.packet import Raw
from scapy.layers.l2 import Ether, GRE
@@ -884,6 +885,9 @@ class TestIPMcast(VppTestCase):
signals = self.vapi.mfib_signal_dump()
self.assertEqual(0, len(signals))
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_ip_mcast_vrf(self):
"""IP Multicast Replication in non-default table"""
@@ -976,6 +980,9 @@ class TestIPMcast(VppTestCase):
self.send_and_expect(self.pg8, tx, self.pg8)
+ @unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests requiring GRE plugin"
+ )
def test_ip_mcast_gre(self):
"""IP Multicast Replication over GRE"""
@@ -1056,6 +1063,9 @@ class TestIPMcast(VppTestCase):
self.assertEqual(rx[IP].dst, gre_if_3.t_dst)
self.assert_packet_checksums_valid(rx)
+ @unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests requiring GRE plugin"
+ )
def test_ip6_mcast_gre(self):
"""IP6 Multicast Replication over GRE"""
diff --git a/test/test_ip_session_redirect.py b/test/test_ip_session_redirect.py
index 620b21626a9..3fed62bfade 100644
--- a/test/test_ip_session_redirect.py
+++ b/test/test_ip_session_redirect.py
@@ -13,8 +13,13 @@ from vpp_papi import VppEnum
from vpp_ip_route import VppRoutePath
from framework import VppTestCase
+from config import config
+@unittest.skipIf(
+ "ip_session_redirect" in config.excluded_plugins,
+ "Exclude IP session redirect plugin tests",
+)
class TestIpSessionRedirect(VppTestCase):
"""IP session redirect Test Case"""
diff --git a/test/test_ipip.py b/test/test_ipip.py
index 9574c2c299c..85b35fa7f24 100644
--- a/test/test_ipip.py
+++ b/test/test_ipip.py
@@ -88,7 +88,7 @@ class TestIPIP(VppTestCase):
self.table.remove_vpp_config()
def validate(self, rx, expected):
- self.assertEqual(rx, expected.__class__(expected))
+ self.assertTrue(bytes(rx), bytes(expected))
def generate_ip4_frags(self, payload_length, fragment_size):
p_ether = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
@@ -764,7 +764,7 @@ class TestIPIP6(VppTestCase):
rv = self.vapi.ipip_del_tunnel(sw_if_index=self.tunnel_if_index)
def validate(self, rx, expected):
- self.assertEqual(rx, expected.__class__(expected))
+ self.assertTrue(bytes(rx), bytes(expected))
def generate_ip6_frags(self, payload_length, fragment_size):
p_ether = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
diff --git a/test/test_ipsec_ah.py b/test/test_ipsec_ah.py
index 8fece500907..bc31a87abb0 100644
--- a/test/test_ipsec_ah.py
+++ b/test/test_ipsec_ah.py
@@ -28,6 +28,7 @@ from vpp_ipsec import VppIpsecSA, VppIpsecSpd, VppIpsecSpdEntry, VppIpsecSpdItfB
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_ip import DpoProto
from vpp_papi import VppEnum
+from config import config
class ConfigIpsecAH(TemplateIpsec):
@@ -526,6 +527,9 @@ class TestIpsecAhAll(ConfigIpsecAH, IpsecTra4, IpsecTra6, IpsecTun4, IpsecTun6):
def tearDown(self):
super(TestIpsecAhAll, self).tearDown()
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_integ_algs(self):
"""All Engines SHA[1_96, 256, 384, 512] w/ & w/o ESN"""
# foreach VPP crypto engine
diff --git a/test/test_ipsec_esp.py b/test/test_ipsec_esp.py
index 4e1957d8b53..bfdef2a78d7 100644
--- a/test/test_ipsec_esp.py
+++ b/test/test_ipsec_esp.py
@@ -1,4 +1,5 @@
import socket
+import unittest
from scapy.layers.ipsec import ESP
from scapy.layers.inet import IP, ICMP, UDP
from scapy.layers.inet6 import IPv6
@@ -27,6 +28,7 @@ from vpp_ipsec import VppIpsecSpd, VppIpsecSpdEntry, VppIpsecSA, VppIpsecSpdItfB
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_ip import DpoProto
from vpp_papi import VppEnum
+from config import config
NUM_PKTS = 67
engines_supporting_chain_bufs = ["openssl", "async"]
@@ -1075,6 +1077,9 @@ class MyParameters:
}
+@unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+)
class RunTestIpsecEspAll(ConfigIpsecESP, IpsecTra4, IpsecTra6, IpsecTun4, IpsecTun6):
"""Ipsec ESP all Algos"""
diff --git a/test/test_ipsec_spd_flow_cache_input.py b/test/test_ipsec_spd_flow_cache_input.py
index 283f345be18..b913a980599 100644
--- a/test/test_ipsec_spd_flow_cache_input.py
+++ b/test/test_ipsec_spd_flow_cache_input.py
@@ -785,9 +785,9 @@ class IPSec4SpdTestCaseCollisionInbound(SpdFlowCacheInbound):
# create the packet streams
# packet hashes to:
# ad727628
- packets1 = self.create_stream(self.pg2, self.pg1, pkt_count, 1, 1)
+ packets1 = self.create_stream(self.pg2, self.pg1, pkt_count, 1, 4500)
# b5512898
- packets2 = self.create_stream(self.pg0, self.pg3, pkt_count, 1, 1)
+ packets2 = self.create_stream(self.pg0, self.pg3, pkt_count, 1, 4500)
# add the streams to the source interfaces
self.pg2.add_stream(packets1)
self.pg0.add_stream(packets2)
@@ -821,9 +821,9 @@ class IPSec4SpdTestCaseCollisionInbound(SpdFlowCacheInbound):
# create the packet streams
# 2f8f90f557eef12c
- packets1 = self.create_stream(self.pg2, self.pg1, pkt_count, 1, 1)
+ packets1 = self.create_stream(self.pg2, self.pg1, pkt_count, 1, 4500)
# 6b7f9987719ffc1c
- packets2 = self.create_stream(self.pg3, self.pg2, pkt_count, 1, 1)
+ packets2 = self.create_stream(self.pg3, self.pg2, pkt_count, 1, 4500)
# add the streams to the source interfaces
self.pg2.add_stream(packets1)
self.pg3.add_stream(packets2)
diff --git a/test/test_ipsec_spd_fp_input.py b/test/test_ipsec_spd_fp_input.py
index ec4a7c71d7b..eb04df49244 100644
--- a/test/test_ipsec_spd_fp_input.py
+++ b/test/test_ipsec_spd_fp_input.py
@@ -8,6 +8,7 @@ from template_ipsec import IPSecIPv4Fwd
from template_ipsec import IPSecIPv6Fwd
from test_ipsec_esp import TemplateIpsecEsp
from template_ipsec import SpdFastPathTemplate
+from config import config
def debug_signal_handler(signal, frame):
@@ -242,6 +243,9 @@ class IPSec4SpdTestCaseDiscard(SpdFastPathInbound):
self.verify_policy_match(0, policy_1)
+@unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+)
class IPSec4SpdTestCaseProtect(SpdFastPathInboundProtect):
""" IPSec/IPv4 inbound: Policy mode test case with fast path \
(add protect)"""
@@ -830,6 +834,9 @@ class IPSec4SpdTestCaseMultiple(SpdFastPathInbound):
self.verify_policy_match(0, policy_22)
+@unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+)
class IPSec6SpdTestCaseProtect(SpdFastPathIPv6InboundProtect):
""" IPSec/IPv6 inbound: Policy mode test case with fast path \
(add protect)"""
diff --git a/test/test_ipsec_tun_if_esp.py b/test/test_ipsec_tun_if_esp.py
index a7f91b9e967..cda52dc64c2 100644
--- a/test/test_ipsec_tun_if_esp.py
+++ b/test/test_ipsec_tun_if_esp.py
@@ -4,7 +4,7 @@ import copy
from scapy.layers.ipsec import SecurityAssociation, ESP
from scapy.layers.l2 import Ether, GRE, Dot1Q
-from scapy.packet import Raw, bind_layers
+from scapy.packet import Raw, bind_layers, Padding
from scapy.layers.inet import IP, UDP, ICMP
from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
from scapy.contrib.mpls import MPLS
@@ -41,6 +41,7 @@ from vpp_papi import VppEnum
from vpp_papi_provider import CliFailedCommandError
from vpp_acl import AclRule, VppAcl, VppAclInterface
from vpp_policer import PolicerAction, VppPolicer, Dir
+from config import config
def config_tun_params(p, encryption_type, tun_if, src=None, dst=None):
@@ -1309,6 +1310,9 @@ class TestIpsec6MultiTunIfEsp(TemplateIpsec6TunProtect, TemplateIpsec, IpsecTun6
self.assertEqual(p.tun_if.get_tx_stats(), 127)
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecGreTebIfEsp(TemplateIpsec, IpsecTun4Tests):
"""Ipsec GRE TEB ESP - TUN tests"""
@@ -1433,6 +1437,9 @@ class TestIpsecGreTebIfEsp(TemplateIpsec, IpsecTun4Tests):
super(TestIpsecGreTebIfEsp, self).tearDown()
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecGreTebVlanIfEsp(TemplateIpsec, IpsecTun4Tests):
"""Ipsec GRE TEB ESP - TUN tests"""
@@ -1568,6 +1575,9 @@ class TestIpsecGreTebVlanIfEsp(TemplateIpsec, IpsecTun4Tests):
self.pg1_11.remove_vpp_config()
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecGreTebIfEspTra(TemplateIpsec, IpsecTun4Tests):
"""Ipsec GRE TEB ESP - Tra tests"""
@@ -1686,6 +1696,9 @@ class TestIpsecGreTebIfEspTra(TemplateIpsec, IpsecTun4Tests):
super(TestIpsecGreTebIfEspTra, self).tearDown()
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecGreTebUdpIfEspTra(TemplateIpsec, IpsecTun4Tests):
"""Ipsec GRE TEB UDP ESP - Tra tests"""
@@ -1819,6 +1832,9 @@ class TestIpsecGreTebUdpIfEspTra(TemplateIpsec, IpsecTun4Tests):
super(TestIpsecGreTebUdpIfEspTra, self).tearDown()
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecGreIfEsp(TemplateIpsec, IpsecTun4Tests):
"""Ipsec GRE ESP - TUN tests"""
@@ -1931,6 +1947,9 @@ class TestIpsecGreIfEsp(TemplateIpsec, IpsecTun4Tests):
super(TestIpsecGreIfEsp, self).tearDown()
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecGreIfEspTra(TemplateIpsec, IpsecTun4Tests):
"""Ipsec GRE ESP - TRA tests"""
@@ -2060,6 +2079,9 @@ class TestIpsecGreIfEspTra(TemplateIpsec, IpsecTun4Tests):
self.assertEqual(err, 1)
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecGre6IfEspTra(TemplateIpsec, IpsecTun6Tests):
"""Ipsec GRE ESP - TRA tests"""
@@ -2174,6 +2196,9 @@ class TestIpsecGre6IfEspTra(TemplateIpsec, IpsecTun6Tests):
super(TestIpsecGre6IfEspTra, self).tearDown()
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecMGreIfEspTra4(TemplateIpsec, IpsecTun4):
"""Ipsec mGRE ESP v4 TRA tests"""
@@ -2329,6 +2354,9 @@ class TestIpsecMGreIfEspTra4(TemplateIpsec, IpsecTun4):
self.verify_tun_44(p, count=N_PKTS)
+@unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests depending on GRE plugin"
+)
class TestIpsecMGreIfEspTra6(TemplateIpsec, IpsecTun6):
"""Ipsec mGRE ESP v6 TRA tests"""
@@ -2591,6 +2619,9 @@ class TestIpsec4TunProtectUdpTfc(TemplateIpsec4TunTfc, TestIpsec4TunProtectUdp):
@tag_fixme_vpp_workers
+@unittest.skipIf(
+ "acl" in config.excluded_plugins, "Exclude tests depending on ACL plugin"
+)
class TestIpsec4TunProtectTun(TemplateIpsec, TemplateIpsec4TunProtect, IpsecTun4):
"""IPsec IPv4 Tunnel protect - tunnel mode"""
@@ -3607,6 +3638,9 @@ class TestIpsecItf6Tfc(TemplateIpsec6TunTfc, TestIpsecItf6):
"""IPsec Interface IPv6 with TFC"""
+@unittest.skipIf(
+ "acl" in config.excluded_plugins, "Exclude tests depending on ACL plugin"
+)
class TestIpsecMIfEsp4(TemplateIpsec, IpsecTun4):
"""Ipsec P2MP ESP v4 tests"""
diff --git a/test/test_l2tp.py b/test/test_l2tp.py
index 172b0b8e0b8..34022629cc6 100644
--- a/test/test_l2tp.py
+++ b/test/test_l2tp.py
@@ -5,9 +5,13 @@ from scapy.layers.inet6 import IPv6
from asfframework import tag_fixme_vpp_workers
from framework import VppTestCase
+from config import config
+
+import unittest
@tag_fixme_vpp_workers
+@unittest.skipIf("l2tp" in config.excluded_plugins, "Exclude L2TP plugin tests")
class TestL2tp(VppTestCase):
"""L2TP Test Case"""
diff --git a/test/test_l3xc.py b/test/test_l3xc.py
index 69267b35817..d94292e5be4 100644
--- a/test/test_l3xc.py
+++ b/test/test_l3xc.py
@@ -11,6 +11,7 @@ from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from vpp_object import VppObject
+from config import config
NUM_PKTS = 67
@@ -56,6 +57,7 @@ class VppL3xc(VppObject):
return "l3xc-%d" % self.intf.sw_if_index
+@unittest.skipIf("l3xc" in config.excluded_plugins, "Exclude L3XC plugin tests")
class TestL3xc(VppTestCase):
"""L3XC Test Case"""
diff --git a/test/test_lacp.py b/test/test_lacp.py
index af209501184..d8739775f27 100644
--- a/test/test_lacp.py
+++ b/test/test_lacp.py
@@ -10,12 +10,14 @@ from asfframework import VppTestRunner
from vpp_memif import VppSocketFilename, VppMemif
from vpp_bond_interface import VppBondInterface
from vpp_papi import VppEnum
+from config import config
bond_mac = "02:02:02:02:02:02"
lacp_dst_mac = "01:80:c2:00:00:02"
LACP_COLLECTION_AND_DISTRIBUTION_STATE = 63
+@unittest.skipIf("lacp" in config.excluded_plugins, "Exclude LACP plugin tests")
class TestMarker(VppTestCase):
"""LACP Marker Protocol Test Case"""
@@ -147,6 +149,7 @@ class TestMarker(VppTestCase):
bond1.remove_vpp_config()
+@unittest.skipIf("lacp" in config.excluded_plugins, "Exclude LACP plugin tests")
class TestLACP(VppTestCase):
"""LACP Test Case"""
diff --git a/test/test_lb.py b/test/test_lb.py
index e44684ecf2b..fc1674aeedf 100644
--- a/test/test_lb.py
+++ b/test/test_lb.py
@@ -11,6 +11,8 @@ from framework import VppTestCase
from util import ppp
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_ip import INVALID_INDEX
+from config import config
+import unittest
""" TestLB is a subclass of VPPTestCase classes.
@@ -32,6 +34,7 @@ from vpp_ip import INVALID_INDEX
"""
+@unittest.skipIf("lb" in config.excluded_plugins, "Exclude LB plugin tests")
class TestLB(VppTestCase):
"""Load Balancer Test Case"""
diff --git a/test/test_linux_cp.py b/test/test_linux_cp.py
index 95a9f1aca1f..ff6023cea26 100644
--- a/test/test_linux_cp.py
+++ b/test/test_linux_cp.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import unittest
+import socket
from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6, Raw
@@ -20,6 +21,7 @@ from template_ipsec import (
IpsecTun4,
)
from test_ipsec_tun_if_esp import TemplateIpsecItf4
+from config import config
class VppLcpPair(VppObject):
@@ -51,6 +53,7 @@ class VppLcpPair(VppObject):
return False
+@unittest.skipIf("linux-cp" in config.excluded_plugins, "Exclude linux-cp plugin tests")
class TestLinuxCP(VppTestCase):
"""Linux Control Plane"""
@@ -239,7 +242,7 @@ class TestLinuxCP(VppTestCase):
self.assertEqual(rx[Ether].dst, phy.remote_mac)
self.assertEqual(rx[IP].dst, phy.remote_ip4)
self.assertEqual(rx[IP].src, phy.local_ip4)
- inner = IP(rx[IP].payload)
+ inner = IP(bytes(rx[IP].payload))
self.assertEqual(inner.src, tun4.local_ip4)
self.assertEqual(inner.dst, "2.2.2.2")
@@ -252,7 +255,7 @@ class TestLinuxCP(VppTestCase):
for rx in rxs:
self.assertEqual(rx[IPv6].dst, phy.remote_ip6)
self.assertEqual(rx[IPv6].src, phy.local_ip6)
- inner = IPv6(rx[IPv6].payload)
+ inner = IPv6(bytes(rx[IPv6].payload))
self.assertEqual(inner.src, tun6.local_ip6)
self.assertEqual(inner.dst, "2::2")
@@ -267,7 +270,7 @@ class TestLinuxCP(VppTestCase):
rxs = self.send_and_expect(phy, p * N_PKTS, self.pg4)
for rx in rxs:
- rx = IP(rx)
+ rx = IP(bytes(rx))
self.assertEqual(rx[IP].dst, tun4.local_ip4)
self.assertEqual(rx[IP].src, tun4.remote_ip4)
@@ -282,7 +285,7 @@ class TestLinuxCP(VppTestCase):
rxs = self.send_and_expect(phy, p * N_PKTS, self.pg5)
for rx in rxs:
- rx = IPv6(rx)
+ rx = IPv6(bytes(rx))
self.assertEqual(rx[IPv6].dst, tun6.local_ip6)
self.assertEqual(rx[IPv6].src, tun6.remote_ip6)
@@ -294,6 +297,7 @@ class TestLinuxCP(VppTestCase):
tun6.unconfig_ip6()
+@unittest.skipIf("linux-cp" in config.excluded_plugins, "Exclude linux-cp plugin tests")
class TestLinuxCPIpsec(TemplateIpsec, TemplateIpsecItf4, IpsecTun4):
"""IPsec Interface IPv4"""
@@ -350,7 +354,7 @@ class TestLinuxCPIpsec(TemplateIpsec, TemplateIpsecItf4, IpsecTun4):
def verify_decrypted(self, p, rxs):
for rx in rxs:
- rx = IP(rx)
+ rx = IP(bytes(rx))
self.assert_equal(rx[IP].src, p.tun_if.remote_ip4)
self.assert_equal(rx[IP].dst, p.tun_if.local_ip4)
self.assert_packet_checksums_valid(rx)
diff --git a/test/test_lisp.py b/test/test_lisp.py
index edc316ea7b2..7b6560eb3c2 100644
--- a/test/test_lisp.py
+++ b/test/test_lisp.py
@@ -19,6 +19,7 @@ from lisp import (
LispRemoteLocator,
)
from util import ppp
+from config import config
# From py_lispnetworking.lisp.py: # GNU General Public License v2.0
@@ -157,6 +158,7 @@ class SimpleDriver(Driver):
self.test.pg0.assert_nothing_captured()
+@unittest.skipIf("lisp" in config.excluded_plugins, "Exclude LISP plugin tests")
class TestLisp(VppTestCase):
"""Basic LISP test"""
@@ -206,6 +208,7 @@ class TestLisp(VppTestCase):
self.test_driver.run(self.deid_ip4)
+@unittest.skipIf("lisp" in config.excluded_plugins, "Exclude LISP plugin tests")
class TestLispUT(VppTestCase):
"""Lisp UT"""
diff --git a/test/test_lldp.py b/test/test_lldp.py
index 0a69be7c7b1..8b3f4cf1da2 100644
--- a/test/test_lldp.py
+++ b/test/test_lldp.py
@@ -96,6 +96,7 @@ class TestLldpCli(VppTestCase):
self.assertNotIn("pg0", reply)
+@unittest.skipIf("lldp" in config.excluded_plugins, "Exclude lldp plugin tests")
class TestLldpVapi(VppTestCase):
"""LLDP plugin test [VAPI]"""
diff --git a/test/test_map.py b/test/test_map.py
index c65c5df7cda..ffa9218b0c3 100644
--- a/test/test_map.py
+++ b/test/test_map.py
@@ -8,6 +8,7 @@ from asfframework import VppTestRunner
from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath
from util import fragment_rfc791, fragment_rfc8200
+from config import config
import scapy.compat
from scapy.layers.l2 import Ether
@@ -22,6 +23,7 @@ from scapy.layers.inet6 import (
)
+@unittest.skipIf("map" in config.excluded_plugins, "Exclude MAP plugin tests")
class TestMAP(VppTestCase):
"""MAP Test Case"""
diff --git a/test/test_map_br.py b/test/test_map_br.py
index a2c00d8d8ea..1f1bcccf792 100644
--- a/test/test_map_br.py
+++ b/test/test_map_br.py
@@ -5,6 +5,7 @@ import unittest
from framework import VppTestCase
from asfframework import VppTestRunner
from vpp_ip_route import VppIpRoute, VppRoutePath
+from config import config
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP, ICMP, TCP, IPerror, UDPerror
@@ -12,6 +13,7 @@ from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded, ICMPv6PacketTooBig
from scapy.layers.inet6 import ICMPv6EchoRequest, ICMPv6EchoReply, IPerror6
+@unittest.skipIf("map" in config.excluded_plugins, "Exclude MAP plugin tests")
class TestMAPBR(VppTestCase):
"""MAP-T Test Cases"""
diff --git a/test/test_memif.py b/test/test_memif.py
index 904343f2775..743c855b943 100644
--- a/test/test_memif.py
+++ b/test/test_memif.py
@@ -14,10 +14,12 @@ from remote_test import RemoteClass, RemoteVppTestCase
from vpp_memif import remove_all_memif_vpp_config, VppSocketFilename, VppMemif
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_papi import VppEnum
+from config import config
@tag_run_solo
@tag_fixme_debian11
+@unittest.skipIf("memif" in config.excluded_plugins, "Exclude Memif plugin tests")
class TestMemif(VppTestCase):
"""Memif Test Case"""
diff --git a/test/test_mpls.py b/test/test_mpls.py
index 0e747ec7cd0..daa0d967d2e 100644
--- a/test/test_mpls.py
+++ b/test/test_mpls.py
@@ -25,6 +25,7 @@ from vpp_ip_route import (
)
from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
from vpp_papi import VppEnum
+from config import config
import scapy.compat
from scapy.packet import Raw
@@ -1520,6 +1521,9 @@ class TestMPLS(VppTestCase):
rx = self.send_and_expect(self.pg1, tx, self.pg1)
self.verify_capture_ip6(self.pg0, rx, tx)
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_deag(self):
"""MPLS Deagg"""
diff --git a/test/test_mtu.py b/test/test_mtu.py
index 6735cc602a8..c5fb4278dfc 100644
--- a/test/test_mtu.py
+++ b/test/test_mtu.py
@@ -55,7 +55,7 @@ class TestMTU(VppTestCase):
i.admin_down()
def validate(self, rx, expected):
- self.assertEqual(rx, expected.__class__(expected))
+ self.assertTrue(bytes(rx), bytes(expected))
def validate_bytes(self, rx, expected):
self.assertEqual(rx, expected)
@@ -104,13 +104,10 @@ class TestMTU(VppTestCase):
/ p_ip4
/ p_payload
)
- n = icmp4_reply.__class__(icmp4_reply)
s = bytes(icmp4_reply)
icmp4_reply = s[0:576]
rx = self.send_and_expect_some(self.pg0, p4 * 11, self.pg0)
for p in rx:
- # p.show2()
- # n.show2()
self.validate_bytes(bytes(p[1]), icmp4_reply)
self.assert_error_counter_equal("/err/ip4-input/mtu_exceeded", 11)
@@ -185,7 +182,6 @@ class TestMTU(VppTestCase):
/ p_payload
)
icmp6_reply[2].hlim -= 1
- n = icmp6_reply.__class__(icmp6_reply)
s = bytes(icmp6_reply)
icmp6_reply_str = s[0:1280]
diff --git a/test/test_nat44_ed.py b/test/test_nat44_ed.py
index eed89f1a399..7615312ac31 100644
--- a/test/test_nat44_ed.py
+++ b/test/test_nat44_ed.py
@@ -21,8 +21,10 @@ from vpp_acl import AclRule, VppAcl, VppAclInterface
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_papi import VppEnum
from util import StatsDiff
+from config import config
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestNAT44ED(VppTestCase):
"""NAT44ED Test Case"""
@@ -90,7 +92,7 @@ class TestNAT44ED(VppTestCase):
@classmethod
def create_and_add_ip4_table(cls, i, table_id=0):
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": table_id})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": table_id})
i.set_table_ip4(table_id)
@classmethod
@@ -162,8 +164,6 @@ class TestNAT44ED(VppTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- if is_distro_ubuntu2204 == True and not hasattr(cls, "vpp"):
- return
cls.create_pg_interfaces(range(12))
cls.interfaces = list(cls.pg_interfaces[:4])
@@ -174,7 +174,7 @@ class TestNAT44ED(VppTestCase):
cls.configure_ip4_interface(i, hosts=3)
# test specific (test-multiple-vrf)
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 1})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 1})
# test specific (test-one-armed-nat44-static)
cls.pg4.generate_remote_hosts(2)
@@ -2607,6 +2607,7 @@ class TestNAT44ED(VppTestCase):
@tag_fixme_ubuntu2204
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestNAT44EDMW(TestNAT44ED):
"""NAT44ED MW Test Case"""
@@ -4399,8 +4400,8 @@ class TestNAT44EDMW(TestNAT44ED):
self.pg7.unconfig()
self.pg8.unconfig()
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id_in})
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id_out})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id_in})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id_out})
def test_dynamic_output_feature_vrf(self):
"""NAT44ED dynamic translation test: output-feature, VRF"""
@@ -4469,7 +4470,7 @@ class TestNAT44EDMW(TestNAT44ED):
self.pg7.unconfig()
self.pg8.unconfig()
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": new_vrf_id})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": new_vrf_id})
def test_next_src_nat(self):
"""NAT44ED On way back forward packet to nat44-in2out node."""
diff --git a/test/test_nat44_ed_output.py b/test/test_nat44_ed_output.py
index dbf1dc40a75..55c43196295 100644
--- a/test/test_nat44_ed_output.py
+++ b/test/test_nat44_ed_output.py
@@ -3,12 +3,15 @@
import random
import unittest
+import struct
+import socket
from scapy.layers.inet import Ether, IP, TCP
from scapy.packet import Raw
from scapy.data import IP_PROTOS
from framework import VppTestCase
from asfframework import VppTestRunner
from vpp_papi import VppEnum
+from config import config
def get_nat44_ed_in2out_worker_index(ip, vpp_worker_count):
@@ -21,6 +24,7 @@ def get_nat44_ed_in2out_worker_index(ip, vpp_worker_count):
return 1 + h % vpp_worker_count
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestNAT44EDOutput(VppTestCase):
"""NAT44 ED output feature Test Case"""
diff --git a/test/test_nat44_ei.py b/test/test_nat44_ei.py
index ae9194b87ce..166044db435 100644
--- a/test/test_nat44_ei.py
+++ b/test/test_nat44_ei.py
@@ -36,6 +36,7 @@ from util import ppp
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_neighbor import VppNeighbor
from vpp_papi import VppEnum
+from config import config
# NAT HA protocol event data
@@ -913,6 +914,7 @@ def get_nat44_ei_in2out_worker_index(ip, vpp_worker_count):
@tag_fixme_debian11
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestNAT44EI(MethodHolder):
"""NAT44EI Test Cases"""
@@ -953,8 +955,8 @@ class TestNAT44EI(MethodHolder):
cls.pg1.configure_ipv4_neighbors()
cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 10})
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 20})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 10})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 20})
cls.pg4._local_ip4 = "172.16.255.1"
cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
@@ -2682,8 +2684,8 @@ class TestNAT44EI(MethodHolder):
self.pg0.unconfig_ip4()
self.pg1.unconfig_ip4()
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id1})
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id2})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id1})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id2})
self.pg0.set_table_ip4(vrf_id1)
self.pg1.set_table_ip4(vrf_id2)
self.pg0.config_ip4()
@@ -2730,8 +2732,8 @@ class TestNAT44EI(MethodHolder):
self.pg1.config_ip4()
self.pg0.resolve_arp()
self.pg1.resolve_arp()
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id1})
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id2})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id1})
+ self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id2})
def test_vrf_feature_independent(self):
"""NAT44EI tenant VRF independent address pool mode"""
@@ -3468,8 +3470,8 @@ class TestNAT44EI(MethodHolder):
self.pg1.unconfig_ip4()
self.pg2.unconfig_ip4()
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id1})
- self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id2})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id1})
+ self.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": vrf_id2})
self.pg1.set_table_ip4(vrf_id1)
self.pg2.set_table_ip4(vrf_id2)
self.pg1.config_ip4()
@@ -4122,6 +4124,7 @@ class TestNAT44EI(MethodHolder):
i.remove_vpp_config()
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestNAT44Out2InDPO(MethodHolder):
"""NAT44EI Test Cases using out2in DPO"""
@@ -4263,6 +4266,7 @@ class TestNAT44Out2InDPO(MethodHolder):
self.verify_capture_in(capture, self.pg0)
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestNAT44EIMW(MethodHolder):
"""NAT44EI Test Cases (multiple workers)"""
@@ -4302,8 +4306,8 @@ class TestNAT44EIMW(MethodHolder):
cls.pg1.configure_ipv4_neighbors()
cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 10})
- cls.vapi.ip_table_add_del(is_add=1, table={"table_id": 20})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 10})
+ cls.vapi.ip_table_add_del_v2(is_add=1, table={"table_id": 20})
cls.pg4._local_ip4 = "172.16.255.1"
cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
diff --git a/test/test_nat64.py b/test/test_nat64.py
index f650b8d5f43..a28d7257aa0 100644
--- a/test/test_nat64.py
+++ b/test/test_nat64.py
@@ -36,10 +36,12 @@ from syslog_rfc5424_parser import SyslogMessage, ParseError
from syslog_rfc5424_parser.constants import SyslogSeverity
from util import ppc, ppp
from vpp_papi import VppEnum
+from config import config
@tag_fixme_vpp_workers
@tag_fixme_ubuntu2204
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestNAT64(VppTestCase):
"""NAT64 Test Cases"""
@@ -55,8 +57,6 @@ class TestNAT64(VppTestCase):
def setUpClass(cls):
super(TestNAT64, cls).setUpClass()
- if is_distro_ubuntu2204 == True and not hasattr(cls, "vpp"):
- return
cls.tcp_port_in = 6303
cls.tcp_port_out = 6303
cls.udp_port_in = 6304
@@ -76,7 +76,7 @@ class TestNAT64(VppTestCase):
cls.ip6_interfaces.append(cls.pg_interfaces[2])
cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
- cls.vapi.ip_table_add_del(
+ cls.vapi.ip_table_add_del_v2(
is_add=1, table={"table_id": cls.vrf1_id, "is_ip6": 1}
)
diff --git a/test/test_nat66.py b/test/test_nat66.py
index 44df7222f9d..54f9321d44e 100644
--- a/test/test_nat66.py
+++ b/test/test_nat66.py
@@ -13,8 +13,10 @@ from scapy.layers.inet6 import (
from scapy.layers.l2 import Ether, GRE
from util import ppp
from vpp_papi import VppEnum
+from config import config
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestNAT66(VppTestCase):
"""NAT66 Test Cases"""
diff --git a/test/test_npt66.py b/test/test_npt66.py
index 307dbabc39b..7479d3029b8 100644
--- a/test/test_npt66.py
+++ b/test/test_npt66.py
@@ -4,12 +4,14 @@ import unittest
import ipaddress
from framework import VppTestCase
from asfframework import VppTestRunner
+from config import config
from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6DestUnreach
from scapy.layers.l2 import Ether
from scapy.packet import Raw
+@unittest.skipIf("npt66" in config.excluded_plugins, "Exclude NPTv6 plugin tests")
class TestNPT66(VppTestCase):
"""NPTv6 Test Case"""
diff --git a/test/test_pcap.py b/test/test_pcap.py
index 72d215cea06..b73a601bcc8 100644
--- a/test/test_pcap.py
+++ b/test/test_pcap.py
@@ -9,8 +9,12 @@ from scapy.packet import Raw
from framework import VppTestCase
from asfframework import VppTestRunner
+from config import config
+@unittest.skipIf(
+ "dispatch-trace" in config.excluded_plugins, "Exclude dispatch trace plugin tests"
+)
class TestPcap(VppTestCase):
"""Pcap Unit Test Cases"""
diff --git a/test/test_pg.py b/test/test_pg.py
index d2e656df58b..da3b2254968 100644
--- a/test/test_pg.py
+++ b/test/test_pg.py
@@ -83,7 +83,7 @@ class TestPgTun(VppTestCase):
rxs = self.send_and_expect(self.pg0, p * N_PKTS, self.pg1)
for rx in rxs:
- rx = IP(rx)
+ rx = IP(bytes(rx))
self.assertFalse(rx.haslayer(Ether))
self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
@@ -97,7 +97,7 @@ class TestPgTun(VppTestCase):
rxs = self.send_and_expect(self.pg0, p * N_PKTS, self.pg2)
for rx in rxs:
- rx = IPv6(rx)
+ rx = IPv6(bytes(rx))
self.assertFalse(rx.haslayer(Ether))
self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
diff --git a/test/test_ping.py b/test/test_ping.py
index f3da7eb96ca..654d47be161 100644
--- a/test/test_ping.py
+++ b/test/test_ping.py
@@ -3,6 +3,9 @@ from scapy.layers.inet import IP, ICMP
from framework import VppTestCase
from vpp_ip_route import VppIpInterfaceAddress, VppIpRoute, VppRoutePath
from vpp_neighbor import VppNeighbor
+from config import config
+
+import unittest
""" TestPing is a subclass of VPPTestCase classes.
@@ -11,6 +14,7 @@ Basic test for sanity check of the ping.
"""
+@unittest.skipIf("ping" in config.excluded_plugins, "Exclude Ping plugin tests")
class TestPing(VppTestCase):
"""Ping Test Case"""
diff --git a/test/test_pipe.py b/test/test_pipe.py
index 83f5f96c998..01d2f30f494 100644
--- a/test/test_pipe.py
+++ b/test/test_pipe.py
@@ -11,6 +11,7 @@ from asfframework import VppTestRunner
from vpp_interface import VppInterface
from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
from vpp_acl import AclRule, VppAcl, VppAclInterface
+from config import config
NUM_PKTS = 67
@@ -63,6 +64,7 @@ class VppPipe(VppInterface):
)
+@unittest.skipIf("acl" in config.excluded_plugins, "Exclude tests requiring ACL plugin")
class TestPipe(VppTestCase):
"""Pipes"""
diff --git a/test/test_pnat.py b/test/test_pnat.py
index a7bd24b612c..ef5b3a107dc 100644
--- a/test/test_pnat.py
+++ b/test/test_pnat.py
@@ -6,8 +6,10 @@ from scapy.layers.inet import Ether, IP, UDP, ICMP
from framework import VppTestCase
from asfframework import VppTestRunner
from vpp_papi import VppEnum
+from config import config
+@unittest.skipIf("nat" in config.excluded_plugins, "Exclude NAT plugin tests")
class TestPNAT(VppTestCase):
"""PNAT Test Case"""
@@ -38,7 +40,7 @@ class TestPNAT(VppTestCase):
i.admin_down()
def validate(self, rx, expected):
- self.assertEqual(rx, expected.__class__(expected))
+ self.assertTrue(bytes(rx), bytes(expected))
def validate_bytes(self, rx, expected):
self.assertEqual(rx, expected)
diff --git a/test/test_pppoe.py b/test/test_pppoe.py
index e396250621f..b0ea5cfe4f4 100644
--- a/test/test_pppoe.py
+++ b/test/test_pppoe.py
@@ -13,8 +13,10 @@ from asfframework import VppTestRunner
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_pppoe_interface import VppPppoeInterface
from util import ppp
+from config import config
+@unittest.skipIf("pppoe" in config.excluded_plugins, "Exclude PPPoE plugin tests")
class TestPPPoE(VppTestCase):
"""PPPoE Test Case"""
@@ -222,7 +224,6 @@ class TestPPPoE(VppTestCase):
)
pppoe_if.add_vpp_config()
pppoe_if.set_unnumbered(self.pg0.sw_if_index)
-
#
# Send tunneled packets that match the created tunnel and
# are decapped and forwarded
diff --git a/test/test_pvti.py b/test/test_pvti.py
new file mode 100644
index 00000000000..94ae7790323
--- /dev/null
+++ b/test/test_pvti.py
@@ -0,0 +1,1153 @@
+#!/usr/bin/env python3
+""" PVTI tests """
+
+import datetime
+import base64
+import os
+import copy
+import struct
+
+from hashlib import blake2s
+from config import config
+from scapy.packet import Raw
+from scapy.compat import raw
+from scapy.layers.l2 import Ether
+from scapy.layers.inet import IP, UDP
+from scapy.layers.inet6 import IPv6
+from scapy.layers.vxlan import VXLAN
+
+from vpp_interface import VppInterface
+from vpp_pg_interface import is_ipv6_misc
+from vpp_ip_route import VppIpRoute, VppRoutePath
+from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort
+from vpp_vxlan_tunnel import VppVxlanTunnel
+from vpp_object import VppObject
+from vpp_papi import VppEnum
+from asfframework import tag_run_solo, tag_fixme_vpp_debug
+from framework import VppTestCase
+from re import compile
+import unittest
+
+
+from scapy.packet import Packet, bind_layers
+from scapy.layers.l2 import Ether
+from scapy.layers.inet import IP, UDP
+from scapy.layers.inet6 import IPv6
+from scapy.fields import (
+ FlagsField,
+ XByteField,
+ XShortField,
+ ThreeBytesField,
+ ConditionalField,
+ ShortField,
+ ByteEnumField,
+ X3BytesField,
+ LEIntField,
+ ByteField,
+ StrLenField,
+ PacketListField,
+ LEShortField,
+ IntField,
+ ShortField,
+ XIntField,
+)
+
+import sys
+
+
+def eprint(*args, **kwargs):
+ print(*args, file=sys.stderr, **kwargs)
+
+
+#
+# A custom decoder for Scapy for PVTI packet format
+#
+
+
+class PVTIChunk(Packet):
+ name = "PVTIChunk"
+ fields_desc = [
+ ShortField("total_chunk_length", None),
+ XShortField("_pad0", 0),
+ XIntField("_pad1", 0),
+ StrLenField("data", "", length_from=lambda pkt: pkt.total_chunk_length - 8),
+ ]
+
+ # This prevents the first chunk from consuming the entire remaining
+ # contents of the packet
+ def extract_padding(self, s):
+ return "", s
+
+ def post_build(self, p, pay):
+ if self.total_chunk_length is None and self.data:
+ chunk_header_size = 8
+ l = chunk_header_size + len(self.data)
+ p = struct.pack("!H", l) + p[2:]
+ return p + pay
+
+
+class PVTI(Packet):
+ name = "PVTI"
+ PVTI_ALIGN_BYTES = 9
+ fields_desc = [
+ IntField("seq", 0x0),
+ ByteField("stream_index", 0),
+ ByteField("chunk_count", None),
+ ByteField("reass_chunk_count", 0),
+ ByteField("mandatory_flags_mask", 0),
+ ByteField("flags_value", 0),
+ ByteField("pad_bytes", PVTI_ALIGN_BYTES),
+ StrLenField(
+ "pad", b"\xca" * PVTI_ALIGN_BYTES, length_from=lambda pkt: pkt.pad_bytes
+ ),
+ PacketListField("chunks", [], PVTIChunk, count_from=lambda p: p.chunk_count),
+ ]
+
+ def mysummary(self):
+ return self.sprintf("PVTI (len=%PVTI.total_len%)")
+
+ def post_build(self, p, pay):
+ if self.chunk_count is None:
+ l = len(self.chunks)
+ # offset of the chunk count within the fields
+ offset_of_chunk_count = 5
+ p = (
+ p[:offset_of_chunk_count]
+ + struct.pack("b", l)
+ + p[offset_of_chunk_count + 1 :]
+ )
+ return p + pay
+
+
+bind_layers(UDP, PVTI, dport=12312)
+# By default, set both ports to the test
+# bind_layers(UDP, PVTI, sport=6192, dport=6192)
+
+
+# PVTI ENcapsulator/DEcapsulator
+class PvtiEnDe(object):
+ """
+ PVTI encapsulator/decapsulator
+ """
+
+ def __init__(
+ self,
+ local_ip,
+ local_port,
+ remote_ip,
+ remote_port,
+ underlay_mtu=1500,
+ for_rx_test=False,
+ ):
+ self.for_rx_test = for_rx_test
+ self.local_ip = local_ip
+ self.local_port = local_port
+ self.remote_ip = remote_ip
+ self.remote_port = remote_port
+ self.underlay_mtu = underlay_mtu
+ self.stream_index = 0
+ self.tx_chunks = []
+ self.tx_n_reass_chunks = 0
+ self.tx_seq = 42
+ # payload = chunk headers + data
+ self.max_payload_len = underlay_mtu - len(raw(IP() / UDP() / PVTI()))
+ self.pvti_header_len = len(raw(PVTI()))
+ self.chunk_header_len = len(raw(PVTIChunk()))
+
+ def get_curr_payload_len(self):
+ tx_len = 0
+ for c in self.tx_chunks:
+ tx_len = tx_len + len(c.data) + self.chunk_header_len
+ return tx_len
+
+ def get_payload_room(self):
+ return self.max_payload_len - self.get_curr_payload_len()
+
+ def flush_tx_chunks(self, more_frags=False):
+ if self.for_rx_test:
+ ip_dst = self.local_ip
+ ip_src = self.remote_ip
+ else:
+ ip_src = self.local_ip
+ ip_dst = self.remote_ip
+ p = (
+ IP(
+ src=ip_src,
+ dst=ip_dst,
+ ttl=127,
+ frag=0,
+ flags=0,
+ id=self.tx_seq,
+ )
+ / UDP(sport=self.local_port, dport=self.remote_port, chksum=0)
+ / PVTI(
+ reass_chunk_count=self.tx_n_reass_chunks,
+ seq=self.tx_seq,
+ stream_index=self.stream_index,
+ chunks=self.tx_chunks,
+ )
+ )
+
+ p = IP(raw(p))
+
+ self.tx_n_reass_chunks = 0
+ self.tx_chunks = []
+ self.tx_seq = self.tx_seq + 1
+ return p
+
+ def encap_pkt(self, p):
+ out = []
+ if IP in p:
+ p[IP].ttl = p[IP].ttl - 1
+ payload_wip = p[IP].build()
+ elif IPv6 in p:
+ p[IPv6].hlim = p[IPv6].hlim - 1
+ payload_wip = p[IPv6].build()
+
+ split_chunks = False
+ huge_solo_packet = (
+ len(payload_wip) + self.chunk_header_len > self.get_payload_room()
+ ) and len(self.tx_chunks) == 0
+
+ while True:
+ available_room = self.get_payload_room()
+ chunk_wip_len = len(payload_wip) + self.chunk_header_len
+ xpad0 = 0xABAB
+ xpad1 = 0xABABABAB
+
+ if chunk_wip_len <= available_room:
+ # happy case - there is enough space to fit the entire chunk
+ if split_chunks:
+ self.tx_n_reass_chunks = self.tx_n_reass_chunks + 1
+ tx = PVTIChunk(data=payload_wip, _pad0=xpad0, _pad1=xpad1)
+ self.tx_chunks.append(tx)
+ if chunk_wip_len == available_room:
+ # an unlikely perfect fit - send this packet.
+ out.append(self.flush_tx_chunks())
+ break
+ elif available_room < self.chunk_header_len + 1:
+ # Can not fit even a chunk header + 1 byte of data
+ # Flush and retry
+ out.append(self.flush_tx_chunks())
+ continue
+ else:
+ # Chop as much as we can from the packet
+ chop_len = available_room - self.chunk_header_len
+ if split_chunks:
+ self.tx_n_reass_chunks = self.tx_n_reass_chunks + 1
+ tx = PVTIChunk(data=payload_wip[:chop_len], _pad0=xpad0, _pad1=xpad1)
+ self.tx_chunks.append(tx)
+ out.append(self.flush_tx_chunks())
+ split_chunks = True
+ payload_wip = payload_wip[chop_len:]
+ continue
+ return out
+
+ def encap_packets(self, pkts):
+ out = []
+ self.start_encap()
+ for p in pkts:
+ out.extend(self.encap_pkt(p))
+ last_pkt = self.finish_encap()
+ if last_pkt != None:
+ out.append(last_pkt)
+ return out
+
+ def start_encap(self):
+ return None
+
+ def finish_encap(self):
+ out = None
+ if len(self.tx_chunks) > 0:
+ out = self.flush_tx_chunks()
+ return out
+
+
+""" TestPvti is a subclass of VPPTestCase classes.
+
+PVTI test.
+
+"""
+
+
+def get_field_bytes(pkt, name):
+ fld, val = pkt.getfield_and_val(name)
+ return fld.i2m(pkt, val)
+
+
+class VppPvtiInterface(VppInterface):
+ """
+ VPP PVTI interface
+ """
+
+ def __init__(
+ self, test, local_ip, local_port, remote_ip, remote_port, underlay_mtu=1500
+ ):
+ super(VppPvtiInterface, self).__init__(test)
+
+ self.local_ip = local_ip
+ self.local_port = local_port
+ self.remote_ip = remote_ip
+ self.remote_port = remote_port
+ self.underlay_mtu = underlay_mtu
+
+ def get_ende(self, for_rx_test=False):
+ return PvtiEnDe(
+ self.local_ip,
+ self.local_port,
+ self.remote_ip,
+ self.remote_port,
+ self.underlay_mtu,
+ for_rx_test,
+ )
+
+ def verify_encap_packets(self, orig_pkts, recv_pkts):
+ ende = self.get_ende()
+ recv2_pkts = ende.encap_packets(orig_pkts)
+ out1 = []
+ out2 = []
+ for i, pkt in enumerate(recv_pkts):
+ if IP in pkt:
+ rx_pkt = pkt[IP]
+ elif IPv6 in pkt:
+ rx_pkt = pkt[IPv6]
+ else:
+ raise "Neither IPv4 nor IPv6"
+ py_pkt = recv2_pkts[i]
+ if rx_pkt != py_pkt:
+ eprint("received packet:")
+ rx_pkt.show()
+ eprint("python packet:")
+ py_pkt.show()
+ out1.append(rx_pkt)
+ out2.append(py_pkt)
+ return (out1, out2)
+
+ def add_vpp_config(self):
+ r = self.test.vapi.pvti_interface_create(
+ interface={
+ "local_ip": self.local_ip,
+ "local_port": self.local_port,
+ "remote_ip": self.remote_ip,
+ "remote_port": self.remote_port,
+ "underlay_mtu": self.underlay_mtu,
+ }
+ )
+ self.set_sw_if_index(r.sw_if_index)
+ self.test.registry.register(self, self.test.logger)
+ return self
+
+ def remove_vpp_config(self):
+ self.test.vapi.pvti_interface_delete(sw_if_index=self._sw_if_index)
+
+ def query_vpp_config(self):
+ ts = self.test.vapi.pvti_interface_dump(sw_if_index=0xFFFFFFFF)
+ for t in ts:
+ if (
+ t.interface.sw_if_index == self._sw_if_index
+ and str(t.interface.local_ip) == self.local_ip
+ and t.interface.local_port == self.local_port
+ and t.interface.remote_port == self.remote_port
+ and str(t.interface.remote_ip) == self.remote_ip
+ ):
+ self.test.logger.info("QUERY AYXX: true")
+ return True
+ return False
+
+ def __str__(self):
+ return self.object_id()
+
+ def object_id(self):
+ return "pvti-%d" % self._sw_if_index
+
+
+@unittest.skipIf("pvti" in config.excluded_plugins, "Exclude PVTI plugin tests")
+# @tag_run_solo
+class TestPvti(VppTestCase):
+ """Packet Vector Tunnel Interface (PVTI) Test Case"""
+
+ error_str = compile(r"Error")
+
+ # maxDiff = None
+
+ wg4_output_node_name = "/err/wg4-output-tun/"
+ wg4_input_node_name = "/err/wg4-input/"
+ wg6_output_node_name = "/err/wg6-output-tun/"
+ wg6_input_node_name = "/err/wg6-input/"
+ kp4_error = wg4_output_node_name + "Keypair error"
+ mac4_error = wg4_input_node_name + "Invalid MAC handshake"
+ peer4_in_err = wg4_input_node_name + "Peer error"
+ peer4_out_err = wg4_output_node_name + "Peer error"
+ kp6_error = wg6_output_node_name + "Keypair error"
+ mac6_error = wg6_input_node_name + "Invalid MAC handshake"
+ peer6_in_err = wg6_input_node_name + "Peer error"
+ peer6_out_err = wg6_output_node_name + "Peer error"
+ cookie_dec4_err = wg4_input_node_name + "Failed during Cookie decryption"
+ cookie_dec6_err = wg6_input_node_name + "Failed during Cookie decryption"
+ ratelimited4_err = wg4_input_node_name + "Handshake ratelimited"
+ ratelimited6_err = wg6_input_node_name + "Handshake ratelimited"
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestPvti, cls).setUpClass()
+ try:
+ cls.create_pg_interfaces(range(2))
+ for i in cls.pg_interfaces:
+ i.admin_up()
+ i.config_ip4()
+ i.config_ip6()
+ i.resolve_arp()
+ i.resolve_ndp()
+
+ except Exception:
+ super(TestPvti, cls).tearDownClass()
+ raise
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestPvti, cls).tearDownClass()
+
+ def setUp(self):
+ super(VppTestCase, self).setUp()
+ self.base_kp4_err = self.statistics.get_err_counter(self.kp4_error)
+ self.base_mac4_err = self.statistics.get_err_counter(self.mac4_error)
+ self.base_peer4_in_err = self.statistics.get_err_counter(self.peer4_in_err)
+ self.base_peer4_out_err = self.statistics.get_err_counter(self.peer4_out_err)
+ self.base_kp6_err = self.statistics.get_err_counter(self.kp6_error)
+ self.base_mac6_err = self.statistics.get_err_counter(self.mac6_error)
+ self.base_peer6_in_err = self.statistics.get_err_counter(self.peer6_in_err)
+ self.base_peer6_out_err = self.statistics.get_err_counter(self.peer6_out_err)
+ self.base_cookie_dec4_err = self.statistics.get_err_counter(
+ self.cookie_dec4_err
+ )
+ self.base_cookie_dec6_err = self.statistics.get_err_counter(
+ self.cookie_dec6_err
+ )
+ self.base_ratelimited4_err = self.statistics.get_err_counter(
+ self.ratelimited4_err
+ )
+ self.base_ratelimited6_err = self.statistics.get_err_counter(
+ self.ratelimited6_err
+ )
+
+ def create_packets(
+ self, src_ip_if, count=1, size=150, for_rx=False, is_ip6=False, af_mix=False
+ ):
+ pkts = []
+ total_packet_count = count
+ padstr0 = ""
+ padstr1 = ""
+ for i in range(0, 2000):
+ padstr0 = padstr0 + (".%03x" % i)
+ padstr1 = padstr1 + ("+%03x" % i)
+
+ for i in range(0, total_packet_count):
+ if af_mix:
+ is_ip6 = i % 2 == 1
+
+ dst_mac = src_ip_if.local_mac
+ src_mac = src_ip_if.remote_mac
+ if for_rx:
+ dst_ip4 = src_ip_if.remote_ip4
+ dst_ip6 = src_ip_if.remote_ip6
+ src_ip4 = "10.0.%d.4" % i
+ src_ip6 = "2001:db8::%x" % i
+ else:
+ src_ip4 = src_ip_if.remote_ip4
+ src_ip6 = src_ip_if.remote_ip6
+ dst_ip4 = "10.0.%d.4" % i
+ dst_ip6 = "2001:db8::%x" % i
+ src_l4 = 1234 + i
+ dst_l4 = 4321 + i
+
+ ulp = UDP(sport=src_l4, dport=dst_l4)
+ payload = "test pkt #%d" % i
+ if i % 2 == 1:
+ padstr = padstr1
+ else:
+ padstr = padstr0
+
+ p = Ether(dst=dst_mac, src=src_mac)
+ if is_ip6:
+ p /= IPv6(src=src_ip6, dst=dst_ip6)
+ else:
+ p /= IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0)
+
+ p /= ulp / Raw(payload)
+
+ if i % 2 == 1 or total_packet_count == 1:
+ self.extend_packet(p, size, padstr)
+ else:
+ self.extend_packet(p, 150, padstr)
+ pkts.append(p)
+ return pkts
+
+ def add_rx_ether_header(self, in_pkts, rx_intf=None):
+ out = []
+ if rx_intf is None:
+ rx_intf = self.pg0
+ dst_mac = rx_intf.local_mac
+ src_mac = rx_intf.remote_mac
+ pkts = []
+ for p in in_pkts:
+ p0 = Ether(dst=dst_mac, src=src_mac) / p[IP]
+ out.append(p0)
+ return out
+
+ def encap_for_rx_test(self, pkts, rx_intf=None):
+ ende = self.pvti0.get_ende(for_rx_test=True)
+ encap_pkts = ende.encap_packets(pkts)
+ return self.add_rx_ether_header(encap_pkts, rx_intf)
+
+ def decrement_ttl_and_build(self, send_pkts):
+ out = []
+ pkts = copy.deepcopy(send_pkts)
+ for p in pkts:
+ p[IP].ttl = p[IP].ttl - 1
+ out.append(Ether(p.build()))
+ return out
+
+ def create_rx_packets(self, dst_ip_if, rx_intf=None, count=1, size=150):
+ pkts = []
+ total_packet_count = count
+ padstr = ""
+ if rx_intf is None:
+ rx_intf = self.pg0
+ for i in range(0, 2000):
+ padstr = padstr + (".%03x" % i)
+
+ dst_mac = rx_intf.local_mac
+ src_mac = rx_intf.remote_mac
+
+ for i in range(0, total_packet_count):
+ dst_ip4 = dst_ip_if.remote_ip4
+ src_ip4 = "10.0.%d.4" % i
+ src_l4 = 1234 + i
+ dst_l4 = 4321 + i
+
+ ulp = UDP(sport=src_l4, dport=dst_l4)
+ payload = "test"
+
+ # if i % 2 == 1 or total_packet_count == 1:
+ # self.extend_packet(p, size, padstr)
+ # else:
+ # self.extend_packet(p, 150, padstr)
+
+ pvti = PVTI(seq=42 + i, chunks=[])
+ for j in range(0, 32):
+ p = (
+ IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0, id=j + 0x4000)
+ / ulp
+ / Raw(payload)
+ )
+ chunk0 = PVTIChunk(data=raw(p))
+ pvti.chunks.append(chunk0)
+
+ p = (
+ Ether(dst=dst_mac, src=src_mac)
+ / IP(src="192.0.2.1", dst=rx_intf.local_ip4, id=0x3000 + i)
+ / UDP(sport=12312, dport=12312)
+ / pvti
+ )
+ # p.show()
+ # Ether(raw(p)).show()
+
+ pkts.append(p)
+ return pkts
+
+ def send_and_assert_no_replies_ignoring_init(
+ self, intf, pkts, remark="", timeout=None
+ ):
+ self.pg_send(intf, pkts)
+
+ def _filter_out_fn(p):
+ return is_ipv6_misc(p) or is_handshake_init(p)
+
+ try:
+ if not timeout:
+ timeout = 1
+ for i in self.pg_interfaces:
+ i.assert_nothing_captured(
+ timeout=timeout, remark=remark, filter_out_fn=_filter_out_fn
+ )
+ timeout = 0.1
+ finally:
+ pass
+
+ def test_0000_pvti_interface(self):
+ """Simple interface creation"""
+ local_port = 12312
+ peer_addr = self.pg0.remote_ip4 # "192.0.2.1"
+ peer_port = 31234
+ peer_port = 12312
+
+ # Create interface
+ pvti0 = VppPvtiInterface(
+ self, self.pg1.local_ip4, local_port, peer_addr, peer_port
+ ).add_vpp_config()
+
+ self.logger.info(self.vapi.cli("sh int"))
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.logger.info(self.vapi.cli("show pvti tx peers"))
+ self.logger.info(self.vapi.cli("show pvti rx peers"))
+
+ # delete interface
+ pvti0.remove_vpp_config()
+ # self.logger.info(self.vapi.cli("show pvti interface"))
+ # pvti0.add_vpp_config()
+
+ def test_0001_pvti_send_simple_1pkt(self):
+ """v4o4 TX: Simple packet: 1 -> 1"""
+
+ self.prepare_for_test("v4o4_1pkt_simple")
+ pkts = self.create_packets(self.pg1)
+
+ recv_pkts = self.send_and_expect(self.pg1, pkts, self.pg0)
+ for p in recv_pkts:
+ self.logger.info(p)
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(pkts, recv_pkts)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_0101_pvti_send_simple_1pkt(self):
+ """v6o4 TX: Simple packet: 1 -> 1"""
+
+ self.prepare_for_test("v6o4_1pkt_simple")
+ pkts = self.create_packets(self.pg1, is_ip6=True)
+
+ recv_pkts = self.send_and_expect(self.pg1, pkts, self.pg0, n_rx=1)
+ for p in recv_pkts:
+ self.logger.info(p)
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(pkts, recv_pkts)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_0002_pvti_send_simple_2pkt(self):
+ """TX: Simple packet: 2 -> 1"""
+ self.prepare_for_test("2pkt_simple")
+
+ send_pkts = self.create_packets(self.pg1, count=2)
+ pkts = copy.deepcopy(send_pkts)
+ rx = self.send_and_expect(self.pg1, pkts, self.pg0, n_rx=1)
+ for p in rx:
+ self.logger.info(p)
+ # p.show()
+
+ payload0 = rx[0][PVTI].chunks[0].data
+ payload1 = rx[0][PVTI].chunks[1].data
+
+ pktA0 = IP(payload0)
+ pktA1 = IP(payload1)
+
+ p0 = pkts[0][IP]
+ p0.ttl = p0.ttl - 1
+ pktB0 = IP(p0.build())
+
+ p1 = pkts[1][IP]
+ p1.ttl = p1.ttl - 1
+ pktB1 = IP(p1.build())
+
+ self.assertEqual(pktA0, pktB0)
+ self.assertEqual(pktA1, pktB1)
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def prepare_for_test(self, test_name, underlay_mtu=1500, is_ip6=False):
+ local_port = 12312
+ peer_ip4_addr = "192.0.2.1"
+ peer_ip6_addr = "2001:db8:dead::1"
+ peer_port = 31234
+ peer_port = 12312
+ for i in self.pg_interfaces:
+ i.test_name = test_name
+ if is_ip6:
+ self.pvti0 = VppPvtiInterface(
+ self,
+ self.pg1.local_ip6,
+ local_port,
+ peer_ip6_addr,
+ peer_port,
+ underlay_mtu,
+ ).add_vpp_config()
+ else:
+ self.pvti0 = VppPvtiInterface(
+ self,
+ self.pg1.local_ip4,
+ local_port,
+ peer_ip4_addr,
+ peer_port,
+ underlay_mtu,
+ ).add_vpp_config()
+ self.pvti0.config_ip4()
+ self.pvti0.config_ip6()
+ self.pvti0.admin_up()
+
+ self.logger.info(self.vapi.cli("ip route add 0.0.0.0/0 via 172.16.3.3"))
+ ## FIXME: using direct "interface" below results in blackouts. intermittently.
+ # self.logger.info(self.vapi.cli("ip route 0.0.0.0/0 via pvti0"))
+ self.logger.info(self.vapi.cli("ip route add ::/0 via pvti0"))
+ self.logger.info(self.vapi.cli("ip route add 192.0.2.1/32 via pg0"))
+ self.logger.info(self.vapi.cli("ip neighbor pg0 192.0.2.1 000c.0102.0304"))
+ self.logger.info(self.vapi.cli("ip route 2001:db8:dead::1/128 via pg0"))
+ self.logger.info(
+ self.vapi.cli("ip neighbor pg0 2001:db8:dead::1 000c.0102.0304")
+ )
+ self.logger.info(self.vapi.cli("ip neighbor pg1 172.16.2.2 000c.0102.0304"))
+ self.logger.info(self.vapi.cli("sh int"))
+ self.logger.info(self.vapi.cli("sh ip fib"))
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.logger.info(self.vapi.cli("set interface ip pvti-bypass pg0"))
+
+ def cleanup_after_test(self):
+ self.logger.info(self.vapi.cli("ip neighbor del pg0 192.0.2.1 000c.0102.0304"))
+ self.logger.info(self.vapi.cli("ip neighbor del pg1 172.16.2.2 000c.0102.0304"))
+ self.logger.info(self.vapi.cli("ip route del 192.0.2.1/32 via pg0"))
+ # self.logger.info(self.vapi.cli("ip route del 0.0.0.0/0 via pvti0"))
+ self.logger.info(self.vapi.cli("ip route del ::/0 via pvti0"))
+ self.logger.info(self.vapi.cli("sh int"))
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.pvti0.remove_vpp_config()
+
+ def test_0003_pvti_send_simple_1pkt_big(self):
+ """TX: Simple big packet: 1 -> 2"""
+ self.prepare_for_test("1big_pkt")
+
+ send_pkts = self.create_packets(self.pg1, count=1, size=1900)
+ pkts = copy.deepcopy(send_pkts)
+ self.logger.info("count: ")
+ self.logger.info(len(pkts))
+ rx = self.send_and_expect(self.pg1, pkts, self.pg0, n_rx=2)
+ for p in rx:
+ self.logger.info(p)
+ self.logger.info(len(p[PVTI].chunks[0].data))
+ # p.show()
+ payload = rx[0][PVTI].chunks[0].data + rx[1][PVTI].chunks[0].data
+
+ pkt1 = IP(payload)
+ p0 = pkts[0][IP]
+ p0.ttl = p0.ttl - 1
+
+ pkt0 = IP(p0.build())
+
+ self.assertEqual(pkt0, pkt1)
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_0004_pvti_send_simple_5pkt_big(self):
+ """v4o4 TX: Simple big packets: 5 -> 2"""
+ self.prepare_for_test("v4o4_5big_pkt")
+
+ send_pkts = self.create_packets(self.pg1, count=5, size=1050)
+ self.logger.info("count: %d " % len(send_pkts))
+ # self.logger.info(len(pkts))
+ rx = self.send_and_expect(self.pg1, send_pkts, self.pg0, n_rx=2)
+ for p in rx:
+ self.logger.info(p)
+ self.logger.info(len(p[PVTI].chunks[0].data))
+ # p.show()
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_0104_pvti_send_simple_5pkt_big(self):
+ """v6o4 TX: Simple big packets: 5 -> 2"""
+ self.prepare_for_test("v4o4_5big_pkt")
+
+ send_pkts = self.create_packets(self.pg1, count=5, size=1050, is_ip6=True)
+ self.logger.info("count: %d " % len(send_pkts))
+ # self.logger.info(len(pkts))
+ rx = self.send_and_expect(self.pg1, send_pkts, self.pg0, n_rx=2)
+ for p in rx:
+ self.logger.info(p)
+ self.logger.info(len(p[PVTI].chunks[0].data))
+ # p.show()
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def Xtest_0204_pvti_send_simple_5pkt_mix(self):
+ """vXo4 TX: Simple packets mix: 5 -> 2"""
+ # FIXME: This test is disabled for now, but left here, to have this comment
+ # The mix of IPv4 and IPv6 packets in VPP will forward two
+ # different graphs, so after encap it will result in two
+ # PV packets: one with IPv4 chunks, and one with IPv6 chunks.
+ # The python test encapsulator does not do this, and it is probably
+ # a useless idea to introduce attempts to mimic this behavior,
+ # because in any case one can not expect the orderly scheduling
+ # of IPv4 vs IPv6 graph processing.
+ self.prepare_for_test("vXo4_5big_pkt")
+
+ send_pkts = self.create_packets(self.pg1, count=5, size=1050, af_mix=True)
+ # self.logger.info(len(pkts))
+ rx = self.send_and_expect(self.pg1, send_pkts, self.pg0, n_rx=2)
+ for p in rx:
+ self.logger.info(p)
+ self.logger.info(len(p[PVTI].chunks[0].data))
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_0005_pvti_send_mix_3pkt_medium_mtu(self):
+ """TX: small+big+small packets over medium mtu: 3 -> 3"""
+ self.prepare_for_test("3pkt_small_mtu", underlay_mtu=400)
+
+ send_pkts = self.create_packets(self.pg1, count=3, size=500)
+ pkts = copy.deepcopy(send_pkts)
+ self.logger.info("count: %d " % len(send_pkts))
+ # self.logger.info(len(pkts))
+ rx = self.send_and_expect(self.pg1, send_pkts, self.pg0, n_rx=3)
+ for p in rx:
+ self.logger.info(p)
+ self.logger.info(len(p[PVTI].chunks[0].data))
+ # p.show()
+
+ # check the middle chunk which is spread across two packets
+ payload = rx[0][PVTI].chunks[1].data + rx[1][PVTI].chunks[0].data
+
+ pkt1 = IP(payload)
+
+ p0 = pkts[1][IP]
+ p0.ttl = p0.ttl - 1
+
+ pkt0 = IP(p0.build())
+ self.assertEqual(pkt0, pkt1)
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_0006_pvti_send_mix_4pkt_medium_mtu(self):
+ """TX: small+big+small packets over 600 mtu: 4 -> 3"""
+ self.prepare_for_test("6pkt_small_mtu", underlay_mtu=600)
+
+ send_pkts = self.create_packets(self.pg1, count=4, size=500)
+ pkts = copy.deepcopy(send_pkts)
+ # self.logger.info(len(pkts))
+ rx = self.send_and_expect(self.pg1, send_pkts, self.pg0, n_rx=3)
+ for p in rx:
+ self.logger.info(p)
+ self.logger.info(len(p[PVTI].chunks[0].data))
+ # p.show()
+
+ # check the middle chunk which is spread across two packets
+ payload = rx[0][PVTI].chunks[1].data + rx[1][PVTI].chunks[0].data
+
+ pkt1 = IP(payload)
+
+ p0 = pkts[1][IP]
+ p0.ttl = p0.ttl - 1
+
+ pkt0 = IP(p0.build())
+ self.assertEqual(pkt0, pkt1)
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_0007_pvti_send_simple_1_3_pkt(self):
+ """TX: Simple packet: 1 -> 3, small mtu"""
+
+ self.prepare_for_test("1_3_pkt_simple", underlay_mtu=520)
+ send_pkts = self.create_packets(self.pg1, count=1, size=1400)
+ pkts = copy.deepcopy(send_pkts)
+
+ rx = self.send_and_expect(self.pg1, pkts, self.pg0, n_rx=3)
+ for p in rx:
+ self.logger.info(p)
+
+ c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_0008_pvti_chained_1_3_pkt(self):
+ """TX: Chained packet: 2700 byte 1 -> 3, mtu 1000"""
+
+ self.prepare_for_test("1_3_pkt_simple", underlay_mtu=1000)
+ send_pkts = self.create_packets(self.pg1, count=1, size=2700)
+ pkts = copy.deepcopy(send_pkts)
+
+ pkt0 = Ether(raw(pkts[0]))[IP]
+
+ rx = self.send_and_expect(self.pg1, send_pkts, self.pg0, n_rx=3)
+ for p in rx:
+ self.logger.info(p)
+
+ p0 = pkts[0][IP]
+ p0.ttl = p0.ttl - 1
+ pkt0 = IP(p0.build())
+
+ payload = (
+ rx[0][PVTI].chunks[0].data
+ + rx[1][PVTI].chunks[0].data
+ + rx[2][PVTI].chunks[0].data
+ # + rx[2][PVTI].chunks[1].data
+ )
+ pkt1 = IP(payload)
+
+ self.assertEqual(pkt0, pkt1)
+
+ # FIXME: this will fail because the send path
+ # does not combine the data from two chained blocks.
+ # when this succeeds, the above checks in this testcase will need to be redone
+ # c_pkts, py_pkts = self.pvti0.verify_encap_packets(send_pkts, rx)
+ # self.assertEqual(c_pkts, py_pkts)
+
+ self.cleanup_after_test()
+
+ def test_1001_pvti_rx_simple_1pkt(self):
+ """RX: Simple packet: 1 -> 32"""
+
+ self.prepare_for_test("1pkt_rx_simple")
+ pkts = self.create_rx_packets(self.pg1, rx_intf=self.pg0)
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.logger.info(self.vapi.cli("show udp ports"))
+
+ recv_pkts = self.send_and_expect(self.pg0, pkts, self.pg1, n_rx=32)
+ for p in recv_pkts:
+ self.logger.info(p)
+
+ self.cleanup_after_test()
+
+ def test_1002_pvti_rx_big_1buf(self):
+ """RX: Orig Big packet, single buf: 2 -> 1"""
+
+ self.prepare_for_test("1buf_rx_big")
+
+ pkts_orig = self.create_packets(self.pg1, count=1, size=1900, for_rx=True)
+ pkts = self.encap_for_rx_test(pkts_orig, rx_intf=self.pg0)
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.logger.info(self.vapi.cli("show udp ports"))
+
+ known_good_pkts = self.decrement_ttl_and_build(pkts_orig)
+
+ recv_pkts = self.send_and_expect(self.pg0, pkts, self.pg1, n_rx=1)
+ for i, p in enumerate(recv_pkts):
+ self.logger.info(p)
+ self.assertEqual(p[IP], known_good_pkts[i][IP])
+
+ self.cleanup_after_test()
+
+ def test_1003_pvti_rx_big_2buf(self):
+ """RX: Very Big packet, chained buf: 3 -> 1"""
+
+ self.prepare_for_test("2buf_rx_big")
+
+ pkts_orig = self.create_packets(self.pg1, count=1, size=3000, for_rx=True)
+
+ pkts = self.encap_for_rx_test(pkts_orig, rx_intf=self.pg0)
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.logger.info(self.vapi.cli("show udp ports"))
+
+ known_good_pkts = self.decrement_ttl_and_build(pkts_orig)
+
+ recv_pkts = self.send_and_expect(self.pg0, pkts, self.pg1, n_rx=1)
+ for i, p in enumerate(recv_pkts):
+ self.logger.info(p)
+ if p[IP] != known_good_pkts[i][IP]:
+ p[IP].show()
+ known_good_pkts[i][IP].show()
+ self.assertEqual(p[IP], known_good_pkts[i][IP])
+
+ self.cleanup_after_test()
+
+ def test_1004_pvti_rx_big_2buf_and_small(self):
+ """RX: Very Big packet, chained buf: 3 -> 1 + small pkt"""
+
+ self.prepare_for_test("2buf_rx_big_and_small")
+
+ pkts_orig = self.create_packets(self.pg1, count=2, size=3000, for_rx=True)
+
+ pkts = self.encap_for_rx_test(pkts_orig, rx_intf=self.pg0)
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.logger.info(self.vapi.cli("show udp ports"))
+
+ known_good_pkts = self.decrement_ttl_and_build(pkts_orig)
+
+ recv_pkts = self.send_and_expect(self.pg0, pkts, self.pg1, n_rx=2)
+ for i, p in enumerate(recv_pkts):
+ self.logger.info(p)
+ if p[IP] != known_good_pkts[i][IP]:
+ p[IP].show()
+ known_good_pkts[i][IP].show()
+ self.assertEqual(p[IP], known_good_pkts[i][IP])
+
+ self.cleanup_after_test()
+
+ def test_1005_pvti_rx_big_2buf_and_small_drop(self):
+ """RX: Very Big packet, chained buf: 3 -> 1 + small pkt, encap pkt lost"""
+
+ self.prepare_for_test("2buf_rx_big_and_small_drop")
+
+ pkts_orig = self.create_packets(self.pg1, count=3, size=3000, for_rx=True)
+
+ pkts = self.encap_for_rx_test(pkts_orig, rx_intf=self.pg0)
+ # drop the second packet after encapsulation (the one with the second frag of the large packet)
+ pkts.pop(1)
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.logger.info(self.vapi.cli("show udp ports"))
+
+ known_good_pkts = self.decrement_ttl_and_build(pkts_orig)
+
+ # drop the large original packet, leaving just two small ones
+ known_good_pkts.pop(1)
+
+ recv_pkts = self.send_and_expect(self.pg0, pkts, self.pg1, n_rx=2)
+ for i, p in enumerate(recv_pkts):
+ self.logger.info(p)
+ if p[IP] != known_good_pkts[i][IP]:
+ p[IP].show()
+ known_good_pkts[i][IP].show()
+ self.assertEqual(p[IP], known_good_pkts[i][IP])
+
+ self.cleanup_after_test()
+
+ def test_1006_pvti_rx_big_2buf_and_small_drop2(self):
+ """RX: Very Big packet, chained buf: 3 -> 1 + small pkt, non-initial frag pkt lost"""
+
+ self.prepare_for_test("2buf_rx_big_and_small_drop2")
+
+ pkts_orig = self.create_packets(self.pg1, count=3, size=6000, for_rx=True)
+
+ pkts = self.encap_for_rx_test(pkts_orig, rx_intf=self.pg0)
+ # drop the second packet after encapsulation (the one with the second frag of the large packet)
+ pkts.pop(2)
+ self.logger.info(self.vapi.cli("show pvti interface"))
+ self.logger.info(self.vapi.cli("show udp ports"))
+
+ known_good_pkts = self.decrement_ttl_and_build(pkts_orig)
+ # drop the large original packet, leaving just two small ones
+ known_good_pkts.pop(1)
+
+ recv_pkts = self.send_and_expect(self.pg0, pkts, self.pg1, n_rx=2)
+ for i, p in enumerate(recv_pkts):
+ self.logger.info(p)
+ if p[IP] != known_good_pkts[i][IP]:
+ p[IP].show()
+ known_good_pkts[i][IP].show()
+ self.assertEqual(p[IP], known_good_pkts[i][IP])
+
+ self.cleanup_after_test()
+
+
+class PvtiHandoffTests(TestPvti):
+ """Pvti Tests in multi worker setup"""
+
+ vpp_worker_count = 2
+
+ def xtest_wg_peer_init(self):
+ """Handoff"""
+
+ port = 12383
+
+ # Create interfaces
+ wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
+ wg0.admin_up()
+ wg0.config_ip4()
+
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ peer_1 = VppWgPeer(
+ self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.2.0/24", "10.11.3.0/24"]
+ ).add_vpp_config()
+ self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)
+
+ r1 = VppIpRoute(
+ self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
+ ).add_vpp_config()
+
+ # skip the first automatic handshake
+ self.pg1.get_capture(1, timeout=HANDSHAKE_JITTER)
+
+ # send a valid handsake init for which we expect a response
+ p = peer_1.mk_handshake(self.pg1)
+
+ rx = self.send_and_expect(self.pg1, [p], self.pg1)
+
+ peer_1.consume_response(rx[0])
+
+ # send a data packet from the peer through the tunnel
+ # this completes the handshake and pins the peer to worker 0
+ p = (
+ IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
+ / UDP(sport=222, dport=223)
+ / Raw()
+ )
+ d = peer_1.encrypt_transport(p)
+ p = peer_1.mk_tunnel_header(self.pg1) / (
+ Pvti(message_type=4, reserved_zero=0)
+ / PvtiTransport(
+ receiver_index=peer_1.sender, counter=0, encrypted_encapsulated_packet=d
+ )
+ )
+ rxs = self.send_and_expect(self.pg1, [p], self.pg0, worker=0)
+
+ for rx in rxs:
+ self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
+ self.assertEqual(rx[IP].ttl, 19)
+
+ # send a packets that are routed into the tunnel
+ # and pins the peer tp worker 1
+ pe = (
+ Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
+ / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
+ / UDP(sport=555, dport=556)
+ / Raw(b"\x00" * 80)
+ )
+ rxs = self.send_and_expect(self.pg0, pe * 255, self.pg1, worker=1)
+ peer_1.validate_encapped(rxs, pe)
+
+ # send packets into the tunnel, from the other worker
+ p = [
+ (
+ peer_1.mk_tunnel_header(self.pg1)
+ / Pvti(message_type=4, reserved_zero=0)
+ / PvtiTransport(
+ receiver_index=peer_1.sender,
+ counter=ii + 1,
+ encrypted_encapsulated_packet=peer_1.encrypt_transport(
+ (
+ IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
+ / UDP(sport=222, dport=223)
+ / Raw()
+ )
+ ),
+ )
+ )
+ for ii in range(255)
+ ]
+
+ rxs = self.send_and_expect(self.pg1, p, self.pg0, worker=1)
+
+ for rx in rxs:
+ self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
+ self.assertEqual(rx[IP].ttl, 19)
+
+ # send a packets that are routed into the tunnel
+ # from worker 0
+ rxs = self.send_and_expect(self.pg0, pe * 255, self.pg1, worker=0)
+
+ peer_1.validate_encapped(rxs, pe)
+
+ r1.remove_vpp_config()
+ peer_1.remove_vpp_config()
+ wg0.remove_vpp_config()
diff --git a/test/test_reassembly.py b/test/test_reassembly.py
index 98c50f9bb61..caac7ce4df1 100644
--- a/test/test_reassembly.py
+++ b/test/test_reassembly.py
@@ -25,6 +25,7 @@ from util import ppp, fragment_rfc791, fragment_rfc8200
from vpp_gre_interface import VppGreInterface
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_papi import VppEnum
+from config import config
# 35 is enough to have >257 400-byte fragments
test_packet_count = 35
@@ -588,6 +589,9 @@ Ethernet-Payload.IPv4-Packet.IPv4-Header.Fragment-Offset; Test-case: 5737"""
self.verify_capture(packets, dropped_packet_indexes)
self.src_if.assert_nothing_captured()
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_local_enable_disable(self):
"""local reassembly enabled/disable"""
self.vapi.ip_reassembly_enable_disable(
@@ -1675,6 +1679,9 @@ class TestIPv6Reassembly(VppTestCase):
)
rx = self.send_and_expect(self.pg0, [pkt], self.pg0)
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_one_fragment(self):
"""whole packet in one fragment processed independently"""
pkt = (
@@ -1702,6 +1709,9 @@ class TestIPv6Reassembly(VppTestCase):
rx = self.send_and_expect(self.pg0, frags[1:], self.pg0, n_rx=1)
self.assertNotIn(IPv6ExtHdrFragment, rx)
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_bunch_of_fragments(self):
"""valid fragments followed by rogue fragments and atomic fragment"""
pkt = (
@@ -1731,6 +1741,9 @@ class TestIPv6Reassembly(VppTestCase):
rx = self.send_and_expect(self.pg0, [pkt], self.pg0)
self.assertNotIn(IPv6ExtHdrFragment, rx)
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_local_enable_disable(self):
"""local reassembly enabled/disable"""
self.vapi.ip_reassembly_enable_disable(
@@ -2366,6 +2379,9 @@ class TestIPv4ReassemblyLocalNode(VppTestCase):
index, seen, "Packet with packet_index %d not received" % index
)
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_reassembly(self):
"""basic reassembly"""
@@ -2492,6 +2508,9 @@ class TestFIFReassembly(VppTestCase):
"Packet with packet_index %d not received" % index,
)
+ @unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests requiring GRE plugin"
+ )
def test_fif4(self):
"""Fragments in fragments (4o4)"""
@@ -2567,6 +2586,9 @@ class TestFIFReassembly(VppTestCase):
self.gre4.remove_vpp_config()
self.logger.debug(self.vapi.ppcli("show interface"))
+ @unittest.skipIf(
+ "gre" in config.excluded_plugins, "Exclude tests requiring GRE plugin"
+ )
def test_fif6(self):
"""Fragments in fragments (6o6)"""
# TODO this should be ideally in setUpClass, but then we hit a bug
diff --git a/test/test_span.py b/test/test_span.py
index 8eea1b0661d..b151ef4f7a1 100644
--- a/test/test_span.py
+++ b/test/test_span.py
@@ -3,7 +3,8 @@
import unittest
from scapy.packet import Raw
-from scapy.layers.l2 import Ether, GRE, ERSPAN
+from scapy.layers.l2 import Ether, GRE
+from scapy.contrib.erspan import ERSPAN
from scapy.layers.inet import IP, UDP
from scapy.layers.vxlan import VXLAN
@@ -14,6 +15,7 @@ from vpp_gre_interface import VppGreInterface
from vpp_vxlan_tunnel import VppVxlanTunnel
from collections import namedtuple
from vpp_papi import VppEnum
+from config import config
Tag = namedtuple("Tag", ["dot1", "vlan"])
@@ -21,6 +23,9 @@ DOT1AD = 0x88A8
DOT1Q = 0x8100
+@unittest.skipIf(
+ "vxlan" in config.excluded_plugins, "Exclude tests requiring VXLAN plugin"
+)
class TestSpan(VppTestCase):
"""SPAN Test Case"""
diff --git a/test/test_srv6_ad.py b/test/test_srv6_ad.py
index 5d7a621a9b8..69bdd313851 100644
--- a/test/test_srv6_ad.py
+++ b/test/test_srv6_ad.py
@@ -15,8 +15,10 @@ from scapy.layers.inet6 import IPv6, UDP, IPv6ExtHdrSegmentRouting
from scapy.layers.inet import IP, UDP
from util import ppp
+from config import config
+@unittest.skipIf("srv6-ad" in config.excluded_plugins, "Exclude srv6-ad plugin tests")
class TestSRv6Ad(VppTestCase):
"""SRv6 Dynamic Proxy plugin Test Case"""
diff --git a/test/test_srv6_ad_flow.py b/test/test_srv6_ad_flow.py
index f776c71ac4b..f1e5109f472 100644
--- a/test/test_srv6_ad_flow.py
+++ b/test/test_srv6_ad_flow.py
@@ -14,8 +14,12 @@ from scapy.layers.inet6 import IPv6, UDP, IPv6ExtHdrSegmentRouting
from scapy.layers.inet import IP, UDP
from util import ppp
+from config import config
+@unittest.skipIf(
+ "srv6-ad-flow" in config.excluded_plugins, "Exclude srv6-ad-flow plugin tests"
+)
class TestSRv6AdFlow(VppTestCase):
"""SRv6 Flow-based Dynamic Proxy plugin Test Case"""
diff --git a/test/test_srv6_as.py b/test/test_srv6_as.py
index 645cf338596..0f78159dccf 100644
--- a/test/test_srv6_as.py
+++ b/test/test_srv6_as.py
@@ -11,10 +11,12 @@ from scapy.packet import Raw
from scapy.layers.l2 import Ether, Dot1Q
from scapy.layers.inet6 import IPv6, UDP, IPv6ExtHdrSegmentRouting
from scapy.layers.inet import IP, UDP
+from config import config
from util import ppp
+@unittest.skipIf("srv6-as" in config.excluded_plugins, "Exclude srv6-as plugin tests")
class TestSRv6As(VppTestCase):
"""SRv6 Static Proxy plugin Test Case"""
diff --git a/test/test_srv6_mobile.py b/test/test_srv6_mobile.py
index 314dfc114e2..7a96e84e34f 100644
--- a/test/test_srv6_mobile.py
+++ b/test/test_srv6_mobile.py
@@ -4,6 +4,7 @@ from framework import VppTestCase
from ipaddress import IPv4Address
from ipaddress import IPv6Address
from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathProto, VppIpTable
+from config import config
from vpp_srv6_mobile import (
SRv6MobileNhtype,
@@ -14,7 +15,12 @@ from vpp_srv6_mobile import (
from scapy.contrib.gtp import *
from scapy.all import *
+import unittest
+
+@unittest.skipIf(
+ "srv6-mobile" in config.excluded_plugins, "Exclude srv6-mobile plugin tests"
+)
class TestSRv6EndMGTP4E(VppTestCase):
"""SRv6 End.M.GTP4.E (SRv6 -> GTP-U)"""
@@ -108,6 +114,9 @@ class TestSRv6EndMGTP4E(VppTestCase):
self.assertEqual(pkt[GTP_U_Header].teid, 0xBBBBBBBB)
+@unittest.skipIf(
+ "srv6-mobile" in config.excluded_plugins, "Exclude srv6-mobile plugin tests"
+)
class TestSRv6TMGTP4D(VppTestCase):
"""SRv6 T.M.GTP4.D (GTP-U -> SRv6)"""
@@ -215,6 +224,9 @@ class TestSRv6TMGTP4D(VppTestCase):
)
+@unittest.skipIf(
+ "srv6-mobile" in config.excluded_plugins, "Exclude srv6-mobile plugin tests"
+)
class TestSRv6EndMGTP6E(VppTestCase):
"""SRv6 End.M.GTP6.E"""
@@ -306,6 +318,9 @@ class TestSRv6EndMGTP6E(VppTestCase):
self.assertEqual(pkt[GTP_U_Header].teid, 0xBBBBBBBB)
+@unittest.skipIf(
+ "srv6-mobile" in config.excluded_plugins, "Exclude srv6-mobile plugin tests"
+)
class TestSRv6EndMGTP6D(VppTestCase):
"""SRv6 End.M.GTP6.D"""
diff --git a/test/test_svs.py b/test/test_svs.py
index 1efc8fc846b..01173a201b7 100644
--- a/test/test_svs.py
+++ b/test/test_svs.py
@@ -12,10 +12,12 @@ from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6
from vpp_papi import VppEnum
+from config import config
NUM_PKTS = 67
+@unittest.skipIf("svs" in config.excluded_plugins, "Exclude SVS plugin tests")
class TestSVS(VppTestCase):
"""SVS Test Case"""
diff --git a/test/test_trace_filter.py b/test/test_trace_filter.py
index c188631c200..45718d6f27f 100644
--- a/test/test_trace_filter.py
+++ b/test/test_trace_filter.py
@@ -8,6 +8,7 @@ from framework import VppTestCase
from asfframework import VppTestRunner
from vpp_papi import VppEnum
from vpp_ipsec import VppIpsecSA, VppIpsecSpd, VppIpsecSpdItfBinding, VppIpsecSpdEntry
+from config import config
from scapy.contrib.geneve import GENEVE
from scapy.packet import Raw
@@ -291,6 +292,9 @@ class TestTracefilter(TemplateTraceFilter):
self.assertEqual(len(pcap), 17)
+@unittest.skipIf(
+ "tracenode" in config.excluded_plugins, "Exclude tests requiring tracenode plugin"
+)
class TestTraceFilterInner(TemplateTraceFilter):
"""Packet Tracer Filter Inner Test"""
diff --git a/test/test_udp.py b/test/test_udp.py
index 34307ef1aab..6315f0efd5e 100644
--- a/test/test_udp.py
+++ b/test/test_udp.py
@@ -17,6 +17,7 @@ from vpp_ip_route import (
)
from vpp_neighbor import VppNeighbor
from vpp_papi import VppEnum
+from config import config
from scapy.packet import Raw
from scapy.layers.l2 import Ether
@@ -632,9 +633,9 @@ class TestUdpEncap(VppTestCase):
)
rx = self.send_and_expect(self.pg0, p_4 * NUM_PKTS, self.pg0)
- p_4 = IP(p_4["UDP"].payload)
+ p_4 = IP(bytes(p_4["UDP"].payload))
for p in rx:
- p = IP(p["Ether"].payload)
+ p = IP(bytes(p["Ether"].payload))
self.validate_inner4(p, p_4, ttl=63)
#
@@ -650,10 +651,10 @@ class TestUdpEncap(VppTestCase):
)
rx = self.send_and_expect(self.pg1, p_6 * NUM_PKTS, self.pg1)
- p_6 = IPv6(p_6["UDP"].payload)
- p = IPv6(rx[0]["Ether"].payload)
+ p_6 = IPv6(bytes(p_6["UDP"].payload))
+ p = IPv6(bytes(rx[0]["Ether"].payload))
for p in rx:
- p = IPv6(p["Ether"].payload)
+ p = IPv6(bytes(p["Ether"].payload))
self.validate_inner6(p, p_6, hlim=63)
#
@@ -672,13 +673,16 @@ class TestUdpEncap(VppTestCase):
self.pg2.enable_mpls()
rx = self.send_and_expect(self.pg2, p_mo4 * NUM_PKTS, self.pg2)
self.pg2.disable_mpls()
- p_mo4 = IP(MPLS(p_mo4["UDP"].payload).payload)
+ p_mo4 = IP(bytes(MPLS(bytes(p_mo4["UDP"].payload)).payload))
for p in rx:
- p = IP(p["Ether"].payload)
+ p = IP(bytes(p["Ether"].payload))
self.validate_inner4(p, p_mo4, ttl=63)
@tag_fixme_vpp_workers
+@unittest.skipIf(
+ "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
+)
class TestUDP(VppTestCase):
"""UDP Test Case"""
@@ -721,6 +725,14 @@ class TestUDP(VppTestCase):
i.unconfig_ip4()
i.set_table_ip4(0)
i.admin_down()
+ # Unconfigure namespaces - remove our locks to the vrf tables
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+
self.vapi.session_enable_disable(is_enable=0)
super(TestUDP, self).tearDown()
diff --git a/test/test_urpf.py b/test/test_urpf.py
index 1e4a6c5bb34..47a260081cc 100644
--- a/test/test_urpf.py
+++ b/test/test_urpf.py
@@ -11,10 +11,12 @@ from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6
from vpp_papi import VppEnum
+from config import config
N_PKTS = 63
+@unittest.skipIf("urpf" in config.excluded_plugins, "Exclude URPF plugin tests")
class TestURPF(VppTestCase):
"""Unicast Reverse Path Forwarding Test Case"""
diff --git a/test/test_vlib.py b/test/test_vlib.py
index 1b92c94a4c4..48e32b6e669 100644
--- a/test/test_vlib.py
+++ b/test/test_vlib.py
@@ -252,6 +252,9 @@ class TestVlibFrameLeak(VppTestCase):
i.unconfig_ip4()
i.admin_down()
+ @unittest.skipIf(
+ "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
+ )
def test_vlib_mw_refork_frame_leak(self):
"""Vlib worker thread refork leak test case"""
icmp_id = 0xB
@@ -271,7 +274,7 @@ class TestVlibFrameLeak(VppTestCase):
rx = self.pg0.get_capture(1)
- self.assertEquals(len(rx), 1)
+ self.assertEqual(len(rx), 1)
rx = rx[0]
ether = rx[Ether]
ipv4 = rx[IP]
@@ -302,7 +305,7 @@ class TestVlibFrameLeak(VppTestCase):
rx = self.pg0.get_capture(1)
- self.assertEquals(len(rx), 1)
+ self.assertEqual(len(rx), 1)
rx = rx[0]
ether = rx[Ether]
ipv4 = rx[IP]
diff --git a/test/test_vrrp.py b/test/test_vrrp.py
index 8575016c326..41b8268e6bc 100644
--- a/test/test_vrrp.py
+++ b/test/test_vrrp.py
@@ -252,6 +252,7 @@ class VppVRRPVirtualRouter(VppObject):
return pkt
+@unittest.skipIf("vrrp" in config.excluded_plugins, "Exclude VRRP plugin tests")
class TestVRRP4(VppTestCase):
"""IPv4 VRRP Test Case"""
@@ -884,6 +885,7 @@ class TestVRRP4(VppTestCase):
self.assertEqual(rx[VRRPv3].addrlist, [vip])
+@unittest.skipIf("vrrp" in config.excluded_plugins, "Exclude VRRP plugin tests")
class TestVRRP6(VppTestCase):
"""IPv6 VRRP Test Case"""
diff --git a/test/test_vxlan.py b/test/test_vxlan.py
index 284e1359116..939a57f7343 100644
--- a/test/test_vxlan.py
+++ b/test/test_vxlan.py
@@ -20,8 +20,10 @@ from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_vxlan_tunnel import VppVxlanTunnel
from vpp_ip import INVALID_INDEX
from vpp_neighbor import VppNeighbor
+from config import config
+@unittest.skipIf("vxlan" in config.excluded_plugins, "Exclude VXLAN plugin tests")
class TestVxlan(BridgeDomain, VppTestCase):
"""VXLAN Test Case"""
@@ -480,6 +482,7 @@ class TestVxlan(BridgeDomain, VppTestCase):
self.logger.info(self.vapi.cli("show vxlan tunnel"))
+@unittest.skipIf("vxlan" in config.excluded_plugins, "Exclude VXLAN plugin tests")
class TestVxlan2(VppTestCase):
"""VXLAN Test Case"""
@@ -527,6 +530,7 @@ class TestVxlan2(VppTestCase):
rx = self.send_and_assert_no_replies(self.pg1, [p])
+@unittest.skipIf("vxlan" in config.excluded_plugins, "Exclude VXLAN plugin tests")
class TestVxlanL2Mode(VppTestCase):
"""VXLAN Test Case"""
diff --git a/test/test_vxlan6.py b/test/test_vxlan6.py
index 1bf01262a48..09a99604311 100644
--- a/test/test_vxlan6.py
+++ b/test/test_vxlan6.py
@@ -14,8 +14,10 @@ import util
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_vxlan_tunnel import VppVxlanTunnel
from vpp_ip import INVALID_INDEX
+from config import config
+@unittest.skipIf("vxlan" in config.excluded_plugins, "Exclude VXLAN plugin tests")
class TestVxlan6(BridgeDomain, VppTestCase):
"""VXLAN over IPv6 Test Case"""
@@ -256,7 +258,7 @@ class TestVxlan6(BridgeDomain, VppTestCase):
reassembled = util.reassemble4(payload)
- self.assertEqual(Ether(raw(frame))[IP], reassembled[IP])
+ self.assertEqual(Ether(bytes(frame))[IP], reassembled[IP])
"""
Tests with default port (4789)
diff --git a/test/test_wireguard.py b/test/test_wireguard.py
index e809daec163..481aa558312 100644
--- a/test/test_wireguard.py
+++ b/test/test_wireguard.py
@@ -261,7 +261,7 @@ class VppWgPeer(VppObject):
def mk_cookie(self, p, tx_itf, is_resp=False, is_ip6=False):
self.verify_header(p, is_ip6)
- wg_pkt = Wireguard(p[Raw])
+ wg_pkt = Wireguard(bytes(p[Raw]))
if is_resp:
self._test.assertEqual(wg_pkt[Wireguard].message_type, 2)
@@ -310,7 +310,7 @@ class VppWgPeer(VppObject):
def consume_cookie(self, p, is_ip6=False):
self.verify_header(p, is_ip6)
- cookie_reply = Wireguard(p[Raw])
+ cookie_reply = Wireguard(bytes(p[Raw]))
self._test.assertEqual(cookie_reply[Wireguard].message_type, 3)
self._test.assertEqual(cookie_reply[Wireguard].reserved_zero, 0)
@@ -390,7 +390,7 @@ class VppWgPeer(VppObject):
self.noise_init(self.itf.public_key)
self.verify_header(p, is_ip6)
- init = Wireguard(p[Raw])
+ init = Wireguard(bytes(p[Raw]))
self._test.assertEqual(init[Wireguard].message_type, 1)
self._test.assertEqual(init[Wireguard].reserved_zero, 0)
@@ -438,9 +438,7 @@ class VppWgPeer(VppObject):
def consume_response(self, p, is_ip6=False):
self.verify_header(p, is_ip6)
-
- resp = Wireguard(p[Raw])
-
+ resp = Wireguard(bytes(p[Raw]))
self._test.assertEqual(resp[Wireguard].message_type, 2)
self._test.assertEqual(resp[Wireguard].reserved_zero, 0)
self._test.assertEqual(
@@ -456,7 +454,7 @@ class VppWgPeer(VppObject):
def decrypt_transport(self, p, is_ip6=False):
self.verify_header(p, is_ip6)
- p = Wireguard(p[Raw])
+ p = Wireguard(bytes(p[Raw]))
self._test.assertEqual(p[Wireguard].message_type, 4)
self._test.assertEqual(p[Wireguard].reserved_zero, 0)
self._test.assertEqual(
@@ -501,7 +499,7 @@ class VppWgPeer(VppObject):
def is_handshake_init(p):
- wg_p = Wireguard(p[Raw])
+ wg_p = Wireguard(bytes(p[Raw]))
return wg_p[Wireguard].message_type == 1
diff --git a/test/vm_vpp_interfaces.py b/test/vm_vpp_interfaces.py
index 85417dcbca0..0f1e33d679b 100644
--- a/test/vm_vpp_interfaces.py
+++ b/test/vm_vpp_interfaces.py
@@ -489,11 +489,15 @@ class TestVPPInterfacesQemu:
except Exception:
pass
try:
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": layer3["ip4_vrf"]})
+ self.vapi.ip_table_add_del_v2(
+ is_add=0, table={"table_id": layer3["ip4_vrf"]}
+ )
except Exception:
pass
try:
- self.vapi.ip_table_add_del(is_add=0, table={"table_id": layer3["ip6_vrf"]})
+ self.vapi.ip_table_add_del_v2(
+ is_add=0, table={"table_id": layer3["ip6_vrf"]}
+ )
except Exception:
pass
try:
@@ -693,7 +697,7 @@ class TestVPPInterfacesQemu:
vrf_id -- vrf_id
"""
is_ipv6 = 0 if ip_version == 4 else 1
- self.vapi.ip_table_add_del(
+ self.vapi.ip_table_add_del_v2(
is_add=1, table={"table_id": vrf_id, "is_ip6": is_ipv6}
)
for sw_if_index, ip_prefix in if_idx_ip_prefixes:
diff --git a/test/vpp_ip_route.py b/test/vpp_ip_route.py
index d36c56761e3..31aab3a03ee 100644
--- a/test/vpp_ip_route.py
+++ b/test/vpp_ip_route.py
@@ -169,16 +169,20 @@ def fib_interface_ip_prefix(test, addr, len, sw_if_index):
class VppIpTable(VppObject):
- def __init__(self, test, table_id, is_ip6=0, register=True, name=""):
+ def __init__(
+ self, test, table_id, is_ip6=0, register=True, name="", create_mfib=True
+ ):
self._test = test
self.name = name
self.table_id = table_id
self.is_ip6 = is_ip6
self.register = register
+ self.create_mfib = True
def add_vpp_config(self):
- self._test.vapi.ip_table_add_del(
+ self._test.vapi.ip_table_add_del_v2(
is_add=1,
+ create_mfib=self.create_mfib,
table={"is_ip6": self.is_ip6, "table_id": self.table_id, "name": self.name},
)
if self.register:
@@ -186,7 +190,7 @@ class VppIpTable(VppObject):
return self
def remove_vpp_config(self):
- self._test.vapi.ip_table_add_del(
+ self._test.vapi.ip_table_add_del_v2(
is_add=0, table={"is_ip6": self.is_ip6, "table_id": self.table_id}
)
diff --git a/test/vpp_pg_interface.py b/test/vpp_pg_interface.py
index cdb91ed1e41..1e02801cda9 100644
--- a/test/vpp_pg_interface.py
+++ b/test/vpp_pg_interface.py
@@ -187,7 +187,7 @@ class VppPGInterface(VppInterface):
self.test.logger.debug(
f"Generating testcase pg streams decode file: {pg_decode}"
)
- ts_opts = "-Vr"
+ ts_opts = "-Vxr"
for p in sorted(Path(pcap_dir).glob(f"{filename_prefix}*.pcap")):
self.test.logger.debug(f"Decoding {p}")
with open(f"{pg_decode}", "a", buffering=1) as f: