xref: /freebsd/tests/sys/netpfil/ipfw/lookup.sh (revision bea17411473bc58608badd425c223ee59d40a465)
1#! /usr/libexec/atf-sh
2#-
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2026 Boris Lytochkin
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
30common_dir="$(atf_get_srcdir)/../common"
31. ${common_dir}/utils.subr
32
33NC="nc -w 1 -dnN"
34
35setup_network_v4()
36{
37	epair="$1"
38
39	atf_check ifconfig ${epair}a 192.0.2.0/31 up
40
41	vnet_mkjail alcatraz ${epair}b
42
43	atf_check jexec alcatraz ifconfig ${epair}b 192.0.2.1/31 up
44
45	atf_check jexec alcatraz inetd -p $(pwd)/inetd.pid $(atf_get_srcdir)/lookup_inetd.conf
46
47	# Sanity checks
48	atf_check -o ignore ping -i .1 -c 3 -s 1200 192.0.2.1
49	atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82
50
51}
52
53atf_test_case "ip4" "cleanup"
54ip4_head()
55{
56	atf_set descr 'IPv4 lookup test'
57	atf_set require.user root
58	atf_set require.progs scapy
59}
60
61ip4_body()
62{
63	firewall_init "ipfw"
64
65	epair=$(vnet_mkepair)
66
67	setup_network_v4 ${epair}
68
69	# Source address match
70	firewall_config "alcatraz" ipfw ipfw \
71		"ipfw -q table 1 create type addr" \
72		"ipfw -q table 1 add 192.0.2.0/32" \
73		"ipfw -q add 100 unreach port tcp from any to any lookup src-ip 1 in"
74	atf_check -s exit:1 ${NC} 192.0.2.1 82
75
76	# Destination address match
77	firewall_config "alcatraz" ipfw ipfw \
78		"ipfw -q table 1 create type addr" \
79		"ipfw -q table 1 add 192.0.2.1/32" \
80		"ipfw -q add 100 unreach port tcp from any to any lookup dst-ip 1 in"
81	atf_check -s exit:1 ${NC} 192.0.2.1 82
82
83	# Masked part
84
85	# Masked source address match
86	firewall_config "alcatraz" ipfw ipfw \
87		"ipfw -q table 1 create type addr" \
88		"ipfw -q table 1 add 192.0.0.0/32" \
89		"ipfw -q add 100 allow tcp from any to any lookup src-ip4:255.255.253.255 1 in" \
90		"ipfw -q add 200 unreach port ip from any to any in"
91	atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82
92
93	# Masked destination address match
94	firewall_config "alcatraz" ipfw ipfw \
95		"ipfw -q table 1 create type addr" \
96		"ipfw -q table 1 add 192.0.0.1/32" \
97		"ipfw -q add 100 allow tcp from any to any lookup dst-ip4:255.255.253.255 1 in" \
98		"ipfw -q add 200 unreach port ip from any to any in"
99	atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82
100
101	# Masked source address !match
102	firewall_config "alcatraz" ipfw ipfw \
103		"ipfw -q table 1 create type addr" \
104		"ipfw -q table 1 add 192.0.0.0/32" \
105		"ipfw -q add 100 allow tcp from any to any lookup src-ip4:128.255.253.255 1 in" \
106		"ipfw -q add 200 unreach port ip from any to any in"
107	atf_check -s exit:1 ${NC} 192.0.2.1 82
108
109	# Masked destination address !match
110	firewall_config "alcatraz" ipfw ipfw \
111		"ipfw -q table 1 create type addr" \
112		"ipfw -q table 1 add 192.0.2.1/32" \
113		"ipfw -q add 100 allow tcp from any to any lookup dst-ip4:128.255.255.255 1 in" \
114		"ipfw -q add 200 unreach port ip from any to any in"
115	atf_check -s exit:1 ${NC} 192.0.2.1 82
116
117}
118
119
120setup_network_v6()
121{
122	epair="$1"
123
124	atf_check ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad -ifdisabled
125
126	vnet_mkjail alcatraz ${epair}b
127
128	atf_check jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad
129
130	atf_check jexec alcatraz inetd -p $(pwd)/inetd.pid $(atf_get_srcdir)/lookup_inetd.conf
131
132	# Sanity checks
133	atf_check -o ignore ping6 -i .1 -c 3 -s 1200 2001:db8:42::2
134	atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82
135
136}
137
138atf_test_case "ip6" "cleanup"
139ip6_head()
140{
141	atf_set descr 'IPv6 lookup test'
142	atf_set require.user root
143	atf_set require.progs scapy
144}
145
146ip6_body()
147{
148	firewall_init "ipfw"
149
150	epair=$(vnet_mkepair)
151
152	setup_network_v6 ${epair}
153
154	# Source address match
155	firewall_config "alcatraz" ipfw ipfw \
156		"ipfw -q table 1 create type addr" \
157		"ipfw -q table 1 add 2001:db8:42::1/128" \
158		"ipfw -q add 100 unreach port tcp from any to any lookup src-ip 1 in"
159	atf_check -s exit:1 ${NC} 2001:db8:42::2 82
160
161	# Destination address match
162	firewall_config "alcatraz" ipfw ipfw \
163		"ipfw -q table 1 create type addr" \
164		"ipfw -q table 1 add 2001:db8:42::2/128" \
165		"ipfw -q add 100 unreach port tcp from any to any lookup dst-ip 1 in"
166	atf_check -s exit:1 ${NC} 2001:db8:42::2 82
167
168	# Source address match
169	firewall_config "alcatraz" ipfw ipfw \
170		"ipfw -q table 1 create type addr" \
171		"ipfw -q table 1 add 2000::/64" \
172		"ipfw -q add 100 unreach port tcp from any to any lookup src-ip 1 in"
173	atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82
174
175	# Masked part
176
177	# Masked source address match
178	firewall_config "alcatraz" ipfw ipfw \
179		"ipfw -q table 1 create type addr" \
180		"ipfw -q table 1 add 2000:db8:42::1/128" \
181		"ipfw -q add 100 allow tcp from any to any lookup src-ip6:fff0:ffff:ffff:ffff:ffff:ffff:ffff:ffff 1 in" \
182		"ipfw -q add 200 unreach port tcp from any to any in"
183	atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82
184
185	# Destination address match
186	firewall_config "alcatraz" ipfw ipfw \
187		"ipfw -q table 1 create type addr" \
188		"ipfw -q table 1 add 2001:0:42::2/128" \
189		"ipfw -q add 100 allow tcp from any to any lookup dst-ip6:ffff:0:ffff:ffff:ffff:ffff:ffff:ffff 1 in" \
190		"ipfw -q add 200 count tcp from any to any in"
191	atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82
192
193	# Masked source address !match
194	firewall_config "alcatraz" ipfw ipfw \
195		"ipfw -q table 1 create type addr" \
196		"ipfw -q table 1 add 2001:db8:42::1/128" \
197		"ipfw -q add 100 allow tcp from any to any lookup src-ip6:fff0:ffff:ffff:ffff:ffff:ffff:ffff:ffff 1 in" \
198		"ipfw -q add 200 unreach port tcp from any to any in"
199	atf_check -s exit:1 ${NC} 2001:db8:42::2 82
200
201	# Masked destination address !match
202	firewall_config "alcatraz" ipfw ipfw \
203		"ipfw -q table 1 create type addr" \
204		"ipfw -q table 1 add 2000:0:42::2/128" \
205		"ipfw -q add 100 allow tcp from any to any lookup dst-ip6:ffff:0:ffff:ffff:ffff:ffff:ffff:ffff 1 in" \
206		"ipfw -q add 200 unreach port tcp from any to any in"
207	atf_check -s exit:1 ${NC} 2001:db8:42::2 82
208
209}
210
211atf_test_case "rulenum" "cleanup"
212rulenum_head()
213{
214	atf_set descr 'Rule number lookup test'
215	atf_set require.user root
216}
217
218rulenum_body()
219{
220	firewall_init "ipfw"
221
222	epair=$(vnet_mkepair)
223
224	setup_network_v6 ${epair}
225
226	firewall_config "alcatraz" ipfw ipfw \
227		"ipfw -q table 1 create type number" \
228		"ipfw -q table 1 add 100" \
229		"ipfw -q add 100 unreach port tcp from any to any lookup rulenum 1 in"
230	atf_check -s exit:1 ${NC} 2001:db8:42::2 82
231
232	firewall_config "alcatraz" ipfw ipfw \
233		"ipfw -q table 1 create type number" \
234		"ipfw -q table 1 add 101" \
235		"ipfw -q add 100 unreach port tcp from any to any lookup rulenum 1 in"
236	atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82
237
238	# Masked part
239
240	firewall_config "alcatraz" ipfw ipfw \
241		"ipfw -q table 1 create type number" \
242		"ipfw -q table 1 add 96" \
243		"ipfw -q add 100 unreach port tcp from any to any lookup rulenum:0x60 1 in"
244	atf_check -s exit:1 ${NC} 2001:db8:42::2 82
245
246	firewall_config "alcatraz" ipfw ipfw \
247		"ipfw -q table 1 create type number" \
248		"ipfw -q table 1 add 101" \
249		"ipfw -q add 100 unreach port tcp from any to any lookup rulenum:32 1 in"
250	atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82
251
252}
253
254atf_test_case "port" "cleanup"
255port_head()
256{
257	atf_set descr 'Lookup src-/dst-port works'
258	atf_set require.user root
259}
260
261port_body()
262{
263	firewall_init "ipfw"
264
265	epair=$(vnet_mkepair)
266
267	setup_network_v4 ${epair}
268
269	firewall_config "alcatraz" ipfw ipfw \
270		"ipfw -q table 1 create type number" \
271		"ipfw -q table 1 add 82" \
272		"ipfw add 10 allow tcp from any to any lookup dst-port 1 in" \
273		"ipfw add 20 unreach port tcp from any to any dst-port 82"
274	atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82
275
276	firewall_config "alcatraz" ipfw ipfw \
277		"ipfw -q table 1 create type number" \
278		"ipfw -q table 1 add 80" \
279		"ipfw add 10 allow tcp from any to any lookup dst-port 1 in" \
280		"ipfw add 20 unreach port tcp from any to any dst-port 82"
281	atf_check -s exit:1 ${NC} 192.0.2.1 82
282
283	firewall_config "alcatraz" ipfw ipfw \
284		"ipfw -q table 1 create type number" \
285		"ipfw -q table 1 add 82" \
286		"ipfw add 10 allow tcp from any to any lookup src-port 1 out" \
287		"ipfw add 20 unreach port tcp from any to any src-port 82 out"
288	atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82
289
290	firewall_config "alcatraz" ipfw ipfw \
291		"ipfw -q table 1 create type number" \
292		"ipfw -q table 1 add 80" \
293		"ipfw add 10 allow tcp from any to any lookup src-port 1 in" \
294		"ipfw add 20 unreach port tcp from any to any src-port 22222 in"
295	atf_check -s exit:1 ${NC} -p 22222 192.0.2.1 82
296
297	# Masked part
298
299	firewall_config "alcatraz" ipfw ipfw \
300		"ipfw -q table 1 create type number" \
301		"ipfw -q table 1 add 18" \
302		"ipfw add 10 allow tcp from any to any lookup dst-port:0x1F 1 in" \
303		"ipfw add 20 unreach port tcp from any to any dst-port 82"
304	atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82
305
306	firewall_config "alcatraz" ipfw ipfw \
307		"ipfw -q table 1 create type number" \
308		"ipfw -q table 1 add 18" \
309		"ipfw add 10 allow tcp from any to any lookup dst-port:255 1 in" \
310		"ipfw add 20 unreach port tcp from any to any dst-port 82"
311	atf_check -s exit:1 ${NC} 192.0.2.1 82
312}
313
314atf_test_case "dscp_v6" "cleanup"
315dscp_v6_head()
316{
317	atf_set descr 'DSCP for IPv6 lookup test'
318	atf_set require.user root
319}
320
321dscp_v6_body()
322{
323	firewall_init "ipfw"
324
325	epair=$(vnet_mkepair)
326
327	setup_network_v6 ${epair}
328
329	firewall_config "alcatraz" ipfw ipfw \
330		"ipfw -q table 1 create type number" \
331		"ipfw -q table 1 add 12" \
332		"ipfw -q add 50 setdscp 12 tcp from any to any" \
333		"ipfw -q add 100 unreach port tcp from any to any lookup dscp 1 in"
334	atf_check -s exit:1 ${NC} 2001:db8:42::2 82
335
336	firewall_config "alcatraz" ipfw ipfw \
337		"ipfw -q table 1 create type number" \
338		"ipfw -q table 1 add 101" \
339		"ipfw -q add 50 setdscp 12 tcp from any to any" \
340		"ipfw -q add 100 unreach port tcp from any to any lookup dscp 1 in"
341	atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82
342
343	# Masked part
344
345	firewall_config "alcatraz" ipfw ipfw \
346		"ipfw -q table 1 create type number" \
347		"ipfw -q table 1 add 12" \
348		"ipfw -q add 50 setdscp 13 tcp from any to any" \
349		"ipfw -q add 100 unreach port tcp from any to any lookup dscp:0xFE 1 in"
350	atf_check -s exit:1 ${NC} 2001:db8:42::2 82
351
352	firewall_config "alcatraz" ipfw ipfw \
353		"ipfw -q table 1 create type number" \
354		"ipfw -q table 1 add 13" \
355		"ipfw -q add 50 setdscp 13 tcp from any to any" \
356		"ipfw -q add 100 unreach port tcp from any to any lookup dscp:1 1 in"
357	atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82
358
359}
360
361atf_test_case "dscp_v4" "cleanup"
362dscp_v4_head()
363{
364	atf_set descr 'Lookup DSCP for IPv4 test'
365	atf_set require.user root
366}
367
368dscp_v4_body()
369{
370	firewall_init "ipfw"
371
372	epair=$(vnet_mkepair)
373
374	setup_network_v4 ${epair}
375
376	firewall_config "alcatraz" ipfw ipfw \
377		"ipfw -q table 1 create type number" \
378		"ipfw -q table 1 add 12" \
379		"ipfw -q add 50 setdscp 12 tcp from any to any dst-port 82 in" \
380		"ipfw -q add 100 allow tcp from any to any lookup dscp 1 in" \
381		"ipfw -q add 200 unreach port tcp from any to any port 82 in"
382	atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82
383
384	firewall_config "alcatraz" ipfw ipfw \
385		"ipfw -q table 1 create type number" \
386		"ipfw -q table 1 add 13" \
387		"ipfw -q add 50 setdscp 12 tcp from any to any dst-port 82 in" \
388		"ipfw -q add 100 allow tcp from any to any lookup dscp 1 in" \
389		"ipfw -q add 200 unreach port tcp from any to any dst-port 82 in"
390	atf_check -s exit:1 ${NC} 192.0.2.1 82
391
392	# Masked part
393
394	firewall_config "alcatraz" ipfw ipfw \
395		"ipfw -q table 1 create type number" \
396		"ipfw -q table 1 add 48" \
397		"ipfw -q add 50 setdscp 50 tcp from any to any dst-port 82 in" \
398		"ipfw -q add 100 allow tcp from any to any lookup dscp:0xF0 1 in" \
399		"ipfw -q add 200 unreach port tcp from any to any dst-port 82"
400	atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82
401
402	firewall_config "alcatraz" ipfw ipfw \
403		"ipfw -q table 1 create type number" \
404		"ipfw -q table 1 add 48" \
405		"ipfw -q add 50 setdscp 50 tcp from any to any dst-port 82 in" \
406		"ipfw -q add 100 allow tcp from any to any lookup dscp:255 1 in" \
407		"ipfw -q add 200 unreach port tcp from any to any dst-port 82"
408	atf_check -s exit:1 ${NC} 192.0.2.1 82
409}
410
411
412lookup_cleanup()
413{
414	 firewall_cleanup $1
415}
416
417atf_init_test_cases()
418{
419	for test in "ip4" "ip6" \
420	    "rulenum" "port" \
421	    "dscp_v4" "dscp_v6" \
422	    ; do
423		atf_add_test_case "${test}"
424		alias "${test}_cleanup"="lookup_cleanup"
425	done
426}
427
428