Subject: bin/12802: mount_nfs forces ipv6 if interface is capable
To: None <gnats-bugs@gnats.netbsd.org>
From: None <adam@algroup.co.uk>
List: netbsd-bugs
Date: 05/01/2001 12:28:00
>Number:         12802
>Category:       bin
>Synopsis:       mount_nfs forces ipv6 if interface is capable
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 01 12:28:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Adam Laurie
>Release:        1.5
>Organization:
A.L. Digital Ltd.
>Environment:
NetBSD gnugget 1.5U NetBSD 1.5U (GNUGGET) #16: Mon Apr 30 15:52:55 BST 2001     root@gnugget:/usr/src/sys/arch/hpcmips/compile/GNUGGET hpcmips

>Description:
mount_nfs will choose ipv6 for the rpcbind request if the interface is 
capable. this will cause it to fail for services that are only registered 
for ipv4.
>How-To-Repeat:
build cfsd (with port 2049 option), run rpcbind, mountd and cfsd. 
you then get the following behaviour:

  gnugget-root# /sbin/mount -o intr,-2 localhost:/null /crypt
  mount_nfs: rpcbind on server: RPC: Program not registered

adding the option to specify ipv4 fixes it:

  gnugget-root# /sbin/mount -o intr,-2,-4 localhost:/null /crypt
  gnugget-root# 

>Fix:
apply the following patch:

--- sbin/mount_nfs/mount_nfs.c.orig     Mon Apr 30 14:38:55 2001
+++ sbin/mount_nfs/mount_nfs.c  Mon Apr 30 14:46:27 2001
@@ -168,6 +168,7 @@
 int nfsproto = IPPROTO_UDP;
 int force2 = 0;
 int force3 = 0;
+int inet4 = 0;
 int mnttcp_ok = 1;
 
 #ifdef NFSKERB
@@ -237,7 +238,7 @@
        nfsargs = nfsdefargs;
        nfsargsp = &nfsargs;
        while ((c = getopt(argc, argv,
-           "23a:bcCdD:g:I:iKL:lm:o:PpqR:r:sTt:w:x:UX")) != -1)
+           "234a:bcCdD:g:I:iKL:lm:o:PpqR:r:sTt:w:x:UX")) != -1)
                switch (c) {
                case '3':
                        if (force2)
@@ -250,6 +251,9 @@
                        force2 = 1;
                        nfsargsp->flags &= ~NFSMNT_NFSV3;
                        break;
+               case '4':
+                       inet4 = 1;
+                       break;
                case 'a':
                        num = strtol(optarg, &p, 10);
                        if (*p || num < 0)
@@ -672,12 +676,12 @@
         * __rpc_*2nconf exist, maybe they should be exported.
         */
        if (nfsargsp->sotype == SOCK_STREAM) {
-               if (ai->ai_family == AF_INET6)  
+               if (ai->ai_family == AF_INET6 && ! inet4)       
                        netid = "tcp6";
                else
                        netid = "tcp";
        } else {
-               if (ai->ai_family == AF_INET6)
+               if (ai->ai_family == AF_INET6 && ! inet4)
                        netid = "udp6";
                else
                        netid = "udp";
@@ -857,7 +861,7 @@
 usage()
 {
        (void)fprintf(stderr, "usage: mount_nfs %s\n%s\n%s\n%s\n%s\n",
-"[-23bcCdiKlpPqsTUX] [-a maxreadahead] [-D deadthresh]",
+"[-234bcCdiKlpPqsTUX] [-a maxreadahead] [-D deadthresh]",
 "\t[-g maxgroups] [-I readdirsize] [-L leaseterm] [-m realm]",
 "\t[-o options] [-R retrycnt] [-r readsize] [-t timeout]",
 "\t[-w writesize] [-x retrans]",
--- sbin/mount_nfs/mount_nfs.8.orig     Mon Apr 30 15:36:52 2001
+++ sbin/mount_nfs/mount_nfs.8  Mon Apr 30 15:36:58 2001
@@ -42,7 +42,7 @@
 .Sh SYNOPSIS
 .Nm ""
 .Bk -words
-.Op Fl 23KPTUbcCdilqs
+.Op Fl 234KPTUbcCdilqs
 .Ek
 .Bk -words
 .Op Fl D Ar deadthresh
@@ -103,6 +103,8 @@
 .It Fl 3
 Use the NFS Version 3 protocol. The default is to try version 3 first, and
 fall back to version 2 if the mount fails.
+.It Fl 4
+Use IPv4 transport. The default is to use IPv6 if the interface supports it.
 .It Fl D
 Used with NQNFS to set the
 .Dq "dead server threshold"

>Release-Note:
>Audit-Trail:
>Unformatted: