aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2019-10-24 22:07:45 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2019-10-24 22:07:45 +0000
commit619456bb59a6b6703c31abc14a72aae7177ae2de (patch)
tree2475e53c1ab9d5d19c3ea7c2741ae545e862a15e /tests
parented9d69b5e89bb5b0685b713f6b7d771d332b8cd3 (diff)
Notes
Diffstat (limited to 'tests')
-rw-r--r--tests/sys/netinet6/frag6/Makefile5
-rwxr-xr-xtests/sys/netinet6/frag6/frag6_20.py137
-rwxr-xr-xtests/sys/netinet6/frag6/frag6_20.sh231
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"
+}