xref: /linux/tools/testing/selftests/net/macvlan_mcast_shared_mac.sh (revision 05e352444b2430de4b183b4a988085381e5fd6ad)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test multicast delivery to macvlan bridge ports when the source MAC
5# matches the macvlan's own MAC address (e.g., VRRP virtual MAC shared
6# across multiple hosts).
7#
8# Topology:
9#
10#   NS_SRC                          NS_BRIDGE
11#   veth_src (SHARED_MAC) <----->  veth_dst
12#                                     |
13#                                     +-- macvlan0 (bridge mode, SHARED_MAC)
14#
15# A multicast packet sent from NS_SRC with source MAC equal to
16# macvlan0's MAC must still be delivered to macvlan0.
17
18source lib.sh
19
20SHARED_MAC="00:00:5e:00:01:01"
21MCAST_ADDR="239.0.0.1"
22
23setup() {
24	setup_ns NS_SRC NS_BRIDGE
25
26	ip -net "${NS_BRIDGE}" link add veth_dst type veth \
27		peer name veth_src netns "${NS_SRC}"
28
29	ip -net "${NS_SRC}" link set veth_src address "${SHARED_MAC}"
30	ip -net "${NS_SRC}" link set veth_src up
31	ip -net "${NS_SRC}" addr add 192.168.1.1/24 dev veth_src
32
33	ip -net "${NS_BRIDGE}" link set veth_dst up
34
35	ip -net "${NS_BRIDGE}" link add macvlan0 link veth_dst \
36		type macvlan mode bridge
37	ip -net "${NS_BRIDGE}" link set macvlan0 address "${SHARED_MAC}"
38	ip -net "${NS_BRIDGE}" link set macvlan0 up
39	ip -net "${NS_BRIDGE}" addr add 192.168.1.2/24 dev macvlan0
40
41	# Accept all multicast so the mc_filter passes for any group.
42	ip -net "${NS_BRIDGE}" link set macvlan0 allmulticast on
43}
44
45cleanup() {
46	rm -f "${CAPFILE}" "${CAPOUT}"
47	cleanup_ns "${NS_SRC}" "${NS_BRIDGE}"
48}
49
50test_macvlan_mcast_shared_mac() {
51	CAPFILE=$(mktemp)
52	CAPOUT=$(mktemp)
53
54	echo "Testing multicast delivery to macvlan with shared source MAC"
55
56	# Listen for one ICMP packet on macvlan0.
57	timeout 5s ip netns exec "${NS_BRIDGE}" \
58		tcpdump -i macvlan0 -c 1 -w "${CAPFILE}" icmp &> "${CAPOUT}" &
59	local pid=$!
60	if ! slowwait 1 grep -qs "listening" "${CAPOUT}"; then
61		echo "[FAIL] tcpdump did not start listening"
62		return "${ksft_fail}"
63	fi
64
65	# Send multicast ping from NS_SRC; source MAC equals macvlan0's MAC.
66	ip netns exec "${NS_SRC}" \
67		ping -W 0.1 -c 3 -I veth_src "${MCAST_ADDR}" &> /dev/null
68
69	wait "${pid}"
70
71	local count
72	count=$(tcpdump -r "${CAPFILE}" 2>/dev/null | wc -l)
73	if [[ "${count}" -ge 1 ]]; then
74		echo "[ OK ]"
75		return "${ksft_pass}"
76	else
77		echo "[FAIL] expected at least 1 ICMP packet on macvlan0," \
78			"got ${count}"
79		return "${ksft_fail}"
80	fi
81}
82
83if [ ! -x "$(command -v tcpdump)" ]; then
84	echo "SKIP: Could not run test without tcpdump tool"
85	exit "${ksft_skip}"
86fi
87
88trap cleanup EXIT
89
90setup
91test_macvlan_mcast_shared_mac
92
93exit $?
94