git: 5e2e3615d91f - main - netinet tests: test carp source MAC address

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Fri, 07 Apr 2023 15:57:54 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=5e2e3615d91f9c0c688987915ff5c8de23c22bde

commit 5e2e3615d91f9c0c688987915ff5c8de23c22bde
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-04-06 16:10:27 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-04-07 15:56:45 +0000

    netinet tests: test carp source MAC address
    
    Ensure that (multicast) CARP packets are sent with the expected source
    MAC address.
    
    Reviewed by:    melifaro
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D39454
---
 tests/sys/netinet/Makefile |  2 ++
 tests/sys/netinet/carp.py  | 53 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/tests/sys/netinet/Makefile b/tests/sys/netinet/Makefile
index d6324367606f..69fffa63fb79 100644
--- a/tests/sys/netinet/Makefile
+++ b/tests/sys/netinet/Makefile
@@ -24,6 +24,8 @@ ATF_TESTS_SH=	arp \
 		output \
 		redirect
 
+ATF_TESTS_PYTEST+=	carp.py
+
 TEST_METADATA.divert+=	required_programs="python"
 TEST_METADATA.forward+=	required_programs="python"
 TEST_METADATA.output+=	required_programs="python"
diff --git a/tests/sys/netinet/carp.py b/tests/sys/netinet/carp.py
new file mode 100644
index 000000000000..ac2c5547fe97
--- /dev/null
+++ b/tests/sys/netinet/carp.py
@@ -0,0 +1,53 @@
+import pytest
+from atf_python.sys.net.tools import ToolsHelper
+from atf_python.sys.net.vnet import VnetTestTemplate
+
+sc = None
+
+
+def filter_f(x):
+    ip = x.getlayer(sc.IP)
+    if not ip:
+        return False
+
+    return ip.proto == 112
+
+
+class TestCarp(VnetTestTemplate):
+    REQUIRED_MODULES = ["carp"]
+    TOPOLOGY = {
+        "vnet1": {"ifaces": ["if1"]},
+        "if1": {"prefixes4": [("192.0.2.1/24", "192.0.2.2/24")]},
+    }
+
+    def setup_method(self, method):
+        global sc
+        if sc is None:
+            import scapy.all as _sc
+
+            sc = _sc
+        super().setup_method(method)
+
+    @classmethod
+    def check_carp_src_mac(self, pkts):
+        for p in pkts:
+            if not filter_f(p):
+                continue
+
+            print("Packet src mac {}".format(p.src))
+
+            if p.src != "00:00:5e:00:01:01":
+                raise
+
+    def test_source_mac(self):
+        "Test carp packets source address"
+
+        if1 = self.vnet.iface_alias_map["if1"]
+
+        ToolsHelper.print_output(
+            "ifconfig {} add vhid 1 192.0.2.203/24".format(if1.name)
+        )
+
+        carp_pkts = sc.sniff(iface=if1.name, stop_filter=filter_f, timeout=5)
+
+        self.check_carp_src_mac(carp_pkts)