svn commit: r313395 - head/tests/sys/netinet

Alan Somers asomers at FreeBSD.org
Tue Feb 7 17:41:00 UTC 2017


Author: asomers
Date: Tue Feb  7 17:40:59 2017
New Revision: 313395
URL: https://svnweb.freebsd.org/changeset/base/313395

Log:
  Add fibs_test:udp_dontroute6, another IPv6 multi-FIB test
  
  PR:		196361
  MFC after:	3 weeks
  Sponsored by:	Spectra Logic Corp

Modified:
  head/tests/sys/netinet/fibs_test.sh
  head/tests/sys/netinet/udp_dontroute.c

Modified: head/tests/sys/netinet/fibs_test.sh
==============================================================================
--- head/tests/sys/netinet/fibs_test.sh	Tue Feb  7 17:31:24 2017	(r313394)
+++ head/tests/sys/netinet/fibs_test.sh	Tue Feb  7 17:40:59 2017	(r313395)
@@ -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()

Modified: head/tests/sys/netinet/udp_dontroute.c
==============================================================================
--- head/tests/sys/netinet/udp_dontroute.c	Tue Feb  7 17:31:24 2017	(r313394)
+++ head/tests/sys/netinet/udp_dontroute.c	Tue Feb  7 17:40:59 2017	(r313395)
@@ -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];
-
-	if (argc != 3) {
-		fprintf(stderr, "Usage: %s ip_address tapdev\n", argv[0]);
+	bool v6 = false;
+	const char *addr, *tapdev;
+	const uint16_t port = 46120;
+
+	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");
 


More information about the svn-src-all mailing list