NetBSD Problem Report #53166

From www@NetBSD.org  Sun Apr  8 00:41:13 2018
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 9CDF97A182
	for <gnats-bugs@gnats.NetBSD.org>; Sun,  8 Apr 2018 00:41:13 +0000 (UTC)
Message-Id: <20180408004112.16E7D7A202@mollari.NetBSD.org>
Date: Sun,  8 Apr 2018 00:41:12 +0000 (UTC)
From: thorpej@me.com
Reply-To: thorpej@me.com
To: gnats-bugs@NetBSD.org
Subject: NFS default to UDP; it should really default to TCP
X-Send-Pr-Version: www-1.0

>Number:         53166
>Category:       kern
>Synopsis:       NFS default to UDP; it should really default to TCP
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    thorpej
>State:          closed
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Apr 08 00:45:00 +0000 2018
>Closed-Date:    Thu May 17 02:39:09 +0000 2018
>Last-Modified:  Thu May 17 02:39:09 +0000 2018
>Originator:     Jason Thorpe
>Release:        NetBSD 8.99.12
>Organization:
>Environment:
NetBSD nixie-dev 8.99.12 NetBSD 8.99.12 (thorpej-RPI-NixieClock) #1: Fri Apr  6 12:34:23 PDT 2018  thorpej@BigMac.local:/Volumes/Data0/Users/thorpej/hack/NetBSD/current/src/sys/arch/evbarm/compile/thorpej-RPI-NixieClock evbarm

>Description:
NFS defaults to using UDP as a transport.  It really should default to using TCP.  There's really no reason to default to UDP anymore (servers that don't properly support TCP are ancient, at this point).
>How-To-Repeat:
Mount an NFS file system and observe the connection on the wire.
>Fix:
Index: sys/nfs/files.nfs
===================================================================
RCS file: /cvsroot/src/sys/nfs/files.nfs,v
retrieving revision 1.14
diff -u -p -r1.14 files.nfs
--- sys/nfs/files.nfs   11 Oct 2014 06:42:20 -0000      1.14
+++ sys/nfs/files.nfs   8 Apr 2018 00:24:12 -0000
@@ -3,7 +3,7 @@
 deffs                          NFS

 defflag opt_nfs_boot.h         NFS_BOOT_BOOTP NFS_BOOT_BOOTPARAM NFS_BOOT_DHCP
-                               NFS_BOOT_GATEWAY NFS_BOOT_TCP
+                               NFS_BOOT_GATEWAY NFS_BOOT_TCP NFS_BOOT_UDP
                                NFS_BOOT_BOOTSTATIC

 defparam opt_nfs_boot.h                NFS_BOOT_BOOTP_REQFILE NFS_BOOT_OPTIONS
Index: sys/nfs/nfs_boot.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_boot.c,v
retrieving revision 1.87
diff -u -p -r1.87 nfs_boot.c
--- sys/nfs/nfs_boot.c  15 Nov 2016 01:50:06 -0000      1.87
+++ sys/nfs/nfs_boot.c  8 Apr 2018 00:24:12 -0000
@@ -43,6 +43,10 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_boot.c,v
 #include "opt_nfs_boot.h"
 #endif

+#ifdef NFS_BOOT_TCP
+#undef NFS_BOOT_UDP
+#endif
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -597,10 +601,10 @@ nfs_boot_getfh(struct nfs_dlmount *ndm, 
        memset((void *) args, 0, sizeof(*args));
        args->addr     = &ndm->ndm_saddr;
        args->addrlen  = args->addr->sa_len;
-#ifdef NFS_BOOT_TCP
-       args->sotype   = SOCK_STREAM;
-#else
+#ifdef NFS_BOOT_UDP
        args->sotype   = SOCK_DGRAM;
+#else
+       args->sotype   = SOCK_STREAM;
 #endif
        args->fh       = ndm->ndm_fh;
        args->hostname = ndm->ndm_host;
Index: sbin/mount_nfs/mount_nfs.8
===================================================================
RCS file: /cvsroot/src/sbin/mount_nfs/mount_nfs.8,v
retrieving revision 1.46
diff -u -p -r1.46 mount_nfs.8
--- sbin/mount_nfs/mount_nfs.8  3 Jul 2017 21:33:41 -0000       1.46
+++ sbin/mount_nfs/mount_nfs.8  8 Apr 2018 00:24:12 -0000
@@ -37,7 +37,7 @@
 .Nd mount NFS file systems
 .Sh SYNOPSIS
 .Nm
-.Op Fl 23bCcdilPpqsTUX
+.Op Fl 23bCcdilPpqsTUuX
 .Op Fl a Ar maxreadahead
 .Op Fl D Ar deadthresh
 .Op Fl g Ar maxgroups
@@ -241,6 +241,9 @@ Same as
 .It Cm tcp
 Same as
 .Fl T .
+.It Cm udp
+Same as
+.Fl u .
 .It Cm timeo Ns = Ns Aq Ar timeout
 Same as
 .Fl t Ar timeout .
@@ -294,11 +297,8 @@ Use
 .Tn TCP
 transport instead of
 .Tn UDP .
-This is recommended for servers that are not on the same physical network as
-the client.
-Not all
-.Tn NFS
-servers, especially not old ones, support this.
+This is the default;
+the flag is maintained for backwards compatibility.
 .It Fl t Ar timeout
 Set the initial retransmit timeout to the specified value in 0.1 seconds.
 May be useful for fine tuning
@@ -323,6 +323,12 @@ mounts.
 This is necessary for some old
 .Bx
 servers.
+.It Fl u
+Use
+.Tn UDP
+transport instead of
+.Tn TCP .
+This may be necessary for some very old servers.
 .It Fl w Ar writesize
 Set the write data size to the specified value in bytes.
 .Pp
Index: sbin/mount_nfs/mount_nfs.c
===================================================================
RCS file: /cvsroot/src/sbin/mount_nfs/mount_nfs.c,v
retrieving revision 1.71
diff -u -p -r1.71 mount_nfs.c
--- sbin/mount_nfs/mount_nfs.c  29 Jun 2013 22:56:26 -0000      1.71
+++ sbin/mount_nfs/mount_nfs.c  8 Apr 2018 00:24:12 -0000
@@ -98,6 +98,7 @@ __RCSID("$NetBSD: mount_nfs.c,v 1.71 201
 #define ALTF_DEADTHRESH        0x00200000
 #define ALTF_TIMEO     0x00400000
 #define ALTF_RETRANS   0x00800000
+#define ALTF_UDP       0x01000000

 static const struct mntopt mopts[] = {
        MOPT_STDOPTS,
@@ -115,6 +116,7 @@ static const struct mntopt mopts[] = {
        { "nqnfs", 0, ALTF_NQNFS, 1 },
        { "soft", 0, ALTF_SOFT, 1 },
        { "tcp", 0, ALTF_TCP, 1 },
+       { "udp", 0, ALTF_UDP, 1 },
        { "nfsv2", 0, ALTF_NFSV2, 1 },
        { "port", 0, ALTF_PORT, 1 },
        { "rsize", 0, ALTF_RSIZE, 1 },
@@ -133,7 +135,7 @@ struct nfs_args nfsdefargs = {
        .version = NFS_ARGSVERSION,
        .addr = NULL,
        .addrlen = sizeof(struct sockaddr_in),
-       .sotype = SOCK_DGRAM,
+       .sotype = SOCK_STREAM,
        .proto = 0,
        .fh = NULL,
        .fhsize = 0,
@@ -201,7 +203,7 @@ mount_nfs_parseargs(int argc, char *argv
        memset(nfsargsp, 0, sizeof(*nfsargsp));
        *nfsargsp = nfsdefargs;
        while ((c = getopt(argc, argv,
-           "23a:bcCdD:g:I:iKL:lm:o:PpqR:r:sTt:w:x:UX")) != -1)
+           "23a:bcCdD:g:I:iKL:lm:o:PpqR:r:sTt:w:x:UuX")) != -1)
                switch (c) {
                case '3':
                case 'q':
@@ -298,6 +300,13 @@ mount_nfs_parseargs(int argc, char *argv
                                nfsargsp->flags &= ~NFSMNT_RESVPORT;
                        if (altflags & ALTF_SOFT)
                                nfsargsp->flags |= NFSMNT_SOFT;
+                       if (altflags & ALTF_UDP) {
+                               nfsargsp->sotype = SOCK_DGRAM;
+                       }
+                       /*
+                        * After UDP, because TCP overrides if both
+                        * are present.
+                        */
                        if (altflags & ALTF_TCP) {
                                nfsargsp->sotype = SOCK_STREAM;
                        }
@@ -404,6 +413,9 @@ mount_nfs_parseargs(int argc, char *argv
                case 'X':
                        nfsargsp->flags |= NFSMNT_XLATECOOKIE;
                        break;
+               case 'u':
+                       nfsargsp->sotype = SOCK_DGRAM;
+                       break;
                case 'U':
                        mnttcp_ok = 0;
                        break;
@@ -500,7 +512,7 @@ static void
 usage(void)
 {
        (void)fprintf(stderr, "usage: %s %s\n%s\n%s\n%s\n%s\n", getprogname(),
-"[-23bCcdilPpqsTUX] [-a maxreadahead] [-D deadthresh]",
+"[-23bCcdilPpqsTUuX] [-a maxreadahead] [-D deadthresh]",
 "\t[-g maxgroups] [-I readdirsize] [-L leaseterm]",
 "\t[-o options] [-R retrycnt] [-r readsize] [-t timeout]",
 "\t[-w writesize] [-x retrans]",

>Release-Note:

>Audit-Trail:
From: Hauke Fath <hauke@Espresso.Rhein-Neckar.DE>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: kern/53166: NFS default to UDP; it should really default to TCP
Date: Sun, 8 Apr 2018 11:29:25 +0200

 On Sun,  8 Apr 2018 00:45:00 +0000 (UTC), thorpej@me.com wrote:
 > NFS defaults to using UDP as a transport.  It really should default=20
 > to using TCP.  There's really no reason to default to UDP anymore=20
 > (servers that don't properly support TCP are ancient, at this point).

 While I have no opinion on changing the default as long as udp=20
 transport is an option, I do want to point out that nfs over udp is a=20
 lot more robust when run through a stateful packet filter.=20

 With tcp, crash your router, and you'll have to walk up to and reboot=20
 all your clients.

 Cheerio,
 hauke

 --=20
 Hauke Fath                        <hauke@Espresso.Rhein-Neckar.DE>
 Ernst-Ludwig-Stra=DFe 15
 64625 Bensheim
 Germany

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/53166: NFS default to UDP; it should really default to TCP
Date: Sun, 8 Apr 2018 10:15:39 -0000 (UTC)

 hauke@Espresso.Rhein-Neckar.DE (Hauke Fath) writes:

 > With tcp, crash your router, and you'll have to walk up to and reboot=20
 > all your clients.

 Depends on the packet filter.

 Normally the packet filter rejects packets for unknown connections
 actively with a RST answer and the clients close their TCP sessions
 and reconnect.

 A filter that silently drops unknown packets on the other hand may
 require some timeout mechanism. NetBSD clients of course could be
 disconnected manually using tcpdrop.

 N.B. the boot code needs to support both protocols, and nowadays
 preferring TCP is the better choice.

 -- 
 -- 
                                 Michael van Elst
 Internet: mlelstv@serpens.de
                                 "A potential Snark may lurk in every tree."

From: christos@zoulas.com (Christos Zoulas)
To: Hauke Fath <hauke@Espresso.Rhein-Neckar.DE>, gnats-bugs@NetBSD.org
Cc: kern-bug-people@NetBSD.org, gnats-admin@NetBSD.org
Subject: Re: kern/53166: NFS default to UDP; it should really default to TCP
Date: Sun, 8 Apr 2018 10:04:13 -0400

 On Apr 8, 11:29am, hauke@Espresso.Rhein-Neckar.DE (Hauke Fath) wrote:
 -- Subject: Re: kern/53166: NFS default to UDP; it should really default to T

 | On Sun,  8 Apr 2018 00:45:00 +0000 (UTC), thorpej@me.com wrote:
 | > NFS defaults to using UDP as a transport.  It really should default=20
 | > to using TCP.  There's really no reason to default to UDP anymore=20
 | > (servers that don't properly support TCP are ancient, at this point).
 | 
 | While I have no opinion on changing the default as long as udp=20
 | transport is an option, I do want to point out that nfs over udp is a=20
 | lot more robust when run through a stateful packet filter.=20
 | 
 | With tcp, crash your router, and you'll have to walk up to and reboot=20
 | all your clients.

 Did this (the default change request) came up because you are trying to
 boot over wifi and it is lossy because of the fragmentation? Or there
 was another reason? I thought that the boot code has been changed to do
 rsize=wsize=1024 for that reason...

 christos

From: Jason Thorpe <thorpej@me.com>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: kern/53166: NFS default to UDP; it should really default to TCP
Date: Sun, 08 Apr 2018 08:00:25 -0700

 > On Apr 8, 2018, at 7:05 AM, Christos Zoulas <christos@zoulas.com> =
 wrote:
 >=20
 > Did this (the default change request) came up because you are trying =
 to
 > boot over wifi and it is lossy because of the fragmentation? Or there
 > was another reason? I thought that the boot code has been changed to =
 do
 > rsize=3Dwsize=3D1024 for that reason=E2=80=A6

 This particular system (an RPI) boots on local micro SD, but I=E2=80=99m =
 using an NFS export from my iMac to host pkgsrc, and a few other odds =
 and ends during development of the project the RPI will reside in.  I =
 noticed the NFS connection (over WiFi with urtwn) was slightly flaky, =
 and it was then I noticed that it was running over UDP.  Changing it to =
 TCP addressed the issue I was seeing (and Wireshark running on the =
 server shows the occasional dropped packet or duplicate ACK that TCP =
 quickly recovers from).

 Yes, I could just remember to use the mount option all the time, but I =
 thought the default should be more sensible because basically there=E2=80=99=
 s no reason to not use TCP these days.

 I only changed the sense of the NFS_BOOT_* option as a matter of =
 consistency.  I did not change the standalone NFS code because I think =
 the standalone code only supports UDP, and it indeed uses a really small =
 read size to avoid problems with fragmentation.

 =E2=80=94thorpej

Responsible-Changed-From-To: kern-bug-people->thorpej
Responsible-Changed-By: thorpej@NetBSD.org
Responsible-Changed-When: Mon, 30 Apr 2018 17:17:13 +0000
Responsible-Changed-Why:
I'll resolve this (which ever way is decided).


From: "Jason R Thorpe" <thorpej@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/53166 CVS commit: src
Date: Thu, 17 May 2018 02:34:32 +0000

 Module Name:	src
 Committed By:	thorpej
 Date:		Thu May 17 02:34:32 UTC 2018

 Modified Files:
 	src/sbin/mount_nfs: mount_nfs.8 mount_nfs.c
 	src/sys/nfs: files.nfs nfs_boot.c

 Log Message:
 Default NFS mounts to using TCP transport instead of UDP.
 PR kern/53166


 To generate a diff of this commit:
 cvs rdiff -u -r1.46 -r1.47 src/sbin/mount_nfs/mount_nfs.8
 cvs rdiff -u -r1.71 -r1.72 src/sbin/mount_nfs/mount_nfs.c
 cvs rdiff -u -r1.14 -r1.15 src/sys/nfs/files.nfs
 cvs rdiff -u -r1.87 -r1.88 src/sys/nfs/nfs_boot.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: thorpej@NetBSD.org
State-Changed-When: Thu, 17 May 2018 02:39:09 +0000
State-Changed-Why:
Change committed.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.