diff options
author | asomers <asomers@FreeBSD.org> | 2014-03-25 15:03:08 +0000 |
---|---|---|
committer | asomers <asomers@FreeBSD.org> | 2014-03-25 15:03:08 +0000 |
commit | 23f37cb12351d3087ba1a331e42732f390a8af55 (patch) | |
tree | 24c5d7325178b75c2d94721e3339df17f85547b5 /tests | |
parent | ae82763de4683ce610990c6d07ce39f518dd8505 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'tests')
-rw-r--r-- | tests/sys/netinet/Makefile | 5 | ||||
-rwxr-xr-x | tests/sys/netinet/fibs_test.sh | 57 | ||||
-rw-r--r-- | tests/sys/netinet/udp_dontroute.c | 85 |
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); -} |