xref: /freebsd/tests/sys/netinet/forward.sh (revision e27970ae8fffd7d14cd106efc150e60ae307607a)
1#!/usr/bin/env atf-sh
2#-
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2020 Alexander V. Chernikov
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28#
29
30. $(atf_get_srcdir)/../common/vnet.subr
31
32atf_test_case "fwd_ip_icmp_iface_fast_success" "cleanup"
33fwd_ip_icmp_iface_fast_success_head() {
34
35	atf_set descr 'Test valid IPv4 on-stick fastforwarding to iface'
36	atf_set require.user root
37	atf_set require.progs scapy
38}
39
40fwd_ip_icmp_iface_fast_success_body() {
41
42	vnet_init
43
44	ip4a="192.0.2.1"
45	ip4b="192.0.2.2"
46	plen=29
47	src_ip="192.0.2.3"
48
49	script_name="../common/sender.py"
50
51	epair=$(vnet_mkepair)
52	ifconfig ${epair}a up
53	ifconfig ${epair}a inet ${ip4a}/${plen}
54
55	jname="v4t-fwd_ip_icmp_iface_fast_success"
56	vnet_mkjail ${jname} ${epair}b
57	jexec ${jname} ifconfig ${epair}b up
58	jexec ${jname} ifconfig ${epair}b inet ${ip4b}/${plen}
59
60	# Get router ip/mac
61	jail_ip=${ip4b}
62	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
63
64	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
65
66	jexec ${jname} sysctl net.inet.ip.forwarding=1
67	# As we're doing router-on-the-stick, turn sending IP redirects off:
68	jexec ${jname} sysctl net.inet.ip.redirect=0
69
70	# echo "LOCAL: ${local_ip} ${local_mac}"
71	# echo "REMOTE: ${remote_rtr_ip} ${remote_rtr_mac}"
72
73	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
74		--test_name fwd_ip_icmp_fast \
75		--smac ${our_mac} --dmac ${jail_mac} \
76		--sip ${src_ip} --dip ${ip4a} \
77		--iface ${epair}a
78
79	# check counters are valid
80	atf_check -o match:'1 packet forwarded \(1 packet fast forwarded\)' jexec ${jname} netstat -sp ip
81}
82
83fwd_ip_icmp_iface_fast_success_cleanup() {
84
85	vnet_cleanup
86}
87
88atf_test_case "fwd_ip_icmp_gw_fast_success" "cleanup"
89fwd_ip_icmp_gw_fast_success_head() {
90
91	atf_set descr 'Test valid IPv4 on-stick fastforwarding to gw'
92	atf_set require.user root
93	atf_set require.progs scapy
94}
95
96fwd_ip_icmp_gw_fast_success_body() {
97
98	vnet_init
99
100	ip4a="192.0.2.1"
101	ip4b="192.0.2.2"
102	plen=29
103	src_ip="192.0.2.3"
104	dst_ip="192.0.2.4"
105
106	script_name="../common/sender.py"
107
108	epair=$(vnet_mkepair)
109	ifconfig ${epair}a up
110	ifconfig ${epair}a inet ${ip4a}/${plen}
111
112	jname="v4t-fwd_ip_icmp_gw_fast_success"
113	vnet_mkjail ${jname} ${epair}b
114	jexec ${jname} ifconfig ${epair}b up
115	jexec ${jname} ifconfig ${epair}b inet ${ip4b}/${plen}
116
117	# Get router ip/mac
118	jail_ip=${ip4b}
119	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
120
121	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
122
123	jexec ${jname} sysctl net.inet.ip.forwarding=1
124	# As we're doing router-on-the-stick, turn sending IP redirects off:
125	jexec ${jname} sysctl net.inet.ip.redirect=0
126
127	# Add host route
128	jexec ${jname} route -4 add -host ${dst_ip} ${ip4a}
129
130	# echo "LOCAL: ${local_ip} ${local_mac}"
131	# echo "REMOTE: ${remote_rtr_ip} ${remote_rtr_mac}"
132
133	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
134		--test_name fwd_ip_icmp_fast \
135		--smac ${our_mac} --dmac ${jail_mac} \
136		--sip ${src_ip} --dip ${dst_ip} \
137		--iface ${epair}a
138
139	# check counters are valid
140	atf_check -o match:'1 packet forwarded \(1 packet fast forwarded\)' jexec ${jname} netstat -sp ip
141}
142
143fwd_ip_icmp_gw_fast_success_cleanup() {
144
145	vnet_cleanup
146}
147
148atf_test_case "fwd_ip_icmp_iface_slow_success" "cleanup"
149fwd_ip_icmp_iface_slow_success_head() {
150
151	atf_set descr 'Test valid IPv4 on-stick "slow" forwarding to iface'
152	atf_set require.user root
153	atf_set require.progs scapy
154}
155
156fwd_ip_icmp_iface_slow_success_body() {
157
158	vnet_init
159
160	ip4a="192.0.2.1"
161	ip4b="192.0.2.2"
162	plen=29
163	src_ip="192.0.2.3"
164
165	script_name="../common/sender.py"
166
167	epair=$(vnet_mkepair)
168	ifconfig ${epair}a up
169	ifconfig ${epair}a inet ${ip4a}/${plen}
170
171	jname="v4t-fwd_ip_icmp_iface_slow_success"
172	vnet_mkjail ${jname} ${epair}b
173	jexec ${jname} ifconfig ${epair}b up
174	jexec ${jname} ifconfig ${epair}b inet ${ip4b}/${plen}
175
176	# Get router ip/mac
177	jail_ip=${ip4b}
178	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
179
180	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
181
182	jexec ${jname} sysctl net.inet.ip.forwarding=1
183	# As we're doing router-on-the-stick, turn sending IP redirects off:
184	jexec ${jname} sysctl net.inet.ip.redirect=0
185
186	# Generate packet with options to force slow-path
187	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
188		--test_name fwd_ip_icmp_slow \
189		--smac ${our_mac} --dmac ${jail_mac} \
190		--sip ${src_ip} --dip ${ip4a} \
191		--iface ${epair}a
192
193	# check counters are valid
194	atf_check -o match:'1 packet forwarded \(0 packets fast forwarded\)' jexec ${jname} netstat -sp ip
195}
196
197fwd_ip_icmp_iface_slow_success_cleanup() {
198
199	vnet_cleanup
200}
201
202atf_test_case "fwd_ip_icmp_gw_slow_success" "cleanup"
203fwd_ip_icmp_gw_slow_success_head() {
204
205	atf_set descr 'Test valid IPv4 on-stick "slow" forwarding to gw'
206	atf_set require.user root
207	atf_set require.progs scapy
208}
209
210fwd_ip_icmp_gw_slow_success_body() {
211
212	vnet_init
213
214	ip4a="192.0.2.1"
215	ip4b="192.0.2.2"
216	plen=29
217	src_ip="192.0.2.3"
218	dst_ip="192.0.2.4"
219
220	script_name="../common/sender.py"
221
222	epair=$(vnet_mkepair)
223	ifconfig ${epair}a up
224	ifconfig ${epair}a inet ${ip4a}/${plen}
225
226	jname="v4t-fwd_ip_icmp_gw_slow_success"
227	vnet_mkjail ${jname} ${epair}b
228	jexec ${jname} ifconfig ${epair}b up
229	jexec ${jname} ifconfig ${epair}b inet ${ip4b}/${plen}
230
231	# Get router ip/mac
232	jail_ip=${ip4b}
233	jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'`
234
235	our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'`
236
237	jexec ${jname} sysctl net.inet.ip.forwarding=1
238	# As we're doing router-on-the-stick, turn sending IP redirects off:
239	jexec ${jname} sysctl net.inet.ip.redirect=0
240
241	# Add host route
242	jexec ${jname} route -4 add -host ${dst_ip} ${ip4a}
243
244	# echo "LOCAL: ${local_ip} ${local_mac}"
245	# echo "REMOTE: ${remote_rtr_ip} ${remote_rtr_mac}"
246
247	atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \
248		--test_name fwd_ip_icmp_fast \
249		--smac ${our_mac} --dmac ${jail_mac} \
250		--sip ${src_ip} --dip ${dst_ip} \
251		--iface ${epair}a
252
253	# check counters are valid
254	atf_check -o match:'1 packet forwarded \(1 packet fast forwarded\)' jexec ${jname} netstat -sp ip
255}
256
257fwd_ip_icmp_gw_slow_success_cleanup() {
258
259	vnet_cleanup
260}
261
262atf_test_case "fwd_ip_blackhole" "cleanup"
263fwd_ip_blackhole_head() {
264
265	atf_set descr 'Test blackhole routes'
266	atf_set require.user root
267}
268
269fwd_ip_blackhole_body() {
270	jname="v4t-fwd_ip_blackhole"
271
272	vnet_init
273
274	epair=$(vnet_mkepair)
275	epair_out=$(vnet_mkepair)
276
277	ifconfig ${epair}a 192.0.2.2/24 up
278
279	vnet_mkjail ${jname} ${epair}b ${epair_out}b
280	jexec ${jname} ifconfig lo0 127.0.0.1/8 up
281	jexec ${jname} ifconfig ${epair}b 192.0.2.1/24 up
282	jexec ${jname} ifconfig ${epair_out}b 198.51.100.1/24 up
283	jexec ${jname} sysctl net.inet.ip.forwarding=1
284
285	route add default 192.0.2.1
286
287	atf_check -s exit:2 -o ignore \
288	    ping -c 1 -t 1 198.51.100.2
289	atf_check -s exit:0 -o match:"0 packets not forwardable" \
290	    jexec ${jname} netstat -s -p ip
291
292	# Create blackhole route
293	jexec ${jname} /sbin/route add 198.51.100.2 -blackhole -fib 0
294	jexec ${jname} netstat -rn
295
296	# Include an IP option to ensure slow path
297	atf_check -s exit:2 -o ignore \
298	    ping -c 1 -t 1 -R 198.51.100.2
299	atf_check -s exit:0 -o match:"1 packet not forwardable" \
300	    jexec ${jname} netstat -s -p ip
301
302	# Now try via the fast path
303	atf_check -s exit:2 -o ignore \
304	    ping -c 1 -t 1 198.51.100.2
305	atf_check -s exit:0 -o match:"2 packets not forwardable" \
306	    jexec ${jname} netstat -s -p ip
307}
308
309fwd_ip_blackhole_cleanup() {
310
311	vnet_cleanup
312}
313
314atf_init_test_cases()
315{
316
317	atf_add_test_case "fwd_ip_icmp_iface_fast_success"
318	atf_add_test_case "fwd_ip_icmp_gw_fast_success"
319	atf_add_test_case "fwd_ip_icmp_iface_slow_success"
320	atf_add_test_case "fwd_ip_icmp_gw_slow_success"
321	atf_add_test_case "fwd_ip_blackhole"
322}
323
324# end
325
326