From nobody@FreeBSD.org  Thu Mar 13 20:02:57 2014
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1])
	(using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by hub.freebsd.org (Postfix) with ESMTPS id CBA00556
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 13 Mar 2014 20:02:57 +0000 (UTC)
Received: from cgiserv.freebsd.org (cgiserv.freebsd.org [IPv6:2001:1900:2254:206a::50:4])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by mx1.freebsd.org (Postfix) with ESMTPS id AB991985
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 13 Mar 2014 20:02:57 +0000 (UTC)
Received: from cgiserv.freebsd.org ([127.0.1.6])
	by cgiserv.freebsd.org (8.14.8/8.14.8) with ESMTP id s2DK2v6B048728
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 13 Mar 2014 20:02:57 GMT
	(envelope-from nobody@cgiserv.freebsd.org)
Received: (from nobody@localhost)
	by cgiserv.freebsd.org (8.14.8/8.14.8/Submit) id s2DK2vx6048727;
	Thu, 13 Mar 2014 20:02:57 GMT
	(envelope-from nobody)
Message-Id: <201403132002.s2DK2vx6048727@cgiserv.freebsd.org>
Date: Thu, 13 Mar 2014 20:02:57 GMT
From: Alan Somers <asomers@freebsd.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Source address selection for UDP packets with SO_DONTROUTE uses the default FIB
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         187553
>Category:       kern
>Synopsis:       Source address selection for UDP packets with SO_DONTROUTE uses the default FIB
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    asomers
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 13 20:10:01 UTC 2014
>Closed-Date:    
>Last-Modified:  Mon Apr 21 16:19:35 UTC 2014
>Originator:     Alan Somers
>Release:        11.0-CURRENT  r262867
>Organization:
Spectra Logic
>Environment:
FreeBSD alans-fbsd-head 11.0-CURRENT FreeBSD 11.0-CURRENT #39 r263109M: Thu Mar 13 11:31:56 MDT 2014     alans@ns1.eng.sldomain.com:/vmpool/obj/usr/home/alans/freebsd/head/sys/GENERIC  amd64
>Description:
I discovered that "setfib 1 netperf -t UDP_STREAM" would timeout.  On further inspection, I found that source address selection for UDP packets with SO_DONTROUTE set was always using the default FIB.  It should be using the process FIB instead.
>How-To-Repeat:
Configure two interfaces on different subnets with different fibs.  Try running netperf -t UDP_STREAM on a nondefault FIB.  I also have an ATF test case for this bug, but it requires a special C helper program to set SO_DONTROUTE.  I will post it as soon as I can.
>Fix:


Patch attached with submission follows:

--- //SpectraBSD/stable/sys/netinet/in_pcb.c	2013-07-19 20:54:44.000000000 -0600
+++ //SpectraBSD/stable/sys/netinet/in_pcb.c	2013-08-27 15:52:29.000000000 -0600
@@ -729,10 +729,10 @@
 		struct ifnet *ifp;
 
 		ia = ifatoia(ifa_ifwithdstaddr((struct sockaddr *)sin,
-		    RT_DEFAULT_FIB));
+		    curthread->td_proc->p_fibnum));
 		if (ia == NULL)
 			ia = ifatoia(ifa_ifwithnet((struct sockaddr *)sin, 0,
-			    RT_DEFAULT_FIB));
+			    curthread->td_proc->p_fibnum));
 		if (ia == NULL) {
 			error = ENETUNREACH;
 			goto done;
@@ -847,10 +847,11 @@
 		sain.sin_len = sizeof(struct sockaddr_in);
 		sain.sin_addr.s_addr = faddr->s_addr;
 
-		ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain), RT_DEFAULT_FIB));
+		ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain),
+		    	     curthread->td_proc->p_fibnum));
 		if (ia == NULL)
 			ia = ifatoia(ifa_ifwithnet(sintosa(&sain), 0,
-			    RT_DEFAULT_FIB));
+			    curthread->td_proc->p_fibnum));
 		if (ia == NULL)
 			ia = ifatoia(ifa_ifwithaddr(sintosa(&sain)));
 
