>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     
[email protected]:/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:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to