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