--- //SpectraBSD/stable/sys/netinet/ip_output.c	2013-07-19 20:54:44.000000000 -0600
+++ //SpectraBSD/stable/sys/netinet/ip_output.c	2013-08-27 15:52:29.000000000 -0600
@@ -119,6 +119,7 @@
 	struct ip *ip;
 	struct ifnet *ifp = NULL;	/* keep compiler happy */
 	struct mbuf *m0;
+	int fib;
 	int hlen = sizeof (struct ip);
 	int mtu;
 	int n;	/* scratchpad */
@@ -226,10 +227,11 @@
 	 * interface is specified by the broadcast address of an interface,
 	 * or the destination address of a ptp interface.
 	 */
+	fib = curthread->td_proc->p_fibnum;
 	if (flags & IP_SENDONES) {
 		if ((ia = ifatoia(ifa_ifwithbroadaddr(sintosa(dst)))) == NULL &&
 		    (ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst),
-						    RT_DEFAULT_FIB))) == NULL) {
+		    				    fib))) == NULL) {
 			IPSTAT_INC(ips_noroute);
 			error = ENETUNREACH;
 			goto bad;
@@ -241,9 +243,9 @@
 		isbroadcast = 1;
 	} else if (flags & IP_ROUTETOIF) {
 		if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst),
