diff options
Diffstat (limited to 'regress/sys/net')
-rw-r--r-- | regress/sys/net/pf_forward/Makefile | 193 | ||||
-rw-r--r-- | regress/sys/net/pf_forward/ping6_mtu.py | 24 | ||||
-rw-r--r-- | regress/sys/net/pf_forward/ping_mtu.py | 22 |
3 files changed, 239 insertions, 0 deletions
diff --git a/regress/sys/net/pf_forward/Makefile b/regress/sys/net/pf_forward/Makefile new file mode 100644 index 00000000000..0ef375ccdca --- /dev/null +++ b/regress/sys/net/pf_forward/Makefile @@ -0,0 +1,193 @@ +# $OpenBSD: Makefile,v 1.1 2012/07/10 12:43:54 bluhm Exp $ + +# The following ports must be installed: +# +# python-2.7 interpreted object-oriented programming language +# py-libdnet python interface to libdnet +# scapy powerful interactive packet manipulation in python + +# This test needs a manual setup of four machines +# The setup is the same as for regress/sys/net/pf_fragment +# Set up machines: SRC PF RT DST +# SRC is the machine where this makefile is running. +# PF is running OpenBSD forwarding through pf, it is the test target. +# RT is a router forwarding packets, maximum MTU is 1300. +# DST is reflecting the ping and UDP and TCP echo packets. +# RDR does not exist, PF redirects the traffic to DST. +# AF does not exist, PF translates address family and sends to DST. +# +# +---+ 1 +--+ 2 +--+ 3 +---+ 4 +---+ 5 +--+ +# |SRC| ----> |PF| ----> |RT| ----> |DST| |RDR| |AF| +# +---+ +--+ +--+ +---+ +---+ +--+ +# out in out in out in in in + +# Configure Addresses on the machines, there must be routes for the networks. +# Adapt interface and addresse variables to your local setup. +# +SRC_IF = tun0 +SRC_MAC = fe:e1:ba:d1:0a:dc +PF_MAC = 52:54:00:12:34:50 + +SRC_OUT = 10.188.211.10 +PF_IN = 10.188.211.50 +PF_OUT = 10.188.212.50 +RT_IN = 10.188.212.51 +RT_OUT = 10.188.213.51 +DST_IN = 10.188.213.52 +RDR_IN = 10.188.214.1 +AF_IN = 10.188.215.82 + +SRC_OUT6 = fdd7:e83e:66bc:211:fce1:baff:fed1:561f +PF_IN6 = fdd7:e83e:66bc:211:5054:ff:fe12:3450 +PF_OUT6 = fdd7:e83e:66bc:212:5054:ff:fe12:3450 +RT_IN6 = fdd7:e83e:66bc:212:5054:ff:fe12:3451 +RT_OUT6 = fdd7:e83e:66bc:213:5054:ff:fe12:3451 +DST_IN6 = fdd7:e83e:66bc:213:5054:ff:fe12:3452 +RDR_IN6 = fdd7:e83e:66bc:214::1 +AF_IN6 = fdd7:e83e:66bc:215:5054:ff:fe12:3434 + +# pf rules on PF must look like this: +# +# pass to { $PF_IN/24 $PF_IN6/64 } +# pass to { $RT_IN/24 $RT_IN6/64 } +# pass to { $DST_IN/24 $DST_IN6/64 } +# pass to { $RDR_IN/24 $RDR_IN6/64 } +# +# pass in to $RDR_IN/24 rdr-to $DST_IN tag rdr +# pass out nat-to $PF_OUT tagged rdr +# pass in to $RDR_IN6/64 rdr-to $DST_IN6 tag rdr +# pass out nat-to $PF_OUT6 tagged rdr + +# pass in to $AF_IN/24 af-to inet6 from $PF_OUT6 to $DST_IN6/120 tag af +# pass out inet6 tagged af +# pass in to $AF_IN6/64 af-to inet from $PF_OUT to $DST_IN/24 tag af +# pass out inet tagged af + +# Currently these test fail as pf does not fix the checksum of +# NATed packets inside of icmp packets. +# ping6-mtu + +depend: addr.py + +# Create python include file containing the addresses. +addr.py: Makefile + rm -f $@ $@.tmp + echo 'SRC_IF = "${SRC_IF}"' >>$@.tmp + echo 'SRC_MAC = "${SRC_MAC}"' >>$@.tmp + echo 'PF_MAC = "${PF_MAC}"' >>$@.tmp +.for var in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT DST_IN RDR_IN AF_IN + echo '${var} = "${${var}}"' >>$@.tmp + echo '${var}6 = "${${var}6}"' >>$@.tmp +.endfor + mv $@.tmp $@ + +# Make sure that the routing table on the SRC machine is correct. +# All packets must be forwarded to PF target machine. +TARGETS += route route6 + +run-regress-route: + @echo '\n======== $@ ========' + @echo Check route SRC_OUT: + route -n get -inet ${SRC_OUT} | fgrep -q 'interface: lo0' + @echo Check route PF_IN: + route -n get -inet ${PF_IN} | fgrep -q 'if address: ${SRC_OUT}' +.for ip in PF_OUT RT_IN RT_OUT DST_IN RDR_IN AF_IN + @echo Check route ${ip}: + route -n get -inet ${${ip}} | fgrep -q 'gateway: ${PF_IN}' +.endfor + +run-regress-route6: + @echo '\n======== $@ ========' + @echo Check route SRC_OUT6: + route -n get -inet6 ${SRC_OUT6} | fgrep -q 'interface: lo0' +.for ip in PF_OUT RT_IN RT_OUT DST_IN RDR_IN AF_IN + @echo Check route ${ip}6: + route -n get -inet6 ${${ip}6} | fgrep -q 'gateway: ${PF_IN6}' +.endfor + +# Ping all addresses. This ensures that the ip addresses are configured +# and all routing table are set up to allow bidirectional packet flow. +# Note that RDR does not exist physically. So this traffic is rewritten +# by PF and handled by DST. +TARGETS += ping ping6 + +run-regress-ping: + @echo '\n======== $@ ========' +.for ip in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT DST_IN RDR_IN AF_IN + @echo Check ping ${ip}: + ping -n -c 1 ${${ip}} +.endfor + +run-regress-ping6: + @echo '\n======== $@ ========' +.for ip in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT DST_IN RDR_IN AF_IN + @echo Check ping ${ip}6: + ping6 -n -c 1 ${${ip}6} +.endfor + +# Send a large IPv4/ICMP-Echo-Request packet with enabled DF bit and +# parse response packet to determine MTU of the router. The MTU has +# to be 1300 octets. The MTU has to be defined at out interface of +# the router RT before. +TARGETS += ping-mtu ping6-mtu + +run-regress-ping-mtu: addr.py + @echo '\n======== $@ ========' +.for ip in DST_IN RDR_IN + @echo Check path MTU to ${ip} is 1300 + ${SUDO} python2.7 ping_mtu.py ${${ip}} 1300 +.endfor + @echo Check path MTU to AF_IN is 1280 + ${SUDO} python2.7 ping_mtu.py ${AF_IN} 1280 + +run-regress-ping6-mtu: addr.py + @echo '\n======== $@ ========' +.for ip in DST_IN RDR_IN + @echo Check path MTU to ${ip}6 is 1300 + ${SUDO} python2.7 ping6_mtu.py ${${ip}6} 1300 +.endfor + @echo Check path MTU to AF_IN6 is 1320 + ${SUDO} python2.7 ping6_mtu.py ${AF_IN6} 1320 + +# Send one udp echo port 7 packet to all destination addresses with netcat. +# The response must arrive in 1 second. +TARGETS += udp udp6 + +run-regress-udp: + @echo '\n======== $@ ========' +.for ip in DST_IN RDR_IN AF_IN + @echo Check udp ${ip}: + ( echo $$$$ | nc -u ${${ip}} 7 & sleep 1; kill $$! ) | grep $$$$ +.endfor + +run-regress-udp6: + @echo '\n======== $@ ========' +.for ip in DST_IN RDR_IN AF_IN + @echo Check udp ${ip}6: + ( echo $$$$ | nc -u ${${ip}6} 7 & sleep 1; kill $$! ) | grep $$$$ +.endfor + +# Send a data stream to tcp echo port 7 to all destination addresses +# with netcat. Use enough data to make sure PMTU discovery works. +# Count the reflected bytes and compare with the transmitted ones. +TARGETS += tcp tcp6 + +run-regress-tcp: + @echo '\n======== $@ ========' +.for ip in DST_IN RDR_IN AF_IN + @echo Check tcp ${ip}: + openssl rand 200000 | nc ${${ip}} 7 | wc -c | grep '200000$$' +.endfor + +run-regress-tcp6: + @echo '\n======== $@ ========' +.for ip in DST_IN RDR_IN AF_IN + @echo Check tcp ${ip}6: + openssl rand 200000 | nc ${${ip}6} 7 | wc -c | grep '200000$$' +.endfor + +REGRESS_TARGETS = ${TARGETS:S/^/run-regress-/} + +CLEANFILES += addr.py *.pyc *.log + +.include <bsd.regress.mk> diff --git a/regress/sys/net/pf_forward/ping6_mtu.py b/regress/sys/net/pf_forward/ping6_mtu.py new file mode 100644 index 00000000000..251a84c24a6 --- /dev/null +++ b/regress/sys/net/pf_forward/ping6_mtu.py @@ -0,0 +1,24 @@ +#!/usr/local/bin/python2.7 +# check wether path mtu to dst is as expected + +import os +from addr import * +from scapy.all import * + +dstaddr=sys.argv[1] +expect=int(sys.argv[2]) +pid=os.getpid() +payload="a" * 1452 +a=srp1(Ether(src=SRC_MAC, dst=PF_MAC)/IPv6(src=SRC_OUT6, dst=dstaddr)/ + ICMPv6EchoRequest(id=pid, data=payload), iface=SRC_IF, timeout=2) +if a and a.type == scapy.layers.dot11.ETHER_TYPES.IPv6 and \ + ipv6nh[a.payload.nh] == 'ICMPv6' and \ + icmp6types[a.payload.payload.type] == 'Packet too big': + mtu=a.payload.payload.mtu + print "mtu=%d" % (mtu) + if mtu == expect: + exit(0) + print "MTU!=%d" % (expect) + exit(1) +print "MTU=UNKNOWN" +exit(2) diff --git a/regress/sys/net/pf_forward/ping_mtu.py b/regress/sys/net/pf_forward/ping_mtu.py new file mode 100644 index 00000000000..76985ae867a --- /dev/null +++ b/regress/sys/net/pf_forward/ping_mtu.py @@ -0,0 +1,22 @@ +#!/usr/local/bin/python2.7 +# check wether path mtu to dst is as expected + +import os +from addr import * +from scapy.all import * + +dstaddr=sys.argv[1] +expect=int(sys.argv[2]) +pid=os.getpid() +payload="a" * 1452 +a=srp1(Ether(src=SRC_MAC, dst=PF_MAC)/IP(flags="DF", src=SRC_OUT, dst=dstaddr)/ + ICMP(id=pid)/payload, iface=SRC_IF, timeout=2) +if a and a.payload.payload.type==3 and a.payload.payload.code==4: + mtu=a.payload.payload.unused + print "mtu=%d" % (mtu) + if mtu == expect: + exit(0) + print "MTU!=%d" % (expect) + exit(1) +print "MTU=UNKNOWN" +exit(2) |