diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2015-08-24 23:12:54 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2015-08-24 23:12:54 +0000 |
commit | a63b802c24c934fb925fa4e67a549edc680f0c73 (patch) | |
tree | 1541024c6874f1e7d1956538ade7a280f4f623ee /regress | |
parent | 9653a62608467bfc6a6065591822692d9a32177e (diff) |
Extend the pf forward and fragment tests with a second challenge
for path MTU discovery. The router behind the pf machine has MTU
1300. The ICMP packet generated by the router matches the pf state
and is NATed correctly. Additionally the pf machine itself has an
interface MTU 1400. So when pf is sending a packet is has to
generate a correct "fragmentation needed" or "packet too big" ICMP
response. This is done with pf route-to and reply-to.
Diffstat (limited to 'regress')
-rw-r--r-- | regress/sys/net/pf_forward/Makefile | 72 | ||||
-rw-r--r-- | regress/sys/net/pf_forward/pf.conf | 16 | ||||
-rw-r--r-- | regress/sys/net/pf_forward/ping6_mtu.py | 15 | ||||
-rw-r--r-- | regress/sys/net/pf_forward/ping_mtu.py | 14 | ||||
-rw-r--r-- | regress/sys/net/pf_fragment/Makefile | 22 | ||||
-rw-r--r-- | regress/sys/net/pf_fragment/pf.conf | 8 | ||||
-rw-r--r-- | regress/sys/net/pf_fragment/ping6_mtu_1300.py | 7 | ||||
-rw-r--r-- | regress/sys/net/pf_fragment/ping_cksum.py | 2 | ||||
-rw-r--r-- | regress/sys/net/pf_fragment/ping_mtu_1300.py | 9 | ||||
-rw-r--r-- | regress/sys/net/pf_fragment/udp_cksum.py | 2 |
10 files changed, 111 insertions, 56 deletions
diff --git a/regress/sys/net/pf_forward/Makefile b/regress/sys/net/pf_forward/Makefile index 947f65cbd36..04a3efc1c2f 100644 --- a/regress/sys/net/pf_forward/Makefile +++ b/regress/sys/net/pf_forward/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.11 2015/08/17 22:06:50 bluhm Exp $ +# $OpenBSD: Makefile,v 1.12 2015/08/24 23:12:53 bluhm Exp $ # The following ports must be installed: # @@ -27,15 +27,15 @@ regress: # RTT addresses exist on ECO, PF has no route and must use route-to RT # RPT addresses exist on SRC, PF has no route and must use reply-to SRC # -# +---+ 0 +--+ 1 +--+ 2 +---+ 3 4 +---+ 5 6 +--+ -# |SRC| ----> |PF| ----> |RT| ----> |ECO| 7 |RDR| |AF| -# +---+ 8 +--+ +--+ +---+ 9 +---+ +--+ -# out in out in out in out in out in +# +---+ 0 +--+ 1 +--+ 2 +---+ 3 +# |SRC| ----> |PF| ----> |RT| ----> |ECO| 7 +# +---+ 8 +--+ +--+ +---+ 9 +# out in out in out in out # -# 7 +---+ +---+ 8 -# |RTT| |RPT| -# +---+ +---+ -# in out +# 4 +---+ 5 6 +--+ 7 +---+ +---+ 8 +# |RDR| |AF| |RTT| |RPT| +# +---+ +--+ +---+ +---+ +# in out in in out # Configure Addresses on the machines, there must be routes for the # networks. Adapt interface and addresse variables to your local @@ -48,7 +48,8 @@ regress: SRC_IF ?= tun0 SRC_MAC ?= fe:e1:ba:d1:0a:dc -PF_IF ?= vio0 +PF_IFIN ?= vio0 +PF_IFOUT ?= vio1 PF_MAC ?= 52:54:00:12:34:50 PF_SSH ?= RT_SSH ?= @@ -107,7 +108,8 @@ addr.py: Makefile rm -f $@ $@.tmp echo 'SRC_IF="${SRC_IF}"' >>$@.tmp echo 'SRC_MAC="${SRC_MAC}"' >>$@.tmp - echo 'PF_IF="${PF_IF}"' >>$@.tmp + echo 'PF_IFIN="${PF_IFIN}"' >>$@.tmp + echo 'PF_IFOUT="${PF_IFOUT}"' >>$@.tmp echo 'PF_MAC="${PF_MAC}"' >>$@.tmp .for var in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN RTT_IN RPT_OUT echo '${var}="${${var}}"' >>$@.tmp @@ -120,7 +122,7 @@ addr.py: Makefile stamp-pfctl: addr.py pf.conf cat addr.py ${.CURDIR}/pf.conf | pfctl -n -f - cat addr.py ${.CURDIR}/pf.conf | \ - sed 's/@$$PF_IF /@${PF_IF} /g' | \ + sed 's/@$$PF_IFIN /@${PF_IFIN} /;s/@$$PF_IFOUT /@${PF_IFOUT} /' | \ ssh ${PF_SSH} ${SUDO} pfctl -a regress -f - @date >$@ @@ -157,30 +159,59 @@ run-regress-ping6: stamp-pfctl ping6 -n -c 1 -S ${RPT_OUT6} ${ECO_IN6} # Send a large IPv4/ICMP-Echo-Request packet with enabled DF bit and +# parse response packet to determine MTU of the packet filter. The +# outgoing MTU of PF has to be 1400 octets. Packet size is 1500. +# Check that the IP length of the original packet and the ICMP +# quoted packet are the same. +TARGETS += ping-mtu-1400 ping6-mtu-1400 + +run-regress-ping-mtu-1400: addr.py stamp-pfctl + @echo '\n======== $@ ========' +.for ip in ECO_IN ECO_OUT RDR_IN RDR_OUT RTT_IN + @echo Check path MTU to ${ip} is 1400 + ${SUDO} ${PYTHON}ping_mtu.py ${SRC_OUT} ${${ip}} 1500 1400 +.endfor + @echo Check path MTU from RPT_OUT is 1400 + ${SUDO} ${PYTHON}ping_mtu.py ${RPT_OUT} ${ECO_IN} 1500 1400 + +run-regress-ping6-mtu-1400: addr.py stamp-pfctl + @echo '\n======== $@ ========' +.for ip in ECO_IN ECO_OUT RDR_IN RDR_OUT RTT_IN + @echo Check path MTU to ${ip}6 is 1400 + ${SUDO} ${PYTHON}ping6_mtu.py ${SRC_OUT6} ${${ip}6} 1500 1400 +.endfor + @echo Check path MTU from RPT_OUT6 is 1400 + ${SUDO} ${PYTHON}ping6_mtu.py ${RPT_OUT6} ${ECO_IN6} 1500 1400 + +# 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. +# the router RT before. Packet size is 1400 to pass PF MTU. # Check that the IP length of the original packet and the ICMP # quoted packet are the same. -TARGETS += ping-mtu ping6-mtu +TARGETS += ping-mtu-1300 ping6-mtu-1300 -run-regress-ping-mtu: addr.py stamp-pfctl +run-regress-ping-mtu-1300: addr.py stamp-pfctl @echo '\n======== $@ ========' .for ip in ECO_IN ECO_OUT RDR_IN RDR_OUT RTT_IN @echo Check path MTU to ${ip} is 1300 - ${SUDO} ${PYTHON}ping_mtu.py ${${ip}} 1300 + ${SUDO} ${PYTHON}ping_mtu.py ${SRC_OUT} ${${ip}} 1400 1300 .endfor @echo Check path MTU to AF_IN is 1280 - ${SUDO} ${PYTHON}ping_mtu.py ${AF_IN} 1280 + ${SUDO} ${PYTHON}ping_mtu.py ${SRC_OUT} ${AF_IN} 1380 1280 + @echo Check path MTU from RPT_OUT is 1300 + ${SUDO} ${PYTHON}ping_mtu.py ${RPT_OUT} ${ECO_IN} 1400 1300 -run-regress-ping6-mtu: addr.py stamp-pfctl +run-regress-ping6-mtu-1300: addr.py stamp-pfctl @echo '\n======== $@ ========' .for ip in ECO_IN ECO_OUT RDR_IN RDR_OUT RTT_IN @echo Check path MTU to ${ip}6 is 1300 - ${SUDO} ${PYTHON}ping6_mtu.py ${${ip}6} 1300 + ${SUDO} ${PYTHON}ping6_mtu.py ${SRC_OUT6} ${${ip}6} 1400 1300 .endfor @echo Check path MTU to AF_IN6 is 1320 - ${SUDO} ${PYTHON}ping6_mtu.py ${AF_IN6} 1320 + ${SUDO} ${PYTHON}ping6_mtu.py ${SRC_OUT6} ${AF_IN6} 1420 1320 + @echo Check path MTU from RPT_OUT6 is 1300 + ${SUDO} ${PYTHON}ping6_mtu.py ${RPT_OUT6} ${ECO_IN6} 1400 1300 # Send one UDP echo port 7 packet to all destination addresses with netcat. # The response must arrive in 1 second. @@ -283,6 +314,7 @@ check-setup: ssh ${PF_SSH} ${SUDO} pfctl -si | grep '^Status: Enabled ' ssh ${PF_SSH} sysctl net.inet.ip.forwarding | fgrep =1 ssh ${PF_SSH} sysctl net.inet6.ip6.forwarding | fgrep =1 + ssh ${PF_SSH} ifconfig ${PF_IFOUT} | fgrep 'mtu 1400' @echo '\n======== $@ RT ========' ssh ${RT_SSH} ping -n -c 1 ${RT_IN} # RT_IN ssh ${RT_SSH} route -n get -inet ${RT_IN} | fgrep -q 'interface: lo0' # RT_IN diff --git a/regress/sys/net/pf_forward/pf.conf b/regress/sys/net/pf_forward/pf.conf index 8f5a3da5642..cfbaca9a80e 100644 --- a/regress/sys/net/pf_forward/pf.conf +++ b/regress/sys/net/pf_forward/pf.conf @@ -17,12 +17,12 @@ pass out inet6 tagged af pass in to $AF_IN6/64 af-to inet from $PF_OUT to $ECO_IN/24 tag af pass out inet tagged af -pass in to $RTT_IN/24 tag rtt -pass out route-to $RT_IN@$PF_IF tagged rtt -pass in to $RTT_IN6/64 tag rtt -pass out route-to $RT_IN6@$PF_IF tagged rtt +pass in to $RTT_IN/24 tag rtt +pass out route-to $RT_IN@$PF_IFOUT tagged rtt +pass in to $RTT_IN6/64 tag rtt +pass out route-to $RT_IN6@$PF_IFOUT tagged rtt -pass in from $RPT_OUT/24 reply-to $SRC_OUT@$PF_IF tag rpt -pass out tagged rpt -pass in from $RPT_OUT6/64 reply-to $SRC_OUT6@$PF_IF tag rpt -pass out tagged rpt +pass in from $RPT_OUT/24 reply-to $SRC_OUT@$PF_IFIN tag rpt +pass out tagged rpt +pass in from $RPT_OUT6/64 reply-to $SRC_OUT6@$PF_IFIN tag rpt +pass out tagged rpt diff --git a/regress/sys/net/pf_forward/ping6_mtu.py b/regress/sys/net/pf_forward/ping6_mtu.py index 7c2a5b925f8..5274103252e 100644 --- a/regress/sys/net/pf_forward/ping6_mtu.py +++ b/regress/sys/net/pf_forward/ping6_mtu.py @@ -5,11 +5,16 @@ import os from addr import * from scapy.all import * -dstaddr=sys.argv[1] -expect=int(sys.argv[2]) +# usage: ping6_mtu src dst size icmp6-size + +srcaddr=sys.argv[1] +dstaddr=sys.argv[2] +size=int(sys.argv[3]) +expect=int(sys.argv[4]) pid=os.getpid() -payload="a" * 1452 -ip=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=pid, data=payload) +hdr=IPv6(src=srcaddr, dst=dstaddr)/ICMPv6EchoRequest(id=pid) +payload="a" * (size - len(str(hdr))) +ip=hdr/payload iplen=IPv6(str(ip)).plen eth=Ether(src=SRC_MAC, dst=PF_MAC)/ip @@ -20,7 +25,7 @@ if os.fork() == 0: sendp(eth, iface=SRC_IF) os._exit(0) ans=sniff(iface=SRC_IF, timeout=3, filter= - "ip6 and dst "+SRC_OUT6+" and icmp6") + "ip6 and dst "+srcaddr+" and icmp6") if len(ans) == 0: print "no packet sniffed" exit(2) diff --git a/regress/sys/net/pf_forward/ping_mtu.py b/regress/sys/net/pf_forward/ping_mtu.py index 08ff2a62911..7b51b6b1c9a 100644 --- a/regress/sys/net/pf_forward/ping_mtu.py +++ b/regress/sys/net/pf_forward/ping_mtu.py @@ -5,14 +5,20 @@ import os from addr import * from scapy.all import * -dstaddr=sys.argv[1] -expect=int(sys.argv[2]) +# usage: ping_mtu src dst size icmp-size + +srcaddr=sys.argv[1] +dstaddr=sys.argv[2] +size=int(sys.argv[3]) +expect=int(sys.argv[4]) pid=os.getpid() -payload="a" * 1452 -ip=IP(flags="DF", src=SRC_OUT, dst=dstaddr)/ICMP(id=pid)/payload +hdr=IP(flags="DF", src=srcaddr, dst=dstaddr)/ICMP(id=pid) +payload="a" * (size - len(str(hdr))) +ip=hdr/payload iplen=IP(str(ip)).len eth=Ether(src=SRC_MAC, dst=PF_MAC)/ip a=srp1(eth, 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) diff --git a/regress/sys/net/pf_fragment/Makefile b/regress/sys/net/pf_fragment/Makefile index 67bf1f6bd0c..096b99e63c8 100644 --- a/regress/sys/net/pf_fragment/Makefile +++ b/regress/sys/net/pf_fragment/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.16 2015/08/24 22:14:01 bluhm Exp $ +# $OpenBSD: Makefile,v 1.17 2015/08/24 23:12:53 bluhm Exp $ # The following ports must be installed: # @@ -41,7 +41,8 @@ regress: SRC_IF ?= tun0 SRC_MAC ?= fe:e1:ba:d1:0a:dc -PF_IF ?= vio0 +PF_IFIN ?= vio0 +PF_IFOUT ?= vio1 PF_MAC ?= 52:54:00:12:34:50 PF_SSH ?= RT_SSH ?= @@ -92,7 +93,8 @@ addr.py: Makefile rm -f $@ $@.tmp echo 'SRC_IF="${SRC_IF}"' >>$@.tmp echo 'SRC_MAC="${SRC_MAC}"' >>$@.tmp - echo 'PF_IF="${PF_IF}"' >>$@.tmp + echo 'PF_IFIN="${PF_IFIN}"' >>$@.tmp + echo 'PF_IFOUT="${PF_IFOUT}"' >>$@.tmp echo 'PF_MAC="${PF_MAC}"' >>$@.tmp .for var in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT ECO_IN RDR_IN RTT_IN echo '${var}="${${var}}"' >>$@.tmp @@ -105,7 +107,7 @@ addr.py: Makefile stamp-pfctl: addr.py pf.conf cat addr.py ${.CURDIR}/pf.conf | pfctl -n -f - cat addr.py ${.CURDIR}/pf.conf | \ - sed 's/@$$PF_IF /@${PF_IF} /g' | \ + sed 's/@$$PF_IFIN /@${PF_IFIN} /;s/@$$PF_IFOUT /@${PF_IFOUT} /' | \ ssh ${PF_SSH} ${SUDO} pfctl -a regress -f - @date >$@ @@ -146,15 +148,21 @@ run-regress-fragping: stamp-pfctl @echo '\n======== $@ ========' .for ip in PF_IN PF_OUT RT_IN RT_OUT ECO_IN RDR_IN RTT_IN @echo Check ping ${ip}: - -ping -n -c 1 -s 1400 -D ${${ip}} ping -n -c 1 -s 5000 ${${ip}} .endfor run-regress-fragping6: stamp-pfctl @echo '\n======== $@ ========' -.for ip in PF_IN PF_OUT RT_IN RT_OUT ECO_IN RDR_IN RTT_IN +.for ip in PF_IN PF_OUT RT_IN RT_OUT + @echo Check ping ${ip}6: + ${SUDO} route -n delete -host -inet6 ${${ip}6} || true + ping6 -n -c 1 -s 1452 -m ${${ip}6} & sleep 1; kill $$! || true + ping6 -n -c 1 -s 5000 -m ${${ip}6} +.endfor +.for ip in ECO_IN RDR_IN RTT_IN @echo Check ping ${ip}6: - -ping6 -n -c 1 -s 1400 -m ${${ip}6} + ${SUDO} route -n delete -host -inet6 ${${ip}6} || true + ping6 -n -c 1 -s 1352 -m ${${ip}6} & sleep 1; kill $$! || true ping6 -n -c 1 -s 5000 -m ${${ip}6} .endfor diff --git a/regress/sys/net/pf_fragment/pf.conf b/regress/sys/net/pf_fragment/pf.conf index 93eccd3b26c..15c8a6635c8 100644 --- a/regress/sys/net/pf_fragment/pf.conf +++ b/regress/sys/net/pf_fragment/pf.conf @@ -10,7 +10,7 @@ pass out nat-to $PF_OUT allow-opts tagged rdr pass in to $RDR_IN6/64 rdr-to $ECO_IN6 allow-opts tag rdr pass out nat-to $PF_OUT6 allow-opts tagged rdr -pass in to $RTT_IN/24 allow-opts tag rtt -pass out route-to $RT_IN@$PF_IF allow-opts tagged rtt -pass in to $RTT_IN6/64 allow-opts tag rtt -pass out route-to $RT_IN6@$PF_IF allow-opts tagged rtt +pass in to $RTT_IN/24 allow-opts tag rtt +pass out route-to $RT_IN@$PF_IFOUT allow-opts tagged rtt +pass in to $RTT_IN6/64 allow-opts tag rtt +pass out route-to $RT_IN6@$PF_IFOUT allow-opts tagged rtt diff --git a/regress/sys/net/pf_fragment/ping6_mtu_1300.py b/regress/sys/net/pf_fragment/ping6_mtu_1300.py index 404ea45e14f..da63974cce7 100644 --- a/regress/sys/net/pf_fragment/ping6_mtu_1300.py +++ b/regress/sys/net/pf_fragment/ping6_mtu_1300.py @@ -7,9 +7,10 @@ from scapy.all import * dstaddr=sys.argv[1] pid=os.getpid() -payload="a" * 1452 -eth=Ether(src=SRC_MAC, dst=PF_MAC)/IPv6(src=SRC_OUT6, dst=dstaddr)/\ - ICMPv6EchoRequest(id=pid, data=payload) +hdr=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=pid) +payload="a" * (1400 - len(str(hdr))) +ip=hdr/payload +eth=Ether(src=SRC_MAC, dst=PF_MAC)/ip # work around the broken sniffing of packages with bad checksum #a=srp1(eth, iface=SRC_IF, timeout=2) diff --git a/regress/sys/net/pf_fragment/ping_cksum.py b/regress/sys/net/pf_fragment/ping_cksum.py index 8b4eddc5a01..005be1462a0 100644 --- a/regress/sys/net/pf_fragment/ping_cksum.py +++ b/regress/sys/net/pf_fragment/ping_cksum.py @@ -7,7 +7,7 @@ from scapy.all import * dstaddr=sys.argv[1] pid=os.getpid() -payload="a" * 1452 +payload="a" * 1472 p=(Ether(src=SRC_MAC, dst=PF_MAC)/IP(flags="DF", src=SRC_OUT, dst=dstaddr)/ ICMP(id=pid)/payload) ipcksum=IP(str(p.payload)).chksum diff --git a/regress/sys/net/pf_fragment/ping_mtu_1300.py b/regress/sys/net/pf_fragment/ping_mtu_1300.py index 9b4d36ba29b..d86de0e205c 100644 --- a/regress/sys/net/pf_fragment/ping_mtu_1300.py +++ b/regress/sys/net/pf_fragment/ping_mtu_1300.py @@ -7,9 +7,12 @@ from scapy.all import * dstaddr=sys.argv[1] 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) +hdr=IP(flags="DF", src=SRC_OUT, dst=dstaddr)/ICMP(id=pid) +payload="a" * (1400 - len(str(hdr))) +ip=hdr/payload +eth=Ether(src=SRC_MAC, dst=PF_MAC)/ip +a=srp1(eth, 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) diff --git a/regress/sys/net/pf_fragment/udp_cksum.py b/regress/sys/net/pf_fragment/udp_cksum.py index 296bdb3353c..75ce54c409a 100644 --- a/regress/sys/net/pf_fragment/udp_cksum.py +++ b/regress/sys/net/pf_fragment/udp_cksum.py @@ -7,7 +7,7 @@ from scapy.all import * dstaddr=sys.argv[1] pid=os.getpid() -payload="a" * 1452 +payload="a" * 1472 p=(Ether(src=SRC_MAC, dst=PF_MAC)/IP(flags="DF", src=SRC_OUT, dst=dstaddr)/ UDP(sport=pid,dport=9)/payload) ipcksum=IP(str(p.payload)).chksum |