-		    				    RT_DEFAULT_FIB))) == NULL &&
+		    				    fib))) == NULL &&
 		    (ia = ifatoia(ifa_ifwithnet(sintosa(dst), 0,
-		    				RT_DEFAULT_FIB))) == NULL) {
+						fib))) == NULL) {
 			IPSTAT_INC(ips_noroute);
 			error = ENETUNREACH;
 			goto bad;


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->asomers 
Responsible-Changed-By: asomers 
Responsible-Changed-When: Thu Mar 13 20:14:18 UTC 2014 
Responsible-Changed-Why:  
I'll take it.  I already have a patch 

http://www.freebsd.org/cgi/query-pr.cgi?pr=187553 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/187553: commit references a PR
Date: Thu, 20 Mar 2014 20:39:49 +0000 (UTC)

 Author: asomers
 Date: Thu Mar 20 20:39:41 2014
 New Revision: 263445
 URL: http://svnweb.freebsd.org/changeset/base/263445
 
 Log:
   Add several ATF tests that deal with multiple fibs.  They're described in
   several different PRs, but the tests share some common code, so I'm
   committing them together.
   
   sbin/ifconfig/tests
   sbin/ifconfig/tests/fibs_test.sh
   sbin/ifconfig/tests/Makefile
   sbin/ifconfig/Makefile
   	Add fibs_test.sh, which regresses bin/187551
   
   tests/sys/netinet
   tests/sys/netinet/fibs_test.sh
   tests/sys/netinet/udp_dontroute.c
   tests/sys/netinet/Makefile
   tests/sys/Makefile
   	Add fibs_test.sh, which regresses kern/167947, kern/187552
   	kern/187549, kern/187550, and kern/187553
   
   etc/mtree/BSD.tests.dist
   	Add newly created directories
   
   PR:		bin/187551
   PR:		kern/167947
   PR:		kern/187552
   PR:		kern/187549
   PR:		kern/187550
   PR:		kern/187553
   Discussed with:	melifaro
   MFC after:	3 weeks
   Sponsored by:	Spectra Logic Corporation
 
 Added:
   head/sbin/ifconfig/tests/
   head/sbin/ifconfig/tests/Makefile   (contents, props changed)
   head/sbin/ifconfig/tests/fibs_test.sh   (contents, props changed)
   head/tests/sys/netinet/
   head/tests/sys/netinet/Makefile   (contents, props changed)
   head/tests/sys/netinet/fibs_test.sh   (contents, props changed)
   head/tests/sys/netinet/udp_dontroute.c   (contents, props changed)
 Modified:
   head/etc/mtree/BSD.tests.dist
   head/sbin/ifconfig/Makefile
   head/tests/sys/Makefile
 
 Modified: head/etc/mtree/BSD.tests.dist
 ==============================================================================
 --- head/etc/mtree/BSD.tests.dist	Thu Mar 20 20:33:18 2014	(r263444)
 +++ head/etc/mtree/BSD.tests.dist	Thu Mar 20 20:39:41 2014	(r263445)
 @@ -75,6 +75,8 @@
              ..
              growfs
              ..
 +            ifconfig
 +            ..
              mdconfig
              ..
          ..
 @@ -91,6 +93,8 @@
          sys
              kern
              ..
 +            netinet
 +            ..
          ..
          usr.bin
              apply
 
 Modified: head/sbin/ifconfig/Makefile
 ==============================================================================
 --- head/sbin/ifconfig/Makefile	Thu Mar 20 20:33:18 2014	(r263444)
 +++ head/sbin/ifconfig/Makefile	Thu Mar 20 20:39:41 2014	(r263445)
 @@ -63,4 +63,8 @@ MAN=	ifconfig.8
  CFLAGS+= -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wnested-externs
  WARNS?=	2
  
 +.if ${MK_TESTS} != "no"
 +SUBDIR+=    tests
 +.endif
 +
  .include <bsd.prog.mk>
 
 Added: head/sbin/ifconfig/tests/Makefile
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/sbin/ifconfig/tests/Makefile	Thu Mar 20 20:39:41 2014	(r263445)
 @@ -0,0 +1,9 @@
 +# $FreeBSD$
 +
 +.include <bsd.own.mk>
 +
 +TESTSDIR=	${TESTSBASE}/sbin/ifconfig
 +
 +ATF_TESTS_SH=	fibs_test
 +
 +.include <bsd.test.mk>
 
 Added: head/sbin/ifconfig/tests/fibs_test.sh
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/sbin/ifconfig/tests/fibs_test.sh	Thu Mar 20 20:39:41 2014	(r263445)
 @@ -0,0 +1,126 @@
 +#
 +#  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$
 +
 +
 +# Regression test for bin/187551
 +atf_test_case process_fib cleanup
 +process_fib_head()
 +{
 +	atf_set "descr" "ifconfig will set its process fib whenever configuring an interface with nondefault fib"
 +	atf_set "require.user" "root"
 +	atf_set "require.config" "fibs"
 +}
 +process_fib_body()
 +{
 +	atf_expect_fail "bin/187551 ifconfig should change its process fib when configuring an interface with nondefault fib"
 +	# Configure the TAP interface to use an RFC5737 nonrouteable address
 +	# and a non-default fib
 +	ADDR="192.0.2.2"
 +	SUBNET="192.0.2.0"
 +	MASK="24"
 +
 +	# 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
 +
 +	# Configure a TAP interface
 +	get_tap
 +	ktrace ifconfig $TAP ${ADDR}/${MASK} fib $FIB0
 +	if kdump -s | egrep -q 'CALL[[:space:]]+setfib'; then
 +		atf_pass
 +	else
 +		atf_fail "ifconfig never called setfib(2)"
 +	fi
 +}
 +
 +process_fib_cleanup()
 +{
 +	cleanup_tap
 +}
 +
 +atf_init_test_cases()
 +{
 +	atf_add_test_case process_fib
 +}
 +
 +
 +# parameter numfibs	The number of fibs to lookup
 +get_fibs()
 +{
 +	NUMFIBS=$1
 +	net_fibs=`sysctl -n net.fibs`
 +	i=0
 +	while [ $i -lt "$NUMFIBS" ]; do
 +		fib=`atf_config_get "fibs" | \
 +			awk -v i=$(( i + 1 )) '{print $i}'`
 +		echo "fib is ${fib}"
 +		eval FIB${i}=${fib}
 +		if [ "$fib" -ge "$net_fibs" ]; then
 +			atf_skip "The ${i}th configured fib is ${fib}, which is not less than net.fibs, which is ${net_fibs}"
 +		fi
 +		i=$(( $i + 1 ))
 +	done
 +}
 +
 +
 +
 +# Creates a new tap(4) interface, registers it for cleanup, and returns the
 +# name via the environment variable TAP
 +get_tap()
 +{
 +	local TAPN=0
 +	while ! ifconfig tap${TAPN} create > /dev/null 2>&1; do
 +		if [ "$TAPN" -ge 8 ]; then
 +			atf_skip "Could not create a tap(4) interface"
 +		else
 +			TAPN=$(($TAPN + 1))
 +		fi
 +	done
 +	local TAPD=tap${TAPN}
 +	# Record the TAP device so we can clean it up later
 +	echo ${TAPD} >> "tap_devices_to_cleanup"
 +	TAP=${TAPD}
 +}
 +
 +
 +
 +
 +cleanup_tap()
 +{
 +	for TAPD in `cat "tap_devices_to_cleanup"`; do
 +		ifconfig ${TAPD} destroy
 +	done
 +}
 +
 
 Modified: head/tests/sys/Makefile
 ==============================================================================
 --- head/tests/sys/Makefile	Thu Mar 20 20:33:18 2014	(r263444)
 +++ head/tests/sys/Makefile	Thu Mar 20 20:39:41 2014	(r263445)
 @@ -5,6 +5,7 @@
  .PATH: ${.CURDIR}/..
  
  TESTS_SUBDIRS+=		kern
 +TESTS_SUBDIRS+=		netinet
  TESTSDIR= ${TESTSBASE}/sys
  
  KYUAFILE= yes
 
 Added: head/tests/sys/netinet/Makefile
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tests/sys/netinet/Makefile	Thu Mar 20 20:39:41 2014	(r263445)
 @@ -0,0 +1,12 @@
 +# $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>
 
 Added: head/tests/sys/netinet/fibs_test.sh
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tests/sys/netinet/fibs_test.sh	Thu Mar 20 20:39:41 2014	(r263445)
 @@ -0,0 +1,371 @@
 +#
 +#  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$
 +
 +# All of the tests in this file requires the test-suite config variable "fibs"
 +# to be defined to a space-delimited list of FIBs that may be used for testing.
 +
 +# arpresolve should check the interface fib for routes to a target when
 +# creating an ARP table entry.  This is a regression for kern/167947, where
 +# arpresolve only checked the default route.
 +#
 +# Outline:
 +# Create two tap(4) interfaces
 +# Simulate a crossover cable between them by using net/socat
 +# Use nping (from security/nmap) to send an ICMP echo request from one
 +# interface to the other, spoofing the source IP.  The source IP must be
 +# spoofed, or else it will already have an entry in the arp table. 
 +# Check whether an arp entry exists for the spoofed IP
 +atf_test_case arpresolve_checks_interface_fib cleanup
 +arpresolve_checks_interface_fib_head()
 +{
 +	atf_set "descr" "arpresolve should check the interface fib, not the default fib, for routes"
 +	atf_set "require.user" "root"
 +	atf_set "require.config" "fibs"
 +	atf_set "require.progs" "socat nping"
 +}
 +arpresolve_checks_interface_fib_body()
 +{
 +	atf_expect_fail "kern/167947 arpresolve checks only the default FIB for the interface route"
 +	# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
 +	# and a non-default fib
 +	ADDR0="192.0.2.2"
 +	ADDR1="192.0.2.3"
 +	SUBNET="192.0.2.0"
 +	# Due to bug TBD (regressed by multiple_fibs_on_same_subnet) we need
 +	# diffferent subnet masks, or FIB1 won't have a subnet route.
 +	MASK0="24"
 +	MASK1="25"
 +	# Spoof a MAC that is reserved per RFC7042
 +	SPOOF_ADDR="192.0.2.4"
 +	SPOOF_MAC="00:00:5E:00:53:00"
 +
 +	# 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 TAP interfaces
 +	setup_tap "$FIB0" ${ADDR0} ${MASK0}
 +	TAP0=$TAP
 +	setup_tap "$FIB1" ${ADDR1} ${MASK1}
 +	TAP1=$TAP
 +
 +	# Simulate a crossover cable
 +	socat /dev/${TAP0} /dev/${TAP1} &
 +	SOCAT_PID=$!
 +	echo ${SOCAT_PID} >> "processes_to_kill"
 +	
 +	# Send an ICMP echo request with a spoofed source IP
 +	setfib 2 nping -c 1 -e ${TAP0} -S ${SPOOF_ADDR} \
 +		--source-mac ${SPOOF_MAC} --icmp --icmp-type "echo-request" \
 +		--icmp-code 0 --icmp-id 0xdead --icmp-seq 1 --data 0xbeef \
 +		${ADDR1}
 +	# For informational and debugging purposes only, look for the
 +	# characteristic error message
 +	dmesg | grep "llinfo.*${SPOOF_ADDR}"
 +	# Check that the ARP entry exists
 +	atf_check -o match:"${SPOOF_ADDR}.*expires" setfib 3 arp ${SPOOF_ADDR}
 +}
 +arpresolve_checks_interface_fib_cleanup()
 +{
 +	for PID in `cat "processes_to_kill"`; do
 +		kill $PID
 +	done
 +	cleanup_tap
 +}
 +
 +
 +# Regression test for kern/187549
 +atf_test_case loopback_and_network_routes_on_nondefault_fib cleanup
 +loopback_and_network_routes_on_nondefault_fib_head()
 +{
 +	atf_set "descr" "When creating and deleting loopback routes, use the interface's fib"
 +	atf_set "require.user" "root"
 +	atf_set "require.config" "fibs"
 +}
 +
 +loopback_and_network_routes_on_nondefault_fib_body()
 +{
 +	atf_expect_fail "kern/187549 Host and network routes for a new interface appear in the wrong FIB"
 +	# Configure the TAP interface to use an RFC5737 nonrouteable address
 +	# and a non-default fib
 +	ADDR="192.0.2.2"
 +	SUBNET="192.0.2.0"
 +	MASK="24"
 +
 +	# 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
 +
 +	# Configure a TAP interface
 +	setup_tap ${FIB0} ${ADDR} ${MASK}
 +
 +	# Check whether the host route exists in only the correct FIB
 +	setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
 +	if [ 0 -ne $? ]; then
 +		setfib ${FIB0} netstat -rn -f inet
 +		atf_fail "Host route did not appear in the correct FIB"
 +	fi
 +	setfib 0 netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
 +	if [ 0 -eq $? ]; then
 +		setfib 0 netstat -rn -f inet
 +		atf_fail "Host route appeared in the wrong FIB"
 +	fi
 +
 +	# Check whether the network route exists in only the correct FIB
 +	setfib ${FIB0} netstat -rn -f inet | \
 +		grep -q "^${SUBNET}/${MASK}.*${TAPD}"
 +	if [ 0 -ne $? ]; then
 +		setfib ${FIB0} netstat -rn -f inet
 +		atf_fail "Network route did not appear in the correct FIB"
 +	fi
 +	setfib 0 netstat -rn -f inet | \
 +		grep -q "^${SUBNET}/${MASK}.*${TAPD}"
 +	if [ 0 -eq $? ]; then
 +		setfib ${FIB0} netstat -rn -f inet
 +		atf_fail "Network route appeared in the wrong FIB"
 +	fi
 +}
 +
 +loopback_and_network_routes_on_nondefault_fib_cleanup()
 +{
 +	cleanup_tap
 +}
 +
 +
 +# Regression test for kern/187552
 +atf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup
 +default_route_with_multiple_fibs_on_same_subnet_head()
 +{
 +	atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default routes"
 +	atf_set "require.user" "root"
 +	atf_set "require.config" "fibs"
 +}
 +
 +default_route_with_multiple_fibs_on_same_subnet_body()
 +{
 +	atf_expect_fail "kern/187552 default route uses the wrong interface when multiple interfaces have the same subnet but different fibs"
 +	# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
 +	# and a non-default fib
 +	ADDR0="192.0.2.2"
 +	ADDR1="192.0.2.3"
 +	GATEWAY="192.0.2.1"
 +	SUBNET="192.0.2.0"
 +	MASK="24"
 +
 +	# 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 TAP interfaces
 +	setup_tap "$FIB0" ${ADDR0} ${MASK}
 +	TAP0=$TAP
 +	setup_tap "$FIB1" ${ADDR1} ${MASK}
 +	TAP1=$TAP
 +
 +	# Attempt to add default routes
 +	setfib ${FIB0} route add default ${GATEWAY}
 +	setfib ${FIB1} route add default ${GATEWAY}
 +
 +	# Verify that the default route exists for both fibs, with their
 +	# respective interfaces.
 +	atf_check -o match:"^default.*${TAP0}$" \
 +		setfib ${FIB0} netstat -rn -f inet
 +	atf_check -o match:"^default.*${TAP1}$" \
 +		setfib ${FIB1} netstat -rn -f inet
 +}
 +
 +default_route_with_multiple_fibs_on_same_subnet_cleanup()
 +{
 +	cleanup_tap
 +}
 +
 +
 +# Regression test for kern/187550
 +atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup
 +subnet_route_with_multiple_fibs_on_same_subnet_head()
 +{
 +	atf_set "descr" "Multiple FIBs can have subnet routes for the same subnet"
 +	atf_set "require.user" "root"
 +	atf_set "require.config" "fibs"
 +}
 +
 +subnet_route_with_multiple_fibs_on_same_subnet_body()
 +{
 +	atf_expect_fail "kern/187550 Multiple interfaces on different FIBs but the same subnet don't all have a subnet route"
 +	# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
 +	# and a non-default fib
 +	ADDR0="192.0.2.2"
 +	ADDR1="192.0.2.3"
 +	SUBNET="192.0.2.0"
 +	MASK="24"
 +
 +	# 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 TAP interfaces
 +	setup_tap "$FIB0" ${ADDR0} ${MASK}
 +	setup_tap "$FIB1" ${ADDR1} ${MASK}
 +
 +	# Check that a subnet route exists on both fibs
 +	atf_check -o ignore setfib "$FIB0" route get $ADDR1
 +	atf_check -o ignore setfib "$FIB1" route get $ADDR0
 +}
 +
 +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.
 +# 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()
 +{
 +	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()
 +{
 +	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"
 +	SUBNET="192.0.2.0"
 +	MASK="24"
 +	# Use a different IP on the same subnet as the target
 +	TARGET="192.0.2.100"
 +
 +	# 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
 +
 +	# 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}
 +}
 +
 +udp_dontroute_cleanup()
 +{
 +	cleanup_tap
 +}
 +
 +
 +atf_init_test_cases()
 +{
 +	atf_add_test_case arpresolve_checks_interface_fib
 +	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
 +}
 +
 +# Looks up one or more fibs from the configuration data and validates them.
 +# Returns the results in the env varilables FIB0, FIB1, etc.
 +
 +# parameter numfibs	The number of fibs to lookup
 +get_fibs()
 +{
 +	NUMFIBS=$1
 +	net_fibs=`sysctl -n net.fibs`
 +	i=0
 +	while [ $i -lt "$NUMFIBS" ]; do
 +		fib=`atf_config_get "fibs" | \
 +			awk -v i=$(( i + 1 )) '{print $i}'`
 +		echo "fib is ${fib}"
 +		eval FIB${i}=${fib}
 +		if [ "$fib" -ge "$net_fibs" ]; then
 +			atf_skip "The ${i}th configured fib is ${fib}, which is not less than net.fibs, which is ${net_fibs}"
 +		fi
 +		i=$(( $i + 1 ))
 +	done
 +}
 +
 +# Creates a new tap(4) interface, registers it for cleanup, and returns the
 +# name via the environment variable TAP
 +get_tap()
 +{
 +	local TAPN=0
 +	while ! ifconfig tap${TAPN} create > /dev/null 2>&1; do
 +		if [ "$TAPN" -ge 8 ]; then
 +			atf_skip "Could not create a tap(4) interface"
 +		else
 +			TAPN=$(($TAPN + 1))
 +		fi
 +	done
 +	local TAPD=tap${TAPN}
 +	# Record the TAP device so we can clean it up later
 +	echo ${TAPD} >> "tap_devices_to_cleanup"
 +	TAP=${TAPD}
 +}
 +
 +# Create a tap(4) interface, configure it, and register it for cleanup.
 +# parameters:
 +# fib
 +# IP address
 +# Netmask in number of bits (eg 24 or 8)
 +# Return: the tap interface name as the env variable TAP
 +setup_tap()
 +{
 +	local FIB=$1
 +	local ADDR=$2
 +	local MASK=$3
 +	get_tap
 +	echo setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB
 +	setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB
 +}
 +
 +cleanup_tap()
 +{
 +	for TAPD in `cat "tap_devices_to_cleanup"`; do
 +		ifconfig ${TAPD} destroy
 +	done
 +}
 
 Added: head/tests/sys/netinet/udp_dontroute.c
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tests/sys/netinet/udp_dontroute.c	Thu Mar 20 20:39:41 2014	(r263445)
 @@ -0,0 +1,85 @@
 +/*
 + *  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);
 +}
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/187553: commit references a PR
Date: Tue, 25 Mar 2014 15:03:11 +0000 (UTC)

 Author: asomers
 Date: Tue Mar 25 15:03:08 2014
 New Revision: 263738
 URL: http://svnweb.freebsd.org/changeset/base/263738
 
 Log:
   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
 
 Deleted:
   head/tests/sys/netinet/udp_dontroute.c
 Modified:
   head/tests/sys/netinet/Makefile
   head/tests/sys/netinet/fibs_test.sh
 
 Modified: head/tests/sys/netinet/Makefile
 ==============================================================================
 --- head/tests/sys/netinet/Makefile	Tue Mar 25 13:41:55 2014	(r263737)
 +++ head/tests/sys/netinet/Makefile	Tue Mar 25 15:03:08 2014	(r263738)
 @@ -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>
 
 Modified: head/tests/sys/netinet/fibs_test.sh
 ==============================================================================
 --- head/tests/sys/netinet/fibs_test.sh	Tue Mar 25 13:41:55 2014	(r263737)
 +++ head/tests/sys/netinet/fibs_test.sh	Tue Mar 25 15:03:08 2014	(r263738)
 @@ -255,45 +255,66 @@ subnet_route_with_multiple_fibs_on_same_
  	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}
 +	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}
  
 -	# 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}
 +	# 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.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Sun Apr 20 22:05:39 UTC 2014 
State-Changed-Why:  
see kern/187549. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=187553 
State-Changed-From-To: closed->open 
State-Changed-By: asomers 
State-Changed-When: Mon Apr 21 16:19:34 UTC 2014 
State-Changed-Why:  
Actually, linimon, this is still open.  Commit 263445 merely added 
regression tests; it did not fix the bug. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=187553 
>Unformatted:
