kern/187553: Source address selection for UDP packets with SO_DONTROUTE uses the default FIB

Alan Somers asomers at freebsd.org
Thu Mar 13 20:10:02 UTC 2014


>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:    freebsd-bugs
>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:
>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 at 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:
>Unformatted:


More information about the freebsd-bugs mailing list