xref: /openbsd/regress/sys/net/pf_forward/Makefile (revision f6aab3d8)
1#	$OpenBSD: Makefile,v 1.35 2021/02/01 12:52:07 bluhm Exp $
2
3# Copyright (c) 2012-2021 Alexander Bluhm <bluhm@openbsd.org>
4#
5# Permission to use, copy, modify, and distribute this software for any
6# purpose with or without fee is hereby granted, provided that the above
7# copyright notice and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17# The following ports must be installed:
18#
19# scapy               powerful interactive packet manipulation in python
20
21.if ! exists(/usr/local/bin/scapy)
22regress:
23	@echo Install scapy package to run this regress.
24	@echo SKIPPED
25.endif
26
27# This test needs a manual setup of four machines
28# The setup is the same as for regress/sys/net/pf_fragment
29# Set up machines: SRC PF RT ECO
30# SRC is the machine where this makefile is running.
31# PF is running OpenBSD forwarding through pf, it is the test target.
32# RT is a router forwarding packets, maximum MTU is 1300.
33# ECO is reflecting the ping and UDP and TCP echo packets.
34# RDR does not exist, PF redirects the traffic to ECO.
35# AF does not exist, PF translates address family and sends to ECO.
36# RTT addresses exist on ECO, PF has no route and must use route-to RT
37# RPT addresses exist on SRC, PF has no route and must use reply-to SRC
38#
39# +---+   1   +--+   2   +--+   3   +---+ 4
40# |SRC| ----> |PF| ----> |RT| ----> |ECO| 7
41# +---+ 8     +--+       +--+       +---+ 9
42#     out    in  out    in  out    in   out
43#
44# 5 +---+ 6   7 +--+    8 +---+ 9   10 +---+ 11
45#   |RDR|       |AF|      |RTT|        |RPT|
46#   +---+       +--+      +---+        +---+
47#  in   out    in        in          out
48
49# Configure Addresses on the machines, there must be routes for the
50# networks.  Adapt interface and addresse variables to your local
51# setup.  To control the remote machine you need a hostname for
52# ssh to log in.
53# You must have an anchor "regress" for the divert rules in the pf.conf
54# of the PF machine.  The kernel of the PF machine gets testet.
55#
56# Run make check-setup to see if you got the setup correct.
57
58SRC_IF ?=	tap0
59SRC_MAC ?=	fe:e1:ba:d1:0a:dc
60PF_IFIN ?=	vio0
61PF_IFOUT ?=	vio1
62PF_MAC ?=	52:54:00:12:34:50
63PF_SSH ?=
64RT_SSH ?=
65ECO_SSH ?=
66
67SRC_OUT ?=	10.188.210.10
68PF_IN ?=	10.188.210.50
69PF_OUT ?=	10.188.211.50
70RT_IN ?=	10.188.211.51
71RT_OUT ?=	10.188.212.51
72ECO_IN ?=	10.188.212.52
73ECO_OUT ?=	10.188.213.52
74RDR_IN ?=	10.188.214.188
75RDR_OUT ?=	10.188.215.188
76AF_IN ?=	10.188.216.82		# /24 must be dec(ECO_IN6/120)
77RTT_IN ?=	10.188.217.52
78RTT_OUT ?=	10.188.218.52
79RPT_IN ?=	10.188.220.10
80RPT_OUT ?=	10.188.221.10
81
82SRC_OUT6 ?=	fdd7:e83e:66bc:210:fce1:baff:fed1:561f
83PF_IN6 ?=	fdd7:e83e:66bc:210:5054:ff:fe12:3450
84PF_OUT6 ?=	fdd7:e83e:66bc:211:5054:ff:fe12:3450
85RT_IN6 ?=	fdd7:e83e:66bc:211:5054:ff:fe12:3451
86RT_OUT6 ?=	fdd7:e83e:66bc:212:5054:ff:fe12:3451
87ECO_IN6 ?=	fdd7:e83e:66bc:212:5054:ff:fe12:3452
88ECO_OUT6 ?=	fdd7:e83e:66bc:213:5054:ff:fe12:3452
89RDR_IN6 ?=	fdd7:e83e:66bc:214::188
90RDR_OUT6 ?=	fdd7:e83e:66bc:215::188
91AF_IN6 ?=	fdd7:e83e:66bc:216::34	# /120 must be hex(ECO_IN/24)
92RTT_IN6 ?=	fdd7:e83e:66bc:217:5054:ff:fe12:3452
93RTT_OUT6 ?=	fdd7:e83e:66bc:218:5054:ff:fe12:3452
94RPT_IN6 ?=	fdd7:e83e:66bc:1220:fce1:baff:fed1:561f
95RPT_OUT6 ?=	fdd7:e83e:66bc:1221:fce1:baff:fed1:561f
96
97.if empty (PF_SSH) || empty (RT_SSH) || empty (ECO_SSH)
98regress:
99	@echo this tests needs three remote machines to operate on
100	@echo PF_SSH RT_SSH ECO_SSH are empty
101	@echo fill out these variables for additional tests, then
102	@echo check wether your test machines are set up properly
103	@echo SKIPPED
104.endif
105
106.MAIN: all
107
108.if ! empty (PF_SSH)
109.if make (regress) || make (all)
110.BEGIN:
111	${SUDO} true
112	ssh -t ${PF_SSH} ${SUDO} true
113	rm -f stamp-pfctl
114	@echo
115.endif
116.endif
117
118# Create python include file containing the addresses.
119addr.py: Makefile
120	rm -f $@ $@.tmp
121	echo 'SRC_IF="${SRC_IF}"' >>$@.tmp
122	echo 'SRC_MAC="${SRC_MAC}"' >>$@.tmp
123	echo 'PF_IFIN="${PF_IFIN}"' >>$@.tmp
124	echo 'PF_IFOUT="${PF_IFOUT}"' >>$@.tmp
125	echo 'PF_MAC="${PF_MAC}"' >>$@.tmp
126.for var in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT\
127    AF_IN RTT_IN RTT_OUT RPT_IN RPT_OUT
128	echo '${var}="${${var}}"' >>$@.tmp
129	echo '${var}6="${${var}6}"' >>$@.tmp
130.endfor
131	mv $@.tmp $@
132
133# Load the pf rules into the kernel of the PF machine.
134# XXX pfctl does not replace variables after @.
135stamp-pfctl: addr.py pf.conf
136	cat addr.py ${.CURDIR}/pf.conf | /sbin/pfctl -n -f -
137	cat addr.py ${.CURDIR}/pf.conf | \
138	    sed 's/@$$PF_IFIN /@${PF_IFIN} /;s/@$$PF_IFOUT /@${PF_IFOUT} /' | \
139	    ssh ${PF_SSH} ${SUDO} pfctl -a regress -f -
140	@date >$@
141
142# Set variables so that make runs with and without obj directory.
143# Only do that if necessary to keep visible output short.
144.if ${.CURDIR} == ${.OBJDIR}
145PYTHON =	python3 -u ./
146.else
147PYTHON =	PYTHONPATH=${.OBJDIR} python3 -u ${.CURDIR}/
148.endif
149
150.for inet in inet inet6
151
152run-ping-mtu-1400-${inet}-RPT_OUT:
153	# RPT_OUT with locally generated ICMP time exceeded cannot work.
154	# The generated packet will not match the out rule with reply-to
155	# so it will be rejected by the route.
156	@echo DISABLED
157
158.for proto in icmp udp
159run-traceroute-${proto}-${inet}-RPT_OUT:
160	# RPT_OUT traceroute cannot work.  The ICMP time exceeded packet
161	# generated by IP forward will not match the out rule with reply-to
162	# so it will be rejected by the route.
163	@echo DISABLED
164.endfor # proto
165
166# Ping all addresses.  This ensures that the IP addresses are configured
167# and all routing table are set up to allow bidirectional packet flow.
168# Note that RDR does not exist physically.  So this traffic is rewritten
169# by PF and handled by ECO.
170
171.for ip in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT\
172    AF_IN RTT_IN RTT_OUT RPT_IN RPT_OUT
173REGRESS_TARGETS +=	run-ping-${inet}-${ip}
174run-ping-${inet}-${ip}: stamp-pfctl
175	@echo Check ping ${ip}${inet:S/inet//}:
176.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
177	ping${inet:S/inet//} -n -c 1 -I ${${ip}${inet:S/inet//}}\
178	    ${ECO_IN${inet:S/inet//}}
179.else
180	ping${inet:S/inet//} -n -c 1 ${${ip}${inet:S/inet//}}
181.endif
182.endfor # ip
183
184.for ip in ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN RTT_IN RTT_OUT RPT_IN RPT_OUT
185
186# Send a large IPv4/ICMP-Echo-Request packet with enabled DF bit and
187# parse response packet to determine MTU of the packet filter.  The
188# outgoing MTU of PF has to be 1400 octets.  Packet size is 1500.
189# Check that the IP length of the original packet and the ICMP
190# quoted packet are the same.
191
192REGRESS_TARGETS +=	run-ping-mtu-1400-${inet}-${ip}
193run-ping-mtu-1400-${inet}-${ip}: stamp-pfctl
194	@echo Check path MTU to ${ip}${inet:S/inet//} is 1400
195.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
196	${SUDO} ${PYTHON}ping${inet:S/inet//}_mtu.py ${${ip}${inet:S/inet//}}\
197	    ${ECO_IN${inet:S/inet//}} 1500 1400
198.elif "AF_IN" == ${ip}
199.if "inet" == ${inet}
200	${SUDO} ${PYTHON}ping_mtu.py ${SRC_OUT} ${${ip}} 1500 1380
201.else
202	${SUDO} ${PYTHON}ping6_mtu.py ${SRC_OUT6} ${${ip}6} 1500 1420
203.endif
204.else
205	${SUDO} ${PYTHON}ping${inet:S/inet//}_mtu.py ${SRC_OUT${inet:S/inet//}}\
206	    ${${ip}${inet:S/inet//}} 1500 1400
207.endif
208
209# Send a large IPv4/ICMP-Echo-Request packet with enabled DF bit and
210# parse response packet to determine MTU of the router.  The MTU has
211# to be 1300 octets.  The MTU has to be defined at out interface of
212# the router RT before.  Packet size is 1400 to pass PF MTU.
213# Check that the IP length of the original packet and the ICMP
214# quoted packet are the same.
215
216REGRESS_TARGETS +=	run-ping-mtu-1300-${inet}-${ip}
217run-ping-mtu-1300-${inet}-${ip}: stamp-pfctl
218	@echo Check path MTU from ${ip}${inet:S/inet//} is 1300
219.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
220	${SUDO} ${PYTHON}ping${inet:S/inet//}_mtu.py ${${ip}${inet:S/inet//}}\
221	    ${ECO_IN${inet:S/inet//}} 1400 1300
222.elif "AF_IN" == ${ip}
223.if "inet" == ${inet}
224	${SUDO} ${PYTHON}ping_mtu.py ${SRC_OUT} ${${ip}} 1380 1280
225.else
226	${SUDO} ${PYTHON}ping6_mtu.py ${SRC_OUT6} ${${ip}6} 1420 1320
227.endif
228.else
229	${SUDO} ${PYTHON}ping${inet:S/inet//}_mtu.py ${SRC_OUT${inet:S/inet//}}\
230	    ${${ip}${inet:S/inet//}} 1400 1300
231.endif
232
233# Send one UDP echo port 7 packet to all destination addresses with netcat.
234# The response must arrive in 1 second.
235
236REGRESS_TARGETS +=	run-udp-${inet}-${ip}
237run-udp-${inet}-${ip}: stamp-pfctl
238	@echo Check UDP ${ip${inet:S/inet//}}:
239.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
240	echo $$$$ | nc -n -u -W 1 -w 3 -s ${${ip}${inet:S/inet//}}\
241	    ${ECO_IN${inet:S/inet//}} 7 | grep $$$$
242.else
243	echo $$$$ | nc -n -u -W 1 -w 3 ${${ip}${inet:S/inet//}} 7 | grep $$$$
244.endif
245
246# Send a data stream to TCP echo port 7 to all destination addresses
247# with netcat.  Use enough data to make sure PMTU discovery works.
248# Count the reflected bytes and compare with the transmitted ones.
249# Delete host route before test to trigger PMTU discovery.
250
251REGRESS_TARGETS +=	run-tcp-${inet}-${ip}
252run-tcp-${inet}-${ip}: stamp-pfctl
253	@echo Check tcp ${ip}${inet:S/inet//}:
254	${SUDO} route -n delete -host -inet ${${ip}${inet:S/inet//}} || true
255.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
256	openssl rand 200000 | nc -n -N -w 10 -s ${${ip}${inet:S/inet//}}\
257	    ${ECO_IN${inet:S/inet//}} 7 | wc -c | grep '200000$$'
258.else
259	openssl rand 200000 | nc -n -N -w 10 ${${ip}${inet:S/inet//}} 7 |\
260	    wc -c | grep '200000$$'
261.endif
262
263.endfor # ip
264
265# Run traceroute with ICMP and UDP to all destination addresses.
266# Expect three hops in output and that every probe has a response.
267
268TRACEROUTE_CHECK =	awk \
269    'BEGIN{ x=0 } \
270    { print $$0 } \
271    { n=$$1 } \
272    /\*/{ x++ } \
273    END{ if (n!=3) { print "hopcount is not 3: "n; exit 1 } } \
274    END{ if (x!=0) { print "unanswered probes: "x; exit 1 } }'
275
276.for ip in ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN RTT_IN RTT_OUT RPT_IN RPT_OUT
277.for proto in icmp udp
278REGRESS_TARGETS +=	run-traceroute-${proto}-${inet}-${ip}
279run-traceroute-${proto}-${inet}-${ip}: stamp-pfctl
280	@echo Check traceroute ${proto} ${ip${inet:S/inet//}}:
281.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
282	traceroute${inet:S/inet//} ${proto:S/icmp/-I/:S/udp//}\
283	    -s ${${ip}${inet:S/inet//}} ${ECO_IN${inet:S/inet//}} |\
284	    ${TRACEROUTE_CHECK}
285.else
286	traceroute${inet:S/inet//} ${proto:S/icmp/-I/:S/udp//}\
287	    ${${ip}${inet:S/inet//}} | ${TRACEROUTE_CHECK}
288.endif
289.endfor # proto
290.endfor # ip
291
292.endfor # inet
293
294CLEANFILES +=		addr.py *.pyc *.log stamp-*
295
296.PHONY: check-setup
297
298# Check wether the address, route and remote setup is correct
299check-setup: check-setup-src check-setup-pf check-setup-rt check-setup-eco
300
301check-setup-src:
302	@echo '\n======== $@ ========'
303.for ip in SRC_OUT RPT_IN RPT_OUT
304	ping -n -c 1 ${${ip}}  # ${ip}
305	/sbin/route -n get -inet ${${ip}} | grep -q 'flags: .*LOCAL'  # ${ip}
306.endfor
307	ping -n -c 1 ${PF_IN}  # PF_IN
308	/sbin/route -n get -inet ${PF_IN} | fgrep -q 'interface: ${SRC_IF}' \
309	    # PF_IN SRC_IF
310.for ip in PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN\
311    RTT_IN RTT_OUT
312	/sbin/route -n get -inet ${${ip}} | fgrep -q 'gateway: ${PF_IN}' \
313	    # ${ip} PF_IN
314.endfor
315.for ip in SRC_OUT RPT_IN RPT_OUT
316	ping6 -n -c 1 ${${ip}6}  # ${ip}6
317	/sbin/route -n get -inet6 ${${ip}6} | grep -q 'flags: .*LOCAL'  # ${ip}6
318.endfor
319	ping6 -n -c 1 ${PF_IN6}  # PF_IN6
320	/sbin/route -n get -inet6 ${PF_IN6} | fgrep -q 'interface: ${SRC_IF}' \
321	    # PF_IN6 SRC_IF
322.for ip in PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN\
323    RTT_IN RTT_OUT
324	/sbin/route -n get -inet6 ${${ip}6} | fgrep -q 'gateway: ${PF_IN6}' \
325	    # ${ip}6 PF_IN6
326.endfor
327	/sbin/sysctl net.inet.ip.forwarding | fgrep =1
328	/sbin/sysctl net.inet6.ip6.forwarding | fgrep =1
329
330check-setup-pf:
331	@echo '\n======== $@ ========'
332	ssh ${PF_SSH} ping -n -c 1 ${PF_IN}  # PF_IN
333	ssh ${PF_SSH} route -n get -inet ${PF_IN} | grep -q 'flags: .*LOCAL' \
334	    # PF_IN
335	ssh ${PF_SSH} ping -n -c 1 ${SRC_OUT}  # SRC_OUT
336	ssh ${PF_SSH} ping -n -c 1 ${PF_OUT}  # PF_OUT
337	ssh ${PF_SSH} route -n get -inet ${PF_OUT} | grep -q 'flags: .*LOCAL' \
338	    # PF_OUT
339	ssh ${PF_SSH} ping -n -c 1 ${RT_IN}  # RT_IN
340.for ip in RT_OUT ECO_IN ECO_OUT
341	ssh ${PF_SSH} route -n get -inet ${${ip}} |\
342	    fgrep -q 'gateway: ${RT_IN}'  # ${ip} RT_IN
343.endfor
344.for ip in RTT_IN RTT_OUT RPT_IN RPT_OUT
345	ssh ${PF_SSH} route -n get -inet ${${ip}} | grep -q 'flags: .*REJECT' \
346	    # ${ip} reject
347.endfor
348	ssh ${PF_SSH} ping6 -n -c 1 ${PF_IN6}  # PF_IN6
349	ssh ${PF_SSH} route -n get -inet6 ${PF_IN6} | grep -q 'flags: .*LOCAL' \
350	    # PF_IN6
351	ssh ${PF_SSH} ping6 -n -c 1 ${SRC_OUT6}  # SRC_OUT6
352	ssh ${PF_SSH} ping6 -n -c 1 ${PF_OUT6}  # PF_OUT6
353	ssh ${PF_SSH} route -n get -inet6 ${PF_OUT6} |\
354	    grep -q 'flags: .*LOCAL'  # PF_OUT6
355	ssh ${PF_SSH} ping6 -n -c 1 ${RT_IN6}  # RT_IN6
356.for ip in RT_OUT ECO_IN ECO_OUT
357	ssh ${PF_SSH} route -n get -inet6 ${${ip}6} |\
358	    fgrep -q 'gateway: ${RT_IN6}'  # ${ip}6 RT_IN6
359.endfor
360.for ip in RTT_IN RTT_OUT RPT_IN RPT_OUT
361	ssh ${PF_SSH} route -n get -inet6 ${${ip}6} |\
362	    grep -q 'flags: .*REJECT'  # ${ip}6 reject
363.endfor
364	ssh ${PF_SSH} ${SUDO} pfctl -sr | grep '^anchor "regress" all$$'
365	ssh ${PF_SSH} ${SUDO} pfctl -si | grep '^Status: Enabled '
366	ssh ${PF_SSH} sysctl net.inet.ip.forwarding | fgrep =1
367	ssh ${PF_SSH} sysctl net.inet6.ip6.forwarding | fgrep =1
368	ssh ${PF_SSH} ifconfig ${PF_IFOUT} | fgrep 'mtu 1400'
369
370check-setup-rt:
371	@echo '\n======== $@ ========'
372	ssh ${RT_SSH} ping -n -c 1 ${RT_IN}  # RT_IN
373	ssh ${RT_SSH} route -n get -inet ${RT_IN} | grep -q 'flags: .*LOCAL' \
374	    # RT_IN
375	ssh ${RT_SSH} ping -n -c 1 ${PF_OUT}  # PF_OUT
376.for ip in PF_IN SRC_OUT RPT_IN RPT_OUT
377	ssh ${RT_SSH} route -n get -inet ${${ip}} |\
378	    fgrep -q 'gateway: ${PF_OUT}'  # ${ip} PF_OUT
379.endfor
380	ssh ${RT_SSH} ping -n -c 1 ${RT_OUT}  # RT_OUT
381	ssh ${RT_SSH} route -n get -inet ${RT_OUT} | grep -q 'flags: .*LOCAL' \
382	    # RT_OUT
383	ssh ${RT_SSH} ping -n -c 1 ${ECO_IN}  # ECO_IN
384.for ip in ECO_OUT RTT_IN RTT_OUT
385	ssh ${RT_SSH} route -n get -inet ${${ip}} |\
386	    fgrep -q 'gateway: ${ECO_IN}'  # ${ip} ECO_IN
387.endfor
388	ssh ${RT_SSH} ping6 -n -c 1 ${RT_IN6}  # RT_IN6
389	ssh ${RT_SSH} route -n get -inet6 ${RT_IN6} | grep -q 'flags: .*LOCAL' \
390	    # RT_IN6
391	ssh ${RT_SSH} ping6 -n -c 1 ${PF_OUT6}  # PF_OUT6
392.for ip in PF_IN SRC_OUT RPT_IN RPT_OUT
393	ssh ${RT_SSH} route -n get -inet6 ${${ip}6} |\
394	    fgrep -q 'gateway: ${PF_OUT6}'  # ${ip}6 PF_OUT6
395.endfor
396	ssh ${RT_SSH} ping6 -n -c 1 ${RT_OUT6}  # RT_OUT6
397	ssh ${RT_SSH} route -n get -inet6 ${RT_OUT6} |\
398	    grep -q 'flags: .*LOCAL'  # RT_OUT6
399	ssh ${RT_SSH} ping6 -n -c 1 ${ECO_IN6}  # ECO_IN6
400.for ip in ECO_OUT RTT_IN RTT_OUT
401	ssh ${RT_SSH} route -n get -inet6 ${${ip}6} |\
402	    fgrep -q 'gateway: ${ECO_IN6}'  # ${ip}6 ECO_IN6
403.endfor
404	ssh ${RT_SSH} sysctl net.inet.ip.forwarding | fgrep =1
405	ssh ${RT_SSH} sysctl net.inet6.ip6.forwarding | fgrep =1
406	ssh ${RT_SSH} ifconfig | fgrep 'mtu 1300'
407
408check-setup-eco:
409	@echo '\n======== $@ ========'
410.for ip in ECO_IN ECO_OUT RTT_IN RTT_OUT
411	ssh ${ECO_SSH} ping -n -c 1 ${${ip}}  # ${ip}
412	ssh ${ECO_SSH} route -n get -inet ${${ip}} | grep -q 'flags: .*LOCAL' \
413	    # ${ip}
414.endfor
415	ssh ${ECO_SSH} ping -n -c 1 ${RT_OUT}  # RT_OUT
416.for ip in RT_IN PF_OUT PF_IN SRC_OUT RPT_IN RPT_OUT
417	ssh ${ECO_SSH} route -n get -inet ${${ip}} |\
418	    fgrep -q 'gateway: ${RT_OUT}'  # ${ip} RT_OUT
419.endfor
420.for ip in ECO_IN ECO_OUT RTT_IN RTT_OUT
421	ssh ${ECO_SSH} ping6 -n -c 1 ${${ip}6}  # ${ip}6
422	ssh ${ECO_SSH} route -n get -inet6 ${${ip}6} |\
423	    grep -q 'flags: .*LOCAL'  # ${ip}6
424.endfor
425	ssh ${ECO_SSH} ping6 -n -c 1 ${RT_OUT6}  # RT_OUT6
426.for ip in RT_IN PF_OUT PF_IN SRC_OUT RPT_IN RPT_OUT
427	ssh ${ECO_SSH} route -n get -inet6 ${${ip}6} |\
428	    fgrep -q 'gateway: ${RT_OUT6}'  # ${ip}6 RT_OUT6
429.endfor
430.for inet in inet inet6
431.for proto in udp tcp
432	ssh ${ECO_SSH} netstat -na -f ${inet} -p ${proto} | fgrep ' *.7 '
433.endfor
434.endfor
435.for ip in ECO_IN ECO_OUT RTT_IN RTT_OUT
436	ssh ${ECO_SSH} netstat -nav -f inet -p udp | fgrep ' ${${ip}}.7 '
437	ssh ${ECO_SSH} netstat -nav -f inet6 -p udp | fgrep ' ${${ip}6}.7 '
438	ssh ${ECO_SSH} sysctl net.inet.ip.forwarding | fgrep =1
439	ssh ${ECO_SSH} sysctl net.inet6.ip6.forwarding | fgrep =1
440.endfor
441
442.include <bsd.regress.mk>
443