2 # SPDX-License-Identifier: GPL-2.0
4 # +--------------------+ +----------------------+
5 # | H1 (vrf) | | H2 (vrf) |
7 # | | 192.0.2.1/28 | | | 192.0.2.2/28 |
8 # +----|---------------+ +--|-------------------+
10 # +----|--------------------------------------------------|-------------------+
12 # | +--|--------------------------------------------------|-----------------+ |
13 # | | + $swp1 BR1 (802.1d) + $swp2 | |
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 # | +-----------------------------------------------------------------------+ |
21 # | 192.0.2.32/28 via 192.0.2.18 |
22 # | 192.0.2.48/28 via 192.0.2.18 |
26 # +----|----------------------------------------------------------------------+
28 # +----|--------------------------------------------------------+
33 # =============================================================================
35 # | + v1 (veth) + v3 (veth) |
36 # | | 192.0.2.33/28 | 192.0.2.49/28 |
37 # +----|---------------------------------------|----------------+
39 # +----|------------------------------+ +----|------------------------------+
40 # | + v2 (veth) NS1 (netns) | | + v4 (veth) NS2 (netns) |
41 # | 192.0.2.34/28 | | 192.0.2.50/28 |
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 |
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 | |
54 # | | + w1 (veth) | | | | + w1 (veth) | |
55 # | +--|----------------------------+ | | +--|----------------------------+ |
57 # | +--|----------------------------+ | | +--|----------------------------+ |
58 # | | | VW2 (vrf) | | | | | VW2 (vrf) | |
59 # | | + w2 (veth) | | | | + w2 (veth) | |
60 # | | 192.0.2.3/28 | | | | 192.0.2.4/28 | |
61 # | +-------------------------------+ | | +-------------------------------+ |
62 # +-----------------------------------+ +-----------------------------------+
87 simple_if_init
$h1 192.0.2.1/28
88 tc qdisc add dev
$h1 clsact
93 tc qdisc del dev
$h1 clsact
94 simple_if_fini
$h1 192.0.2.1/28
99 simple_if_init
$h2 192.0.2.2/28
100 tc qdisc add dev
$h2 clsact
105 tc qdisc del dev
$h2 clsact
106 simple_if_fini
$h2 192.0.2.2/28
111 ip address add dev
$rp1 192.0.2.17/28
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
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
122 ip address del dev
$rp1 192.0.2.17/28
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
133 ip link
set dev
$rp1 up
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
141 ip link
set dev vx1 master br1
142 ip link
set dev
$swp1 master br1
143 ip link
set dev
$swp1 up
145 ip link
set dev
$swp2 master br1
146 ip link
set dev
$swp2 up
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
155 ip link
set dev
$rp1 down
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
160 ip link
set dev vx1 nomaster
161 ip link
set dev vx1 down
164 ip link
set dev
$swp2 down
165 ip link
set dev
$swp2 nomaster
167 ip link
set dev
$swp1 down
168 ip link
set dev
$swp1 nomaster
170 ip link
set dev br1 down
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
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
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
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
202 ip link add name br2
type bridge vlan_filtering
0
203 ip link
set dev br2 up
205 ip link add name w1
type veth peer name w2
207 ip link
set dev w1 master br2
208 ip link
set dev w1 up
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
215 ip link
set dev vx2 master br2
216 tc qdisc add dev vx2 clsact
218 simple_if_init w2
$host_addr/28
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
223 export -f ns_init_common
228 ip link
set dev v2 netns ns1
230 ns_init_common v2
192.0.2.34 192.0.2.50 192.0.2.33 192.0.2.3
235 ip netns
exec ns1 ip link
set dev v2 netns
1
242 ip link
set dev v4 netns ns2
244 ns_init_common v4
192.0.2.50 192.0.2.34 192.0.2.49 192.0.2.4
249 ip netns
exec ns2 ip link
set dev v4 netns
1
271 ip link add name v1
type veth peer name v2
272 ip link add name v3
type veth peer name v4
277 r1_mac
=$
(in_ns ns1 mac_get w2
)
278 r2_mac
=$
(in_ns ns2 mac_get w2
)
279 h2_mac
=$
(mac_get
$h2)
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.
306 echo "Reapplying configuration"
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
311 ip link
set dev vx1 nomaster
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
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"
334 __flood_counter_add_del
()
336 local add_del
=$1; shift
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.
347 # So try to install with skip_sw and fall back to skip_sw if that fails.
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
355 flood_counter_install
()
357 __flood_counter_add_del add
"$@"
360 flood_counter_uninstall
()
362 __flood_counter_add_del del
"$@"
370 $
(maybe_in_ns
$ns) tc_rule_stats_get
$dev 100 ingress
375 local counters
=("${@}")
378 for counter
in "${counters[@]}"; do
379 flood_fetch_stat
$counter
387 local -a expects
=("${@}")
389 local -a counters
=($h2 "vx2 ns1" "vx2 ns2")
393 for counter
in "${counters[@]}"; do
394 flood_counter_install
$counter
397 local -a t0s
=($
(flood_fetch_stats
"${counters[@]}"))
398 $MZ $h1 -c 10 -d 100msec
-p 64 -b $mac -B $dst -t icmp
-q
400 local -a t1s
=($
(flood_fetch_stats
"${counters[@]}"))
402 for key
in ${!t0s[@]}; do
403 local delta
=$
((t1s
[$key] - t0s
[$key]))
404 local expect
=${expects[$key]}
407 check_err $?
"${counters[$key]}: Expected to capture $expect packets, got $delta."
410 for counter
in "${counters[@]}"; do
411 flood_counter_uninstall
$counter
423 vxlan_flood_test
$mac $dst 10 10 10
425 log_test
"VXLAN: $what"
430 __test_flood de
:ad
:be
:ef
:13:37 192.0.2.100 "flood"
435 local add_del
=$1; shift
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
449 local hit_idx
=$1; shift
454 local -a expects
=(0 0 0)
457 vxlan_flood_test
$mac $dst "${expects[@]}"
459 log_test
"VXLAN: $what"
464 local -a targets
=("$h2_mac $h2"
465 "$r1_mac vx1 192.0.2.34"
466 "$r2_mac vx1 192.0.2.50")
469 for target
in "${targets[@]}"; do
470 vxlan_fdb_add_del add
$target
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"
477 for target
in "${targets[@]}"; do
478 vxlan_fdb_add_del del
$target
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
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
))
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."
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
511 log_test
"VXLAN: envelope TTL"
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
524 log_test
"VXLAN: envelope TOS inheritance"
534 tc filter add dev v1 egress pref
77 prot ip \
535 flower ip_tos
$tos action pass
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
540 log_test
"VXLAN: ECN encap: $q->$tos"
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
552 vxlan_encapped_ping_do
()
554 local count
=$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
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
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
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"
595 export -f vxlan_encapped_ping_do
597 vxlan_encapped_ping_test
()
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
607 local t0
=$
($stat_get)
610 vxlan_encapped_ping_do
10 $ping_dev $
(mac_get
$nh_dev) \
611 $ping_dip $
(mac_get
$h1) \
612 $inner_tos $outer_tos
614 local t1
=$
($stat_get)
615 local delta
=$
((t1
- t0
))
617 # Tolerate a couple stray extra packets.
618 ((expect
<= delta
&& delta
<= expect
+ 2))
619 check_err $?
"Expected to capture $expect packets, got $delta."
621 export -f vxlan_encapped_ping_test
625 local orig_inner_tos
=$1; shift
626 local orig_outer_tos
=$1; shift
627 local decapped_tos
=$1; shift
631 tc filter add dev
$h1 ingress pref
77 prot ip \
632 flower ip_tos
$decapped_tos action drop
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
639 log_test
"VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->$decapped_tos"
642 test_ecn_decap_error
()
644 local orig_inner_tos
=00
645 local orig_outer_tos
=03
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
653 log_test
"VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->error"
658 # In accordance with INET_ECN_decapsulate()
659 __test_ecn_decap
00 00 0x00
660 __test_ecn_decap
01 01 0x01
661 __test_ecn_decap
02 01 0x02
662 __test_ecn_decap
01 03 0x03
663 __test_ecn_decap
02 03 0x03
669 local mac
=de
:ad
:be
:ef
:13:37
670 local dst
=192.0.2.100
672 # Enable learning on the VxLAN device and set ageing time to 10 seconds
673 ip link
set dev br1
type bridge ageing_time
1000
674 ip link
set dev vx1
type vxlan ageing
10
675 ip link
set dev vx1
type vxlan learning
678 # Check that flooding works
681 vxlan_flood_test
$mac $dst 10 10 10
683 log_test
"VXLAN: flood before learning"
685 # Send a packet with source mac set to $mac from host w2 and check that
686 # a corresponding entry is created in VxLAN device vx1
689 in_ns ns1
$MZ w2
-c 1 -p 64 -a $mac -b ff
:ff
:ff
:ff
:ff
:ff
-B $dst \
693 bridge fdb show brport vx1 |
grep $mac |
grep -q self
695 bridge fdb show brport vx1 |
grep $mac |
grep -q -v self
698 log_test
"VXLAN: show learned FDB entry"
700 # Repeat first test and check that packets only reach host w2 in ns1
703 vxlan_flood_test
$mac $dst 0 10 0
705 log_test
"VXLAN: learned FDB entry"
707 # Delete the learned FDB entry from the VxLAN and bridge devices and
708 # check that packets are flooded
711 bridge fdb del dev vx1
$mac master self
714 vxlan_flood_test
$mac $dst 10 10 10
716 log_test
"VXLAN: deletion of learned FDB entry"
718 # Re-learn the first FDB entry and check that it is correctly aged-out
721 in_ns ns1
$MZ w2
-c 1 -p 64 -a $mac -b ff
:ff
:ff
:ff
:ff
:ff
-B $dst \
725 bridge fdb show brport vx1 |
grep $mac |
grep -q self
727 bridge fdb show brport vx1 |
grep $mac |
grep -q -v self
730 vxlan_flood_test
$mac $dst 0 10 0
734 bridge fdb show brport vx1 |
grep $mac |
grep -q self
736 bridge fdb show brport vx1 |
grep $mac |
grep -q -v self
739 vxlan_flood_test
$mac $dst 10 10 10
741 log_test
"VXLAN: Ageing of learned FDB entry"
743 # Toggle learning on the bridge port and check that the bridge's FDB
744 # is populated only when it should
747 ip link
set dev vx1
type bridge_slave learning off
749 in_ns ns1
$MZ w2
-c 1 -p 64 -a $mac -b ff
:ff
:ff
:ff
:ff
:ff
-B $dst \
753 bridge fdb show brport vx1 |
grep $mac |
grep -q -v self
756 ip link
set dev vx1
type bridge_slave learning on
758 in_ns ns1
$MZ w2
-c 1 -p 64 -a $mac -b ff
:ff
:ff
:ff
:ff
:ff
-B $dst \
762 bridge fdb show brport vx1 |
grep $mac |
grep -q -v self
765 log_test
"VXLAN: learning toggling on bridge port"
767 # Restore previous settings
768 ip link
set dev vx1
type vxlan nolearning
769 ip link
set dev vx1
type vxlan ageing
300
770 ip link
set dev br1
type bridge ageing_time
30000
776 echo "Running tests with UDP port $VXPORT"