Date: Wed, 8 Jan 2020 16:32:17 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r356493 - in stable/12/tests/sys/netinet6: . frag6 Message-ID: <202001081632.008GWHe5043070@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bz Date: Wed Jan 8 16:32:16 2020 New Revision: 356493 URL: https://svnweb.freebsd.org/changeset/base/356493 Log: MFC r354357-354358,354390,354395: frag6 tests: set end to catch timeout as error ipv6 tests: Add very simplistic extension header tests ipv6 tests: cleanup ipv6 tests: test case for scapy bpf parsing bug PR: 239380 Added: stable/12/tests/sys/netinet6/exthdr.py - copied unchanged from r354358, head/tests/sys/netinet6/exthdr.py stable/12/tests/sys/netinet6/exthdr.sh - copied, changed from r354358, head/tests/sys/netinet6/exthdr.sh stable/12/tests/sys/netinet6/scapyi386.py - copied unchanged from r354395, head/tests/sys/netinet6/scapyi386.py stable/12/tests/sys/netinet6/scapyi386.sh - copied unchanged from r354395, head/tests/sys/netinet6/scapyi386.sh Modified: stable/12/tests/sys/netinet6/Makefile stable/12/tests/sys/netinet6/frag6/frag6.subr stable/12/tests/sys/netinet6/frag6/frag6_02.py stable/12/tests/sys/netinet6/frag6/frag6_04.py Directory Properties: stable/12/ (props changed) Modified: stable/12/tests/sys/netinet6/Makefile ============================================================================== --- stable/12/tests/sys/netinet6/Makefile Wed Jan 8 16:15:43 2020 (r356492) +++ stable/12/tests/sys/netinet6/Makefile Wed Jan 8 16:32:16 2020 (r356493) @@ -1,6 +1,19 @@ # $FreeBSD$ +PACKAGE= tests + TESTSDIR= ${TESTSBASE}/sys/netinet6 +FILESDIR= ${TESTSDIR} + +ATF_TESTS_SH= \ + exthdr \ + scapyi386 + +${PACKAGE}FILES+= exthdr.py +${PACKAGE}FILES+= scapyi386.py + +${PACKAGE}FILESMODE_exthdr.py= 0555 +${PACKAGE}FILESMODE_scapyi386.py=0555 TESTS_SUBDIRS+= frag6 Copied: stable/12/tests/sys/netinet6/exthdr.py (from r354358, head/tests/sys/netinet6/exthdr.py) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/tests/sys/netinet6/exthdr.py Wed Jan 8 16:32:16 2020 (r356493, copy of r354358, head/tests/sys/netinet6/exthdr.py) @@ -0,0 +1,273 @@ +#!/usr/bin/env python +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2019 Netflix, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +import argparse +import scapy.all as sp +import socket +import sys +import frag6.sniffer as Sniffer +from time import sleep + +def check_icmp6_error_dst_unreach_noport(args, packet): + ip6 = packet.getlayer(sp.IPv6) + if not ip6: + return False + oip6 = sp.IPv6(src=args.src[0], dst=args.to[0]) + if ip6.dst != oip6.src: + return False + icmp6 = packet.getlayer(sp.ICMPv6DestUnreach) + if not icmp6: + return False + # ICMP6_DST_UNREACH_NOPORT 4 + if icmp6.code != 4: + return False + # Should we check the payload as well? + # We are running in a very isolated environment and nothing else + # should trigger an ICMPv6 Dest Unreach / Port Unreach so leave it. + #icmp6.display() + return True + +def check_icmp6_error_paramprob_header(args, packet): + ip6 = packet.getlayer(sp.IPv6) + if not ip6: + return False + oip6 = sp.IPv6(src=args.src[0], dst=args.to[0]) + if ip6.dst != oip6.src: + return False + icmp6 = packet.getlayer(sp.ICMPv6ParamProblem) + if not icmp6: + return False + # ICMP6_PARAMPROB_HEADER 0 + if icmp6.code != 0: + return False + # Should we check the payload as well? + # We are running in a very isolated environment and nothing else + # should trigger an ICMPv6 Param Prob so leave it. + #icmp6.display() + return True + +def check_tcp_rst(args, packet): + ip6 = packet.getlayer(sp.IPv6) + if not ip6: + return False + oip6 = sp.IPv6(src=args.src[0], dst=args.to[0]) + if ip6.dst != oip6.src: + return False + tcp = packet.getlayer(sp.TCP) + if not tcp: + return False + # Is TCP RST? + if tcp.flags & 0x04: + #tcp.display() + return True + return False + +def addExt(ext, h): + if h is None: + return ext + if ext is None: + ext = h + else: + ext = ext / h + return ext + +def getExtHdrs(args): + ext = None + + # XXX-TODO Try to put them in an order which could make sense + # in real life packets and according to the RFCs. + if args.hbh: + hbh = sp.IPv6ExtHdrHopByHop(options = \ + sp.PadN(optdata="\x00\x00\x00\x00\x00\x00")) + ext = addExt(ext, hbh) + + if args.rh: + rh = sp.IPv6ExtHdrRouting(type = 0) + ext = addExt(ext, rh) + + if args.frag6: + frag6 = sp.IPv6ExtHdrFragment(offset=0, m=0, id=0x1234) + ext = addExt(ext, frag6) + + if args.esp: + # XXX TODO + esp = None + ext = addExt(ext, esp) + + if args.ah: + # XXX TODO + ah = None + ext = addExt(ext, ah) + + if args.dest: + dest = sp.IPv6ExtHdrDestOpt(options = \ + sp.PadN(optdata="\x00\x00\x00\x00\x00\x00")) + ext = addExt(ext, dest) + + if args.mobi: + # XXX TODO + mobi = None + ext = addExt(ext, mobi) + + if args.hip: + # XXX TODO + hip = None + ext = addExt(ext, hip) + + if args.shim6: + # XXX TODO + shim6 = None + ext = addExt(ext, shim6) + + if args.proto253: + # XXX TODO + tft = None + ext = addExt(ext, tft) + + if args.proto254: + # XXX TODO + tff = None + ext = addExt(ext, tff) + + if args.hbhbad: + hbhbad = sp.IPv6ExtHdrHopByHop(options = \ + sp.PadN(optdata="\x00\x00\x00\x00\x00\x00")) + ext = addExt(ext, hbhbad) + + return ext + +def main(): + parser = argparse.ArgumentParser("exthdr.py", + description="IPv6 extension header test tool") + parser.add_argument('--sendif', nargs=1, + required=True, + help='The interface through which the packet will be sent') + parser.add_argument('--recvif', nargs=1, + required=True, + help='The interface on which to check for the packet') + parser.add_argument('--src', nargs=1, + required=True, + help='The source IP address') + parser.add_argument('--to', nargs=1, + required=True, + help='The destination IP address') + parser.add_argument('--debug', + required=False, action='store_true', + help='Enable test debugging') + # Extension Headers + # See https://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml + parser.add_argument('--hbh', + required=False, action='store_true', + help='Add IPv6 Hop-by-Hop Option') + parser.add_argument('--hbhbad', + required=False, action='store_true', + help='Add IPv6 Hop-by-Hop Option at an invalid position') + parser.add_argument('--rh', + required=False, action='store_true', + help='Add Routing Header for IPv6') + parser.add_argument('--frag6', + required=False, action='store_true', + help='Add Fragment Header for IPv6') + parser.add_argument('--esp', + required=False, action='store_true', + help='Add Encapsulating Security Payload') + parser.add_argument('--ah', + required=False, action='store_true', + help='Add Authentication Header') + parser.add_argument('--dest', + required=False, action='store_true', + help='Add Destination Options for IPv6') + parser.add_argument('--mobi', + required=False, action='store_true', + help='Add Mobility Header') + parser.add_argument('--hip', + required=False, action='store_true', + help='Add Host Identity Protocol') + parser.add_argument('--shim6', + required=False, action='store_true', + help='Add Shim6 Protocol') + parser.add_argument('--proto253', + required=False, action='store_true', + help='Use for experimentation and testing (253)') + parser.add_argument('--proto254', + required=False, action='store_true', + help='Use for experimentation and testing (254)') + + args = parser.parse_args() + + if args.hbhbad: + ok = 0 + else: + ok = 1 + + ######################################################################## + # + # Send IPv6 packets with one or more extension headers (combinations + # mmight not always make sense depending what user tells us). + # We are trying to cover the basic loop and passing mbufs on + # and making sure m_pullup() works. + # Try for at least UDP and TCP upper layer payloads. + # + # Expectations: no panics + # We are not testing for any other outcome here. + # + data = "6" * 88 + udp = sp.UDP(dport=3456, sport=6543) / data + tcp = sp.TCP(dport=4567, sport=7654) + ip6 = sp.Ether() / sp.IPv6(src=args.src[0], dst=args.to[0]) + for ulp in [ udp, tcp ]: + ext = getExtHdrs(args) + if ext is not None: + pkt = ip6 / ext / ulp + else: + pkt = ip6 / ulp + if args.debug : + pkt.display() + if not ok: + sc = check_icmp6_error_paramprob_header; + elif ulp == udp: + sc = check_icmp6_error_dst_unreach_noport; + elif ulp == tcp: + sc = check_tcp_rst; + else: + sys.exit(2) + # Start sniffing on recvif + sniffer = Sniffer.Sniffer(args, sc) + sp.sendp(pkt, iface=args.sendif[0], verbose=False) + sleep(0.10) + sniffer.setEnd() + sniffer.join() + if not sniffer.foundCorrectPacket: + sys.exit(not ok) + + sys.exit(0) + +if __name__ == '__main__': + main() Copied and modified: stable/12/tests/sys/netinet6/exthdr.sh (from r354358, head/tests/sys/netinet6/exthdr.sh) ============================================================================== --- head/tests/sys/netinet6/exthdr.sh Tue Nov 5 10:59:33 2019 (r354358, copy source) +++ stable/12/tests/sys/netinet6/exthdr.sh Wed Jan 8 16:32:16 2020 (r356493) @@ -31,7 +31,7 @@ atf_test_case "exthdr" "cleanup" exthdr_head() { - atf_set descr 'Test IPv6 fragmentation code' + atf_set descr 'Test IPv6 extension header code paths' atf_set require.user root atf_set require.progs scapy } @@ -54,12 +54,12 @@ exthdr_body() { ip6b="2001:db8:6666:0000:${yl}:${id}:2:${xl}" epair=$(vnet_mkepair) - ifconfig ${epair}a mtu 131071 up + ifconfig ${epair}a up ifconfig ${epair}a inet6 ${ip6a}/64 jname="v6t-${id}-${yl}-${xl}" vnet_mkjail ${jname} ${epair}b - jexec ${jname} ifconfig ${epair}b mtu 131071 up + jexec ${jname} ifconfig ${epair}b up jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/64 # Let IPv6 ND do its thing. @@ -70,7 +70,7 @@ exthdr_body() { # Clear statistics. jexec ${jname} netstat -z -s > /dev/null - # Run fragment tests. + # Run extension header tests. pyname=$(atf_get ident) pyname=${pyname%*_[0-9]} Modified: stable/12/tests/sys/netinet6/frag6/frag6.subr ============================================================================== --- stable/12/tests/sys/netinet6/frag6/frag6.subr Wed Jan 8 16:15:43 2020 (r356492) +++ stable/12/tests/sys/netinet6/frag6/frag6.subr Wed Jan 8 16:32:16 2020 (r356493) @@ -54,12 +54,12 @@ frag6_body() ip6b="2001:db8:6666:6666:${yl}:${id}:2:${xl}" epair=$(vnet_mkepair) - ifconfig ${epair}a mtu 131071 up + ifconfig ${epair}a up ifconfig ${epair}a inet6 ${ip6a}/64 jname="v6t-${id}-${yl}-${xl}" vnet_mkjail ${jname} ${epair}b - jexec ${jname} ifconfig ${epair}b mtu 131071 up + jexec ${jname} ifconfig ${epair}b up jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/64 # Let IPv6 ND do its thing. Modified: stable/12/tests/sys/netinet6/frag6/frag6_02.py ============================================================================== --- stable/12/tests/sys/netinet6/frag6/frag6_02.py Wed Jan 8 16:15:43 2020 (r356492) +++ stable/12/tests/sys/netinet6/frag6/frag6_02.py Wed Jan 8 16:32:16 2020 (r356493) @@ -98,6 +98,7 @@ def main(): sp.sendp(ip6f01, iface=args.sendif[0], verbose=False) sleep(0.10) + sniffer.setEnd() sniffer.join() if not sniffer.foundCorrectPacket: sys.exit(1) Modified: stable/12/tests/sys/netinet6/frag6/frag6_04.py ============================================================================== --- stable/12/tests/sys/netinet6/frag6/frag6_04.py Wed Jan 8 16:15:43 2020 (r356492) +++ stable/12/tests/sys/netinet6/frag6/frag6_04.py Wed Jan 8 16:32:16 2020 (r356493) @@ -95,6 +95,7 @@ def main(): sp.sendp(ip6f01, iface=args.sendif[0], verbose=False) sleep(0.10) + sniffer.setEnd() sniffer.join() if not sniffer.foundCorrectPacket: sys.exit(1) Copied: stable/12/tests/sys/netinet6/scapyi386.py (from r354395, head/tests/sys/netinet6/scapyi386.py) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/tests/sys/netinet6/scapyi386.py Wed Jan 8 16:32:16 2020 (r356493, copy of r354395, head/tests/sys/netinet6/scapyi386.py) @@ -0,0 +1,85 @@ +#!/usr/bin/env python +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2019 Netflix, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +import argparse +import scapy.all as sp +import socket +import sys + +def main(): + parser = argparse.ArgumentParser("scapyi386.py", + description="IPv6 Ethernet Dest MAC test") + parser.add_argument('--sendif', nargs=1, + required=True, + help='The interface through which the packet will be sent') + parser.add_argument('--recvif', nargs=1, + required=True, + help='The interface on which to check for the packet') + parser.add_argument('--src', nargs=1, + required=True, + help='The source IP address') + parser.add_argument('--to', nargs=1, + required=True, + help='The destination IP address') + parser.add_argument('--debug', + required=False, action='store_true', + help='Enable test debugging') + + args = parser.parse_args() + + ######################################################################## + # + # A test case to check that IPv6 packets are sent with a proper + # (resolved) Ethernet Destination MAC address instead of the BCAST one. + # This was needed as test cases did not work properly on i386 due to a + # scapy BPF parsing bug. (See PR 239380 and duplicates). + # + bcmac = sp.Ether(dst="ff:ff:ff:ff:ff:ff").dst + data = "6" * 88 + pkt = sp.Ether() / \ + sp.IPv6(src=args.src[0], dst=args.to[0]) / \ + sp.UDP(dport=3456, sport=6543) / \ + data + sp.sendp(pkt, iface=args.sendif[0], verbose=False) + + eth = pkt.getlayer(sp.Ether) + if eth is None: + print("No Ether in packet") + pkt.display() + sys.exit(1) + if eth.dst == bcmac: + print("Broadcast dMAC on packet") + eth.display() + sys.exit(1) + + sys.exit(0) + +if __name__ == '__main__': + main() Copied: stable/12/tests/sys/netinet6/scapyi386.sh (from r354395, head/tests/sys/netinet6/scapyi386.sh) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/tests/sys/netinet6/scapyi386.sh Wed Jan 8 16:32:16 2020 (r356493, copy of r354395, head/tests/sys/netinet6/scapyi386.sh) @@ -0,0 +1,94 @@ +# $FreeBSD$ +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2019 Netflix, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +. $(atf_get_srcdir)/../common/vnet.subr + +atf_test_case "scapyi386" "cleanup" +scapyi386_head() { + + atf_set descr 'Test for correct Ethernet Destination MAC address' + atf_set require.user root + atf_set require.progs scapy +} + +scapyi386_body() { + + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "i386" ]; then + atf_skip "https://bugs.freebsd.org/239380" + fi + + ids=65533 + id=`printf "%x" ${ids}` + if [ $$ -gt 65535 ]; then + xl=`printf "%x" $(($$ - 65535))` + yl="1" + else + xl=`printf "%x" $$` + yl="" + fi + + vnet_init + + ip6a="2001:db8:6666:0000:${yl}:${id}:1:${xl}" + ip6b="2001:db8:6666:0000:${yl}:${id}:2:${xl}" + + epair=$(vnet_mkepair) + ifconfig ${epair}a up + ifconfig ${epair}a inet6 ${ip6a}/64 + + jname="v6t-${id}-${yl}-${xl}" + vnet_mkjail ${jname} ${epair}b + jexec ${jname} ifconfig ${epair}b up + jexec ${jname} ifconfig ${epair}b inet6 ${ip6b}/64 + + # Let IPv6 ND do its thing. + #ping6 -q -c 1 ff02::1%${epair}a + #ping6 -q -c 1 ${ip6b} + sleep 3 + + pyname=$(atf_get ident) + pyname=${pyname%*_[0-9]} + + atf_check -s exit:0 $(atf_get_srcdir)/${pyname}.py \ + --sendif ${epair}a --recvif ${epair}a \ + --src ${ip6a} --to ${ip6b} +} + +scapyi386_cleanup() { + + vnet_cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case "scapyi386" +} + +# end
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001081632.008GWHe5043070>