# ping: SRC->[encap at veth2:ingress]->GRE:decap->DST
# ping replies go DST->SRC directly
-set -e # exit on error
-
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
echo "FAIL"
readonly IPv6_SRC=$IPv6_1
readonly IPv6_DST=$IPv6_4
-setup() {
-set -e # exit on error
+TEST_STATUS=0
+TESTS_SUCCEEDED=0
+TESTS_FAILED=0
+
+process_test_results()
+{
+ if [[ "${TEST_STATUS}" -eq 0 ]] ; then
+ echo "PASS"
+ TESTS_SUCCEEDED=$((TESTS_SUCCEEDED+1))
+ else
+ echo "FAIL"
+ TESTS_FAILED=$((TESTS_FAILED+1))
+ fi
+}
+
+print_test_summary_and_exit()
+{
+ echo "passed tests: ${TESTS_SUCCEEDED}"
+ echo "failed tests: ${TESTS_FAILED}"
+ if [ "${TESTS_FAILED}" -eq "0" ] ; then
+ exit 0
+ else
+ exit 1
+ fi
+}
+
+setup()
+{
+ set -e # exit on error
+ TEST_STATUS=0
+
# create devices and namespaces
ip netns add "${NS1}"
ip netns add "${NS2}"
# configure IPv4 GRE device in NS3, and a route to it via the "bottom" route
ip -netns ${NS3} tunnel add gre_dev mode gre remote ${IPv4_1} local ${IPv4_GRE} ttl 255
ip -netns ${NS3} link set gre_dev up
- ip -netns ${NS3} addr add ${IPv4_GRE} dev gre_dev
+ ip -netns ${NS3} addr add ${IPv4_GRE} nodad dev gre_dev
ip -netns ${NS1} route add ${IPv4_GRE}/32 dev veth5 via ${IPv4_6}
ip -netns ${NS2} route add ${IPv4_GRE}/32 dev veth7 via ${IPv4_8}
ip netns exec ${NS1} sysctl -wq net.ipv4.conf.all.rp_filter=0
ip netns exec ${NS2} sysctl -wq net.ipv4.conf.all.rp_filter=0
ip netns exec ${NS3} sysctl -wq net.ipv4.conf.all.rp_filter=0
+
+ sleep 1 # reduce flakiness
+ set +e
}
-cleanup() {
+cleanup()
+{
ip netns del ${NS1} 2> /dev/null
ip netns del ${NS2} 2> /dev/null
ip netns del ${NS3} 2> /dev/null
trap cleanup EXIT
-test_ping() {
+remove_routes_to_gredev()
+{
+ ip -netns ${NS1} route del ${IPv4_GRE} dev veth5
+ ip -netns ${NS2} route del ${IPv4_GRE} dev veth7
+ ip -netns ${NS1} -6 route del ${IPv6_GRE}/128 dev veth5
+ ip -netns ${NS2} -6 route del ${IPv6_GRE}/128 dev veth7
+}
+
+add_unreachable_routes_to_gredev()
+{
+ ip -netns ${NS1} route add unreachable ${IPv4_GRE}/32
+ ip -netns ${NS2} route add unreachable ${IPv4_GRE}/32
+ ip -netns ${NS1} -6 route add unreachable ${IPv6_GRE}/128
+ ip -netns ${NS2} -6 route add unreachable ${IPv6_GRE}/128
+}
+
+test_ping()
+{
local readonly PROTO=$1
local readonly EXPECTED=$2
local RET=0
- set +e
if [ "${PROTO}" == "IPv4" ] ; then
ip netns exec ${NS1} ping -c 1 -W 1 -I ${IPv4_SRC} ${IPv4_DST} 2>&1 > /dev/null
RET=$?
ip netns exec ${NS1} ping6 -c 1 -W 6 -I ${IPv6_SRC} ${IPv6_DST} 2>&1 > /dev/null
RET=$?
else
- echo "test_ping: unknown PROTO: ${PROTO}"
- exit 1
+ echo " test_ping: unknown PROTO: ${PROTO}"
+ TEST_STATUS=1
fi
- set -e
if [ "0" != "${RET}" ]; then
RET=1
fi
if [ "${EXPECTED}" != "${RET}" ] ; then
- echo "FAIL: test_ping: ${RET}"
- exit 1
+ echo " test_ping failed: expected: ${EXPECTED}; got ${RET}"
+ TEST_STATUS=1
fi
}
-test_egress() {
+test_egress()
+{
local readonly ENCAP=$1
echo "starting egress ${ENCAP} encap test"
setup
- # need to wait a bit for IPv6 to autoconf, otherwise
- # ping6 sometimes fails with "unable to bind to address"
-
# by default, pings work
test_ping IPv4 0
test_ping IPv6 0
ip -netns ${NS1} route add ${IPv4_DST} encap bpf xmit obj test_lwt_ip_encap.o sec encap_gre6 dev veth1
ip -netns ${NS1} -6 route add ${IPv6_DST} encap bpf xmit obj test_lwt_ip_encap.o sec encap_gre6 dev veth1
else
- echo "FAIL: unknown encap ${ENCAP}"
+ echo " unknown encap ${ENCAP}"
+ TEST_STATUS=1
fi
test_ping IPv4 0
test_ping IPv6 0
+ # a negative test: remove routes to GRE devices: ping fails
+ remove_routes_to_gredev
+ test_ping IPv4 1
+ test_ping IPv6 1
+
+ # another negative test
+ add_unreachable_routes_to_gredev
+ test_ping IPv4 1
+ test_ping IPv6 1
+
cleanup
- echo "PASS"
+ process_test_results
}
-test_ingress() {
+test_ingress()
+{
local readonly ENCAP=$1
echo "starting ingress ${ENCAP} encap test"
setup
test_ping IPv4 0
test_ping IPv6 0
+ # a negative test: remove routes to GRE devices: ping fails
+ remove_routes_to_gredev
+ test_ping IPv4 1
+ test_ping IPv6 1
+
+ # another negative test
+ add_unreachable_routes_to_gredev
+ test_ping IPv4 1
+ test_ping IPv6 1
+
cleanup
- echo "PASS"
+ process_test_results
}
test_egress IPv4
test_egress IPv6
-
test_ingress IPv4
test_ingress IPv6
-echo "all tests passed"
+print_test_summary_and_exit