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