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_ipv6.sh (24931B)


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