diff options
| author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2019-10-24 22:07:45 +0000 |
|---|---|---|
| committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2019-10-24 22:07:45 +0000 |
| commit | 619456bb59a6b6703c31abc14a72aae7177ae2de (patch) | |
| tree | 2475e53c1ab9d5d19c3ea7c2741ae545e862a15e /tests | |
| parent | ed9d69b5e89bb5b0685b713f6b7d771d332b8cd3 (diff) | |
Notes
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/sys/netinet6/frag6/Makefile | 5 | ||||
| -rwxr-xr-x | tests/sys/netinet6/frag6/frag6_20.py | 137 | ||||
| -rwxr-xr-x | tests/sys/netinet6/frag6/frag6_20.sh | 231 |
3 files changed, 372 insertions, 1 deletions
diff --git a/tests/sys/netinet6/frag6/Makefile b/tests/sys/netinet6/frag6/Makefile index 0a1bf9cf6a94b..d9ff45c6d8f7c 100644 --- a/tests/sys/netinet6/frag6/Makefile +++ b/tests/sys/netinet6/frag6/Makefile @@ -27,7 +27,8 @@ ATF_TESTS_SH= \ frag6_16 \ frag6_17 \ frag6_18 \ - frag6_19 + frag6_19 \ + frag6_20 ${PACKAGE}FILES+= frag6.subr ${PACKAGE}FILES+= sniffer.py @@ -50,6 +51,7 @@ ${PACKAGE}FILES+= frag6_16.py ${PACKAGE}FILES+= frag6_17.py ${PACKAGE}FILES+= frag6_18.py ${PACKAGE}FILES+= frag6_19.py +${PACKAGE}FILES+= frag6_20.py ${PACKAGE}FILESMODE_frag6.subr= 0444 ${PACKAGE}FILESMODE_sniffer.py= 0555 @@ -72,5 +74,6 @@ ${PACKAGE}FILESMODE_frag6_16.py= 0555 ${PACKAGE}FILESMODE_frag6_17.py= 0555 ${PACKAGE}FILESMODE_frag6_18.py= 0555 ${PACKAGE}FILESMODE_frag6_19.py= 0555 +${PACKAGE}FILESMODE_frag6_20.py= 0555 .include <bsd.test.mk> diff --git a/tests/sys/netinet6/frag6/frag6_20.py b/tests/sys/netinet6/frag6/frag6_20.py new file mode 100755 index 0000000000000..4e935a1f640a2 --- /dev/null +++ b/tests/sys/netinet6/frag6/frag6_20.py @@ -0,0 +1,137 @@ +#!/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 +from sniffer import Sniffer +from time import sleep + +def check_icmp6_error(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.ICMPv6TimeExceeded) + if not icmp6: + return False + # ICMP6_TIME_EXCEED_REASSEMBLY 1 + if icmp6.code != 1: + return False + # Should we check the payload as well? + # We are running in a very isolated environment and nothing else + # should trigger an ICMPv6 Time Exceeded / Frag reassembly so leave it. + #icmp6.display() + return True + + +def main(): + parser = argparse.ArgumentParser("frag6.py", + description="IPv6 fragementation 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') + + args = parser.parse_args() + + + # Start sniffing on recvif + sniffer = Sniffer(args, check_icmp6_error) + + + ######################################################################## + # + # Send a proper first fragment (off=0) and a second fragment which + # just fits the 64k. The re-send the first fragment with an extra + # unfragmentable part making the 64k to exceed the limit. + # This is to make sure we don't allow to update meta-data for a + # 1st fragmented packet should a second arrive but given the + # fragmentable part is an exact duplicate only that fragment + # will be silently discarded. + # + # A: Reassembly failure, timeout after + # R: ICMPv6 time exceeded / statistics for the duplicate + # + data = "6" * 8 + ip6f00 = \ + sp.Ether() / \ + sp.IPv6(src=args.src[0], dst=args.to[0]) / \ + sp.IPv6ExtHdrFragment(offset=0, m=1, id=20) / \ + sp.UDP(dport=3456, sport=6543) / \ + data + data = "6" * 15 + ip6f01 = \ + sp.Ether() / \ + sp.IPv6(src=args.src[0], dst=args.to[0]) / \ + sp.IPv6ExtHdrFragment(offset=0x1ffc, m=0, id=20) / \ + sp.UDP(dport=3456, sport=6543) / \ + data + data = "6" * 8 + ip6f02 = \ + sp.Ether() / \ + sp.IPv6(src=args.src[0], dst=args.to[0]) / \ + sp.IPv6ExtHdrDestOpt(options = \ + sp.PadN(optdata="\x00\x00\x00\x00\x00\x00")) / \ + sp.IPv6ExtHdrFragment(offset=0, m=1, id=20) / \ + sp.UDP(dport=3456, sport=6543) / \ + data + if args.debug : + ip6f00.display() + ip6f01.display() + ip6f02.display() + sp.sendp(ip6f00, iface=args.sendif[0], verbose=False) + sp.sendp(ip6f01, iface=args.sendif[0], verbose=False) + sp.sendp(ip6f02, iface=args.sendif[0], verbose=False) + + sleep(75) + sniffer.setEnd() + sniffer.join() + if not sniffer.foundCorrectPacket: + sys.exit(1) + + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/tests/sys/netinet6/frag6/frag6_20.sh b/tests/sys/netinet6/frag6/frag6_20.sh new file mode 100755 index 0000000000000..d05451fec3202 --- /dev/null +++ b/tests/sys/netinet6/frag6/frag6_20.sh @@ -0,0 +1,231 @@ +# $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)/frag6.subr + +frag6_20_check_stats() { + + local jname ifname + jname=$1 + ifname=$2 + + case "${jname}" in + "") echo "ERROR: jname is empty"; return ;; + esac + case "${ifname}" in + "") echo "ERROR: ifname is empty"; return ;; + esac + + # Defaults are: IPV6_FRAGTTL 120 slowtimo ticks. + # pfslowtimo() is run at hz/2. So this takes 60s. + # This is awefully long for a test case. + # The Python script has to wait for this already to get the ICMPv6 + # hence we do not sleep here anymore. + + nf=`jexec ${jname} sysctl -n net.inet6.ip6.frag6_nfragpackets` + case ${nf} in + 0) break ;; + *) atf_fail "VNET frag6_nfragpackets not 0 but: ${nf}" ;; + esac + nf=`sysctl -n net.inet6.ip6.frag6_nfrags` + case ${nf} in + 0) break ;; + *) atf_fail "Global frag6_nfrags not 0 but: ${nf}" ;; + esac + + # + # Check selection of global UDP stats. + # + cat <<EOF > ${HOME}/filter-${jname}.txt + <received-datagrams>0</received-datagrams> + <dropped-incomplete-headers>0</dropped-incomplete-headers> + <dropped-bad-data-length>0</dropped-bad-data-length> + <dropped-bad-checksum>0</dropped-bad-checksum> + <dropped-no-checksum>0</dropped-no-checksum> + <dropped-no-socket>0</dropped-no-socket> + <dropped-broadcast-multicast>0</dropped-broadcast-multicast> + <dropped-full-socket-buffer>0</dropped-full-socket-buffer> + <not-for-hashed-pcb>0</not-for-hashed-pcb> +EOF + count=`jexec ${jname} netstat -s -p udp --libxo xml,pretty | grep -E -x -c -f ${HOME}/filter-${jname}.txt` + rm -f ${HOME}/filter-${jname}.txt + case ${count} in + 9) ;; + *) jexec ${jname} netstat -s -p udp --libxo xml,pretty + atf_fail "Global UDP statistics do not match: ${count} != 9" ;; + esac + + + # + # Check selection of global IPv6 stats. + # + cat <<EOF > ${HOME}/filter-${jname}.txt + <dropped-below-minimum-size>0</dropped-below-minimum-size> + <dropped-short-packets>0</dropped-short-packets> + <dropped-bad-options>0</dropped-bad-options> + <dropped-bad-version>0</dropped-bad-version> + <received-fragments>3</received-fragments> + <dropped-fragment>1</dropped-fragment> + <dropped-fragment-after-timeout>2</dropped-fragment-after-timeout> + <dropped-fragments-overflow>0</dropped-fragments-overflow> + <atomic-fragments>0</atomic-fragments> + <reassembled-packets>0</reassembled-packets> + <forwarded-packets>0</forwarded-packets> + <packets-not-forwardable>0</packets-not-forwardable> + <sent-redirects>0</sent-redirects> + <send-packets-fabricated-header>0</send-packets-fabricated-header> + <discard-no-mbufs>0</discard-no-mbufs> + <discard-no-route>0</discard-no-route> + <sent-fragments>0</sent-fragments> + <fragments-created>0</fragments-created> + <discard-cannot-fragment>0</discard-cannot-fragment> + <discard-scope-violations>0</discard-scope-violations> +EOF + count=`jexec ${jname} netstat -s -p ip6 --libxo xml,pretty | grep -E -x -c -f ${HOME}/filter-${jname}.txt` + rm -f ${HOME}/filter-${jname}.txt + case ${count} in + 20) ;; + *) jexec ${jname} netstat -s -p ip6 --libxo xml,pretty + atf_fail "Global IPv6 statistics do not match: ${count} != 20" ;; + esac + + # + # Check selection of global ICMPv6 stats. + # XXX-TODO check output histogram (just too hard to parse [no multi-line-grep]) + # + cat <<EOF > ${HOME}/filter-${jname}.txt + <icmp6-calls>1</icmp6-calls> + <no-route>0</no-route> + <admin-prohibited>0</admin-prohibited> + <beyond-scope>0</beyond-scope> + <address-unreachable>0</address-unreachable> + <port-unreachable>0</port-unreachable> + <packet-too-big>0</packet-too-big> + <time-exceed-transmit>0</time-exceed-transmit> + <time-exceed-reassembly>1</time-exceed-reassembly> + <bad-header>0</bad-header> + <bad-next-header>0</bad-next-header> + <bad-option>0</bad-option> + <redirects>0</redirects> + <unknown>0</unknown> + <reflect>0</reflect> + <too-many-nd-options>0</too-many-nd-options> + <bad-nd-options>0</bad-nd-options> + <bad-neighbor-solicitation>0</bad-neighbor-solicitation> + <bad-neighbor-advertisement>0</bad-neighbor-advertisement> + <bad-router-solicitation>0</bad-router-solicitation> + <bad-router-advertisement>0</bad-router-advertisement> + <bad-redirect>0</bad-redirect> +EOF + count=`jexec ${jname} netstat -s -p icmp6 --libxo xml,pretty | grep -E -x -c -f ${HOME}/filter-${jname}.txt` + rm -f ${HOME}/filter-${jname}.txt + case ${count} in + 22) ;; + *) jexec ${jname} netstat -s -p icmp6 --libxo xml,pretty + atf_fail "Global ICMPv6 statistics do not match: ${count} != 22" ;; + esac + + # + # Check selection of interface IPv6 stats. + # + cat <<EOF > ${HOME}/filter-${jname}.txt + <dropped-invalid-header>0</dropped-invalid-header> + <dropped-mtu-exceeded>0</dropped-mtu-exceeded> + <dropped-no-route>0</dropped-no-route> + <dropped-invalid-destination>0</dropped-invalid-destination> + <dropped-unknown-protocol>0</dropped-unknown-protocol> + <dropped-truncated>0</dropped-truncated> + <sent-forwarded>0</sent-forwarded> + <discard-packets>0</discard-packets> + <discard-fragments>0</discard-fragments> + <fragments-failed>0</fragments-failed> + <fragments-created>0</fragments-created> + <reassembly-required>3</reassembly-required> + <reassembled-packets>0</reassembled-packets> + <reassembly-failed>1</reassembly-failed> +EOF + count=`jexec ${jname} netstat -s -p ip6 -I ${ifname} --libxo xml,pretty | grep -E -x -c -f ${HOME}/filter-${jname}.txt` + rm -f ${HOME}/filter-${jname}.txt + case ${count} in + 14) ;; + *) jexec ${jname} netstat -s -p ip6 -I ${ifname} --libxo xml,pretty + atf_fail "Interface IPv6 statistics do not match: ${count} != 14" ;; + esac + + # + # Check selection of interface ICMPv6 stats. + # + cat <<EOF > ${HOME}/filter-${jname}.txt + <received-errors>0</received-errors> + <received-destination-unreachable>0</received-destination-unreachable> + <received-admin-prohibited>0</received-admin-prohibited> + <received-time-exceeded>0</received-time-exceeded> + <received-bad-parameter>0</received-bad-parameter> + <received-packet-too-big>0</received-packet-too-big> + <received-echo-requests>0</received-echo-requests> + <received-echo-replies>0</received-echo-replies> + <received-router-solicitation>0</received-router-solicitation> + <received-router-advertisement>0</received-router-advertisement> + <sent-errors>1</sent-errors> + <sent-destination-unreachable>0</sent-destination-unreachable> + <sent-admin-prohibited>0</sent-admin-prohibited> + <sent-time-exceeded>1</sent-time-exceeded> + <sent-bad-parameter>0</sent-bad-parameter> + <sent-packet-too-big>0</sent-packet-too-big> + <sent-echo-requests>0</sent-echo-requests> + <sent-echo-replies>0</sent-echo-replies> + <sent-router-solicitation>0</sent-router-solicitation> + <sent-router-advertisement>0</sent-router-advertisement> + <sent-redirects>0</sent-redirects> +EOF + count=`jexec ${jname} netstat -s -p icmp6 -I ${ifname} --libxo xml,pretty | grep -E -x -c -f ${HOME}/filter-${jname}.txt` + rm -f ${HOME}/filter-${jname}.txt + case ${count} in + 21) ;; + *) jexec ${jname} netstat -s -p icmp6 -I ${ifname} --libxo xml,pretty + atf_fail "Interface ICMPv6 statistics do not match: ${count} != 21" ;; + esac +} + +atf_test_case "frag6_20" "cleanup" +frag6_20_head() { + frag6_head 20 +} + +frag6_20_body() { + frag6_body 20 frag6_20_check_stats +} + +frag6_20_cleanup() { + frag6_cleanup 20 +} + +atf_init_test_cases() +{ + atf_add_test_case "frag6_20" +} |
