1# SPDX-License-Identifier: GPL-2.0
2
3mirror_install()
4{
5	local from_dev=$1; shift
6	local direction=$1; shift
7	local to_dev=$1; shift
8	local filter=$1; shift
9
10	tc filter add dev $from_dev $direction \
11	   pref 1000 $filter \
12	   action mirred egress mirror dev $to_dev
13}
14
15mirror_uninstall()
16{
17	local from_dev=$1; shift
18	local direction=$1; shift
19
20	tc filter del dev $swp1 $direction pref 1000
21}
22
23is_ipv6()
24{
25	local addr=$1; shift
26
27	[[ -z ${addr//[0-9a-fA-F:]/} ]]
28}
29
30mirror_test()
31{
32	local vrf_name=$1; shift
33	local sip=$1; shift
34	local dip=$1; shift
35	local dev=$1; shift
36	local pref=$1; shift
37	local expect=$1; shift
38
39	if is_ipv6 $dip; then
40		local proto=-6
41		local type="icmp6 type=128" # Echo request.
42	else
43		local proto=
44		local type="icmp echoreq"
45	fi
46
47	if [[ -z ${expect//[[:digit:]]/} ]]; then
48		expect="== $expect"
49	fi
50
51	local t0=$(tc_rule_stats_get $dev $pref)
52	$MZ $proto $vrf_name ${sip:+-A $sip} -B $dip -a own -b bc -q \
53	    -c 10 -d 100msec -t $type
54	sleep 0.5
55	local t1=$(tc_rule_stats_get $dev $pref)
56	local delta=$((t1 - t0))
57	((delta $expect))
58	check_err $? "Expected to capture $expect packets, got $delta."
59}
60
61do_test_span_dir_ips()
62{
63	local expect=$1; shift
64	local dev=$1; shift
65	local ip1=$1; shift
66	local ip2=$1; shift
67	local forward_type=${1-8}; shift
68	local backward_type=${1-0}; shift
69
70	icmp_capture_install $dev "type $forward_type"
71	mirror_test v$h1 $ip1 $ip2 $dev 100 $expect
72	icmp_capture_uninstall $dev
73
74	icmp_capture_install $dev "type $backward_type"
75	mirror_test v$h2 $ip2 $ip1 $dev 100 $expect
76	icmp_capture_uninstall $dev
77}
78
79quick_test_span_dir_ips()
80{
81	local dev=$1; shift
82	local ip1=$1; shift
83	local ip2=$1; shift
84	local forward_type=${1-8}; shift
85	local backward_type=${1-0}; shift
86
87	do_test_span_dir_ips 10 "$dev" "$ip1" "$ip2" \
88			     "$forward_type" "$backward_type"
89}
90
91test_span_dir_ips()
92{
93	local dev=$1; shift
94	local forward_type=$1; shift
95	local backward_type=$1; shift
96	local ip1=$1; shift
97	local ip2=$1; shift
98
99	quick_test_span_dir_ips "$dev" "$ip1" "$ip2" \
100				"$forward_type" "$backward_type"
101
102	icmp_capture_install $dev "type $forward_type"
103	mirror_test v$h1 $ip1 $ip2 $dev 100 10
104	icmp_capture_uninstall $dev
105
106	icmp_capture_install $dev "type $backward_type"
107	mirror_test v$h2 $ip2 $ip1 $dev 100 10
108	icmp_capture_uninstall $dev
109}
110
111test_span_dir()
112{
113	local dev=$1; shift
114	local forward_type=$1; shift
115	local backward_type=$1; shift
116
117	test_span_dir_ips "$dev" "$forward_type" "$backward_type" \
118			  192.0.2.1 192.0.2.2
119}
120
121do_test_span_vlan_dir_ips()
122{
123	local expect=$1; shift
124	local dev=$1; shift
125	local vid=$1; shift
126	local ul_proto=$1; shift
127	local ip1=$1; shift
128	local ip2=$1; shift
129
130	# Install the capture as skip_hw to avoid double-counting of packets.
131	# The traffic is meant for local box anyway, so will be trapped to
132	# kernel.
133	vlan_capture_install $dev "skip_hw vlan_id $vid vlan_ethtype $ul_proto"
134	mirror_test v$h1 $ip1 $ip2 $dev 100 "$expect"
135	mirror_test v$h2 $ip2 $ip1 $dev 100 "$expect"
136	vlan_capture_uninstall $dev
137}
138
139quick_test_span_vlan_dir_ips()
140{
141	local dev=$1; shift
142	local vid=$1; shift
143	local ul_proto=$1; shift
144	local ip1=$1; shift
145	local ip2=$1; shift
146
147	do_test_span_vlan_dir_ips '>= 10' "$dev" "$vid" "$ul_proto" \
148				  "$ip1" "$ip2"
149}
150
151fail_test_span_vlan_dir_ips()
152{
153	local dev=$1; shift
154	local vid=$1; shift
155	local ul_proto=$1; shift
156	local ip1=$1; shift
157	local ip2=$1; shift
158
159	do_test_span_vlan_dir_ips 0 "$dev" "$vid" "$ul_proto" "$ip1" "$ip2"
160}
161
162quick_test_span_vlan_dir()
163{
164	local dev=$1; shift
165	local vid=$1; shift
166	local ul_proto=$1; shift
167
168	quick_test_span_vlan_dir_ips "$dev" "$vid" "$ul_proto" \
169				     192.0.2.1 192.0.2.2
170}
171
172fail_test_span_vlan_dir()
173{
174	local dev=$1; shift
175	local vid=$1; shift
176	local ul_proto=$1; shift
177
178	fail_test_span_vlan_dir_ips "$dev" "$vid" "$ul_proto" \
179				    192.0.2.1 192.0.2.2
180}
181