cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vxlan_bridge_1q.sh (23462B)


      1#!/bin/bash
      2# SPDX-License-Identifier: GPL-2.0
      3
      4# +-----------------------+                          +------------------------+
      5# | H1 (vrf)              |                          | H2 (vrf)               |
      6# |  + $h1.10             |                          |  + $h2.10              |
      7# |  | 192.0.2.1/28       |                          |  | 192.0.2.2/28        |
      8# |  |                    |                          |  |                     |
      9# |  | + $h1.20           |                          |  | + $h2.20            |
     10# |  \ | 198.51.100.1/24  |                          |  \ | 198.51.100.2/24   |
     11# |   \|                  |                          |   \|                   |
     12# |    + $h1              |                          |    + $h2               |
     13# +----|------------------+                          +----|-------------------+
     14#      |                                                  |
     15# +----|--------------------------------------------------|-------------------+
     16# | SW |                                                  |                   |
     17# | +--|--------------------------------------------------|-----------------+ |
     18# | |  + $swp1                   BR1 (802.1q)             + $swp2           | |
     19# | |     vid 10                                             vid 10         | |
     20# | |     vid 20                                             vid 20         | |
     21# | |                                                                       | |
     22# | |  + vx10 (vxlan)                        + vx20 (vxlan)                 | |
     23# | |    local 192.0.2.17                      local 192.0.2.17             | |
     24# | |    remote 192.0.2.34 192.0.2.50          remote 192.0.2.34 192.0.2.50 | |
     25# | |    id 1000 dstport $VXPORT               id 2000 dstport $VXPORT      | |
     26# | |    vid 10 pvid untagged                  vid 20 pvid untagged         | |
     27# | +-----------------------------------------------------------------------+ |
     28# |                                                                           |
     29# |  192.0.2.32/28 via 192.0.2.18                                             |
     30# |  192.0.2.48/28 via 192.0.2.18                                             |
     31# |                                                                           |
     32# |    + $rp1                                                                 |
     33# |    | 192.0.2.17/28                                                        |
     34# +----|----------------------------------------------------------------------+
     35#      |
     36# +----|--------------------------------------------------------+
     37# |    |                                             VRP2 (vrf) |
     38# |    + $rp2                                                   |
     39# |      192.0.2.18/28                                          |
     40# |                                                             |   (maybe) HW
     41# =============================================================================
     42# |                                                             |  (likely) SW
     43# |    + v1 (veth)                             + v3 (veth)      |
     44# |    | 192.0.2.33/28                         | 192.0.2.49/28  |
     45# +----|---------------------------------------|----------------+
     46#      |                                       |
     47# +----|------------------------------+   +----|------------------------------+
     48# |    + v2 (veth)        NS1 (netns) |   |    + v4 (veth)        NS2 (netns) |
     49# |      192.0.2.34/28                |   |      192.0.2.50/28                |
     50# |                                   |   |                                   |
     51# |   192.0.2.16/28 via 192.0.2.33    |   |   192.0.2.16/28 via 192.0.2.49    |
     52# |   192.0.2.50/32 via 192.0.2.33    |   |   192.0.2.34/32 via 192.0.2.49    |
     53# |                                   |   |                                   |
     54# | +-------------------------------+ |   | +-------------------------------+ |
     55# | |                  BR2 (802.1q) | |   | |                  BR2 (802.1q) | |
     56# | |  + vx10 (vxlan)               | |   | |  + vx10 (vxlan)               | |
     57# | |    local 192.0.2.34           | |   | |    local 192.0.2.50           | |
     58# | |    remote 192.0.2.17          | |   | |    remote 192.0.2.17          | |
     59# | |    remote 192.0.2.50          | |   | |    remote 192.0.2.34          | |
     60# | |    id 1000 dstport $VXPORT    | |   | |    id 1000 dstport $VXPORT    | |
     61# | |    vid 10 pvid untagged       | |   | |    vid 10 pvid untagged       | |
     62# | |                               | |   | |                               | |
     63# | |  + vx20 (vxlan)               | |   | |  + vx20 (vxlan)               | |
     64# | |    local 192.0.2.34           | |   | |    local 192.0.2.50           | |
     65# | |    remote 192.0.2.17          | |   | |    remote 192.0.2.17          | |
     66# | |    remote 192.0.2.50          | |   | |    remote 192.0.2.34          | |
     67# | |    id 2000 dstport $VXPORT    | |   | |    id 2000 dstport $VXPORT    | |
     68# | |    vid 20 pvid untagged       | |   | |    vid 20 pvid untagged       | |
     69# | |                               | |   | |                               | |
     70# | |  + w1 (veth)                  | |   | |  + w1 (veth)                  | |
     71# | |  | vid 10                     | |   | |  | vid 10                     | |
     72# | |  | vid 20                     | |   | |  | vid 20                     | |
     73# | +--|----------------------------+ |   | +--|----------------------------+ |
     74# |    |                              |   |    |                              |
     75# | +--|----------------------------+ |   | +--|----------------------------+ |
     76# | |  + w2 (veth)        VW2 (vrf) | |   | |  + w2 (veth)        VW2 (vrf) | |
     77# | |  |\                           | |   | |  |\                           | |
     78# | |  | + w2.10                    | |   | |  | + w2.10                    | |
     79# | |  |   192.0.2.3/28             | |   | |  |   192.0.2.4/28             | |
     80# | |  |                            | |   | |  |                            | |
     81# | |  + w2.20                      | |   | |  + w2.20                      | |
     82# | |    198.51.100.3/24            | |   | |    198.51.100.4/24            | |
     83# | +-------------------------------+ |   | +-------------------------------+ |
     84# +-----------------------------------+   +-----------------------------------+
     85
     86: ${VXPORT:=4789}
     87export VXPORT
     88
     89: ${ALL_TESTS:="
     90	ping_ipv4
     91	test_flood
     92	test_unicast
     93	reapply_config
     94	ping_ipv4
     95	test_flood
     96	test_unicast
     97	test_learning
     98	test_pvid
     99    "}
    100
    101NUM_NETIFS=6
    102source lib.sh
    103
    104h1_create()
    105{
    106	simple_if_init $h1
    107	tc qdisc add dev $h1 clsact
    108	vlan_create $h1 10 v$h1 192.0.2.1/28
    109	vlan_create $h1 20 v$h1 198.51.100.1/24
    110}
    111
    112h1_destroy()
    113{
    114	vlan_destroy $h1 20
    115	vlan_destroy $h1 10
    116	tc qdisc del dev $h1 clsact
    117	simple_if_fini $h1
    118}
    119
    120h2_create()
    121{
    122	simple_if_init $h2
    123	tc qdisc add dev $h2 clsact
    124	vlan_create $h2 10 v$h2 192.0.2.2/28
    125	vlan_create $h2 20 v$h2 198.51.100.2/24
    126}
    127
    128h2_destroy()
    129{
    130	vlan_destroy $h2 20
    131	vlan_destroy $h2 10
    132	tc qdisc del dev $h2 clsact
    133	simple_if_fini $h2
    134}
    135
    136rp1_set_addr()
    137{
    138	ip address add dev $rp1 192.0.2.17/28
    139
    140	ip route add 192.0.2.32/28 nexthop via 192.0.2.18
    141	ip route add 192.0.2.48/28 nexthop via 192.0.2.18
    142}
    143
    144rp1_unset_addr()
    145{
    146	ip route del 192.0.2.48/28 nexthop via 192.0.2.18
    147	ip route del 192.0.2.32/28 nexthop via 192.0.2.18
    148
    149	ip address del dev $rp1 192.0.2.17/28
    150}
    151
    152switch_create()
    153{
    154	ip link add name br1 type bridge vlan_filtering 1 vlan_default_pvid 0 \
    155		mcast_snooping 0
    156	# Make sure the bridge uses the MAC address of the local port and not
    157	# that of the VxLAN's device.
    158	ip link set dev br1 address $(mac_get $swp1)
    159	ip link set dev br1 up
    160
    161	ip link set dev $rp1 up
    162	rp1_set_addr
    163
    164	ip link add name vx10 type vxlan id 1000	\
    165		local 192.0.2.17 dstport "$VXPORT"	\
    166		nolearning noudpcsum tos inherit ttl 100
    167	ip link set dev vx10 up
    168
    169	ip link set dev vx10 master br1
    170	bridge vlan add vid 10 dev vx10 pvid untagged
    171
    172	ip link add name vx20 type vxlan id 2000	\
    173		local 192.0.2.17 dstport "$VXPORT"	\
    174		nolearning noudpcsum tos inherit ttl 100
    175	ip link set dev vx20 up
    176
    177	ip link set dev vx20 master br1
    178	bridge vlan add vid 20 dev vx20 pvid untagged
    179
    180	ip link set dev $swp1 master br1
    181	ip link set dev $swp1 up
    182	bridge vlan add vid 10 dev $swp1
    183	bridge vlan add vid 20 dev $swp1
    184
    185	ip link set dev $swp2 master br1
    186	ip link set dev $swp2 up
    187	bridge vlan add vid 10 dev $swp2
    188	bridge vlan add vid 20 dev $swp2
    189
    190	bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.34 self
    191	bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.50 self
    192
    193	bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.34 self
    194	bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.50 self
    195}
    196
    197switch_destroy()
    198{
    199	bridge fdb del dev vx20 00:00:00:00:00:00 dst 192.0.2.50 self
    200	bridge fdb del dev vx20 00:00:00:00:00:00 dst 192.0.2.34 self
    201
    202	bridge fdb del dev vx10 00:00:00:00:00:00 dst 192.0.2.50 self
    203	bridge fdb del dev vx10 00:00:00:00:00:00 dst 192.0.2.34 self
    204
    205	bridge vlan del vid 20 dev $swp2
    206	bridge vlan del vid 10 dev $swp2
    207	ip link set dev $swp2 down
    208	ip link set dev $swp2 nomaster
    209
    210	bridge vlan del vid 20 dev $swp1
    211	bridge vlan del vid 10 dev $swp1
    212	ip link set dev $swp1 down
    213	ip link set dev $swp1 nomaster
    214
    215	bridge vlan del vid 20 dev vx20
    216	ip link set dev vx20 nomaster
    217
    218	ip link set dev vx20 down
    219	ip link del dev vx20
    220
    221	bridge vlan del vid 10 dev vx10
    222	ip link set dev vx10 nomaster
    223
    224	ip link set dev vx10 down
    225	ip link del dev vx10
    226
    227	rp1_unset_addr
    228	ip link set dev $rp1 down
    229
    230	ip link set dev br1 down
    231	ip link del dev br1
    232}
    233
    234vrp2_create()
    235{
    236	simple_if_init $rp2 192.0.2.18/28
    237	__simple_if_init v1 v$rp2 192.0.2.33/28
    238	__simple_if_init v3 v$rp2 192.0.2.49/28
    239	tc qdisc add dev v1 clsact
    240}
    241
    242vrp2_destroy()
    243{
    244	tc qdisc del dev v1 clsact
    245	__simple_if_fini v3 192.0.2.49/28
    246	__simple_if_fini v1 192.0.2.33/28
    247	simple_if_fini $rp2 192.0.2.18/28
    248}
    249
    250ns_init_common()
    251{
    252	local in_if=$1; shift
    253	local in_addr=$1; shift
    254	local other_in_addr=$1; shift
    255	local nh_addr=$1; shift
    256	local host_addr1=$1; shift
    257	local host_addr2=$1; shift
    258
    259	ip link set dev $in_if up
    260	ip address add dev $in_if $in_addr/28
    261	tc qdisc add dev $in_if clsact
    262
    263	ip link add name br2 type bridge vlan_filtering 1 vlan_default_pvid 0
    264	ip link set dev br2 up
    265
    266	ip link add name w1 type veth peer name w2
    267
    268	ip link set dev w1 master br2
    269	ip link set dev w1 up
    270
    271	bridge vlan add vid 10 dev w1
    272	bridge vlan add vid 20 dev w1
    273
    274	ip link add name vx10 type vxlan id 1000 local $in_addr \
    275		dstport "$VXPORT"
    276	ip link set dev vx10 up
    277	bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.17 self
    278	bridge fdb append dev vx10 00:00:00:00:00:00 dst $other_in_addr self
    279
    280	ip link set dev vx10 master br2
    281	tc qdisc add dev vx10 clsact
    282
    283	bridge vlan add vid 10 dev vx10 pvid untagged
    284
    285	ip link add name vx20 type vxlan id 2000 local $in_addr \
    286		dstport "$VXPORT"
    287	ip link set dev vx20 up
    288	bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.17 self
    289	bridge fdb append dev vx20 00:00:00:00:00:00 dst $other_in_addr self
    290
    291	ip link set dev vx20 master br2
    292	tc qdisc add dev vx20 clsact
    293
    294	bridge vlan add vid 20 dev vx20 pvid untagged
    295
    296	simple_if_init w2
    297        vlan_create w2 10 vw2 $host_addr1/28
    298        vlan_create w2 20 vw2 $host_addr2/24
    299
    300	ip route add 192.0.2.16/28 nexthop via $nh_addr
    301	ip route add $other_in_addr/32 nexthop via $nh_addr
    302}
    303export -f ns_init_common
    304
    305ns1_create()
    306{
    307	ip netns add ns1
    308	ip link set dev v2 netns ns1
    309	in_ns ns1 \
    310	      ns_init_common v2 192.0.2.34 192.0.2.50 192.0.2.33 192.0.2.3 \
    311	      198.51.100.3
    312}
    313
    314ns1_destroy()
    315{
    316	ip netns exec ns1 ip link set dev v2 netns 1
    317	ip netns del ns1
    318}
    319
    320ns2_create()
    321{
    322	ip netns add ns2
    323	ip link set dev v4 netns ns2
    324	in_ns ns2 \
    325	      ns_init_common v4 192.0.2.50 192.0.2.34 192.0.2.49 192.0.2.4 \
    326	      198.51.100.4
    327}
    328
    329ns2_destroy()
    330{
    331	ip netns exec ns2 ip link set dev v4 netns 1
    332	ip netns del ns2
    333}
    334
    335setup_prepare()
    336{
    337	h1=${NETIFS[p1]}
    338	swp1=${NETIFS[p2]}
    339
    340	swp2=${NETIFS[p3]}
    341	h2=${NETIFS[p4]}
    342
    343	rp1=${NETIFS[p5]}
    344	rp2=${NETIFS[p6]}
    345
    346	vrf_prepare
    347	forwarding_enable
    348
    349	h1_create
    350	h2_create
    351	switch_create
    352
    353	ip link add name v1 type veth peer name v2
    354	ip link add name v3 type veth peer name v4
    355	vrp2_create
    356	ns1_create
    357	ns2_create
    358
    359	r1_mac=$(in_ns ns1 mac_get w2)
    360	r2_mac=$(in_ns ns2 mac_get w2)
    361	h2_mac=$(mac_get $h2)
    362}
    363
    364cleanup()
    365{
    366	pre_cleanup
    367
    368	ns2_destroy
    369	ns1_destroy
    370	vrp2_destroy
    371	ip link del dev v3
    372	ip link del dev v1
    373
    374	switch_destroy
    375	h2_destroy
    376	h1_destroy
    377
    378	forwarding_restore
    379	vrf_cleanup
    380}
    381
    382# For the first round of tests, vx10 and vx20 were the first devices to get
    383# attached to the bridge, and that at the point that the local IP is already
    384# configured. Try the other scenario of attaching these devices to a bridge
    385# that already has local ports members, and only then assign the local IP.
    386reapply_config()
    387{
    388	log_info "Reapplying configuration"
    389
    390	bridge fdb del dev vx20 00:00:00:00:00:00 dst 192.0.2.50 self
    391	bridge fdb del dev vx20 00:00:00:00:00:00 dst 192.0.2.34 self
    392
    393	bridge fdb del dev vx10 00:00:00:00:00:00 dst 192.0.2.50 self
    394	bridge fdb del dev vx10 00:00:00:00:00:00 dst 192.0.2.34 self
    395
    396	ip link set dev vx20 nomaster
    397	ip link set dev vx10 nomaster
    398
    399	rp1_unset_addr
    400	sleep 5
    401
    402	ip link set dev vx10 master br1
    403	bridge vlan add vid 10 dev vx10 pvid untagged
    404
    405	ip link set dev vx20 master br1
    406	bridge vlan add vid 20 dev vx20 pvid untagged
    407
    408	bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.34 self
    409	bridge fdb append dev vx10 00:00:00:00:00:00 dst 192.0.2.50 self
    410
    411	bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.34 self
    412	bridge fdb append dev vx20 00:00:00:00:00:00 dst 192.0.2.50 self
    413
    414	rp1_set_addr
    415	sleep 5
    416}
    417
    418ping_ipv4()
    419{
    420	ping_test $h1.10 192.0.2.2 ": local->local vid 10"
    421	ping_test $h1.20 198.51.100.2 ": local->local vid 20"
    422	ping_test $h1.10 192.0.2.3 ": local->remote 1 vid 10"
    423	ping_test $h1.10 192.0.2.4 ": local->remote 2 vid 10"
    424	ping_test $h1.20 198.51.100.3 ": local->remote 1 vid 20"
    425	ping_test $h1.20 198.51.100.4 ": local->remote 2 vid 20"
    426}
    427
    428maybe_in_ns()
    429{
    430	echo ${1:+in_ns} $1
    431}
    432
    433__flood_counter_add_del()
    434{
    435	local add_del=$1; shift
    436	local dev=$1; shift
    437	local ns=$1; shift
    438
    439	# Putting the ICMP capture both to HW and to SW will end up
    440	# double-counting the packets that are trapped to slow path, such as for
    441	# the unicast test. Adding either skip_hw or skip_sw fixes this problem,
    442	# but with skip_hw, the flooded packets are not counted at all, because
    443	# those are dropped due to MAC address mismatch; and skip_sw is a no-go
    444	# for veth-based topologies.
    445	#
    446	# So try to install with skip_sw and fall back to skip_sw if that fails.
    447
    448	$(maybe_in_ns $ns) __icmp_capture_add_del          \
    449			   $add_del 100 "" $dev skip_sw 2>/dev/null || \
    450	$(maybe_in_ns $ns) __icmp_capture_add_del          \
    451			   $add_del 100 "" $dev skip_hw
    452}
    453
    454flood_counter_install()
    455{
    456	__flood_counter_add_del add "$@"
    457}
    458
    459flood_counter_uninstall()
    460{
    461	__flood_counter_add_del del "$@"
    462}
    463
    464flood_fetch_stat()
    465{
    466	local dev=$1; shift
    467	local ns=$1; shift
    468
    469	$(maybe_in_ns $ns) tc_rule_stats_get $dev 100 ingress
    470}
    471
    472flood_fetch_stats()
    473{
    474	local counters=("${@}")
    475	local counter
    476
    477	for counter in "${counters[@]}"; do
    478		flood_fetch_stat $counter
    479	done
    480}
    481
    482vxlan_flood_test()
    483{
    484	local mac=$1; shift
    485	local dst=$1; shift
    486	local vid=$1; shift
    487	local -a expects=("${@}")
    488
    489	local -a counters=($h2 "vx10 ns1" "vx20 ns1" "vx10 ns2" "vx20 ns2")
    490	local counter
    491	local key
    492
    493	# Packets reach the local host tagged whereas they reach the VxLAN
    494	# devices untagged. In order to be able to use the same filter for
    495	# all counters, make sure the packets also reach the local host
    496	# untagged
    497	bridge vlan add vid $vid dev $swp2 untagged
    498	for counter in "${counters[@]}"; do
    499		flood_counter_install $counter
    500	done
    501
    502	local -a t0s=($(flood_fetch_stats "${counters[@]}"))
    503	$MZ $h1 -Q $vid -c 10 -d 100msec -p 64 -b $mac -B $dst -t icmp -q
    504	sleep 1
    505	local -a t1s=($(flood_fetch_stats "${counters[@]}"))
    506
    507	for key in ${!t0s[@]}; do
    508		local delta=$((t1s[$key] - t0s[$key]))
    509		local expect=${expects[$key]}
    510
    511		((expect == delta))
    512		check_err $? "${counters[$key]}: Expected to capture $expect packets, got $delta."
    513	done
    514
    515	for counter in "${counters[@]}"; do
    516		flood_counter_uninstall $counter
    517	done
    518	bridge vlan add vid $vid dev $swp2
    519}
    520
    521__test_flood()
    522{
    523	local mac=$1; shift
    524	local dst=$1; shift
    525	local vid=$1; shift
    526	local what=$1; shift
    527	local -a expects=("${@}")
    528
    529	RET=0
    530
    531	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    532
    533	log_test "VXLAN: $what"
    534}
    535
    536test_flood()
    537{
    538	__test_flood de:ad:be:ef:13:37 192.0.2.100 10 "flood vlan 10" \
    539		10 10 0 10 0
    540	__test_flood ca:fe:be:ef:13:37 198.51.100.100 20 "flood vlan 20" \
    541		10 0 10 0 10
    542}
    543
    544vxlan_fdb_add_del()
    545{
    546	local add_del=$1; shift
    547	local vid=$1; shift
    548	local mac=$1; shift
    549	local dev=$1; shift
    550	local dst=$1; shift
    551
    552	bridge fdb $add_del dev $dev $mac self static permanent \
    553		${dst:+dst} $dst 2>/dev/null
    554	bridge fdb $add_del dev $dev $mac master static vlan $vid 2>/dev/null
    555}
    556
    557__test_unicast()
    558{
    559	local mac=$1; shift
    560	local dst=$1; shift
    561	local hit_idx=$1; shift
    562	local vid=$1; shift
    563	local what=$1; shift
    564
    565	RET=0
    566
    567	local -a expects=(0 0 0 0 0)
    568	expects[$hit_idx]=10
    569
    570	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    571
    572	log_test "VXLAN: $what"
    573}
    574
    575test_unicast()
    576{
    577	local -a targets=("$h2_mac $h2"
    578			  "$r1_mac vx10 192.0.2.34"
    579			  "$r2_mac vx10 192.0.2.50")
    580	local target
    581
    582	log_info "unicast vlan 10"
    583
    584	for target in "${targets[@]}"; do
    585		vxlan_fdb_add_del add 10 $target
    586	done
    587
    588	__test_unicast $h2_mac 192.0.2.2 0 10 "local MAC unicast"
    589	__test_unicast $r1_mac 192.0.2.3 1 10 "remote MAC 1 unicast"
    590	__test_unicast $r2_mac 192.0.2.4 3 10 "remote MAC 2 unicast"
    591
    592	for target in "${targets[@]}"; do
    593		vxlan_fdb_add_del del 10 $target
    594	done
    595
    596	log_info "unicast vlan 20"
    597
    598	targets=("$h2_mac $h2" "$r1_mac vx20 192.0.2.34" \
    599		 "$r2_mac vx20 192.0.2.50")
    600
    601	for target in "${targets[@]}"; do
    602		vxlan_fdb_add_del add 20 $target
    603	done
    604
    605	__test_unicast $h2_mac 198.51.100.2 0 20 "local MAC unicast"
    606	__test_unicast $r1_mac 198.51.100.3 2 20 "remote MAC 1 unicast"
    607	__test_unicast $r2_mac 198.51.100.4 4 20 "remote MAC 2 unicast"
    608
    609	for target in "${targets[@]}"; do
    610		vxlan_fdb_add_del del 20 $target
    611	done
    612}
    613
    614test_pvid()
    615{
    616	local -a expects=(0 0 0 0 0)
    617	local mac=de:ad:be:ef:13:37
    618	local dst=192.0.2.100
    619	local vid=10
    620
    621	# Check that flooding works
    622	RET=0
    623
    624	expects[0]=10; expects[1]=10; expects[3]=10
    625	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    626
    627	log_test "VXLAN: flood before pvid off"
    628
    629	# Toggle PVID off and test that flood to remote hosts does not work
    630	RET=0
    631
    632	bridge vlan add vid 10 dev vx10
    633
    634	expects[0]=10; expects[1]=0; expects[3]=0
    635	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    636
    637	log_test "VXLAN: flood after pvid off"
    638
    639	# Toggle PVID on and test that flood to remote hosts does work
    640	RET=0
    641
    642	bridge vlan add vid 10 dev vx10 pvid untagged
    643
    644	expects[0]=10; expects[1]=10; expects[3]=10
    645	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    646
    647	log_test "VXLAN: flood after pvid on"
    648
    649	# Add a new VLAN and test that it does not affect flooding
    650	RET=0
    651
    652	bridge vlan add vid 30 dev vx10
    653
    654	expects[0]=10; expects[1]=10; expects[3]=10
    655	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    656
    657	bridge vlan del vid 30 dev vx10
    658
    659	log_test "VXLAN: flood after vlan add"
    660
    661	# Remove currently mapped VLAN and test that flood to remote hosts does
    662	# not work
    663	RET=0
    664
    665	bridge vlan del vid 10 dev vx10
    666
    667	expects[0]=10; expects[1]=0; expects[3]=0
    668	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    669
    670	log_test "VXLAN: flood after vlan delete"
    671
    672	# Re-add the VLAN and test that flood to remote hosts does work
    673	RET=0
    674
    675	bridge vlan add vid 10 dev vx10 pvid untagged
    676
    677	expects[0]=10; expects[1]=10; expects[3]=10
    678	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    679
    680	log_test "VXLAN: flood after vlan re-add"
    681}
    682
    683__test_learning()
    684{
    685	local -a expects=(0 0 0 0 0)
    686	local mac=$1; shift
    687	local dst=$1; shift
    688	local vid=$1; shift
    689	local idx1=$1; shift
    690	local idx2=$1; shift
    691	local vx=vx$vid
    692
    693	# Check that flooding works
    694	RET=0
    695
    696	expects[0]=10; expects[$idx1]=10; expects[$idx2]=10
    697	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    698
    699	log_test "VXLAN: flood before learning"
    700
    701	# Send a packet with source mac set to $mac from host w2 and check that
    702	# a corresponding entry is created in the VxLAN device
    703	RET=0
    704
    705	in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \
    706		-B $dst -t icmp -q
    707	sleep 1
    708
    709	bridge fdb show brport $vx | grep $mac | grep -q self
    710	check_err $?
    711	bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \
    712		| grep -q -v self
    713	check_err $?
    714
    715	log_test "VXLAN: show learned FDB entry"
    716
    717	# Repeat first test and check that packets only reach host w2 in ns1
    718	RET=0
    719
    720	expects[0]=0; expects[$idx1]=10; expects[$idx2]=0
    721	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    722
    723	log_test "VXLAN: learned FDB entry"
    724
    725	# Delete the learned FDB entry from the VxLAN and bridge devices and
    726	# check that packets are flooded
    727	RET=0
    728
    729	bridge fdb del dev $vx $mac master self vlan $vid
    730	sleep 1
    731
    732	expects[0]=10; expects[$idx1]=10; expects[$idx2]=10
    733	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    734
    735	log_test "VXLAN: deletion of learned FDB entry"
    736
    737	# Re-learn the first FDB entry and check that it is correctly aged-out
    738	RET=0
    739
    740	in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \
    741		-B $dst -t icmp -q
    742	sleep 1
    743
    744	bridge fdb show brport $vx | grep $mac | grep -q self
    745	check_err $?
    746	bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \
    747		| grep -q -v self
    748	check_err $?
    749
    750	expects[0]=0; expects[$idx1]=10; expects[$idx2]=0
    751	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    752
    753	sleep 20
    754
    755	bridge fdb show brport $vx | grep $mac | grep -q self
    756	check_fail $?
    757	bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \
    758		| grep -q -v self
    759	check_fail $?
    760
    761	expects[0]=10; expects[$idx1]=10; expects[$idx2]=10
    762	vxlan_flood_test $mac $dst $vid "${expects[@]}"
    763
    764	log_test "VXLAN: Ageing of learned FDB entry"
    765
    766	# Toggle learning on the bridge port and check that the bridge's FDB
    767	# is populated only when it should
    768	RET=0
    769
    770	ip link set dev $vx type bridge_slave learning off
    771
    772	in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \
    773		-B $dst -t icmp -q
    774	sleep 1
    775
    776	bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \
    777		| grep -q -v self
    778	check_fail $?
    779
    780	ip link set dev $vx type bridge_slave learning on
    781
    782	in_ns ns1 $MZ w2 -Q $vid -c 1 -p 64 -a $mac -b ff:ff:ff:ff:ff:ff \
    783		-B $dst -t icmp -q
    784	sleep 1
    785
    786	bridge fdb show brport $vx | grep $mac | grep "vlan $vid" \
    787		| grep -q -v self
    788	check_err $?
    789
    790	log_test "VXLAN: learning toggling on bridge port"
    791}
    792
    793test_learning()
    794{
    795	local mac=de:ad:be:ef:13:37
    796	local dst=192.0.2.100
    797	local vid=10
    798
    799	# Enable learning on the VxLAN devices and set ageing time to 10 seconds
    800	ip link set dev br1 type bridge ageing_time 1000
    801	ip link set dev vx10 type vxlan ageing 10
    802	ip link set dev vx10 type vxlan learning
    803	ip link set dev vx20 type vxlan ageing 10
    804	ip link set dev vx20 type vxlan learning
    805	reapply_config
    806
    807	log_info "learning vlan 10"
    808
    809	__test_learning $mac $dst $vid 1 3
    810
    811	log_info "learning vlan 20"
    812
    813	mac=ca:fe:be:ef:13:37
    814	dst=198.51.100.100
    815	vid=20
    816
    817	__test_learning $mac $dst $vid 2 4
    818
    819	# Restore previous settings
    820	ip link set dev vx20 type vxlan nolearning
    821	ip link set dev vx20 type vxlan ageing 300
    822	ip link set dev vx10 type vxlan nolearning
    823	ip link set dev vx10 type vxlan ageing 300
    824	ip link set dev br1 type bridge ageing_time 30000
    825	reapply_config
    826}
    827
    828test_all()
    829{
    830	log_info "Running tests with UDP port $VXPORT"
    831	tests_run
    832}
    833
    834trap cleanup EXIT
    835
    836setup_prepare
    837setup_wait
    838test_all
    839
    840exit $EXIT_STATUS