| #!/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 $? |