Add fibs_test:udp_dontroute6, another IPv6 multi-FIB test
PR: 196361 MFC after: 3 weeks Sponsored by: Spectra Logic Corp
This commit is contained in:
parent
beaa6e1e64
commit
9d6c66cb9f
@ -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()
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user