Date: Thu, 13 Mar 2014 20:02:57 GMT From: Alan Somers <asomers@freebsd.org> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/187553: Source address selection for UDP packets with SO_DONTROUTE uses the default FIB Message-ID: <201403132002.s2DK2vx6048727@cgiserv.freebsd.org> Resent-Message-ID: <201403132010.s2DKA1FY042537@freefall.freebsd.org>
index | next in thread | raw e-mail
>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@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:
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403132002.s2DK2vx6048727>
