FILE
bridge_fdb_local_vlan_0.sh
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/net/forwarding/bridge_fdb_local_vlan_0.sh
1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# +-----------------------+ +-----------------------+ +-----------------------+ 5# | H1 (vrf) | | H2 (vrf) | | H3 (vrf) | 6# | + $h1 | | + $h2 | | + $h3 | 7# | | 192.0.2.1/28 | | | 192.0.2.2/28 | | | 192.0.2.18/28 | 8# | | 2001:db8:1::1/64 | | | 2001:db8:1::2/64 | | | 2001:db8:2::2/64 | 9# | | | | | | | | | 10# +----|------------------+ +----|------------------+ +----|------------------+ 11# | | | 12# +----|-------------------------|-------------------------|------------------+ 13# | +--|-------------------------|------------------+ | | 14# | | + $swp1 + $swp2 | + $swp3 | 15# | | | 192.0.2.17/28 | 16# | | BR1 (802.1q) | 2001:db8:2::1/64 | 17# | | 192.0.2.3/28 | | 18# | | 2001:db8:1::3/64 | | 19# | +-----------------------------------------------+ SW | 20# +---------------------------------------------------------------------------+ 21# 22#shellcheck disable=SC2317 # SC doesn't see our uses of functions. 23#shellcheck disable=SC2034 # ... and global variables 24 25ALL_TESTS=" 26 test_d_no_sharing 27 test_d_sharing 28 test_q_no_sharing 29 test_q_sharing 30 test_addr_set 31" 32 33NUM_NETIFS=6 34source lib.sh 35 36pMAC=00:11:22:33:44:55 37bMAC=00:11:22:33:44:66 38mMAC=00:11:22:33:44:77 39xMAC=00:11:22:33:44:88 40 41host_create() 42{ 43 local h=$1; shift 44 local ipv4=$1; shift 45 local ipv6=$1; shift 46 47 adf_simple_if_init "$h" "$ipv4" "$ipv6" 48 adf_ip_route_add vrf "v$h" 192.0.2.16/28 nexthop via 192.0.2.3 49 adf_ip_route_add vrf "v$h" 2001:db8:2::/64 nexthop via 2001:db8:1::3 50} 51 52h3_create() 53{ 54 adf_simple_if_init "$h3" 192.0.2.18/28 2001:db8:2::2/64 55 adf_ip_route_add vrf "v$h3" 192.0.2.0/28 nexthop via 192.0.2.17 56 adf_ip_route_add vrf "v$h3" 2001:db8:1::/64 nexthop via 2001:db8:2::1 57 58 tc qdisc add dev "$h3" clsact 59 defer tc qdisc del dev "$h3" clsact 60 61 tc filter add dev "$h3" ingress proto ip pref 104 \ 62 flower skip_hw ip_proto udp dst_port 4096 \ 63 action pass 64 defer tc filter del dev "$h3" ingress proto ip pref 104 65 66 tc qdisc add dev "$h2" clsact 67 defer tc qdisc del dev "$h2" clsact 68 69 tc filter add dev "$h2" ingress proto ip pref 104 \ 70 flower skip_hw ip_proto udp dst_port 4096 \ 71 action pass 72 defer tc filter del dev "$h2" ingress proto ip pref 104 73} 74 75switch_create() 76{ 77 adf_ip_link_set_up "$swp1" 78 79 adf_ip_link_set_up "$swp2" 80 81 adf_ip_addr_add "$swp3" 192.0.2.17/28 82 adf_ip_addr_add "$swp3" 2001:db8:2::1/64 83 adf_ip_link_set_up "$swp3" 84} 85 86setup_prepare() 87{ 88 h1=${NETIFS[p1]} 89 swp1=${NETIFS[p2]} 90 91 swp2=${NETIFS[p3]} 92 h2=${NETIFS[p4]} 93 94 swp3=${NETIFS[p5]} 95 h3=${NETIFS[p6]} 96 97 adf_vrf_prepare 98 adf_forwarding_enable 99 100 host_create "$h1" 192.0.2.1/28 2001:db8:1::1/64 101 host_create "$h2" 192.0.2.2/28 2001:db8:1::2/64 102 h3_create 103 104 switch_create 105} 106 107adf_bridge_configure() 108{ 109 local dev 110 111 adf_ip_addr_add br 192.0.2.3/28 112 adf_ip_addr_add br 2001:db8:1::3/64 113 114 adf_bridge_vlan_add dev br vid 1 pvid untagged self 115 adf_bridge_vlan_add dev br vid 2 self 116 adf_bridge_vlan_add dev br vid 3 self 117 118 for dev in "$swp1" "$swp2"; do 119 adf_ip_link_set_master "$dev" br 120 adf_bridge_vlan_add dev "$dev" vid 1 pvid untagged 121 adf_bridge_vlan_add dev "$dev" vid 2 122 adf_bridge_vlan_add dev "$dev" vid 3 123 done 124} 125 126adf_bridge_create() 127{ 128 local mac 129 130 adf_ip_link_add br up type bridge vlan_default_pvid 0 "$@" 131 mac=$(mac_get br) 132 adf_bridge_configure 133 adf_ip_link_set_addr br "$mac" 134} 135 136check_fdb_local_vlan_0_support() 137{ 138 if adf_ip_link_add XXbr up type bridge vlan_filtering 1 \ 139 fdb_local_vlan_0 1 &>/dev/null; then 140 return 0 141 fi 142 143 log_test_skip "FDB sharing" \ 144 "iproute 2 or the kernel do not support fdb_local_vlan_0" 145} 146 147check_mac_presence() 148{ 149 local should_fail=$1; shift 150 local dev=$1; shift 151 local vlan=$1; shift 152 local mac 153 154 mac=$(mac_get "$dev") 155 156 if ((vlan == 0)); then 157 vlan=null 158 fi 159 160 bridge -j fdb show dev "$dev" | 161 jq -e --arg mac "$mac" --argjson vlan "$vlan" \ 162 '.[] | select(.mac == $mac) | select(.vlan == $vlan)' > /dev/null 163 check_err_fail "$should_fail" $? "FDB dev $dev vid $vlan addr $mac exists" 164} 165 166do_sharing_test() 167{ 168 local should_fail=$1; shift 169 local what=$1; shift 170 local dev 171 172 RET=0 173 174 for dev in "$swp1" "$swp2" br; do 175 check_mac_presence 0 "$dev" 0 176 check_mac_presence "$should_fail" "$dev" 1 177 check_mac_presence "$should_fail" "$dev" 2 178 check_mac_presence "$should_fail" "$dev" 3 179 done 180 181 log_test "$what" 182} 183 184do_end_to_end_test() 185{ 186 local mac=$1; shift 187 local what=$1; shift 188 local probe_dev=${1-$h3}; shift 189 local expect=${1-10}; shift 190 191 local t0 192 local t1 193 local dd 194 195 RET=0 196 197 # In mausezahn, use $dev MAC as the destination MAC. In the MAC sharing 198 # context, that will cause an FDB miss on VLAN 1 and prompt a second 199 # lookup in VLAN 0. 200 201 t0=$(tc_rule_stats_get "$probe_dev" 104 ingress) 202 203 $MZ "$h1" -c 10 -p 64 -a own -b "$mac" \ 204 -A 192.0.2.1 -B 192.0.2.18 -t udp "dp=4096,sp=2048" -q 205 sleep 1 206 207 t1=$(tc_rule_stats_get "$probe_dev" 104 ingress) 208 dd=$((t1 - t0)) 209 210 ((dd == expect)) 211 check_err $? "Expected $expect packets on $probe_dev got $dd" 212 213 log_test "$what" 214} 215 216do_tests() 217{ 218 local should_fail=$1; shift 219 local what=$1; shift 220 local swp1_mac 221 local br_mac 222 223 swp1_mac=$(mac_get "$swp1") 224 br_mac=$(mac_get br) 225 226 do_sharing_test "$should_fail" "$what" 227 do_end_to_end_test "$swp1_mac" "$what: end to end, $swp1 MAC" 228 do_end_to_end_test "$br_mac" "$what: end to end, br MAC" 229} 230 231bridge_standard() 232{ 233 local vlan_filtering=$1; shift 234 235 if ((vlan_filtering)); then 236 echo 802.1q 237 else 238 echo 802.1d 239 fi 240} 241 242nonexistent_fdb_test() 243{ 244 local vlan_filtering=$1; shift 245 local standard 246 247 standard=$(bridge_standard "$vlan_filtering") 248 249 # We expect flooding, so $h2 should get the traffic. 250 do_end_to_end_test "$xMAC" "$standard: Nonexistent FDB" "$h2" 251} 252 253misleading_fdb_test() 254{ 255 local vlan_filtering=$1; shift 256 local standard 257 258 standard=$(bridge_standard "$vlan_filtering") 259 260 defer_scope_push 261 # Add an FDB entry on VLAN 0. The lookup on VLAN-aware bridge 262 # shouldn't pick this up even with fdb_local_vlan_0 enabled, so 263 # the traffic should be flooded. This all holds on 264 # vlan_filtering bridge, on non-vlan_filtering one the FDB entry 265 # is expected to be found as usual, no flooding takes place. 266 # 267 # Adding only on VLAN 0 is a bit tricky, because bridge is 268 # trying to be nice and interprets the request as if the FDB 269 # should be added on each VLAN. 270 271 bridge fdb add "$mMAC" dev "$swp1" master 272 bridge fdb del "$mMAC" dev "$swp1" vlan 1 master 273 bridge fdb del "$mMAC" dev "$swp1" vlan 2 master 274 bridge fdb del "$mMAC" dev "$swp1" vlan 3 master 275 276 local expect=$((vlan_filtering ? 10 : 0)) 277 do_end_to_end_test "$mMAC" \ 278 "$standard: Lookup of non-local MAC on VLAN 0" \ 279 "$h2" "$expect" 280 defer_scope_pop 281} 282 283change_mac() 284{ 285 local dev=$1; shift 286 local mac=$1; shift 287 local cur_mac 288 289 cur_mac=$(mac_get "$dev") 290 291 log_info "Change $dev MAC $cur_mac -> $mac" 292 adf_ip_link_set_addr "$dev" "$mac" 293 defer log_info "Change $dev MAC back" 294} 295 296do_test_no_sharing() 297{ 298 local vlan_filtering=$1; shift 299 local standard 300 301 standard=$(bridge_standard "$vlan_filtering") 302 303 adf_bridge_create vlan_filtering "$vlan_filtering" 304 setup_wait 305 306 do_tests 0 "$standard, no FDB sharing" 307 308 change_mac "$swp1" "$pMAC" 309 change_mac br "$bMAC" 310 311 do_tests 0 "$standard, no FDB sharing after MAC change" 312 313 in_defer_scope check_fdb_local_vlan_0_support || return 314 315 log_info "Set fdb_local_vlan_0=1" 316 ip link set dev br type bridge fdb_local_vlan_0 1 317 318 do_tests 1 "$standard, fdb sharing after toggle" 319} 320 321do_test_sharing() 322{ 323 local vlan_filtering=$1; shift 324 local standard 325 326 standard=$(bridge_standard "$vlan_filtering") 327 328 in_defer_scope check_fdb_local_vlan_0_support || return 329 330 adf_bridge_create vlan_filtering "$vlan_filtering" fdb_local_vlan_0 1 331 setup_wait 332 333 do_tests 1 "$standard, FDB sharing" 334 335 nonexistent_fdb_test "$vlan_filtering" 336 misleading_fdb_test "$vlan_filtering" 337 338 change_mac "$swp1" "$pMAC" 339 change_mac br "$bMAC" 340 341 do_tests 1 "$standard, FDB sharing after MAC change" 342 343 log_info "Set fdb_local_vlan_0=0" 344 ip link set dev br type bridge fdb_local_vlan_0 0 345 346 do_tests 0 "$standard, No FDB sharing after toggle" 347} 348 349test_d_no_sharing() 350{ 351 do_test_no_sharing 0 352} 353 354test_d_sharing() 355{ 356 do_test_sharing 0 357} 358 359test_q_no_sharing() 360{ 361 do_test_no_sharing 1 362} 363 364test_q_sharing() 365{ 366 do_test_sharing 1 367} 368 369adf_addr_set_bridge_create() 370{ 371 adf_ip_link_add br up type bridge vlan_filtering 0 372 adf_ip_link_set_addr br "$(mac_get br)" 373 adf_bridge_configure 374} 375 376test_addr_set() 377{ 378 adf_addr_set_bridge_create 379 setup_wait 380 381 do_end_to_end_test "$(mac_get br)" "NET_ADDR_SET: end to end, br MAC" 382} 383 384trap cleanup EXIT 385 386setup_prepare 387tests_run
~/
Read-only file preview.