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 # | | 2001:db8:1::1/64 | | | 2001:db8:1::2/64 |
9 # +----|------------------+ +----|-------------------+
11 # +----|--------------------------------------------------|-------------------+
13 # | +--|--------------------------------------------------|-----------------+ |
14 # | | + $swp1 BR1 (802.1d) + $swp2 | |
16 # | | + vx1 (vxlan) | |
17 # | | local 2001:db8:3::1 | |
18 # | | remote 2001:db8:4::1 2001:db8:5::1 | |
19 # | | id 1000 dstport $VXPORT | |
20 # | +-----------------------------------------------------------------------+ |
22 # | 2001:db8:4::0/64 via 2001:db8:3::2 |
23 # | 2001:db8:5::0/64 via 2001:db8:3::2 |
26 # | | 2001:db8:3::1/64 |
27 # +----|----------------------------------------------------------------------+
29 # +----|----------------------------------------------------------+
32 # | 2001:db8:3::2/64 |
34 # =============================================================================
36 # | + v1 (veth) + v3 (veth) |
37 # | | 2001:db8:4::2/64 | 2001:db8:5::2/64 |
38 # +----|---------------------------------------|------------------+
40 # +----|--------------------------------+ +----|-------------------------------+
41 # | + v2 (veth) NS1 (netns) | | + v4 (veth) NS2 (netns) |
42 # | 2001:db8:4::1/64 | | 2001:db8:5::1/64 |
44 # | 2001:db8:3::0/64 via 2001:db8:4::2 | | 2001:db8:3::0/64 via 2001:db8:5::2 |
45 # | 2001:db8:5::1/128 via 2001:db8:4::2 | | 2001:db8:4::1/128 via |
46 # | | | 2001:db8:5::2 |
48 # | +-------------------------------+ | | +-------------------------------+ |
49 # | | BR2 (802.1d) | | | | BR2 (802.1d) | |
50 # | | + vx2 (vxlan) | | | | + vx2 (vxlan) | |
51 # | | local 2001:db8:4::1 | | | | local 2001:db8:5::1 | |
52 # | | remote 2001:db8:3::1 | | | | remote 2001:db8:3::1 | |
53 # | | remote 2001:db8:5::1 | | | | remote 2001:db8:4::1 | |
54 # | | id 1000 dstport $VXPORT | | | | id 1000 dstport $VXPORT | |
56 # | | + w1 (veth) | | | | + w1 (veth) | |
57 # | +--|----------------------------+ | | +--|----------------------------+ |
59 # | +--|----------------------------+ | | +--|----------------------------+ |
60 # | | + w2 (veth) VW2 (vrf) | | | | + w2 (veth) VW2 (vrf) | |
61 # | | 192.0.2.3/28 | | | | 192.0.2.4/28 | |
62 # | | 2001:db8:1::3/64 | | | | 2001:db8:1::4/64 | |
63 # | +-------------------------------+ | | +-------------------------------+ |
64 # +-------------------------------------+ +------------------------------------+
91 simple_if_init
$h1 192.0.2.1/28 2001:db8
:1::1/64
92 tc qdisc add dev
$h1 clsact
97 tc qdisc del dev
$h1 clsact
98 simple_if_fini
$h1 192.0.2.1/28 2001:db8
:1::1/64
103 simple_if_init
$h2 192.0.2.2/28 2001:db8
:1::2/64
104 tc qdisc add dev
$h2 clsact
109 tc qdisc del dev
$h2 clsact
110 simple_if_fini
$h2 192.0.2.2/28 2001:db8
:1::2/64
115 ip address add dev
$rp1 2001:db8
:3::1/64
117 ip route add
2001:db8
:4::0/64 nexthop via
2001:db8
:3::2
118 ip route add
2001:db8
:5::0/64 nexthop via
2001:db8
:3::2
123 ip route del
2001:db8
:5::0/64 nexthop via
2001:db8
:3::2
124 ip route del
2001:db8
:4::0/64 nexthop via
2001:db8
:3::2
126 ip address del dev
$rp1 2001:db8
:3::1/64
131 ip link add name br1
type bridge vlan_filtering
0 mcast_snooping
0
132 # Make sure the bridge uses the MAC address of the local port and not
133 # that of the VxLAN's device.
134 ip link
set dev br1 address $
(mac_get
$swp1)
135 ip link
set dev br1 up
137 ip link
set dev
$rp1 up
139 tc qdisc add dev
$rp1 clsact
141 ip link add name vx1
type vxlan id
1000 local 2001:db8
:3::1 \
142 dstport
"$VXPORT" nolearning udp6zerocsumrx udp6zerocsumtx \
144 ip link
set dev vx1 up
146 ip link
set dev vx1 master br1
147 ip link
set dev
$swp1 master br1
148 ip link
set dev
$swp1 up
149 tc qdisc add dev
$swp1 clsact
151 ip link
set dev
$swp2 master br1
152 ip link
set dev
$swp2 up
154 bridge fdb append dev vx1
00:00:00:00:00:00 dst
2001:db8
:4::1 self
155 bridge fdb append dev vx1
00:00:00:00:00:00 dst
2001:db8
:5::1 self
160 bridge fdb del dev vx1
00:00:00:00:00:00 dst
2001:db8
:5::1 self
161 bridge fdb del dev vx1
00:00:00:00:00:00 dst
2001:db8
:4::1 self
163 ip link
set dev
$swp2 down
164 ip link
set dev
$swp2 nomaster
166 tc qdisc del dev
$swp1 clsact
167 ip link
set dev
$swp1 down
168 ip link
set dev
$swp1 nomaster
170 ip link
set dev vx1 nomaster
171 ip link
set dev vx1 down
174 tc qdisc del dev
$rp1 clsact
176 ip link
set dev
$rp1 down
178 ip link
set dev br1 down
184 simple_if_init
$rp2 2001:db8
:3::2/64
185 __simple_if_init v1 v
$rp2 2001:db8
:4::2/64
186 __simple_if_init v3 v
$rp2 2001:db8
:5::2/64
187 tc qdisc add dev v1 clsact
192 tc qdisc del dev v1 clsact
193 __simple_if_fini v3
2001:db8
:5::2/64
194 __simple_if_fini v1
2001:db8
:4::2/64
195 simple_if_fini
$rp2 2001:db8
:3::2/64
200 local in_if
=$1; shift
201 local in_addr
=$1; shift
202 local other_in_addr
=$1; shift
203 local nh_addr
=$1; shift
204 local host_addr_ipv4
=$1; shift
205 local host_addr_ipv6
=$1; shift
207 ip link
set dev
$in_if up
208 ip address add dev
$in_if $in_addr/64
209 tc qdisc add dev
$in_if clsact
211 ip link add name br2
type bridge vlan_filtering
0
212 ip link
set dev br2 up
214 ip link add name w1
type veth peer name w2
216 ip link
set dev w1 master br2
217 ip link
set dev w1 up
219 ip link add name vx2
type vxlan id
1000 local $in_addr \
220 dstport
"$VXPORT" udp6zerocsumrx
221 ip link
set dev vx2 up
222 bridge fdb append dev vx2
00:00:00:00:00:00 dst
2001:db8
:3::1 self
223 bridge fdb append dev vx2
00:00:00:00:00:00 dst
$other_in_addr self
225 ip link
set dev vx2 master br2
226 tc qdisc add dev vx2 clsact
228 simple_if_init w2
$host_addr_ipv4/28 $host_addr_ipv6/64
230 ip route add
2001:db8
:3::0/64 nexthop via
$nh_addr
231 ip route add
$other_in_addr/128 nexthop via
$nh_addr
233 export -f ns_init_common
238 ip link
set dev v2 netns ns1
240 ns_init_common v2
2001:db8
:4::1 2001:db8
:5::1 2001:db8
:4::2 \
241 192.0.2.3 2001:db8
:1::3
246 ip netns
exec ns1 ip link
set dev v2 netns
1
253 ip link
set dev v4 netns ns2
255 ns_init_common v4
2001:db8
:5::1 2001:db8
:4::1 2001:db8
:5::2 \
256 192.0.2.4 2001:db8
:1::4
261 ip netns
exec ns2 ip link
set dev v4 netns
1
283 ip link add name v1
type veth peer name v2
284 ip link add name v3
type veth peer name v4
289 r1_mac
=$
(in_ns ns1 mac_get w2
)
290 r2_mac
=$
(in_ns ns2 mac_get w2
)
291 h2_mac
=$
(mac_get
$h2)
312 # For the first round of tests, vx1 is the first device to get
313 # attached to the bridge, and at that point the local IP is already
314 # configured. Try the other scenario of attaching the devices to a an
315 # already-offloaded bridge, and only then assign the local IP.
318 log_info
"Reapplying configuration"
320 bridge fdb del dev vx1
00:00:00:00:00:00 dst
2001:db8
:5::1 self
321 bridge fdb del dev vx1
00:00:00:00:00:00 dst
2001:db8
:4::1 self
322 ip link
set dev vx1 nomaster
326 ip link
set dev vx1 master br1
327 bridge fdb append dev vx1
00:00:00:00:00:00 dst
2001:db8
:4::1 self
328 bridge fdb append dev vx1
00:00:00:00:00:00 dst
2001:db8
:5::1 self
336 local vxlan_local_ip
=$1; shift
337 local vxlan_remote_ip
=$1; shift
338 local src_ip
=$1; shift
339 local dst_ip
=$1; shift
345 tc filter add dev
$rp1 egress protocol ipv6 pref
1 handle
101 \
346 flower ip_proto udp src_ip
$vxlan_local_ip \
347 dst_ip
$vxlan_remote_ip dst_port
$VXPORT $TC_FLAG action pass
348 # Match ICMP-reply packets after decapsulation, so source IP is
349 # destination IP of the ping and destination IP is source IP of the
351 tc filter add dev
$swp1 egress protocol ip pref
1 handle
101 \
352 flower src_ip
$dst_ip dst_ip
$src_ip \
355 # Send 100 packets and verify that at least 100 packets hit the rule,
356 # to overcome ARP noise.
357 PING_COUNT
=100 PING_TIMEOUT
=20 ping_do
$dev $dst_ip
358 check_err $?
"Ping failed"
360 tc_check_at_least_x_packets
"dev $rp1 egress" 101 10 100
361 check_err $?
"Encapsulated packets did not go through router"
363 tc_check_at_least_x_packets
"dev $swp1 egress" 101 10 100
364 check_err $?
"Decapsulated packets did not go through switch"
366 log_test
"ping: $info"
368 tc filter del dev
$swp1 egress
369 tc filter del dev
$rp1 egress
376 local local_sw_ip
=2001:db8
:3::1
377 local remote_ns1_ip
=2001:db8
:4::1
378 local remote_ns2_ip
=2001:db8
:5::1
379 local h1_ip
=192.0.2.1
380 local w2_ns1_ip
=192.0.2.3
381 local w2_ns2_ip
=192.0.2.4
383 ping_test
$h1 192.0.2.2 ": local->local"
385 __ping_ipv4
$local_sw_ip $remote_ns1_ip $h1_ip $w2_ns1_ip $h1 \
387 __ping_ipv4
$local_sw_ip $remote_ns2_ip $h1_ip $w2_ns2_ip $h1 \
393 local vxlan_local_ip
=$1; shift
394 local vxlan_remote_ip
=$1; shift
395 local src_ip
=$1; shift
396 local dst_ip
=$1; shift
402 tc filter add dev
$rp1 egress protocol ipv6 pref
1 handle
101 \
403 flower ip_proto udp src_ip
$vxlan_local_ip \
404 dst_ip
$vxlan_remote_ip dst_port
$VXPORT $TC_FLAG action pass
405 # Match ICMP-reply packets after decapsulation, so source IP is
406 # destination IP of the ping and destination IP is source IP of the
408 tc filter add dev
$swp1 egress protocol ipv6 pref
1 handle
101 \
409 flower src_ip
$dst_ip dst_ip
$src_ip $TC_FLAG action pass
411 # Send 100 packets and verify that at least 100 packets hit the rule,
412 # to overcome neighbor discovery noise.
413 PING_COUNT
=100 PING_TIMEOUT
=20 ping6_do
$dev $dst_ip
414 check_err $?
"Ping failed"
416 tc_check_at_least_x_packets
"dev $rp1 egress" 101 100
417 check_err $?
"Encapsulated packets did not go through router"
419 tc_check_at_least_x_packets
"dev $swp1 egress" 101 100
420 check_err $?
"Decapsulated packets did not go through switch"
422 log_test
"ping6: $info"
424 tc filter del dev
$swp1 egress
425 tc filter del dev
$rp1 egress
432 local local_sw_ip
=2001:db8
:3::1
433 local remote_ns1_ip
=2001:db8
:4::1
434 local remote_ns2_ip
=2001:db8
:5::1
435 local h1_ip
=2001:db8
:1::1
436 local w2_ns1_ip
=2001:db8
:1::3
437 local w2_ns2_ip
=2001:db8
:1::4
439 ping6_test
$h1 2001:db8
:1::2 ": local->local"
441 __ping_ipv6
$local_sw_ip $remote_ns1_ip $h1_ip $w2_ns1_ip $h1 \
443 __ping_ipv6
$local_sw_ip $remote_ns2_ip $h1_ip $w2_ns2_ip $h1 \
452 __flood_counter_add_del
()
454 local add_del
=$1; shift
455 local dst_ip
=$1; shift
459 # Putting the ICMP capture both to HW and to SW will end up
460 # double-counting the packets that are trapped to slow path, such as for
461 # the unicast test. Adding either skip_hw or skip_sw fixes this problem,
462 # but with skip_hw, the flooded packets are not counted at all, because
463 # those are dropped due to MAC address mismatch; and skip_sw is a no-go
464 # for veth-based topologies.
466 # So try to install with skip_sw and fall back to skip_sw if that fails.
468 $
(maybe_in_ns
$ns) tc filter
$add_del dev
"$dev" ingress \
469 proto ipv6 pref
100 flower dst_ip
$dst_ip ip_proto \
470 icmpv6 skip_sw action pass
2>/dev
/null || \
471 $
(maybe_in_ns
$ns) tc filter
$add_del dev
"$dev" ingress \
472 proto ipv6 pref
100 flower dst_ip
$dst_ip ip_proto \
473 icmpv6 skip_hw action pass
476 flood_counter_install
()
478 __flood_counter_add_del add
"$@"
481 flood_counter_uninstall
()
483 __flood_counter_add_del del
"$@"
491 $
(maybe_in_ns
$ns) tc_rule_stats_get
$dev 100 ingress
496 local counters
=("${@}")
499 for counter
in "${counters[@]}"; do
500 flood_fetch_stat
$counter
508 local -a expects
=("${@}")
510 local -a counters
=($h2 "vx2 ns1" "vx2 ns2")
514 for counter
in "${counters[@]}"; do
515 flood_counter_install
$dst $counter
518 local -a t0s
=($
(flood_fetch_stats
"${counters[@]}"))
519 $MZ -6 $h1 -c 10 -d 100msec
-p 64 -b $mac -B $dst -t icmp6
type=128 -q
521 local -a t1s
=($
(flood_fetch_stats
"${counters[@]}"))
523 for key
in ${!t0s[@]}; do
524 local delta
=$
((t1s
[$key] - t0s
[$key]))
525 local expect
=${expects[$key]}
528 check_err $?
"${counters[$key]}: Expected to capture $expect packets, got $delta."
531 for counter
in "${counters[@]}"; do
532 flood_counter_uninstall
$dst $counter
544 vxlan_flood_test
$mac $dst 10 10 10
546 log_test
"VXLAN: $what"
551 __test_flood de
:ad
:be
:ef
:13:37 2001:db8
:1::100 "flood"
556 local add_del
=$1; shift
561 bridge fdb
$add_del dev
$dev $mac self static permanent \
562 ${dst:+dst} $dst 2>/dev
/null
563 bridge fdb
$add_del dev
$dev $mac master static
2>/dev
/null
570 local hit_idx
=$1; shift
575 local -a expects
=(0 0 0)
578 vxlan_flood_test
$mac $dst "${expects[@]}"
580 log_test
"VXLAN: $what"
585 local -a targets
=("$h2_mac $h2"
586 "$r1_mac vx1 2001:db8:4::1"
587 "$r2_mac vx1 2001:db8:5::1")
590 for target
in "${targets[@]}"; do
591 vxlan_fdb_add_del add
$target
594 __test_unicast
$h2_mac 2001:db8
:1::2 0 "local MAC unicast"
595 __test_unicast
$r1_mac 2001:db8
:1::3 1 "remote MAC 1 unicast"
596 __test_unicast
$r2_mac 2001:db8
:1::4 2 "remote MAC 2 unicast"
598 for target
in "${targets[@]}"; do
599 vxlan_fdb_add_del del
$target
605 local ping_dev
=$1; shift
606 local ping_dip
=$1; shift
607 local ping_args
=$1; shift
608 local capture_dev
=$1; shift
609 local capture_dir
=$1; shift
610 local capture_pref
=$1; shift
611 local expect
=$1; shift
613 local t0
=$
(tc_rule_stats_get
$capture_dev $capture_pref $capture_dir)
614 ping6_do
$ping_dev $ping_dip "$ping_args"
615 local t1
=$
(tc_rule_stats_get
$capture_dev $capture_pref $capture_dir)
616 local delta
=$
((t1
- t0
))
618 # Tolerate a couple stray extra packets.
619 ((expect
<= delta
&& delta
<= expect
+ 5))
620 check_err $?
"$capture_dev: Expected to capture $expect packets, got $delta."
627 tc filter add dev v1 egress pref
77 protocol ipv6 \
628 flower ip_ttl
99 action pass
629 vxlan_ping_test
$h1 2001:db8
:1::3 "" v1 egress
77 10
630 tc filter del dev v1 egress pref
77 protocol ipv6
632 log_test
"VXLAN: envelope TTL"
639 tc filter add dev v1 egress pref
77 protocol ipv6 \
640 flower ip_tos
0x14 action pass
641 vxlan_ping_test
$h1 2001:db8
:1::3 "-Q 0x14" v1 egress
77 10
642 vxlan_ping_test
$h1 2001:db8
:1::3 "-Q 0x18" v1 egress
77 0
643 tc filter del dev v1 egress pref
77 protocol ipv6
645 log_test
"VXLAN: envelope TOS inheritance"
655 tc filter add dev v1 egress pref
77 protocol ipv6 \
656 flower ip_tos
$tos ip_proto udp dst_port
$VXPORT action pass
658 vxlan_ping_test
$h1 2001:db8
:1::3 "-Q $q" v1 egress
77 10
659 tc filter del dev v1 egress pref
77 protocol ipv6
661 log_test
"VXLAN: ECN encap: $q->$tos"
666 # In accordance with INET_ECN_encapsulate()
667 __test_ecn_encap
0x00 0x00
668 __test_ecn_encap
0x01 0x01
669 __test_ecn_encap
0x02 0x02
670 __test_ecn_encap
0x03 0x02
673 vxlan_encapped_ping_do
()
675 local count
=$1; shift
677 local next_hop_mac
=$1; shift
678 local dest_ip
=$1; shift
679 local dest_mac
=$1; shift
680 local inner_tos
=$1; shift
681 local outer_tos
=$1; shift
682 local saddr
="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03"
683 local daddr
="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01"
685 $MZ -6 $dev -c $count -d 100msec
-q \
686 -b $next_hop_mac -B $dest_ip \
687 -t udp tos
=$outer_tos,sp
=23456,dp
=$VXPORT,p
=$
(:
688 )"08:"$
( : VXLAN flags
689 )"00:00:00:"$
( : VXLAN reserved
690 )"00:03:e8:"$
( : VXLAN VNI
691 )"00:"$
( : VXLAN reserved
692 )"$dest_mac:"$
( : ETH daddr
693 )"$(mac_get w2):"$
( : ETH saddr
694 )"86:dd:"$
( : ETH
type
696 )"$inner_tos"$
( : Traffic class
697 )"0:00:00:"$
( : Flow label
698 )"00:08:"$
( : Payload length
699 )"3a:"$
( : Next header
701 )"$saddr:"$
( : IP saddr
702 )"$daddr:"$
( : IP daddr
703 )"80:"$
( : ICMPv6.
type
704 )"00:"$
( : ICMPv6.code
705 )"00:"$
( : ICMPv6.checksum
708 export -f vxlan_encapped_ping_do
710 vxlan_encapped_ping_test
()
712 local ping_dev
=$1; shift
713 local nh_dev
=$1; shift
714 local ping_dip
=$1; shift
715 local inner_tos
=$1; shift
716 local outer_tos
=$1; shift
717 local stat_get
=$1; shift
718 local expect
=$1; shift
720 local t0
=$
($stat_get)
723 vxlan_encapped_ping_do
10 $ping_dev $
(mac_get
$nh_dev) \
724 $ping_dip $
(mac_get
$h1) \
725 $inner_tos $outer_tos
727 local t1
=$
($stat_get)
728 local delta
=$
((t1
- t0
))
730 # Tolerate a couple stray extra packets.
731 ((expect
<= delta
&& delta
<= expect
+ 2))
732 check_err $?
"Expected to capture $expect packets, got $delta."
734 export -f vxlan_encapped_ping_test
738 local orig_inner_tos
=$1; shift
739 local orig_outer_tos
=$1; shift
740 local decapped_tos
=$1; shift
744 tc filter add dev
$h1 ingress pref
77 protocol ipv6 \
745 flower src_ip
2001:db8
:1::3 dst_ip
2001:db8
:1::1 \
746 ip_tos
$decapped_tos action drop
748 vxlan_encapped_ping_test v2 v1
2001:db8
:3::1 \
749 $orig_inner_tos $orig_outer_tos \
750 "tc_rule_stats_get $h1 77 ingress" 10
751 tc filter del dev
$h1 ingress pref
77
753 log_test
"VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->$decapped_tos"
756 test_ecn_decap_error
()
758 local orig_inner_tos
="0:0"
759 local orig_outer_tos
=03
763 vxlan_encapped_ping_test v2 v1
2001:db8
:3::1 \
764 $orig_inner_tos $orig_outer_tos \
765 "link_stats_rx_errors_get vx1" 10
767 log_test
"VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->error"
772 # In accordance with INET_ECN_decapsulate()
773 __test_ecn_decap
"0:0" 00 0x00
774 __test_ecn_decap
"0:0" 01 0x00
775 __test_ecn_decap
"0:0" 02 0x00
776 # 00 03 is tested in test_ecn_decap_error()
777 __test_ecn_decap
"0:1" 00 0x01
778 __test_ecn_decap
"0:1" 01 0x01
779 __test_ecn_decap
"0:1" 02 0x01
780 __test_ecn_decap
"0:1" 03 0x03
781 __test_ecn_decap
"0:2" 00 0x02
782 __test_ecn_decap
"0:2" 01 0x01
783 __test_ecn_decap
"0:2" 02 0x02
784 __test_ecn_decap
"0:2" 03 0x03
785 __test_ecn_decap
"0:3" 00 0x03
786 __test_ecn_decap
"0:3" 01 0x03
787 __test_ecn_decap
"0:3" 02 0x03
788 __test_ecn_decap
"0:3" 03 0x03
794 log_info
"Running tests with UDP port $VXPORT"