summaryrefslogtreecommitdiffhomepage
path: root/test/packetimpact/tests
diff options
context:
space:
mode:
Diffstat (limited to 'test/packetimpact/tests')
-rw-r--r--test/packetimpact/tests/BUILD13
-rw-r--r--test/packetimpact/tests/icmpv6_param_problem_test.go73
-rwxr-xr-xtest/packetimpact/tests/test_runner.sh41
3 files changed, 125 insertions, 2 deletions
diff --git a/test/packetimpact/tests/BUILD b/test/packetimpact/tests/BUILD
index 47c722ccd..42f87e3f3 100644
--- a/test/packetimpact/tests/BUILD
+++ b/test/packetimpact/tests/BUILD
@@ -96,6 +96,19 @@ packetimpact_go_test(
],
)
+packetimpact_go_test(
+ name = "icmpv6_param_problem",
+ srcs = ["icmpv6_param_problem_test.go"],
+ # TODO(b/153485026): Fix netstack then remove the line below.
+ netstack = False,
+ deps = [
+ "//pkg/tcpip",
+ "//pkg/tcpip/header",
+ "//test/packetimpact/testbench",
+ "@org_golang_x_sys//unix:go_default_library",
+ ],
+)
+
sh_binary(
name = "test_runner",
srcs = ["test_runner.sh"],
diff --git a/test/packetimpact/tests/icmpv6_param_problem_test.go b/test/packetimpact/tests/icmpv6_param_problem_test.go
new file mode 100644
index 000000000..b48e55df4
--- /dev/null
+++ b/test/packetimpact/tests/icmpv6_param_problem_test.go
@@ -0,0 +1,73 @@
+// Copyright 2020 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package icmpv6_param_problem_test
+
+import (
+ "encoding/binary"
+ "testing"
+ "time"
+
+ "gvisor.dev/gvisor/pkg/tcpip/header"
+ tb "gvisor.dev/gvisor/test/packetimpact/testbench"
+)
+
+// TestICMPv6ParamProblemTest sends a packet with a bad next header. The DUT
+// should respond with an ICMPv6 Parameter Problem message.
+func TestICMPv6ParamProblemTest(t *testing.T) {
+ dut := tb.NewDUT(t)
+ defer dut.TearDown()
+ conn := tb.NewIPv6Conn(t, tb.IPv6{}, tb.IPv6{})
+ defer conn.Close()
+ ipv6 := tb.IPv6{
+ // 254 is reserved and used for experimentation and testing. This should
+ // cause an error.
+ NextHeader: tb.Uint8(254),
+ }
+ icmpv6 := tb.ICMPv6{
+ Type: tb.ICMPv6Type(header.ICMPv6EchoRequest),
+ NDPPayload: []byte("hello world"),
+ }
+
+ toSend := conn.CreateFrame(ipv6, &icmpv6)
+ conn.SendFrame(toSend)
+
+ // Build the expected ICMPv6 payload, which includes an index to the
+ // problematic byte and also the problematic packet as described in
+ // https://tools.ietf.org/html/rfc4443#page-12 .
+ ipv6Sent := toSend[1:]
+ expectedPayload, err := ipv6Sent.ToBytes()
+ if err != nil {
+ t.Fatalf("can't convert %s to bytes: %s", ipv6Sent, err)
+ }
+
+ // The problematic field is the NextHeader.
+ b := make([]byte, 4)
+ binary.BigEndian.PutUint32(b, header.IPv6NextHeaderOffset)
+ expectedPayload = append(b, expectedPayload...)
+ expectedICMPv6 := tb.ICMPv6{
+ Type: tb.ICMPv6Type(header.ICMPv6ParamProblem),
+ NDPPayload: expectedPayload,
+ }
+
+ paramProblem := tb.Layers{
+ &tb.Ether{},
+ &tb.IPv6{},
+ &expectedICMPv6,
+ }
+ timeout := time.Second
+ if _, err := conn.ExpectFrame(paramProblem, timeout); err != nil {
+ t.Errorf("expected %s within %s but got none: %s", paramProblem, timeout, err)
+ }
+}
diff --git a/test/packetimpact/tests/test_runner.sh b/test/packetimpact/tests/test_runner.sh
index e938de782..706441cce 100755
--- a/test/packetimpact/tests/test_runner.sh
+++ b/test/packetimpact/tests/test_runner.sh
@@ -192,6 +192,8 @@ docker pull "${IMAGE_TAG}"
# Create the DUT container and connect to network.
DUT=$(docker create ${RUNTIME_ARG} --privileged --rm \
+ --cap-add NET_ADMIN \
+ --sysctl net.ipv6.conf.all.disable_ipv6=0 \
--stop-timeout ${TIMEOUT} -it ${IMAGE_TAG})
docker network connect "${CTRL_NET}" \
--ip "${CTRL_NET_PREFIX}${DUT_NET_SUFFIX}" "${DUT}" \
@@ -203,6 +205,8 @@ docker start "${DUT}"
# Create the test bench container and connect to network.
TESTBENCH=$(docker create --privileged --rm \
+ --cap-add NET_ADMIN \
+ --sysctl net.ipv6.conf.all.disable_ipv6=0 \
--stop-timeout ${TIMEOUT} -it ${IMAGE_TAG})
docker network connect "${CTRL_NET}" \
--ip "${CTRL_NET_PREFIX}${TESTBENCH_NET_SUFFIX}" "${TESTBENCH}" \
@@ -237,6 +241,32 @@ declare -r REMOTE_MAC=$(docker exec -t "${DUT}" ip link show \
"${TEST_DEVICE}" | tail -1 | cut -d' ' -f6)
declare -r LOCAL_MAC=$(docker exec -t "${TESTBENCH}" ip link show \
"${TEST_DEVICE}" | tail -1 | cut -d' ' -f6)
+declare REMOTE_IPV6=$(docker exec -t "${DUT}" ip addr show scope link \
+ "${TEST_DEVICE}" | grep inet6 | cut -d' ' -f6 | cut -d'/' -f1)
+declare -r LOCAL_IPV6=$(docker exec -t "${TESTBENCH}" ip addr show scope link \
+ "${TEST_DEVICE}" | grep inet6 | cut -d' ' -f6 | cut -d'/' -f1)
+
+# Netstack as DUT doesn't assign IPv6 addresses automatically so do it if
+# needed. Convert the MAC address to an IPv6 link local address as described in
+# RFC 4291 page 20: https://tools.ietf.org/html/rfc4291#page-20
+if [[ -z "${REMOTE_IPV6}" ]]; then
+ # Split the octets of the MAC into an array of strings.
+ IFS=":" read -a REMOTE_OCTETS <<< "${REMOTE_MAC}"
+ # Flip the global bit.
+ REMOTE_OCTETS[0]=$(printf '%x' "$((0x${REMOTE_OCTETS[0]} ^ 2))")
+ # Add the IPv6 address.
+ docker exec "${DUT}" \
+ ip addr add $(printf 'fe80::%02x%02x:%02xff:fe%02x:%02x%02x/64' \
+ "0x${REMOTE_OCTETS[0]}" "0x${REMOTE_OCTETS[1]}" "0x${REMOTE_OCTETS[2]}" \
+ "0x${REMOTE_OCTETS[3]}" "0x${REMOTE_OCTETS[4]}" "0x${REMOTE_OCTETS[5]}") \
+ scope link \
+ dev "${TEST_DEVICE}"
+ # Re-extract the IPv6 address.
+ # TODO(eyalsoha): Add "scope link" below when netstack supports correctly
+ # creating link-local IPv6 addresses.
+ REMOTE_IPV6=$(docker exec -t "${DUT}" ip addr show \
+ "${TEST_DEVICE}" | grep inet6 | cut -d' ' -f6 | cut -d'/' -f1)
+fi
declare -r DOCKER_TESTBENCH_BINARY="/$(basename ${TESTBENCH_BINARY})"
docker cp -L "${TESTBENCH_BINARY}" "${TESTBENCH}:${DOCKER_TESTBENCH_BINARY}"
@@ -245,7 +275,10 @@ if [[ -z "${TSHARK-}" ]]; then
# Run tcpdump in the test bench unbuffered, without dns resolution, just on
# the interface with the test packets.
docker exec -t "${TESTBENCH}" \
- tcpdump -S -vvv -U -n -i "${TEST_DEVICE}" net "${TEST_NET_PREFIX}/24" &
+ tcpdump -S -vvv -U -n -i "${TEST_DEVICE}" \
+ net "${TEST_NET_PREFIX}/24" or \
+ host "${REMOTE_IPV6}" or \
+ host "${LOCAL_IPV6}" &
else
# Run tshark in the test bench unbuffered, without dns resolution, just on the
# interface with the test packets.
@@ -253,7 +286,9 @@ else
tshark -V -l -n -i "${TEST_DEVICE}" \
-o tcp.check_checksum:TRUE \
-o udp.check_checksum:TRUE \
- host "${TEST_NET_PREFIX}${TESTBENCH_NET_SUFFIX}" &
+ net "${TEST_NET_PREFIX}/24" or \
+ host "${REMOTE_IPV6}" or \
+ host "${LOCAL_IPV6}" &
fi
# tcpdump and tshark take time to startup
@@ -272,6 +307,8 @@ docker exec \
--posix_server_port=${CTRL_PORT} \
--remote_ipv4=${TEST_NET_PREFIX}${DUT_NET_SUFFIX} \
--local_ipv4=${TEST_NET_PREFIX}${TESTBENCH_NET_SUFFIX} \
+ --remote_ipv6=${REMOTE_IPV6} \
+ --local_ipv6=${LOCAL_IPV6} \
--remote_mac=${REMOTE_MAC} \
--local_mac=${LOCAL_MAC} \
--device=${TEST_DEVICE}" && true