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