]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/net: Add selftest for IPv4 RTM_GETMULTICAST support
authorYuyang Huang <yuyanghuang@google.com>
Fri, 7 Feb 2025 11:08:36 +0000 (20:08 +0900)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 11 Feb 2025 10:26:53 +0000 (11:26 +0100)
This change introduces a new selftest case to verify the functionality
of dumping IPv4 multicast addresses using the RTM_GETMULTICAST netlink
message. The test utilizes the ynl library to interact with the
netlink interface and validate that the kernel correctly reports the
joined IPv4 multicast addresses.

To run the test, execute the following command:

$ vng -v --user root --cpus 16 -- \
    make -C tools/testing/selftests TARGETS=net \
    TEST_PROGS=rtnetlink.py TEST_GEN_PROGS="" run_tests

Cc: Maciej Żenczykowski <maze@google.com>
Cc: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
Link: https://patch.msgid.link/20250207110836.2407224-2-yuyanghuang@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/netlink/specs/rt_addr.yaml
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/lib/py/__init__.py
tools/testing/selftests/net/lib/py/ynl.py
tools/testing/selftests/net/rtnetlink.py [new file with mode: 0755]

index cbee1cedb177c440fdd3f20d882c1ac3b0909c7a..5dd5469044c7930123da9cf7136f419dda4d5650 100644 (file)
@@ -168,6 +168,29 @@ operations:
         reply:
           value: 20
           attributes: *ifaddr-all
+    -
+      name: getmaddrs
+      doc: Get / dump IPv4/IPv6 multicast addresses.
+      attribute-set: addr-attrs
+      fixed-header: ifaddrmsg
+      do:
+        request:
+          value: 58
+          attributes:
+            - ifa-family
+            - ifa-index
+        reply:
+          value: 58
+          attributes: &mcaddr-attrs
+            - ifa-multicast
+            - ifa-cacheinfo
+      dump:
+        request:
+          value: 58
+            - ifa-family
+        reply:
+          value: 58
+          attributes: *mcaddr-attrs
 
 mcast-groups:
   list:
index 73ee88d6b043004be23b444de667a1d99a6045de..e2f03211f9b382affcffdb1bb69549147f24a33b 100644 (file)
@@ -36,6 +36,7 @@ TEST_PROGS += cmsg_so_priority.sh
 TEST_PROGS += cmsg_time.sh cmsg_ipv6.sh
 TEST_PROGS += netns-name.sh
 TEST_PROGS += nl_netdev.py
+TEST_PROGS += rtnetlink.py
 TEST_PROGS += srv6_end_dt46_l3vpn_test.sh
 TEST_PROGS += srv6_end_dt4_l3vpn_test.sh
 TEST_PROGS += srv6_end_dt6_l3vpn_test.sh
index 54d8f5eba8101ac132f4ac5be0e0bd58315a9341..7294578593165c0afa5f2844b0f2d84a6c25fbae 100644 (file)
@@ -5,5 +5,5 @@ from .ksft import *
 from .netns import NetNS
 from .nsim import *
 from .utils import *
-from .ynl import NlError, YnlFamily, EthtoolFamily, NetdevFamily, RtnlFamily
+from .ynl import NlError, YnlFamily, EthtoolFamily, NetdevFamily, RtnlFamily, RtnlAddrFamily
 from .ynl import NetshaperFamily
index ad1e36baee2a165104e1181c40d25cb731ea7e5e..8986c584cb371ae354430353517b76bc8503dd69 100644 (file)
@@ -42,6 +42,10 @@ class RtnlFamily(YnlFamily):
         super().__init__((SPEC_PATH / Path('rt_link.yaml')).as_posix(),
                          schema='', recv_size=recv_size)
 
+class RtnlAddrFamily(YnlFamily):
+    def __init__(self, recv_size=0):
+        super().__init__((SPEC_PATH / Path('rt_addr.yaml')).as_posix(),
+                         schema='', recv_size=recv_size)
 
 class NetdevFamily(YnlFamily):
     def __init__(self, recv_size=0):
diff --git a/tools/testing/selftests/net/rtnetlink.py b/tools/testing/selftests/net/rtnetlink.py
new file mode 100755 (executable)
index 0000000..8095088
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+from lib.py import ksft_exit, ksft_run, ksft_ge, RtnlAddrFamily
+import socket
+
+IPV4_ALL_HOSTS_MULTICAST = b'\xe0\x00\x00\x01'
+
+def dump_mcaddr_check(rtnl: RtnlAddrFamily) -> None:
+    """
+    Verify that at least one interface has the IPv4 all-hosts multicast address.
+    At least the loopback interface should have this address.
+    """
+
+    addresses = rtnl.getmaddrs({"ifa-family": socket.AF_INET}, dump=True)
+
+    all_host_multicasts = [
+        addr for addr in addresses if addr['ifa-multicast'] == IPV4_ALL_HOSTS_MULTICAST
+    ]
+
+    ksft_ge(len(all_host_multicasts), 1,
+            "No interface found with the IPv4 all-hosts multicast address")
+
+def main() -> None:
+    rtnl = RtnlAddrFamily()
+    ksft_run([dump_mcaddr_check], args=(rtnl, ))
+    ksft_exit()
+
+if __name__ == "__main__":
+    main()