diff options
Diffstat (limited to 'test')
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: |