summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasomers <asomers@FreeBSD.org>2014-03-25 15:03:08 +0000
committerasomers <asomers@FreeBSD.org>2014-03-25 15:03:08 +0000
commit23f37cb12351d3087ba1a331e42732f390a8af55 (patch)
tree24c5d7325178b75c2d94721e3339df17f85547b5
parentae82763de4683ce610990c6d07ce39f518dd8505 (diff)
downloadFreeBSD-src-23f37cb12351d3087ba1a331e42732f390a8af55.zip
FreeBSD-src-23f37cb12351d3087ba1a331e42732f390a8af55.tar.gz
tests/sys/netinet/Makefile
tests/sys/netinet/fibs.sh Replace fibs:udp_dontroute with fibs:src_addr_selection_by_subnet. The original test was poorly written; it was actually testing kern/167947 instead of the desired kern/187553. The root cause of the bug is that ifa_ifwithnet did not have a fib argument. The new test more directly targets that behavior. tests/sys/netinet/udp_dontroute.c Delete the auxilliary binary used by the old test PR: kern/187553 MFC after: 3 weeks Sponsored by: Spectra Logic Corporation
-rw-r--r--tests/sys/netinet/Makefile5
-rwxr-xr-xtests/sys/netinet/fibs_test.sh57
-rw-r--r--tests/sys/netinet/udp_dontroute.c85
3 files changed, 39 insertions, 108 deletions
diff --git a/tests/sys/netinet/Makefile b/tests/sys/netinet/Makefile
index aff1b42..6caf89c 100644
--- a/tests/sys/netinet/Makefile
+++ b/tests/sys/netinet/Makefile
@@ -1,12 +1,7 @@
# $FreeBSD$
TESTSDIR= ${TESTSBASE}/sys/netinet
-BINDIR= ${TESTSDIR}
ATF_TESTS_SH+= fibs_test
-PROG= udp_dontroute
-SRCS= udp_dontroute.c
-NO_MAN=
-WARNS?= 6
.include <bsd.test.mk>
diff --git a/tests/sys/netinet/fibs_test.sh b/tests/sys/netinet/fibs_test.sh
index 174a576..5b58f71 100755
--- a/tests/sys/netinet/fibs_test.sh
+++ b/tests/sys/netinet/fibs_test.sh
@@ -255,45 +255,66 @@ subnet_route_with_multiple_fibs_on_same_subnet_cleanup()
cleanup_tap
}
-# Test that source address selection works correctly for UDP packets with
-# SO_DONTROUTE set that are sent on non-default FIBs.
+# Regression test for kern/187553 "Source address selection for UDP packets
+# with SO_DONTROUTE uses the default FIB". The original complaint was that a
+# UDP packet with SO_DONTROUTE set would select a source address from an
+# interface on the default FIB instead of the process FIB.
# This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host"
# Regression test for kern/187553
-atf_test_case udp_dontroute cleanup
-udp_dontroute_head()
+
+# The root cause was that ifa_ifwithnet() did not have a fib argument. It
+# would return an address from an interface on any FIB that had a subnet route
+# for the destination. If more than one were available, it would choose the
+# most specific. The root cause is most easily tested by creating two
+# interfaces with overlapping subnet routes, adding a default route to the
+# interface with the less specific subnet route, and looking up a host that
+# requires the default route using the FIB of the interface with the less
+# specific subnet route. "route get" should provide a route that uses the
+# interface on the chosen FIB. However, absent the patch for this bug it will
+# instead use the other interface.
+atf_test_case src_addr_selection_by_subnet cleanup
+src_addr_selection_by_subnet_head()
{
atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works"
atf_set "require.user" "root"
atf_set "require.config" "fibs"
}
-udp_dontroute_body()
+src_addr_selection_by_subnet_body()
{
atf_expect_fail "kern/187553 Source address selection for UDP packets with SO_DONTROUTE uses the default FIB"
# Configure the TAP interface to use an RFC5737 nonrouteable address
# and a non-default fib
- ADDR="192.0.2.2"
+ ADDR0="192.0.2.2"
+ ADDR1="192.0.2.3"
+ GATEWAY0="192.0.2.1"
+ TARGET="192.0.2.128"
SUBNET="192.0.2.0"
- MASK="24"
- # Use a different IP on the same subnet as the target
- TARGET="192.0.2.100"
+ MASK0="25"
+ MASK1="26"
# Check system configuration
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
atf_skip "This test requires net.add_addr_allfibs=0"
fi
- get_fibs 1
+ get_fibs 2
# Configure a TAP interface
- setup_tap ${FIB0} ${ADDR} ${MASK}
-
- # Send a UDP packet with SO_DONTROUTE. In the failure case, it will
- # return ENETUNREACH
- SRCDIR=`atf_get_srcdir`
- atf_check -o ignore setfib ${FIB0} ${SRCDIR}/udp_dontroute ${TARGET}
+ setup_tap ${FIB0} ${ADDR0} ${MASK0}
+ TAP0=${TAP}
+ setup_tap ${FIB1} ${ADDR1} ${MASK1}
+ TAP1=${TAP}
+
+ # Add a gateway to the interface with the less specific subnet route
+ setfib ${FIB0} route add default ${GATEWAY0}
+
+ # Lookup a route
+ echo "Looking up route to ${TARGET} with fib ${FIB0}"
+ echo "Expected behavior is to use interface ${TAP0}"
+ atf_check -o match:"interface:.${TAP0}" setfib ${FIB0} route -n get ${TARGET}
}
-udp_dontroute_cleanup()
+src_addr_selection_by_subnet_cleanup()
{
cleanup_tap
}
@@ -305,7 +326,7 @@ atf_init_test_cases()
atf_add_test_case loopback_and_network_routes_on_nondefault_fib
atf_add_test_case default_route_with_multiple_fibs_on_same_subnet
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet
- atf_add_test_case udp_dontroute
+ atf_add_test_case src_addr_selection_by_subnet
}
# Looks up one or more fibs from the configuration data and validates them.
diff --git a/tests/sys/netinet/udp_dontroute.c b/tests/sys/netinet/udp_dontroute.c
deleted file mode 100644
index 6952f99..0000000
--- a/tests/sys/netinet/udp_dontroute.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2014 Spectra Logic Corporation
- * All rights reserved.
- *
- * 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,
- * without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- * substantially similar to the "NO WARRANTY" disclaimer below
- * ("Disclaimer") and any redistribution must be conditioned upon
- * including a substantially similar Disclaimer requirement for further
- * binary redistribution.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
- *
- * Authors: Alan Somers (Spectra Logic Corporation)
- *
- * $FreeBSD$
- */
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * Sends a single UDP packet to the provided address, with SO_DONTROUTE set
- * I couldn't find a way to do this with builtin utilities like nc(1)
- */
-int main(int argc, char **argv)
-{
- struct sockaddr_in dst;
- int s;
- int opt;
- int ret;
- const char* buf = "Hello, World!";
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s ip_address\n", argv[0]);
- exit(2);
- }
- s = socket(PF_INET, SOCK_DGRAM, 0);
- if (s < 0)
- err(errno, "socket");
- opt = 1;
-
- ret = setsockopt(s, SOL_SOCKET, SO_DONTROUTE, &opt, sizeof(opt));
- if (ret == -1)
- err(errno, "setsockopt(SO_DONTROUTE)");
-
- dst.sin_len = sizeof(dst);
- dst.sin_family = AF_INET;
- dst.sin_port = htons(46120);
- dst.sin_addr.s_addr = inet_addr(argv[1]);
- if (dst.sin_addr.s_addr == htonl(INADDR_NONE)) {
- fprintf(stderr, "Invalid address: %s\n", argv[1]);
- exit(2);
- }
- ret = sendto(s, buf, strlen(buf), 0, (struct sockaddr*)&dst,
- dst.sin_len);
- if (ret == -1)
- err(errno, "sendto");
-
- return (0);
-}
OpenPOWER on IntegriCloud