94 lines
2.4 KiB
Bash
Executable File
94 lines
2.4 KiB
Bash
Executable File
#!/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 $?
|