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_1d.sh (20863B)


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