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