Page MenuHomeFreeBSD

tests: Add scapy as a required program
ClosedPublic

Authored by jlduran on Feb 10 2025, 10:02 PM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Mar 12, 11:52 PM
Unknown Object (File)
Sun, Mar 9, 10:34 AM
Unknown Object (File)
Wed, Mar 5, 9:22 PM
Unknown Object (File)
Wed, Feb 26, 2:25 AM
Unknown Object (File)
Feb 24 2025, 2:59 PM
Unknown Object (File)
Feb 24 2025, 3:41 AM
Unknown Object (File)
Feb 24 2025, 2:45 AM
Unknown Object (File)
Feb 23 2025, 7:53 PM

Details

Summary

The utils.subr file includes a couple of subroutines
(ping_dummy_check_request and ping_server_check_reply) that require
scapy.

Add this requirement in the header of each test that makes use of them.

Reported by: Jenkins

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

This is good, but it doesn't fix everything. There are several Python tests (e.g. frag6.py, nat64.py, ..) that have the same issue. We need this as well:

diff --git a/tests/sys/netpfil/pf/frag6.py b/tests/sys/netpfil/pf/frag6.py
index f274fc28a3bf..108b53874d0b 100644
--- a/tests/sys/netpfil/pf/frag6.py
+++ b/tests/sys/netpfil/pf/frag6.py
@@ -43,6 +43,7 @@ def check_ping_reply(self, packet):
         return False

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_dup_frag_hdr(self):
         "Test packets with duplicate fragment headers"
         srv_vnet = self.vnet_map["vnet2"]
@@ -64,6 +65,7 @@ def test_dup_frag_hdr(self):
             assert not p.getlayer(sp.ICMPv6EchoReply)

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_overlong(self):
         "Test overly long fragmented packet"

@@ -112,6 +114,7 @@ def vnet2_handler(self, vnet):
         ])

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_overlap(self):
         "Ensure we discard packets with overlapping fragments"

diff --git a/tests/sys/netpfil/pf/icmp.py b/tests/sys/netpfil/pf/icmp.py
index e54f9f20a058..6ab649f62be7 100644
--- a/tests/sys/netpfil/pf/icmp.py
+++ b/tests/sys/netpfil/pf/icmp.py
@@ -86,6 +86,7 @@ def checkfn(packet):
         vnet.pipe.send("Got ICMP destination unreachable packet")

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_inner_match(self):
         vnet = self.vnet_map["vnet1"]
         dst_vnet = self.vnet_map["vnet3"]
@@ -160,6 +161,7 @@ def check_icmp_echo(self, sp, payload_size):
         return

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_fragmentation_needed(self):
         ToolsHelper.print_output("/sbin/route add default 192.0.2.1")
diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py
index 64ec5ae15262..070b7a82e6d9 100644
--- a/tests/sys/netpfil/pf/nat64.py
+++ b/tests/sys/netpfil/pf/nat64.py
@@ -93,6 +93,7 @@ def vnet2_handler(self, vnet):
             "pass in on %s inet6 af-to inet from 192.0.2.1" % ifname])

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_tcp_rst(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -126,6 +127,7 @@ def test_tcp_rst(self):
         assert "A" in tcp.flags

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_udp_port_closed(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -147,6 +149,7 @@ def test_udp_port_closed(self):
         assert udp.dport == 1222

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_address_unreachable(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -172,6 +175,7 @@ def test_address_unreachable(self):
         assert ip6.hlim == 62

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_udp_checksum(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

diff --git a/tests/sys/netpfil/pf/nat66.py b/tests/sys/netpfil/pf/nat66.py
index 3a037ac710fc..f93512b5b99c 100644
--- a/tests/sys/netpfil/pf/nat66.py
+++ b/tests/sys/netpfil/pf/nat66.py
@@ -140,6 +140,7 @@ def check_icmp_echo(self, sp, payload_size, src="2001:db8::2"):
         assert found

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_npt_icmp(self):
         cl_vnet = self.vnet_map["vnet1"]
         ifname = cl_vnet.iface_alias_map["if1"].name
@@ -168,6 +169,7 @@ def test_npt_icmp(self):
         self.check_icmp_too_big(sp, 12000, 5000)

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_npt_route_to_icmp(self):
         cl_vnet = self.vnet_map["vnet1"]
         ifname = cl_vnet.iface_alias_map["if1"].name

Do you want to include that with this change, or should we do a separate commit for it?

This revision is now accepted and ready to land.Feb 11 2025, 1:33 PM
ngie added a subscriber: ngie.

The kyuafile solution would have involved less change, but I get the merits/demerits of going that route vs injecting the metadata in the _head() functions.

In D48917#1116124, @kp wrote:

This is good, but it doesn't fix everything. There are several Python tests (e.g. frag6.py, nat64.py, ..) that have the same issue. We need this as well:

diff --git a/tests/sys/netpfil/pf/frag6.py b/tests/sys/netpfil/pf/frag6.py
index f274fc28a3bf..108b53874d0b 100644
--- a/tests/sys/netpfil/pf/frag6.py
+++ b/tests/sys/netpfil/pf/frag6.py
@@ -43,6 +43,7 @@ def check_ping_reply(self, packet):
         return False

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_dup_frag_hdr(self):
         "Test packets with duplicate fragment headers"
         srv_vnet = self.vnet_map["vnet2"]
@@ -64,6 +65,7 @@ def test_dup_frag_hdr(self):
             assert not p.getlayer(sp.ICMPv6EchoReply)

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_overlong(self):
         "Test overly long fragmented packet"

@@ -112,6 +114,7 @@ def vnet2_handler(self, vnet):
         ])

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_overlap(self):
         "Ensure we discard packets with overlapping fragments"

diff --git a/tests/sys/netpfil/pf/icmp.py b/tests/sys/netpfil/pf/icmp.py
index e54f9f20a058..6ab649f62be7 100644
--- a/tests/sys/netpfil/pf/icmp.py
+++ b/tests/sys/netpfil/pf/icmp.py
@@ -86,6 +86,7 @@ def checkfn(packet):
         vnet.pipe.send("Got ICMP destination unreachable packet")

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_inner_match(self):
         vnet = self.vnet_map["vnet1"]
         dst_vnet = self.vnet_map["vnet3"]
@@ -160,6 +161,7 @@ def check_icmp_echo(self, sp, payload_size):
         return

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_fragmentation_needed(self):
         ToolsHelper.print_output("/sbin/route add default 192.0.2.1")
diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py
index 64ec5ae15262..070b7a82e6d9 100644
--- a/tests/sys/netpfil/pf/nat64.py
+++ b/tests/sys/netpfil/pf/nat64.py
@@ -93,6 +93,7 @@ def vnet2_handler(self, vnet):
             "pass in on %s inet6 af-to inet from 192.0.2.1" % ifname])

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_tcp_rst(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -126,6 +127,7 @@ def test_tcp_rst(self):
         assert "A" in tcp.flags

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_udp_port_closed(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -147,6 +149,7 @@ def test_udp_port_closed(self):
         assert udp.dport == 1222

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_address_unreachable(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -172,6 +175,7 @@ def test_address_unreachable(self):
         assert ip6.hlim == 62

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_udp_checksum(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

diff --git a/tests/sys/netpfil/pf/nat66.py b/tests/sys/netpfil/pf/nat66.py
index 3a037ac710fc..f93512b5b99c 100644
--- a/tests/sys/netpfil/pf/nat66.py
+++ b/tests/sys/netpfil/pf/nat66.py
@@ -140,6 +140,7 @@ def check_icmp_echo(self, sp, payload_size, src="2001:db8::2"):
         assert found

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_npt_icmp(self):
         cl_vnet = self.vnet_map["vnet1"]
         ifname = cl_vnet.iface_alias_map["if1"].name
@@ -168,6 +169,7 @@ def test_npt_icmp(self):
         self.check_icmp_too_big(sp, 12000, 5000)

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_npt_route_to_icmp(self):
         cl_vnet = self.vnet_map["vnet1"]
         ifname = cl_vnet.iface_alias_map["if1"].name

Do you want to include that with this change, or should we do a separate commit for it?

I'll commit it separately, given this is already approved.
The reason why those are already being skipped is because there is no pytest installed.

Thank you!

This revision was automatically updated to reflect the committed changes.
In D48917#1116124, @kp wrote:

This is good, but it doesn't fix everything. There are several Python tests (e.g. frag6.py, nat64.py, ..) that have the same issue. We need this as well:

diff --git a/tests/sys/netpfil/pf/frag6.py b/tests/sys/netpfil/pf/frag6.py
index f274fc28a3bf..108b53874d0b 100644
--- a/tests/sys/netpfil/pf/frag6.py
+++ b/tests/sys/netpfil/pf/frag6.py
@@ -43,6 +43,7 @@ def check_ping_reply(self, packet):
         return False

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_dup_frag_hdr(self):
         "Test packets with duplicate fragment headers"
         srv_vnet = self.vnet_map["vnet2"]
@@ -64,6 +65,7 @@ def test_dup_frag_hdr(self):
             assert not p.getlayer(sp.ICMPv6EchoReply)

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_overlong(self):
         "Test overly long fragmented packet"

@@ -112,6 +114,7 @@ def vnet2_handler(self, vnet):
         ])

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_overlap(self):
         "Ensure we discard packets with overlapping fragments"

diff --git a/tests/sys/netpfil/pf/icmp.py b/tests/sys/netpfil/pf/icmp.py
index e54f9f20a058..6ab649f62be7 100644
--- a/tests/sys/netpfil/pf/icmp.py
+++ b/tests/sys/netpfil/pf/icmp.py
@@ -86,6 +86,7 @@ def checkfn(packet):
         vnet.pipe.send("Got ICMP destination unreachable packet")

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_inner_match(self):
         vnet = self.vnet_map["vnet1"]
         dst_vnet = self.vnet_map["vnet3"]
@@ -160,6 +161,7 @@ def check_icmp_echo(self, sp, payload_size):
         return

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_fragmentation_needed(self):
         ToolsHelper.print_output("/sbin/route add default 192.0.2.1")
diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py
index 64ec5ae15262..070b7a82e6d9 100644
--- a/tests/sys/netpfil/pf/nat64.py
+++ b/tests/sys/netpfil/pf/nat64.py
@@ -93,6 +93,7 @@ def vnet2_handler(self, vnet):
             "pass in on %s inet6 af-to inet from 192.0.2.1" % ifname])

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_tcp_rst(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -126,6 +127,7 @@ def test_tcp_rst(self):
         assert "A" in tcp.flags

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_udp_port_closed(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -147,6 +149,7 @@ def test_udp_port_closed(self):
         assert udp.dport == 1222

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_address_unreachable(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

@@ -172,6 +175,7 @@ def test_address_unreachable(self):
         assert ip6.hlim == 62

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_udp_checksum(self):
         ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")

diff --git a/tests/sys/netpfil/pf/nat66.py b/tests/sys/netpfil/pf/nat66.py
index 3a037ac710fc..f93512b5b99c 100644
--- a/tests/sys/netpfil/pf/nat66.py
+++ b/tests/sys/netpfil/pf/nat66.py
@@ -140,6 +140,7 @@ def check_icmp_echo(self, sp, payload_size, src="2001:db8::2"):
         assert found

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_npt_icmp(self):
         cl_vnet = self.vnet_map["vnet1"]
         ifname = cl_vnet.iface_alias_map["if1"].name
@@ -168,6 +169,7 @@ def test_npt_icmp(self):
         self.check_icmp_too_big(sp, 12000, 5000)

     @pytest.mark.require_user("root")
+    @pytest.mark.require_progs(["scapy"])
     def test_npt_route_to_icmp(self):
         cl_vnet = self.vnet_map["vnet1"]
         ifname = cl_vnet.iface_alias_map["if1"].name

Do you want to include that with this change, or should we do a separate commit for it?

Submitted as D48946.

I'm planning on also adding python3 to require.progs. It is possible to have Scapy and not have python3.