1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4ALL_TESTS="standalone bridge" 5NUM_NETIFS=2 6PING_COUNT=1 7REQUIRE_MTOOLS=yes 8REQUIRE_MZ=no 9 10source lib.sh 11 12H1_IPV4="192.0.2.1" 13H2_IPV4="192.0.2.2" 14H1_IPV6="2001:db8:1::1" 15H2_IPV6="2001:db8:1::2" 16 17BRIDGE_ADDR="00:00:de:ad:be:ee" 18MACVLAN_ADDR="00:00:de:ad:be:ef" 19UNKNOWN_UC_ADDR1="de:ad:be:ef:ee:03" 20UNKNOWN_UC_ADDR2="de:ad:be:ef:ee:04" 21UNKNOWN_UC_ADDR3="de:ad:be:ef:ee:05" 22JOINED_IPV4_MC_ADDR="225.1.2.3" 23UNKNOWN_IPV4_MC_ADDR1="225.1.2.4" 24UNKNOWN_IPV4_MC_ADDR2="225.1.2.5" 25UNKNOWN_IPV4_MC_ADDR3="225.1.2.6" 26JOINED_IPV6_MC_ADDR="ff2e::0102:0304" 27UNKNOWN_IPV6_MC_ADDR1="ff2e::0102:0305" 28UNKNOWN_IPV6_MC_ADDR2="ff2e::0102:0306" 29UNKNOWN_IPV6_MC_ADDR3="ff2e::0102:0307" 30 31JOINED_MACV4_MC_ADDR="01:00:5e:01:02:03" 32UNKNOWN_MACV4_MC_ADDR1="01:00:5e:01:02:04" 33UNKNOWN_MACV4_MC_ADDR2="01:00:5e:01:02:05" 34UNKNOWN_MACV4_MC_ADDR3="01:00:5e:01:02:06" 35JOINED_MACV6_MC_ADDR="33:33:01:02:03:04" 36UNKNOWN_MACV6_MC_ADDR1="33:33:01:02:03:05" 37UNKNOWN_MACV6_MC_ADDR2="33:33:01:02:03:06" 38UNKNOWN_MACV6_MC_ADDR3="33:33:01:02:03:07" 39 40NON_IP_MC="01:02:03:04:05:06" 41NON_IP_PKT="00:04 48:45:4c:4f" 42BC="ff:ff:ff:ff:ff:ff" 43 44# Disable promisc to ensure we don't receive unknown MAC DA packets 45export TCPDUMP_EXTRA_FLAGS="-pl" 46 47h1=${NETIFS[p1]} 48h2=${NETIFS[p2]} 49 50send_non_ip() 51{ 52 local if_name=$1 53 local smac=$2 54 local dmac=$3 55 56 $MZ -q $if_name "$dmac $smac $NON_IP_PKT" 57} 58 59send_uc_ipv4() 60{ 61 local if_name=$1 62 local dmac=$2 63 64 ip neigh add $H2_IPV4 lladdr $dmac dev $if_name 65 ping_do $if_name $H2_IPV4 66 ip neigh del $H2_IPV4 dev $if_name 67} 68 69check_rcv() 70{ 71 local if_name=$1 72 local type=$2 73 local pattern=$3 74 local should_receive=$4 75 local should_fail= 76 77 [ $should_receive = true ] && should_fail=0 || should_fail=1 78 RET=0 79 80 tcpdump_show $if_name | grep -q "$pattern" 81 82 check_err_fail "$should_fail" "$?" "reception" 83 84 log_test "$if_name: $type" 85} 86 87mc_route_prepare() 88{ 89 local if_name=$1 90 local vrf_name=$(master_name_get $if_name) 91 92 ip route add 225.100.1.0/24 dev $if_name vrf $vrf_name 93 ip -6 route add ff2e::/64 dev $if_name vrf $vrf_name 94} 95 96mc_route_destroy() 97{ 98 local if_name=$1 99 local vrf_name=$(master_name_get $if_name) 100 101 ip route del 225.100.1.0/24 dev $if_name vrf $vrf_name 102 ip -6 route del ff2e::/64 dev $if_name vrf $vrf_name 103} 104 105run_test() 106{ 107 local rcv_if_name=$1 108 local smac=$(mac_get $h1) 109 local rcv_dmac=$(mac_get $rcv_if_name) 110 111 tcpdump_start $rcv_if_name 112 113 mc_route_prepare $h1 114 mc_route_prepare $rcv_if_name 115 116 send_uc_ipv4 $h1 $rcv_dmac 117 send_uc_ipv4 $h1 $MACVLAN_ADDR 118 send_uc_ipv4 $h1 $UNKNOWN_UC_ADDR1 119 120 ip link set dev $rcv_if_name promisc on 121 send_uc_ipv4 $h1 $UNKNOWN_UC_ADDR2 122 mc_send $h1 $UNKNOWN_IPV4_MC_ADDR2 123 mc_send $h1 $UNKNOWN_IPV6_MC_ADDR2 124 ip link set dev $rcv_if_name promisc off 125 126 mc_join $rcv_if_name $JOINED_IPV4_MC_ADDR 127 mc_send $h1 $JOINED_IPV4_MC_ADDR 128 mc_leave 129 130 mc_join $rcv_if_name $JOINED_IPV6_MC_ADDR 131 mc_send $h1 $JOINED_IPV6_MC_ADDR 132 mc_leave 133 134 mc_send $h1 $UNKNOWN_IPV4_MC_ADDR1 135 mc_send $h1 $UNKNOWN_IPV6_MC_ADDR1 136 137 ip link set dev $rcv_if_name allmulticast on 138 send_uc_ipv4 $h1 $UNKNOWN_UC_ADDR3 139 mc_send $h1 $UNKNOWN_IPV4_MC_ADDR3 140 mc_send $h1 $UNKNOWN_IPV6_MC_ADDR3 141 ip link set dev $rcv_if_name allmulticast off 142 143 mc_route_destroy $rcv_if_name 144 mc_route_destroy $h1 145 146 sleep 1 147 148 tcpdump_stop $rcv_if_name 149 150 check_rcv $rcv_if_name "Unicast IPv4 to primary MAC address" \ 151 "$smac > $rcv_dmac, ethertype IPv4 (0x0800)" \ 152 true 153 154 check_rcv $rcv_if_name "Unicast IPv4 to macvlan MAC address" \ 155 "$smac > $MACVLAN_ADDR, ethertype IPv4 (0x0800)" \ 156 true 157 158 check_rcv $rcv_if_name "Unicast IPv4 to unknown MAC address" \ 159 "$smac > $UNKNOWN_UC_ADDR1, ethertype IPv4 (0x0800)" \ 160 false 161 162 check_rcv $rcv_if_name "Unicast IPv4 to unknown MAC address, promisc" \ 163 "$smac > $UNKNOWN_UC_ADDR2, ethertype IPv4 (0x0800)" \ 164 true 165 166 check_rcv $rcv_if_name "Unicast IPv4 to unknown MAC address, allmulti" \ 167 "$smac > $UNKNOWN_UC_ADDR3, ethertype IPv4 (0x0800)" \ 168 false 169 170 check_rcv $rcv_if_name "Multicast IPv4 to joined group" \ 171 "$smac > $JOINED_MACV4_MC_ADDR, ethertype IPv4 (0x0800)" \ 172 true 173 174 check_rcv $rcv_if_name "Multicast IPv4 to unknown group" \ 175 "$smac > $UNKNOWN_MACV4_MC_ADDR1, ethertype IPv4 (0x0800)" \ 176 false 177 178 check_rcv $rcv_if_name "Multicast IPv4 to unknown group, promisc" \ 179 "$smac > $UNKNOWN_MACV4_MC_ADDR2, ethertype IPv4 (0x0800)" \ 180 true 181 182 check_rcv $rcv_if_name "Multicast IPv4 to unknown group, allmulti" \ 183 "$smac > $UNKNOWN_MACV4_MC_ADDR3, ethertype IPv4 (0x0800)" \ 184 true 185 186 check_rcv $rcv_if_name "Multicast IPv6 to joined group" \ 187 "$smac > $JOINED_MACV6_MC_ADDR, ethertype IPv6 (0x86dd)" \ 188 true 189 190 check_rcv $rcv_if_name "Multicast IPv6 to unknown group" \ 191 "$smac > $UNKNOWN_MACV6_MC_ADDR1, ethertype IPv6 (0x86dd)" \ 192 false 193 194 check_rcv $rcv_if_name "Multicast IPv6 to unknown group, promisc" \ 195 "$smac > $UNKNOWN_MACV6_MC_ADDR2, ethertype IPv6 (0x86dd)" \ 196 true 197 198 check_rcv $rcv_if_name "Multicast IPv6 to unknown group, allmulti" \ 199 "$smac > $UNKNOWN_MACV6_MC_ADDR3, ethertype IPv6 (0x86dd)" \ 200 true 201 202 tcpdump_cleanup $rcv_if_name 203} 204 205h1_create() 206{ 207 simple_if_init $h1 $H1_IPV4/24 $H1_IPV6/64 208} 209 210h1_destroy() 211{ 212 simple_if_fini $h1 $H1_IPV4/24 $H1_IPV6/64 213} 214 215h2_create() 216{ 217 simple_if_init $h2 $H2_IPV4/24 $H2_IPV6/64 218} 219 220h2_destroy() 221{ 222 simple_if_fini $h2 $H2_IPV4/24 $H2_IPV6/64 223} 224 225bridge_create() 226{ 227 ip link add br0 type bridge 228 ip link set br0 address $BRIDGE_ADDR 229 ip link set br0 up 230 231 ip link set $h2 master br0 232 ip link set $h2 up 233 234 simple_if_init br0 $H2_IPV4/24 $H2_IPV6/64 235} 236 237bridge_destroy() 238{ 239 simple_if_fini br0 $H2_IPV4/24 $H2_IPV6/64 240 241 ip link del br0 242} 243 244standalone() 245{ 246 h1_create 247 h2_create 248 249 ip link add link $h2 name macvlan0 type macvlan mode private 250 ip link set macvlan0 address $MACVLAN_ADDR 251 ip link set macvlan0 up 252 253 run_test $h2 254 255 ip link del macvlan0 256 257 h2_destroy 258 h1_destroy 259} 260 261bridge() 262{ 263 h1_create 264 bridge_create 265 266 ip link add link br0 name macvlan0 type macvlan mode private 267 ip link set macvlan0 address $MACVLAN_ADDR 268 ip link set macvlan0 up 269 270 run_test br0 271 272 ip link del macvlan0 273 274 bridge_destroy 275 h1_destroy 276} 277 278cleanup() 279{ 280 pre_cleanup 281 282 ip link set $h2 down 283 ip link set $h1 down 284 285 vrf_cleanup 286} 287 288setup_prepare() 289{ 290 vrf_prepare 291 # setup_wait() needs this 292 ip link set $h1 up 293 ip link set $h2 up 294} 295 296trap cleanup EXIT 297 298setup_prepare 299setup_wait 300 301tests_run 302 303exit $EXIT_STATUS 304