aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAlan Somers <asomers@FreeBSD.org>2017-02-07 17:40:59 +0000
committerAlan Somers <asomers@FreeBSD.org>2017-02-07 17:40:59 +0000
commit9d6c66cb9f119b51a828777810cb1ffff0d68fab (patch)
tree51dc67c20e79f8e2b4627466840ff9bee2f38ef8 /tests
parentbeaa6e1e6486684141b98ed9115ffda0b8920423 (diff)
downloadsrc-9d6c66cb9f119b51a828777810cb1ffff0d68fab.tar.gz
src-9d6c66cb9f119b51a828777810cb1ffff0d68fab.zip
Add fibs_test:udp_dontroute6, another IPv6 multi-FIB test
PR: 196361 MFC after: 3 weeks Sponsored by: Spectra Logic Corp
Notes
Notes: svn path=/head/; revision=313395
Diffstat (limited to 'tests')
-rwxr-xr-xtests/sys/netinet/fibs_test.sh62
-rw-r--r--tests/sys/netinet/udp_dontroute.c53
2 files changed, 100 insertions, 15 deletions
diff --git a/tests/sys/netinet/fibs_test.sh b/tests/sys/netinet/fibs_test.sh
index bf5a54b451a2..16213071baff 100755
--- a/tests/sys/netinet/fibs_test.sh
+++ b/tests/sys/netinet/fibs_test.sh
@@ -595,6 +595,61 @@ udp_dontroute_cleanup()
cleanup_tap
}
+atf_test_case udp_dontroute6 cleanup
+udp_dontroute6_head()
+{
+ atf_set "descr" "Source address selection for UDP IPv6 packets with SO_DONTROUTE on non-default FIBs works"
+ atf_set "require.user" "root"
+ atf_set "require.config" "fibs"
+}
+
+udp_dontroute6_body()
+{
+ # Configure the TAP interface to use an RFC3849 nonrouteable address
+ # and a non-default fib
+ ADDR0="2001:db8::2"
+ ADDR1="2001:db8::3"
+ SUBNET="2001:db8::"
+ MASK="64"
+ # Use a different IP on the same subnet as the target
+ TARGET="2001:db8::100"
+ SRCDIR=`atf_get_srcdir`
+
+ atf_expect_fail "PR196361 IPv6 network routes don't respect net.add_addr_allfibs=0"
+
+ # 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 2
+
+ # Configure the TAP interfaces. Use no_dad so the addresses will be
+ # ready right away and won't be marked as tentative until DAD
+ # completes.
+ setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad
+ TARGET_TAP=${TAP}
+ setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad
+
+ # Send a UDP packet with SO_DONTROUTE. In the failure case, it will
+ # return ENETUNREACH, or send the packet to the wrong tap
+ atf_check -o ignore setfib ${FIB0} \
+ ${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP}
+ cleanup_tap
+
+ # Repeat, but this time target the other tap
+ setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad
+ setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad
+ TARGET_TAP=${TAP}
+
+ atf_check -o ignore setfib ${FIB1} \
+ ${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP}
+}
+
+udp_dontroute6_cleanup()
+{
+ cleanup_tap
+}
+
atf_init_test_cases()
{
@@ -609,6 +664,7 @@ atf_init_test_cases()
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6
atf_add_test_case udp_dontroute
+ atf_add_test_case udp_dontroute6
}
# Looks up one or more fibs from the configuration data and validates them.
@@ -656,6 +712,7 @@ get_tap()
# Protocol (inet or inet6)
# IP address
# Netmask in number of bits (eg 24 or 8)
+# Extra flags
# Return: the tap interface name as the env variable TAP
setup_tap()
{
@@ -663,9 +720,10 @@ setup_tap()
local PROTO=$2
local ADDR=$3
local MASK=$4
+ local FLAGS=$5
get_tap
- echo setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB
- setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB
+ echo setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB $FLAGS
+ setfib ${FIB} ifconfig $TAP ${PROTO} ${ADDR}/${MASK} fib $FIB $FLAGS
}
cleanup_tap()
diff --git a/tests/sys/netinet/udp_dontroute.c b/tests/sys/netinet/udp_dontroute.c
index 79421fd0b707..24e3fc4166aa 100644
--- a/tests/sys/netinet/udp_dontroute.c
+++ b/tests/sys/netinet/udp_dontroute.c
@@ -41,6 +41,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -52,7 +53,7 @@
int
main(int argc, char **argv)
{
- struct sockaddr_in dst;
+ struct sockaddr_storage dst;
int s, t;
int opt;
int ret;
@@ -60,17 +61,33 @@ main(int argc, char **argv)
const char* sendbuf = "Hello, World!";
const size_t buflen = 80;
char recvbuf[buflen];
+ bool v6 = false;
+ const char *addr, *tapdev;
+ const uint16_t port = 46120;
- if (argc != 3) {
- fprintf(stderr, "Usage: %s ip_address tapdev\n", argv[0]);
+ bzero(&dst, sizeof(dst));
+ if (argc < 3 || argc > 4) {
+ fprintf(stderr, "Usage: %s [-6] ip_address tapdev\n", argv[0]);
exit(2);
}
- t = open(argv[2], O_RDWR | O_NONBLOCK);
+ if (strcmp("-6", argv[1]) == 0) {
+ v6 = true;
+ addr = argv[2];
+ tapdev = argv[3];
+ } else {
+ addr = argv[1];
+ tapdev = argv[2];
+ }
+
+ t = open(tapdev, O_RDWR | O_NONBLOCK);
if (t < 0)
err(EXIT_FAILURE, "open");
- s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (v6)
+ s = socket(PF_INET6, SOCK_DGRAM, 0);
+ else
+ s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0)
err(EXIT_FAILURE, "socket");
opt = 1;
@@ -79,16 +96,26 @@ main(int argc, char **argv)
if (ret == -1)
err(EXIT_FAILURE, "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);
+ if (v6) {
+ struct sockaddr_in6 *dst6 = ((struct sockaddr_in6*)&dst);
+
+ dst.ss_len = sizeof(struct sockaddr_in6);
+ dst.ss_family = AF_INET6;
+ dst6->sin6_port = htons(port);
+ ret = inet_pton(AF_INET6, addr, &dst6->sin6_addr);
+ } else {
+ struct sockaddr_in *dst4 = ((struct sockaddr_in*)&dst);
+
+ dst.ss_len = sizeof(struct sockaddr_in);
+ dst.ss_family = AF_INET;
+ dst4->sin_port = htons(port);
+ ret = inet_pton(AF_INET, addr, &dst4->sin_addr);
}
+ if (ret != 1)
+ err(EXIT_FAILURE, "inet_pton returned %d", ret);
+
ret = sendto(s, sendbuf, strlen(sendbuf), 0, (struct sockaddr*)&dst,
- dst.sin_len);
+ dst.ss_len);
if (ret == -1)
err(EXIT_FAILURE, "sendto");