getport: Recognize "rdma" and "rdma6" netid
authorChuck Lever <chuck.lever@oracle.com>
Wed, 8 Sep 2010 17:25:56 +0000 (13:25 -0400)
committerSteve Dickson <steved@redhat.com>
Thu, 9 Sep 2010 14:38:47 +0000 (10:38 -0400)
The mount.nfs command must recognize the values of "rdma" and "rdma6"
with the "proto=" mount option.  Typically the mount.nfs command
relies on libtirpc or getprotobyname(3) to recognize netids and
translate them to protocol numbers.

RFCs 5665 and 5666 define the "rdma" and "rdma6" netids.  IANA defines
a specific port number for NFS over RDMA (20049), but has not provided
a protocol name and number for RDMA transports, and is not expected
to.  The best we can do is translate these by hand, as needed, to get
RDMA mount requests to the kernel without erroring out.

Only the forward translation is needed until such time that "rdma" and
"rdma6" start to appear in rpcbind registries.  For now, the version
and transport negotiation logic is skipped, avoiding rpcbind queries
for RDMA mounts.

Note: As of kernel 2.6.36, the kernel's NFS over RDMA transport
capability does not support IPv6.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
support/include/nfsrpc.h
support/nfs/getport.c

index 6ebefca..d50fe94 100644 (file)
 #include <rpc/clnt.h>
 
 /*
+ * IANA does not define an IP protocol number for RDMA transports.
+ * Choose an arbitrary value we can use locally.
+ */
+#define NFSPROTO_RDMA          (3939)
+
+/*
  * Conventional RPC program numbers
  */
 #ifndef RPCBPROG
index c930539..d74400b 100644 (file)
@@ -216,6 +216,21 @@ nfs_get_proto(const char *netid, sa_family_t *family, unsigned long *protocol)
        struct netconfig *nconf;
        struct protoent *proto;
 
+       /*
+        * IANA does not define a protocol number for rdma netids,
+        * since "rdma" is not an IP protocol.
+        */
+       if (strcmp(netid, "rdma") == 0) {
+               *family = AF_INET;
+               *protocol = NFSPROTO_RDMA;
+               return 1;
+       }
+       if (strcmp(netid, "rdma6") == 0) {
+               *family = AF_INET6;
+               *protocol = NFSPROTO_RDMA;
+               return 1;
+       }
+
        nconf = getnetconfigent(netid);
        if (nconf == NULL)
                return 0;
@@ -242,6 +257,16 @@ nfs_get_proto(const char *netid, sa_family_t *family, unsigned long *protocol)
 {
        struct protoent *proto;
 
+       /*
+        * IANA does not define a protocol number for rdma netids,
+        * since "rdma" is not an IP protocol.
+        */
+       if (strcmp(netid, "rdma") == 0) {
+               *family = AF_INET;
+               *protocol = NFSPROTO_RDMA;
+               return 1;
+       }
+
        proto = getprotobyname(netid);
        if (proto == NULL)
                return 0;