1# $OpenBSD: Makefile,v 1.10 2023/10/19 18:36:40 anton Exp $ 2 3# Copyright (c) 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# Basic testing of the pflog(4) interface. Create special routing 18# domain, load rules into pf(4) regress anchor, tcpdump on pflog, 19# send packets over lo(4), grep for expected result in tcpdump output. 20 21# This test uses routing domain 11 and pflog interface number 11, 12, 13. 22# Adjust it here, if you want to use something else. 23N1 = 11 24N2 = 12 25N3 = 13 26N = ${N1} 27NUMS = ${N1} ${N2} ${N3} 28IPS = 1 2 3 4 5 6 11 12 14 29 30UID !!= id -u 31 32.include <bsd.own.mk> 33 34.if ! (make(clean) || make(cleandir) || make(obj)) 35 36PF_STATUS != ${SUDO} /sbin/pfctl -si | sed -n 's/^Status: \([^ ]*\) .*/\1/p' 37.if empty(PF_STATUS:MEnabled) 38regress: 39 @echo pf status: "${PF_STATUS}" 40 @echo Enable pf to run this regress. 41 @echo SKIPPED 42.endif 43 44PF_SKIP != ${SUDO} /sbin/pfctl -sI -v | sed -n 's/ (skip)//p' | \ 45 grep -w -e lo${N1} -e lo${N2} -e lo${N3} || : 46.if ! empty(PF_SKIP) 47regress: 48 @echo pf skip: "${PF_SKIP}" 49 @echo Do not set skip on interface lo, lo${N1}, lo${N2}, or lo${N3}. 50 @echo SKIPPED 51.endif 52 53PF_ANCHOR != ${SUDO} /sbin/pfctl -sr |\ 54 sed -n 's/^anchor "\([^"]*\)" all$$/\1/p' 55.if empty(PF_ANCHOR:Mregress) 56regress: 57 @echo pf anchor: "${PF_ANCHOR}" 58 @echo Need anchor '"regress"' in pf.conf to load additional rules. 59 @echo SKIPPED 60.endif 61 62SYSCTL_FORWARDING != sysctl net.inet.ip.forwarding 63SYSCTL_FORWARDING6 != sysctl net.inet6.ip6.forwarding 64.if ${SYSCTL_FORWARDING:C/.*=//} != 1 || ${SYSCTL_FORWARDING6:C/.*=//} != 1 65# Do not skip, but run tests. Although they fail, their packets are logged. 66REGRESS_EXPECTED_FAILURES = run-ping-14 run-ping6-14 67.endif 68 69.endif 70 71.PHONY: busy-rdomains ifconfig unconfig pfctl 72 73REGRESS_SETUP_ONCE += busy-rdomains 74busy-rdomains: 75 # Check if rdomains are busy. 76 @if /sbin/ifconfig | grep -v '^lo$N:' | grep ' rdomain $N '; then\ 77 echo routing domain $N is already used >&2; exit 1; fi 78 79REGRESS_SETUP_ONCE += ifconfig 80ifconfig: unconfig 81 # Create and configure pflog and loopback interfaces. 82.for n in ${NUMS} 83 ${SUDO} /sbin/ifconfig pflog$n create 84.endfor 85 ${SUDO} /sbin/ifconfig lo$N rdomain $N 86 ${SUDO} /sbin/ifconfig lo$N inet 127.0.0.1/8 87 ${SUDO} /sbin/ifconfig lo$N inet6 ::1/128 88.for i in ${IPS} 21 22 23 24 89 ${SUDO} /sbin/ifconfig lo$N inet 169.254.0.$i/32 alias 90 ${SUDO} /sbin/ifconfig lo$N inet6 fc00::$i/128 91.endfor 92 # Wait until IPv6 addresses are no longer tentative. 93 for i in `jot 50`; do\ 94 if ! { /sbin/ifconfig pair${N1}; /sbin/ifconfig pair${N2};\ 95 /sbin/ifconfig lo${N3}; } | fgrep -q tentative; then\ 96 break;\ 97 fi;\ 98 sleep .1;\ 99 done 100 ! { /sbin/ifconfig pair${N1}; /sbin/ifconfig pair${N2};\ 101 /sbin/ifconfig lo${N3}; } | fgrep tentative 102 103 104REGRESS_CLEANUP += unconfig 105unconfig: stamp-stop 106 # Destroy interfaces. 107 -${SUDO} /sbin/ifconfig lo$N rdomain $N 108.for i in ${IPS} 21 22 23 24 109 -${SUDO} /sbin/ifconfig lo$N inet 169.254.0.$i delete 110 -${SUDO} /sbin/ifconfig lo$N inet6 fc00::$i delete 111.endfor 112 -${SUDO} /sbin/ifconfig lo$N inet 127.0.0.1 delete 113 -${SUDO} /sbin/ifconfig lo$N inet6 ::1 delete 114.for n in ${NUMS} 115 -${SUDO} /sbin/ifconfig pflog$n destroy 116.endfor 117 -${SUDO} /sbin/ifconfig lo$N destroy 118 rm -f stamp-ifconfig 119 120addr.py: Makefile 121 # Create python include file containing the addresses. 122 rm -f $@ $@.tmp 123 echo 'N="$N"' >>$@.tmp 124 echo 'LO="lo$N"' >>$@.tmp 125.for var in N1 N2 N3 126 echo '${var}="${${var}}"' >>$@.tmp 127 echo 'PFLOG_${var}="pflog${${var}}"' >>$@.tmp 128.endfor 129 mv $@.tmp $@ 130 131REGRESS_SETUP_ONCE += pfctl 132pfctl: addr.py pf.conf 133 # Load the pf rules into the kernel. 134 cat addr.py ${.CURDIR}/pf.conf | /sbin/pfctl -n -f - 135 cat addr.py ${.CURDIR}/pf.conf | ${SUDO} /sbin/pfctl -a regress -f - 136 137# Run tcpdump on pflog devices. 138DUMPCMD = /usr/sbin/tcpdump -l -e -vvv -s 2048 -ni 139 140stamp-bpf: stamp-bpf-${N1} stamp-bpf-${N2} stamp-bpf-${N3} 141 sleep 2 # XXX 142 @date >$@ 143 144.for n in ${NUMS} 145 146stamp-bpf-$n: stamp-ifconfig 147 rm -f pflog$n.tcpdump 148 ${SUDO} pkill -f '^${DUMPCMD} pflog$n' || true 149 ${SUDO} ${DUMPCMD} pflog$n >pflog$n.tcpdump & 150 rm -f stamp-stop 151 @date >$@ 152 153.endfor 154 155stamp-stop: 156 sleep 2 # XXX 157 -${SUDO} pkill -f '^${DUMPCMD}' 158 rm -f stamp-bpf* 159 @date >$@ 160 161.for i in ${IPS} 162REGRESS_TARGETS += run-ping-$i 163run-ping-$i: stamp-bpf 164 /sbin/ping -n -w 1 -c 1 -V $N 169.254.0.$i 165 166REGRESS_TARGETS += run-ping6-$i 167run-ping6-$i: stamp-bpf 168 /sbin/ping6 -n -w 1 -c 1 -V $N fc00::$i 169 170REGRESS_TARGETS += run-udp-$i 171run-udp-$i: stamp-bpf 172 # ignore errors, just send packet fast 173 echo foo | nc -u -w 1 -V $N 169.254.0.$i discard & 174 175REGRESS_TARGETS += run-udp6-$i 176run-udp6-$i: stamp-bpf 177 # ignore errors, just send packet fast 178 echo foo | nc -u -w 1 -V $N fc00::$i discard & 179.endfor 180 181REGRESS_TARGETS += run-ping6-0 182run-ping6-0: stamp-bpf 183 /sbin/ping6 -n -w 1 -c 1 -V $N ::1 184 185REGRESS_TARGETS += run-udp6-0 186run-udp6-0: stamp-bpf 187 echo foo | nc -u -w 1 -V $N ::1 discard 188 189.for n in ${NUMS} 190REGRESS_TARGETS += run-bpf-$n 191run-bpf-$n: stamp-stop 192 # show full logs 193 cat pflog$n.tcpdump 194.endfor 195 196REGRESS_TARGETS += run-bpf-nothing 197run-bpf-nothing: stamp-stop 198 # rule with pflog${N3} is never used 199 ! grep . pflog${N3}.tcpdump 200 201REGRESS_TARGETS += run-bpf-everything 202run-bpf-everything: stamp-stop 203 # rule with pflog${N2} matches on every packet 204.for i in ${IPS} 205 grep 'regress\.1/.* > 169.254.0.$i:' pflog${N2}.tcpdump 206.endfor 207 208REGRESS_TARGETS += run-bpf-everything6 209run-bpf-everything6: stamp-stop 210 # rule with pflog${N2} matches on every packet 211.for i in ${IPS} 212 grep 'regress\.1/.* > fc00::$i:' pflog${N2}.tcpdump 213.endfor 214 215REGRESS_TARGETS += run-bpf-all 216run-bpf-all: stamp-stop 217 # reply without keep state 218 grep 'regress\.3/.* 169.254.0.1 > 169.254.0.1:\ 219 icmp: echo request' pflog${N1}.tcpdump 220 grep 'regress\.3/.* 169.254.0.1 > 169.254.0.1:\ 221 icmp: echo reply' pflog${N1}.tcpdump 222 # no reply with keep state and without all 223 grep 'regress\.4/.* 169.254.0.2 > 169.254.0.2:\ 224 icmp: echo request' pflog${N1}.tcpdump 225 ! grep 'regress\.4/.* 169.254.0.2 >169.254.0.2:\ 226 icmp: echo reply' pflog${N1}.tcpdump 227 # reply with keep state and with all 228 grep 'regress\.5/.* 169.254.0.3 > 169.254.0.3:\ 229 icmp: echo request' pflog${N1}.tcpdump 230 # XXX anchor name missing 231 grep '/.* 169.254.0.3 > 169.254.0.3:\ 232 icmp: echo reply' pflog${N1}.tcpdump 233 234REGRESS_TARGETS += run-bpf-all6 235run-bpf-all6: stamp-stop 236 # reply without keep state 237 grep 'regress\.11/.* fc00::1 > fc00::1:\ 238 icmp6: echo request' pflog${N1}.tcpdump 239 grep 'regress\.11/.* fc00::1 > fc00::1:\ 240 icmp6: echo reply' pflog${N1}.tcpdump 241 # no reply with keep state and without all 242 grep 'regress\.12/.* fc00::2 > fc00::2:\ 243 icmp6: echo request' pflog${N1}.tcpdump 244 ! grep 'regress\.12/.* fc00::2 > fc00::2:\ 245 icmp6: echo reply' pflog${N1}.tcpdump 246 # reply with keep state and with all 247 grep 'regress\.13/.* fc00::3 > fc00::3:\ 248 icmp6: echo request' pflog${N1}.tcpdump 249 # XXX anchor name missing 250 grep '/.* fc00::3 > fc00::3:\ 251 icmp6: echo reply' pflog${N1}.tcpdump 252 253REGRESS_TARGETS += run-bpf-user 254run-bpf-user: stamp-stop 255 # out rule creates log entry with uid 256 grep 'regress\.6/.* pass out on lo$N: \[uid ${UID}, pid [0-9]*\]\ 257 169.254.0.4\.[0-9]* > 169.254.0.4\.9:\ 258 .* udp [0-9]' pflog${N1}.tcpdump 259 # in rule has no uid at log entry 260 grep 'regress\.6/.* pass in on lo$N:\ 261 169.254.0.4\.[0-9]* > 169.254.0.4\.9:\ 262 .* udp [0-9]' pflog${N1}.tcpdump 263 # icmp has no uid at log entry 264 grep 'regress\.6/.* pass out on lo$N:\ 265 169.254.0.4 > 169.254.0\.4:\ 266 icmp: echo request' pflog${N1}.tcpdump 267 # rule without user has no uid in log entry 268 grep 'regress\.3/.* pass out on lo$N:\ 269 169.254.0.1\.[0-9]* > 169.254.0.1\.9:\ 270 .* udp [0-9]' pflog${N1}.tcpdump 271 272REGRESS_TARGETS += run-bpf-user6 273run-bpf-user6: stamp-stop 274 # out rule creates log entry with uid 275 grep 'regress\.14/.* pass out on lo$N: \[uid ${UID}, pid [0-9]*\]\ 276 fc00::4\.[0-9]* > fc00::4\.9:.* udp [0-9]' pflog${N1}.tcpdump 277 # in rule has no uid at log entry 278 grep 'regress\.14/.* pass in on lo$N:\ 279 fc00::4\.[0-9]* > fc00::4\.9:.* udp [0-9]' pflog${N1}.tcpdump 280 # icmp has no uid at log entry 281 grep 'regress\.14/.* pass out on lo$N:\ 282 fc00::4 > fc00::4: icmp6: echo request' pflog${N1}.tcpdump 283 # rule without user has no uid in log entry 284 grep 'regress\.11/.* pass out on lo$N:\ 285 fc00::1\.[0-9]* > fc00::1\.9:.* udp [0-9]' pflog${N1}.tcpdump 286 287run-bpf-matches run-bpf-matches6: 288 # XXX The log matches keyword seems to be totally broken. 289 # pf_log_matches() is never called. Investigate later. 290 @echo DISABLED 291 292REGRESS_TARGETS += run-bpf-matches 293run-bpf-matches: stamp-stop 294 grep 'regress\.9/.* .*: 169.254.0.6 > 169.254.0.6:\ 295 icmp: echo request' pflog${N1}.tcpdump 296 ! grep 'regress\.8/.* icmp: echo request' pflog${N1}.tcpdump 297 ! grep 'regress\.7/.* icmp: echo request' pflog${N1}.tcpdump 298 299REGRESS_TARGETS += run-bpf-rdr 300run-bpf-rdr: stamp-stop 301 # loopback input logs redirected packet 302 grep 'regress\.2/.* pass in .*:.* 169.254.0.11 > 169.254.0.21:\ 303 icmp: echo request' pflog${N1}.tcpdump 304 # loopback output redirects and logs original packet 305 grep 'regress\.18/.* pass out .*:.* 169.254.0.11 > 169.254.0.11:\ 306 icmp: echo request' pflog${N1}.tcpdump 307 308REGRESS_TARGETS += run-bpf-rdr6 309run-bpf-rdr6: stamp-stop 310 # loopback input logs redirected packet 311 grep 'regress\.10/.* pass in .*:.* fc00::11 > fc00::21:\ 312 icmp6: echo request' pflog${N1}.tcpdump 313 # loopback output redirects and logs original packet 314 grep 'regress\.20/.* pass out .*:.* fc00::11 > fc00::11:\ 315 icmp6: echo request' pflog${N1}.tcpdump 316 317REGRESS_TARGETS += run-bpf-nat 318run-bpf-nat: stamp-stop 319 # loopback input logs redirected packet 320 grep 'regress\.2/.* pass in .*:.* 169.254.0.22 > 169.254.0.12:\ 321 icmp: echo request' pflog${N1}.tcpdump 322 # loopback output redirects and logs original packet 323 grep 'regress\.19/.* pass out .*:.* 169.254.0.12 > 169.254.0.12:\ 324 icmp: echo request' pflog${N1}.tcpdump 325 326REGRESS_TARGETS += run-bpf-nat6 327run-bpf-nat6: stamp-stop 328 # loopback input logs redirected packet 329 grep 'regress\.10/.* pass in .*:.* fc00::22 > fc00::12:\ 330 icmp6: echo request' pflog${N1}.tcpdump 331 # loopback output redirects and logs original packet 332 grep 'regress\.21/.* pass out .*:.* fc00::12 > fc00::12:\ 333 icmp6: echo request' pflog${N1}.tcpdump 334 335REGRESS_TARGETS += run-bpf-af 336run-bpf-af: stamp-stop 337 # pf in rule logs original IPv4 packet 338 grep 'regress\.22/.* pass in .*:.* 169.254.0.14 > 169.254.0.14:\ 339 icmp: echo request' pflog${N1}.tcpdump 340 341REGRESS_TARGETS += run-bpf-af6 342run-bpf-af6: stamp-stop 343 # pf in rule logs original IPv6 packet 344 grep 'regress\.23/.* pass in .*:.* fc00::14 > fc00::14:\ 345 icmp6: echo request' pflog${N1}.tcpdump 346 347REGRESS_TARGETS += run-bpf-rewrite 348run-bpf-rewrite: stamp-stop 349 # rdr-to address has been rewritten 350 grep '\[rewritten: src 169.254.0.11:[0-9]*, dst 169.254.0.21:[0-9]*\]\ 351 169.254.0.11 > 169.254.0.11' pflog${N1}.tcpdump 352 # nat-to address has been rewritten 353 grep '\[rewritten: src 169.254.0.22:[0-9]*, dst 169.254.0.12:[0-9]*\]\ 354 169.254.0.12 > 169.254.0.12' pflog${N1}.tcpdump 355 # af-to address has been rewritten 356 grep '\[rewritten: src fc00::23:[0-9]*, dst fc00::24:[0-9]*\]\ 357 169.254.0.14 > 169.254.0.14' pflog${N1}.tcpdump 358 359REGRESS_TARGETS += run-bpf-rewrite6 360run-bpf-rewrite6: stamp-stop 361 # rdr-to address has been rewritten 362 grep '\[rewritten: src fc00::11:[0-9]*, dst fc00::21:[0-9]*\]\ 363 fc00::11 > fc00::11' pflog${N1}.tcpdump 364 # nat-to address has been rewritten 365 grep '\[rewritten: src fc00::22:[0-9]*, dst fc00::12:[0-9]*\]\ 366 fc00::12 > fc00::12' pflog${N1}.tcpdump 367 # af-to address has been rewritten 368 grep '\[rewritten: src 169.254.0.23:[0-9]*, dst 169.254.0.24:[0-9]*\]\ 369 fc00::14 > fc00::14' pflog${N1}.tcpdump 370 371CLEANFILES += addr.py *.pyc *.tcpdump *.log stamp-* 372 373.include <bsd.regress.mk> 374