]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests: net: add macvlan multicast test for shared source MAC
authorKibaek Yoo <psykibaek@gmail.com>
Sat, 28 Feb 2026 07:16:13 +0000 (16:16 +0900)
committerJakub Kicinski <kuba@kernel.org>
Wed, 4 Mar 2026 02:08:13 +0000 (18:08 -0800)
Add a selftest that verifies multicast delivery to a macvlan bridge
port when the source MAC of the incoming frame matches the macvlan's
own MAC address.

This scenario occurs with protocols like VRRP where multiple hosts
share the same virtual MAC address. Without the corresponding kernel
change, macvlan bridge mode does not handle this case and the
multicast frame is not delivered.

Signed-off-by: Kibaek Yoo <psykibaek@gmail.com>
Link: https://patch.msgid.link/20260228071613.4360-2-psykibaek@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/macvlan_mcast_shared_mac.sh [new file with mode: 0755]

index ede107fa6ea85ba9f7d9b3d03de2cd607cd106ef..997056697ec8e521ca1701044dec94aa7296aa36 100644 (file)
@@ -55,6 +55,7 @@ TEST_PROGS := \
        l2tp.sh \
        link_netns.py \
        lwt_dst_cache_ref_loop.sh \
+       macvlan_mcast_shared_mac.sh \
        msg_zerocopy.sh \
        nat6to4.sh \
        ndisc_unsolicited_na_test.sh \
diff --git a/tools/testing/selftests/net/macvlan_mcast_shared_mac.sh b/tools/testing/selftests/net/macvlan_mcast_shared_mac.sh
new file mode 100755 (executable)
index 0000000..ff5b893
--- /dev/null
@@ -0,0 +1,93 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test multicast delivery to macvlan bridge ports when the source MAC
+# matches the macvlan's own MAC address (e.g., VRRP virtual MAC shared
+# across multiple hosts).
+#
+# Topology:
+#
+#   NS_SRC                          NS_BRIDGE
+#   veth_src (SHARED_MAC) <----->  veth_dst
+#                                     |
+#                                     +-- macvlan0 (bridge mode, SHARED_MAC)
+#
+# A multicast packet sent from NS_SRC with source MAC equal to
+# macvlan0's MAC must still be delivered to macvlan0.
+
+source lib.sh
+
+SHARED_MAC="00:00:5e:00:01:01"
+MCAST_ADDR="239.0.0.1"
+
+setup() {
+       setup_ns NS_SRC NS_BRIDGE
+
+       ip -net "${NS_BRIDGE}" link add veth_dst type veth \
+               peer name veth_src netns "${NS_SRC}"
+
+       ip -net "${NS_SRC}" link set veth_src address "${SHARED_MAC}"
+       ip -net "${NS_SRC}" link set veth_src up
+       ip -net "${NS_SRC}" addr add 192.168.1.1/24 dev veth_src
+
+       ip -net "${NS_BRIDGE}" link set veth_dst up
+
+       ip -net "${NS_BRIDGE}" link add macvlan0 link veth_dst \
+               type macvlan mode bridge
+       ip -net "${NS_BRIDGE}" link set macvlan0 address "${SHARED_MAC}"
+       ip -net "${NS_BRIDGE}" link set macvlan0 up
+       ip -net "${NS_BRIDGE}" addr add 192.168.1.2/24 dev macvlan0
+
+       # Accept all multicast so the mc_filter passes for any group.
+       ip -net "${NS_BRIDGE}" link set macvlan0 allmulticast on
+}
+
+cleanup() {
+       rm -f "${CAPFILE}" "${CAPOUT}"
+       cleanup_ns "${NS_SRC}" "${NS_BRIDGE}"
+}
+
+test_macvlan_mcast_shared_mac() {
+       CAPFILE=$(mktemp)
+       CAPOUT=$(mktemp)
+
+       echo "Testing multicast delivery to macvlan with shared source MAC"
+
+       # Listen for one ICMP packet on macvlan0.
+       timeout 5s ip netns exec "${NS_BRIDGE}" \
+               tcpdump -i macvlan0 -c 1 -w "${CAPFILE}" icmp &> "${CAPOUT}" &
+       local pid=$!
+       if ! slowwait 1 grep -qs "listening" "${CAPOUT}"; then
+               echo "[FAIL] tcpdump did not start listening"
+               return "${ksft_fail}"
+       fi
+
+       # Send multicast ping from NS_SRC; source MAC equals macvlan0's MAC.
+       ip netns exec "${NS_SRC}" \
+               ping -W 0.1 -c 3 -I veth_src "${MCAST_ADDR}" &> /dev/null
+
+       wait "${pid}"
+
+       local count
+       count=$(tcpdump -r "${CAPFILE}" 2>/dev/null | wc -l)
+       if [[ "${count}" -ge 1 ]]; then
+               echo "[ OK ]"
+               return "${ksft_pass}"
+       else
+               echo "[FAIL] expected at least 1 ICMP packet on macvlan0," \
+                       "got ${count}"
+               return "${ksft_fail}"
+       fi
+}
+
+if [ ! -x "$(command -v tcpdump)" ]; then
+       echo "SKIP: Could not run test without tcpdump tool"
+       exit "${ksft_skip}"
+fi
+
+trap cleanup EXIT
+
+setup
+test_macvlan_mcast_shared_mac
+
+exit $?