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