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
23mirror_test()
24{
25	local vrf_name=$1; shift
26	local sip=$1; shift
27	local dip=$1; shift
28	local dev=$1; shift
29	local pref=$1; shift
30	local expect=$1; shift
31
32	local ping_timeout=$((PING_TIMEOUT * 5))
33	local t0=$(tc_rule_stats_get $dev $pref)
34	ip vrf exec $vrf_name \
35	   ${PING} ${sip:+-I $sip} $dip -c 10 -i 0.5 -w $ping_timeout \
36		   &> /dev/null
37	sleep 0.5
38	local t1=$(tc_rule_stats_get $dev $pref)
39	local delta=$((t1 - t0))
40	# Tolerate a couple stray extra packets.
41	((expect <= delta && delta <= expect + 2))
42	check_err $? "Expected to capture $expect packets, got $delta."
43}
44
45do_test_span_dir_ips()
46{
47	local expect=$1; shift
48	local dev=$1; shift
49	local direction=$1; shift
50	local ip1=$1; shift
51	local ip2=$1; shift
52
53	icmp_capture_install $dev
54	mirror_test v$h1 $ip1 $ip2 $dev 100 $expect
55	mirror_test v$h2 $ip2 $ip1 $dev 100 $expect
56	icmp_capture_uninstall $dev
57}
58
59quick_test_span_dir_ips()
60{
61	do_test_span_dir_ips 10 "$@"
62}
63
64fail_test_span_dir_ips()
65{
66	do_test_span_dir_ips 0 "$@"
67}
68
69test_span_dir_ips()
70{
71	local dev=$1; shift
72	local direction=$1; shift
73	local forward_type=$1; shift
74	local backward_type=$1; shift
75	local ip1=$1; shift
76	local ip2=$1; shift
77
78	quick_test_span_dir_ips "$dev" "$direction" "$ip1" "$ip2"
79
80	icmp_capture_install $dev "type $forward_type"
81	mirror_test v$h1 $ip1 $ip2 $dev 100 10
82	icmp_capture_uninstall $dev
83
84	icmp_capture_install $dev "type $backward_type"
85	mirror_test v$h2 $ip2 $ip1 $dev 100 10
86	icmp_capture_uninstall $dev
87}
88
89fail_test_span_dir()
90{
91	fail_test_span_dir_ips "$@" 192.0.2.1 192.0.2.2
92}
93
94test_span_dir()
95{
96	test_span_dir_ips "$@" 192.0.2.1 192.0.2.2
97}
98
99do_test_span_vlan_dir_ips()
100{
101	local expect=$1; shift
102	local dev=$1; shift
103	local vid=$1; shift
104	local direction=$1; shift
105	local ip1=$1; shift
106	local ip2=$1; shift
107
108	# Install the capture as skip_hw to avoid double-counting of packets.
109	# The traffic is meant for local box anyway, so will be trapped to
110	# kernel.
111	vlan_capture_install $dev "skip_hw vlan_id $vid vlan_ethtype ip"
112	mirror_test v$h1 $ip1 $ip2 $dev 100 $expect
113	mirror_test v$h2 $ip2 $ip1 $dev 100 $expect
114	vlan_capture_uninstall $dev
115}
116
117quick_test_span_vlan_dir_ips()
118{
119	do_test_span_vlan_dir_ips 10 "$@"
120}
121
122fail_test_span_vlan_dir_ips()
123{
124	do_test_span_vlan_dir_ips 0 "$@"
125}
126
127quick_test_span_vlan_dir()
128{
129	quick_test_span_vlan_dir_ips "$@" 192.0.2.1 192.0.2.2
130}
131
132fail_test_span_vlan_dir()
133{
134	fail_test_span_vlan_dir_ips "$@" 192.0.2.1 192.0.2.2
135}
136