1 # SPDX-License-Identifier: GPL-2.0
2 
3 mirror_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 
15 mirror_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 
23 is_ipv6()
24 {
25 	local addr=$1; shift
26 
27 	[[ -z ${addr//[0-9a-fA-F:]/} ]]
28 }
29 
30 mirror_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 
61 do_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 
79 quick_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 
91 test_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 
111 test_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 
121 do_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 
139 quick_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 
151 fail_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 
162 quick_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 
172 fail_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