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 xfail_on_veth $h1 \ 159 check_rcv $rcv_if_name "Unicast IPv4 to unknown MAC address" \ 160 "$smac > $UNKNOWN_UC_ADDR1, ethertype IPv4 (0x0800)" \ 161 false 162 163 check_rcv $rcv_if_name "Unicast IPv4 to unknown MAC address, promisc" \ 164 "$smac > $UNKNOWN_UC_ADDR2, ethertype IPv4 (0x0800)" \ 165 true 166 167 xfail_on_veth $h1 \ 168 check_rcv $rcv_if_name \ 169 "Unicast IPv4 to unknown MAC address, allmulti" \ 170 "$smac > $UNKNOWN_UC_ADDR3, ethertype IPv4 (0x0800)" \ 171 false 172 173 check_rcv $rcv_if_name "Multicast IPv4 to joined group" \ 174 "$smac > $JOINED_MACV4_MC_ADDR, ethertype IPv4 (0x0800)" \ 175 true 176 177 xfail_on_veth $h1 \ 178 check_rcv $rcv_if_name \ 179 "Multicast IPv4 to unknown group" \ 180 "$smac > $UNKNOWN_MACV4_MC_ADDR1, ethertype IPv4 (0x0800)" \ 181 false 182 183 check_rcv $rcv_if_name "Multicast IPv4 to unknown group, promisc" \ 184 "$smac > $UNKNOWN_MACV4_MC_ADDR2, ethertype IPv4 (0x0800)" \ 185 true 186 187 check_rcv $rcv_if_name "Multicast IPv4 to unknown group, allmulti" \ 188 "$smac > $UNKNOWN_MACV4_MC_ADDR3, ethertype IPv4 (0x0800)" \ 189 true 190 191 check_rcv $rcv_if_name "Multicast IPv6 to joined group" \ 192 "$smac > $JOINED_MACV6_MC_ADDR, ethertype IPv6 (0x86dd)" \ 193 true 194 195 xfail_on_veth $h1 \ 196 check_rcv $rcv_if_name "Multicast IPv6 to unknown group" \ 197 "$smac > $UNKNOWN_MACV6_MC_ADDR1, ethertype IPv6 (0x86dd)" \ 198 false 199 200 check_rcv $rcv_if_name "Multicast IPv6 to unknown group, promisc" \ 201 "$smac > $UNKNOWN_MACV6_MC_ADDR2, ethertype IPv6 (0x86dd)" \ 202 true 203 204 check_rcv $rcv_if_name "Multicast IPv6 to unknown group, allmulti" \ 205 "$smac > $UNKNOWN_MACV6_MC_ADDR3, ethertype IPv6 (0x86dd)" \ 206 true 207 208 tcpdump_cleanup $rcv_if_name 209} 210 211h1_create() 212{ 213 simple_if_init $h1 $H1_IPV4/24 $H1_IPV6/64 214} 215 216h1_destroy() 217{ 218 simple_if_fini $h1 $H1_IPV4/24 $H1_IPV6/64 219} 220 221h2_create() 222{ 223 simple_if_init $h2 $H2_IPV4/24 $H2_IPV6/64 224} 225 226h2_destroy() 227{ 228 simple_if_fini $h2 $H2_IPV4/24 $H2_IPV6/64 229} 230 231bridge_create() 232{ 233 ip link add br0 type bridge 234 ip link set br0 address $BRIDGE_ADDR 235 ip link set br0 up 236 237 ip link set $h2 master br0 238 ip link set $h2 up 239 240 simple_if_init br0 $H2_IPV4/24 $H2_IPV6/64 241} 242 243bridge_destroy() 244{ 245 simple_if_fini br0 $H2_IPV4/24 $H2_IPV6/64 246 247 ip link del br0 248} 249 250standalone() 251{ 252 h1_create 253 h2_create 254 255 ip link add link $h2 name macvlan0 type macvlan mode private 256 ip link set macvlan0 address $MACVLAN_ADDR 257 ip link set macvlan0 up 258 259 run_test $h2 260 261 ip link del macvlan0 262 263 h2_destroy 264 h1_destroy 265} 266 267bridge() 268{ 269 h1_create 270 bridge_create 271 272 ip link add link br0 name macvlan0 type macvlan mode private 273 ip link set macvlan0 address $MACVLAN_ADDR 274 ip link set macvlan0 up 275 276 run_test br0 277 278 ip link del macvlan0 279 280 bridge_destroy 281 h1_destroy 282} 283 284cleanup() 285{ 286 pre_cleanup 287 vrf_cleanup 288} 289 290setup_prepare() 291{ 292 vrf_prepare 293 # setup_wait() needs this 294 ip link set $h1 up 295 ip link set $h2 up 296} 297 298trap cleanup EXIT 299 300setup_prepare 301setup_wait 302 303tests_run 304 305exit $EXIT_STATUS 306