xref: /openbsd/regress/sys/net/pf_divert/Makefile (revision 1073f88e)
1*1073f88eSbluhm#	$OpenBSD: Makefile,v 1.24 2021/12/12 21:16:53 bluhm Exp $
2336dfed2Sbluhm
3336dfed2Sbluhm# The following ports must be installed for the regression tests:
4336dfed2Sbluhm# p5-Socket6		Perl defines relating to AF_INET6 sockets
51e607023Sbluhm#
61e607023Sbluhm# Check wether all required perl packages are installed.  If some
71e607023Sbluhm# are missing print a warning and skip the tests, but do not fail.
8336dfed2Sbluhm
91e607023SbluhmPERL_REQUIRE !=	perl -Mstrict -Mwarnings -e ' \
101e607023Sbluhm    eval { require Socket6 } or print $@; \
111e607023Sbluhm'
121e607023Sbluhm.if ! empty(PERL_REQUIRE)
131e607023Sbluhmregress:
141e607023Sbluhm	@echo "${PERL_REQUIRE}"
151e607023Sbluhm	@echo install these perl packages for additional tests
1654eefd0cSbluhm	@echo SKIPPED
17336dfed2Sbluhm.endif
18336dfed2Sbluhm
19336dfed2Sbluhm# Fill out these variables as you have to test divert with the pf
20336dfed2Sbluhm# kernel running on a remote machine.  You have to specify a local
21336dfed2Sbluhm# and remote ip address for the test connections.  The fake ip address
22336dfed2Sbluhm# will be routed via the remote address to test divert with non-existing
23336dfed2Sbluhm# addresses.  To control the remote machine you need a hostname for
24336dfed2Sbluhm# ssh to log in.  All the test files must be in the same directory
25336dfed2Sbluhm# local and remote.
26336dfed2Sbluhm# You must have an anchor "regress" for the divert rules in the pf.conf
27336dfed2Sbluhm# of the remote machine.  The kernel of the remote machine gets testet.
2802079822Sbluhm#
2902079822Sbluhm# Run make check-setup to see if you got the setup correct.
30336dfed2Sbluhm
3111f7eadfSbluhmLOCAL_ADDR ?=
3211f7eadfSbluhmREMOTE_ADDR ?=
3311f7eadfSbluhmFAKE_ADDR ?=
3411f7eadfSbluhmLOCAL_ADDR6 ?=
3511f7eadfSbluhmREMOTE_ADDR6 ?=
3611f7eadfSbluhmFAKE_ADDR6 ?=
3711f7eadfSbluhmREMOTE_SSH ?=
38336dfed2Sbluhm
391e607023Sbluhm.if empty (LOCAL_ADDR) || empty (REMOTE_ADDR) || empty (FAKE_ADDR) || \
401e607023Sbluhm    empty (LOCAL_ADDR6) || empty (REMOTE_ADDR6) || empty (FAKE_ADDR6) || \
411e607023Sbluhm    empty (REMOTE_SSH)
421e607023Sbluhmregress:
43aa8f1300Sbluhm	@echo This tests needs a remote machine to operate on.
441e607023Sbluhm	@echo LOCAL_ADDR REMOTE_ADDR FAKE_ADDR LOCAL_ADDR6
45aa8f1300Sbluhm	@echo REMOTE_ADDR6 FAKE_ADDR6 REMOTE_SSH are empty.
46aa8f1300Sbluhm	@echo Fill out these variables for additional tests.
4754eefd0cSbluhm	@echo SKIPPED
481e607023Sbluhm.endif
491e607023Sbluhm
501e607023Sbluhm# Automatically generate regress targets from test cases in directory.
511e607023Sbluhm
52068b97e5SbluhmPERLS =			Client.pm Packet.pm Proc.pm Remote.pm Server.pm \
53068b97e5Sbluhm			funcs.pl remote.pl
541e607023SbluhmARGS !=			cd ${.CURDIR} && ls args-*.pl
55d76821b9SbluhmTARGETS ?=		\
56d76821b9Sbluhm	inet-args-tcp-to inet6-args-tcp-to \
57d0e91fd6Sbluhm	inet-args-tcp-reply inet6-args-tcp-reply \
58d0e91fd6Sbluhm	inet-args-udp-to inet6-args-udp-to \
59d0e91fd6Sbluhm	inet-args-udp-reply inet6-args-udp-reply \
60c30a42c2Sbluhm	inet-args-udp-reply-to inet6-args-udp-reply-to \
61d0e91fd6Sbluhm	inet-args-rip-to inet6-args-rip-to \
62d0e91fd6Sbluhm	inet-args-rip-reply inet6-args-rip-reply \
63c30a42c2Sbluhm	inet-args-rip-reply-to inet6-args-rip-reply-to \
64d0e91fd6Sbluhm	inet-args-icmp-to inet6-args-icmp-to \
65c30a42c2Sbluhm	inet-args-icmp-reply-to inet6-args-icmp-reply-to \
66c30a42c2Sbluhm	inet-args-icmp-reply-reuse inet6-args-icmp-reply-reuse \
676a1cb87eSbluhm	inet-reuse-tcp-to-to inet6-reuse-tcp-to-to \
686a1cb87eSbluhm	inet-reuse-tcp-to-reply inet6-reuse-tcp-to-reply \
696a1cb87eSbluhm	inet-reuse-tcp-reply-to inet6-reuse-tcp-reply-to \
706a1cb87eSbluhm	inet-reuse-tcp-reply-reply inet6-reuse-tcp-reply-reply \
716a1cb87eSbluhm	inet-reuse-udp-to-to inet6-reuse-udp-to-to \
726a1cb87eSbluhm	inet-reuse-udp-to-reply inet6-reuse-udp-to-reply \
736a1cb87eSbluhm	inet-reuse-udp-to-reply-to inet6-reuse-udp-to-reply-to \
746a1cb87eSbluhm	inet-reuse-udp-reply-to inet6-reuse-udp-reply-to \
756a1cb87eSbluhm	inet-reuse-udp-reply-reply inet6-reuse-udp-reply-reply \
766a1cb87eSbluhm	inet-reuse-udp-reply-reply-to inet6-reuse-udp-reply-reply-to \
776a1cb87eSbluhm	inet-reuse-udp-reply-to-to inet6-reuse-udp-reply-to-to \
786a1cb87eSbluhm	inet-reuse-udp-reply-to-reply inet6-reuse-udp-reply-to-reply \
796a1cb87eSbluhm	inet-reuse-udp-reply-to-reply-to inet6-reuse-udp-reply-to-reply-to \
806a1cb87eSbluhm	inet-reuse-rip-to-to inet6-reuse-rip-to-to \
816a1cb87eSbluhm	inet-reuse-rip-to-reply inet6-reuse-rip-to-reply \
826a1cb87eSbluhm	inet-reuse-rip-to-reply-to inet6-reuse-rip-to-reply-to \
836a1cb87eSbluhm	inet-reuse-rip-reply-to inet6-reuse-rip-reply-to \
846a1cb87eSbluhm	inet-reuse-rip-reply-reply inet6-reuse-rip-reply-reply \
856a1cb87eSbluhm	inet-reuse-rip-reply-reply-to inet6-reuse-rip-reply-reply-to \
866a1cb87eSbluhm	inet-reuse-rip-reply-to-to inet6-reuse-rip-reply-to-to \
876a1cb87eSbluhm	inet-reuse-rip-reply-to-reply inet6-reuse-rip-reply-to-reply \
88068b97e5Sbluhm	inet-reuse-rip-reply-to-reply-to inet6-reuse-rip-reply-to-reply-to \
890c490069Sbluhm	inet-args-udp-packet-in inet6-args-udp-packet-in \
9040df215eSbluhm	inet-args-udp-packet-out inet6-args-udp-packet-out
9131432b1dSbluhmREGRESS_TARGETS =	${TARGETS:S/^/run-/}
92d76821b9SbluhmCLEANFILES +=		*.log *.port *.ktrace ktrace.out stamp-*
931e607023Sbluhm
94336dfed2Sbluhm.MAIN: all
95336dfed2Sbluhm
961e607023Sbluhm.if ! empty (REMOTE_SSH)
97336dfed2Sbluhm.if make (regress) || make (all)
98336dfed2Sbluhm.BEGIN:
99336dfed2Sbluhm	@echo
100336dfed2Sbluhm	${SUDO} true
1011e607023Sbluhm	ssh -t ${REMOTE_SSH} ${SUDO} true
1021e607023Sbluhm.if ! empty (FAKE_ADDR) && ! empty (REMOTE_ADDR)
103336dfed2Sbluhm	-${SUDO} route -n delete -inet -host ${FAKE_ADDR} 2>/dev/null
104336dfed2Sbluhm	${SUDO} route -n add -inet -host ${FAKE_ADDR} ${REMOTE_ADDR}
1051e607023Sbluhm.endif
1061e607023Sbluhm.if ! empty (FAKE_ADDR6) && ! empty (REMOTE_ADDR6)
107336dfed2Sbluhm	-${SUDO} route -n delete -inet6 -host ${FAKE_ADDR6} 2>/dev/null
108336dfed2Sbluhm	${SUDO} route -n add -inet6 -host ${FAKE_ADDR6} ${REMOTE_ADDR6}
109336dfed2Sbluhm.endif
1101e607023Sbluhm.endif
1111e607023Sbluhm.endif
112336dfed2Sbluhm
113336dfed2Sbluhm# Set variables so that make runs with and without obj directory.
114336dfed2Sbluhm# Only do that if necessary to keep visible output short.
115336dfed2Sbluhm
116336dfed2Sbluhm.if ${.CURDIR} == ${.OBJDIR}
117336dfed2SbluhmPERLINC =	-I.
118336dfed2SbluhmPERLPATH =
119336dfed2Sbluhm.else
120336dfed2SbluhmPERLINC =	-I${.CURDIR}
121336dfed2SbluhmPERLPATH =	${.CURDIR}/
122336dfed2Sbluhm.endif
123336dfed2Sbluhm
124336dfed2Sbluhm# The arg tests take a perl hash with arguments controlling the test
125336dfed2Sbluhm# parameters.  The remote.pl test has local client or server and the
126336dfed2Sbluhm# diverted process is running on the remote machine reachable with
127336dfed2Sbluhm# ssh.
128336dfed2Sbluhm
129d0e91fd6Sbluhm.for  inet addr  in  inet ADDR  inet6 ADDR6
130d0e91fd6Sbluhm
13131432b1dSbluhmrun-${inet}-reuse-rip-to-reply-to:
1326a1cb87eSbluhm	@echo 'rip to before reply is broken, it does not remove the state.'
1336a1cb87eSbluhm	@echo DISABLED
1346a1cb87eSbluhm
135336dfed2Sbluhm.for a in ${ARGS}
13631432b1dSbluhmrun-${inet}-${a:R}: ${a}
137068b97e5Sbluhm.if ${@:M*-packet-*}
138d76821b9Sbluhm	time ${SUDO} SUDO=${SUDO} KTRACE=${KTRACE} \
139d76821b9Sbluhm	    perl ${PERLINC} ${PERLPATH}remote.pl -f ${inet} \
140d76821b9Sbluhm	    ${LOCAL_${addr}} ${REMOTE_${addr}} ${REMOTE_SSH} \
141d76821b9Sbluhm	    ${PERLPATH}${a}
142068b97e5Sbluhm.else
143d76821b9Sbluhm	time ${SUDO} SUDO=${SUDO} KTRACE=${KTRACE} \
144d76821b9Sbluhm	    perl ${PERLINC} ${PERLPATH}remote.pl -f ${inet} \
145d76821b9Sbluhm	    ${LOCAL_${addr}} ${FAKE_${addr}} ${REMOTE_SSH} \
146d76821b9Sbluhm	    ${PERLPATH}${a}
147068b97e5Sbluhm.endif
148d0e91fd6Sbluhm.endfor
149d0e91fd6Sbluhm
1502316dd1bSbluhmSTATE_EXIST_tcp_to =		!
1512316dd1bSbluhmSTATE_EXIST_udp_to =
1522316dd1bSbluhmSTATE_EXIST_rip_to =
1532316dd1bSbluhmSTATE_EXIST_tcp_reply =		!
1542316dd1bSbluhmSTATE_EXIST_udp_reply =		!
1552316dd1bSbluhmSTATE_EXIST_rip_reply =		!
1562316dd1bSbluhmSTATE_EXIST_tcp_reply-to =	!
1572316dd1bSbluhmSTATE_EXIST_udp_reply-to =	!
1582316dd1bSbluhmSTATE_EXIST_rip_reply-to =	!
1592316dd1bSbluhm
160d0e91fd6Sbluhm.for proto in tcp udp rip
1616a1cb87eSbluhm
1626a1cb87eSbluhm.for  first second  in  to to  to reply  to reply-to  reply to  reply reply  reply reply-to  reply-to to  reply-to reply  reply-to reply-to
1636a1cb87eSbluhm
16431432b1dSbluhmrun-${inet}-reuse-${proto}-${first}-${second}:
1652316dd1bSbluhm	# create state with ${first} divert rule
166d76821b9Sbluhm	time ${SUDO} SUDO=${SUDO} KTRACE=${KTRACE} \
167d76821b9Sbluhm	    perl ${PERLINC} ${PERLPATH}remote.pl -f ${inet} \
168d76821b9Sbluhm	    ${LOCAL_${addr}} ${FAKE_${addr}} ${REMOTE_SSH} \
169d76821b9Sbluhm	    ${PERLPATH}args-${proto}-${first}.pl
170d0e91fd6Sbluhm	sed -n '/^connect peer:/s/.* //p' client.log >client.port
171d0e91fd6Sbluhm	sed -n '/^connect sock:/s/.* //p' client.log >server.port
172d0e91fd6Sbluhm.if "tcp" == ${proto}
1732316dd1bSbluhm	# drop client tcp socket still in time wait to allow reuse
1742316dd1bSbluhm.if "reply" == ${first} || "reply-to" == ${first}
175d76821b9Sbluhm	${SUDO} tcpdrop \
176d76821b9Sbluhm	    ${LOCAL_${addr}} `cat client.port` \
177d76821b9Sbluhm	    ${FAKE_${addr}} `cat server.port`
1780c2ea69fSbluhm	# to avoid SYN retransmit, kill local tcp state that will be reused
1790c2ea69fSbluhm.if "inet" == ${inet}
1800c2ea69fSbluhm	${SUDO} pfctl -k key -k '${proto} ${LOCAL_${addr}}:'`cat client.port`' <- ${FAKE_${addr}}:'`cat server.port`''
1810c2ea69fSbluhm.elif "inet6" == ${inet}
1820c2ea69fSbluhm	${SUDO} pfctl -k key -k '${proto} ${LOCAL_${addr}}['`cat client.port`'] <- ${FAKE_${addr}}['`cat server.port`']'
1830c2ea69fSbluhm.endif
1842316dd1bSbluhm.else # "to" == ${first}
1850c2ea69fSbluhm	# to avoid SYN retransmit, kill local tcp state that will be reused
1860c2ea69fSbluhm.if "inet" == ${inet}
1870c2ea69fSbluhm	${SUDO} pfctl -k key -k '${proto} ${LOCAL_${addr}}:'`cat server.port`' -> ${FAKE_${addr}}:'`cat client.port`''
1880c2ea69fSbluhm.elif "inet6" == ${inet}
1890c2ea69fSbluhm	${SUDO} pfctl -k key -k '${proto} ${LOCAL_${addr}}['`cat server.port`'] -> ${FAKE_${addr}}['`cat client.port`']'
1900c2ea69fSbluhm.endif
1912316dd1bSbluhm	# tcp socket is in time wait so state must still exist
1922316dd1bSbluhm	ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | \
1930c2ea69fSbluhm	    egrep 'all ${proto} ${FAKE_${addr}}:?\[?'`cat client.port`'\]? .. ${LOCAL_${addr}}:?\[?'`cat server.port`'\]? '
194d76821b9Sbluhm	ssh ${REMOTE_SSH} ${SUDO} tcpdrop \
195d76821b9Sbluhm	    ${FAKE_${addr}} `cat client.port` \
196d76821b9Sbluhm	    ${LOCAL_${addr}} `cat server.port`
1972316dd1bSbluhm	# divert-to state disappeared when the tcp socket was dropped
1982316dd1bSbluhm	ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | ! \
1990c2ea69fSbluhm	    egrep 'all ${proto} ${FAKE_${addr}}:?\[?'`cat client.port`'\]? .. ${LOCAL_${addr}}:?\[?'`cat server.port`'\]? '
2006a1cb87eSbluhm.endif
2016a1cb87eSbluhm.endif
2022316dd1bSbluhm.if "to" == ${first}
2032316dd1bSbluhm.if "tcp" == ${proto}
2042316dd1bSbluhm	# divert-to state has disappeared as tcp socket is always connected
2052316dd1bSbluhm.else
2062316dd1bSbluhm	# divert-to state still exists as the socket is unconnected
2072316dd1bSbluhm.endif
2082316dd1bSbluhm.else
2092316dd1bSbluhm	# divert-reply state has disappeared when the connected socket closed
2102316dd1bSbluhm.endif
2112316dd1bSbluhm	ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | ${STATE_EXIST_${proto}_${first}} \
2122316dd1bSbluhm	    egrep ' (tcp|udp|254) ${FAKE_${addr}}[][0-9:]* .. ${LOCAL_${addr}}[][0-9:]* '
2132316dd1bSbluhm	# create state again with ${second} divert rule
214d76821b9Sbluhm	time ${SUDO} SUDO=${SUDO} KTRACE=${KTRACE} \
215d76821b9Sbluhm	    perl ${PERLINC} ${PERLPATH}remote.pl ${inet} \
216d76821b9Sbluhm	    ${LOCAL_${addr}} ${FAKE_${addr}} ${REMOTE_SSH} \
217d76821b9Sbluhm	    `cat client.port` `cat server.port` \
218d76821b9Sbluhm	    ${PERLPATH}args-${proto}-${second}.pl
2193c0bd7e8Sbluhm.if "tcp" == ${proto}
2202316dd1bSbluhm.if "reply" == ${second} || "reply-to" == ${second}
2212316dd1bSbluhm	# drop client tcp socket still in time wait to clean up
222d76821b9Sbluhm	${SUDO} tcpdrop \
223d76821b9Sbluhm	    ${LOCAL_${addr}} `cat server.port` \
224d76821b9Sbluhm	    ${FAKE_${addr}} `cat client.port`
2252316dd1bSbluhm.else # "to" == ${second}
2262316dd1bSbluhm	# dropping the server tcp socket in time wait must remove the state
2276a1cb87eSbluhm	ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | \
2280c2ea69fSbluhm	    egrep 'all ${proto} ${FAKE_${addr}}:?\[?'`cat server.port`'\]? .. ${LOCAL_${addr}}:?\[?'`cat client.port`'\]? '
229d76821b9Sbluhm	ssh ${REMOTE_SSH} ${SUDO} tcpdrop \
230d76821b9Sbluhm	    ${FAKE_${addr}} `cat server.port` \
231d76821b9Sbluhm	    ${LOCAL_${addr}} `cat client.port`
2322316dd1bSbluhm	ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | ! \
2330c2ea69fSbluhm	    egrep 'all ${proto} ${FAKE_${addr}}:?\[?'`cat server.port`'\]? .. ${LOCAL_${addr}}:?\[?'`cat client.port`'\]? '
234cee6974dSbluhm.endif
235cee6974dSbluhm.endif
2362316dd1bSbluhm	# states must disappear after connected socket has been closed
2372316dd1bSbluhm	ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | ${STATE_EXIST_${proto}_${second}} \
2382316dd1bSbluhm	    egrep ' (tcp|udp|254) ${FAKE_${addr}}[][0-9:]* .. ${LOCAL_${addr}}[][0-9:]* '
239d0e91fd6Sbluhm
240336dfed2Sbluhm.endfor
2416a1cb87eSbluhm.endfor
2426a1cb87eSbluhm.endfor
243336dfed2Sbluhm
24479a2adffSbluhm.PHONY: syntax check-setup
245336dfed2Sbluhm
2463c0bd7e8Sbluhm# make perl syntax check for all args files
247336dfed2Sbluhmsyntax: stamp-syntax
248336dfed2Sbluhm
249068b97e5Sbluhmstamp-syntax: ${PERLS} ${ARGS}
250068b97e5Sbluhm.for p in ${PERLS}
251068b97e5Sbluhm	@perl -c ${PERLINC} ${PERLPATH}$p
252068b97e5Sbluhm.endfor
253336dfed2Sbluhm.for a in ${ARGS}
254336dfed2Sbluhm	@perl -c ${PERLPATH}$a
255336dfed2Sbluhm.endfor
256336dfed2Sbluhm	@date >$@
257336dfed2Sbluhm
25879a2adffSbluhm# Check wether the address, route and remote setup is correct
25979a2adffSbluhmcheck-setup:
26002079822Sbluhm	@echo '\n======== $@ ========'
26179a2adffSbluhm	ping -n -c 1 ${LOCAL_ADDR}
26279a2adffSbluhm	ping -n -c 1 ${REMOTE_ADDR}
26379a2adffSbluhm	ping6 -n -c 1 ${LOCAL_ADDR6}
26479a2adffSbluhm	ping6 -n -c 1 ${REMOTE_ADDR6}
2653c0bd7e8Sbluhm	route -n get -inet ${FAKE_ADDR} | grep 'if address: ${LOCAL_ADDR}$$'
2663c0bd7e8Sbluhm	route -n get -inet ${FAKE_ADDR} | grep 'gateway: ${REMOTE_ADDR}$$'
2673c0bd7e8Sbluhm	route -n get -inet6 ${FAKE_ADDR6} | grep 'if address: ${LOCAL_ADDR6}$$'
2683c0bd7e8Sbluhm	route -n get -inet6 ${FAKE_ADDR6} | grep 'gateway: ${REMOTE_ADDR6}$$'
26979a2adffSbluhm	ssh ${REMOTE_SSH} ${SUDO} pfctl -sr | grep '^anchor "regress" all$$'
27079a2adffSbluhm	ssh ${REMOTE_SSH} ${SUDO} pfctl -si | grep '^Status: Enabled '
271*1073f88eSbluhm	ssh ${REMOTE_SSH} perl -MSocket6 -e 1
27279a2adffSbluhm
273336dfed2Sbluhm.include <bsd.regress.mk>
274