SUNRPC: Use short-hand IPv6 ANYADDR for RPCB_SET
[safe/jmp/linux-2.6] / net / sunrpc / rpcb_clnt.c
index 21c698d..0fa1086 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/in6.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <net/ipv6.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/sched.h>
 #define RPCBIND_PROGRAM                (100000u)
 #define RPCBIND_PORT           (111u)
 
+#define RPCBVERS_2             (2u)
+#define RPCBVERS_3             (3u)
+#define RPCBVERS_4             (4u)
+
 enum {
        RPCBPROC_NULL,
        RPCBPROC_SET,
@@ -64,6 +69,7 @@ enum {
 #define RPCB_MAXOWNERLEN       sizeof(RPCB_OWNER_STRING)
 
 static void                    rpcb_getport_done(struct rpc_task *, void *);
+static void                    rpcb_map_release(void *data);
 static struct rpc_program      rpcb_program;
 
 struct rpcbind_args {
@@ -76,41 +82,73 @@ struct rpcbind_args {
        const char *            r_netid;
        const char *            r_addr;
        const char *            r_owner;
+
+       int                     r_status;
 };
 
 static struct rpc_procinfo rpcb_procedures2[];
 static struct rpc_procinfo rpcb_procedures3[];
+static struct rpc_procinfo rpcb_procedures4[];
 
 struct rpcb_info {
-       int                     rpc_vers;
+       u32                     rpc_vers;
        struct rpc_procinfo *   rpc_proc;
 };
 
 static struct rpcb_info rpcb_next_version[];
 static struct rpcb_info rpcb_next_version6[];
 
+static const struct rpc_call_ops rpcb_getport_ops = {
+       .rpc_call_done          = rpcb_getport_done,
+       .rpc_release            = rpcb_map_release,
+};
+
+static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
+{
+       xprt_clear_binding(xprt);
+       rpc_wake_up_status(&xprt->binding, status);
+}
+
 static void rpcb_map_release(void *data)
 {
        struct rpcbind_args *map = data;
 
+       rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
        xprt_put(map->r_xprt);
        kfree(map);
 }
 
-static const struct rpc_call_ops rpcb_getport_ops = {
-       .rpc_call_done          = rpcb_getport_done,
-       .rpc_release            = rpcb_map_release,
+static const struct sockaddr_in rpcb_inaddr_loopback = {
+       .sin_family             = AF_INET,
+       .sin_addr.s_addr        = htonl(INADDR_LOOPBACK),
+       .sin_port               = htons(RPCBIND_PORT),
 };
 
-static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
+static const struct sockaddr_in6 rpcb_in6addr_loopback = {
+       .sin6_family            = AF_INET6,
+       .sin6_addr              = IN6ADDR_LOOPBACK_INIT,
+       .sin6_port              = htons(RPCBIND_PORT),
+};
+
+static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
+                                         size_t addrlen, u32 version)
 {
-       xprt_clear_binding(xprt);
-       rpc_wake_up_status(&xprt->binding, status);
+       struct rpc_create_args args = {
+               .protocol       = XPRT_TRANSPORT_UDP,
+               .address        = addr,
+               .addrsize       = addrlen,
+               .servername     = "localhost",
+               .program        = &rpcb_program,
+               .version        = version,
+               .authflavor     = RPC_AUTH_UNIX,
+               .flags          = RPC_CLNT_CREATE_NOPING,
+       };
+
+       return rpc_create(&args);
 }
 
 static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
-                                   size_t salen, int proto, u32 version,
-                                   int privileged)
+                                   size_t salen, int proto, u32 version)
 {
        struct rpc_create_args args = {
                .protocol       = proto,
@@ -120,7 +158,8 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
                .program        = &rpcb_program,
                .version        = version,
                .authflavor     = RPC_AUTH_UNIX,
-               .flags          = RPC_CLNT_CREATE_NOPING,
+               .flags          = (RPC_CLNT_CREATE_NOPING |
+                                       RPC_CLNT_CREATE_NONPRIVPORT),
        };
 
        switch (srvaddr->sa_family) {
@@ -134,29 +173,73 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
                return NULL;
        }
 
-       if (!privileged)
-               args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
        return rpc_create(&args);
 }
 
+static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
+                             u32 version, struct rpc_message *msg)
+{
+       struct rpc_clnt *rpcb_clnt;
+       int result, error = 0;
+
+       msg->rpc_resp = &result;
+
+       rpcb_clnt = rpcb_create_local(addr, addrlen, version);
+       if (!IS_ERR(rpcb_clnt)) {
+               error = rpc_call_sync(rpcb_clnt, msg, 0);
+               rpc_shutdown_client(rpcb_clnt);
+       } else
+               error = PTR_ERR(rpcb_clnt);
+
+       if (error < 0) {
+               printk(KERN_WARNING "RPC: failed to contact local rpcbind "
+                               "server (errno %d).\n", -error);
+               return error;
+       }
+
+       if (!result) {
+               dprintk("RPC:       registration failed\n");
+               return -EACCES;
+       }
+
+       dprintk("RPC:       registration succeeded\n");
+       return 0;
+}
+
 /**
  * rpcb_register - set or unset a port registration with the local rpcbind svc
  * @prog: RPC program number to bind
  * @vers: RPC version number to bind
- * @prot: transport protocol to use to make this request
+ * @prot: transport protocol to register
  * @port: port value to register
- * @okay: result code
  *
- * port == 0 means unregister, port != 0 means register.
+ * Returns zero if the registration request was dispatched successfully
+ * and the rpcbind daemon returned success.  Otherwise, returns an errno
+ * value that reflects the nature of the error (request could not be
+ * dispatched, timed out, or rpcbind returned an error).
  *
- * This routine supports only rpcbind version 2.
+ * RPC services invoke this function to advertise their contact
+ * information via the system's rpcbind daemon.  RPC services
+ * invoke this function once for each [program, version, transport]
+ * tuple they wish to advertise.
+ *
+ * Callers may also unregister RPC services that are no longer
+ * available by setting the passed-in port to zero.  This removes
+ * all registered transports for [program, version] from the local
+ * rpcbind database.
+ *
+ * This function uses rpcbind protocol version 2 to contact the
+ * local rpcbind daemon.
+ *
+ * Registration works over both AF_INET and AF_INET6, and services
+ * registered via this function are advertised as available for any
+ * address.  If the local rpcbind daemon is listening on AF_INET6,
+ * services registered via this function will be advertised on
+ * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6
+ * addresses).
  */
-int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
+int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 {
-       struct sockaddr_in sin = {
-               .sin_family             = AF_INET,
-               .sin_addr.s_addr        = htonl(INADDR_LOOPBACK),
-       };
        struct rpcbind_args map = {
                .r_prog         = prog,
                .r_vers         = vers,
@@ -164,32 +247,152 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
                .r_port         = port,
        };
        struct rpc_message msg = {
-               .rpc_proc       = &rpcb_procedures2[port ?
-                                       RPCBPROC_SET : RPCBPROC_UNSET],
                .rpc_argp       = &map,
-               .rpc_resp       = okay,
        };
-       struct rpc_clnt *rpcb_clnt;
-       int error = 0;
 
        dprintk("RPC:       %sregistering (%u, %u, %d, %u) with local "
                        "rpcbind\n", (port ? "" : "un"),
                        prog, vers, prot, port);
 
-       rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin,
-                               sizeof(sin), XPRT_TRANSPORT_UDP, 2, 1);
-       if (IS_ERR(rpcb_clnt))
-               return PTR_ERR(rpcb_clnt);
+       msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
+       if (port)
+               msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
 
-       error = rpc_call_sync(rpcb_clnt, &msg, 0);
+       return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
+                                       sizeof(rpcb_inaddr_loopback),
+                                       RPCBVERS_2, &msg);
+}
 
-       rpc_shutdown_client(rpcb_clnt);
-       if (error < 0)
-               printk(KERN_WARNING "RPC: failed to contact local rpcbind "
-                               "server (errno %d).\n", -error);
-       dprintk("RPC:       registration status %d/%d\n", error, *okay);
+/*
+ * Fill in AF_INET family-specific arguments to register
+ */
+static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
+                               struct rpc_message *msg)
+{
+       struct rpcbind_args *map = msg->rpc_argp;
+       unsigned short port = ntohs(address_to_register->sin_port);
+       char buf[32];
+
+       /* Construct AF_INET universal address */
+       snprintf(buf, sizeof(buf),
+                       NIPQUAD_FMT".%u.%u",
+                       NIPQUAD(address_to_register->sin_addr.s_addr),
+                       port >> 8, port & 0xff);
+       map->r_addr = buf;
+
+       dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
+               "local rpcbind\n", (port ? "" : "un"),
+                       map->r_prog, map->r_vers,
+                       map->r_addr, map->r_netid);
+
+       msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
+       if (port)
+               msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
+
+       return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
+                                       sizeof(rpcb_inaddr_loopback),
+                                       RPCBVERS_4, msg);
+}
 
-       return error;
+/*
+ * Fill in AF_INET6 family-specific arguments to register
+ */
+static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
+                               struct rpc_message *msg)
+{
+       struct rpcbind_args *map = msg->rpc_argp;
+       unsigned short port = ntohs(address_to_register->sin6_port);
+       char buf[64];
+
+       /* Construct AF_INET6 universal address */
+       if (ipv6_addr_any(&address_to_register->sin6_addr))
+               snprintf(buf, sizeof(buf), "::.%u.%u",
+                               port >> 8, port & 0xff);
+       else
+               snprintf(buf, sizeof(buf), NIP6_FMT".%u.%u",
+                               NIP6(address_to_register->sin6_addr),
+                               port >> 8, port & 0xff);
+       map->r_addr = buf;
+
+       dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
+               "local rpcbind\n", (port ? "" : "un"),
+                       map->r_prog, map->r_vers,
+                       map->r_addr, map->r_netid);
+
+       msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
+       if (port)
+               msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
+
+       return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback,
+                                       sizeof(rpcb_in6addr_loopback),
+                                       RPCBVERS_4, msg);
+}
+
+/**
+ * rpcb_v4_register - set or unset a port registration with the local rpcbind
+ * @program: RPC program number of service to (un)register
+ * @version: RPC version number of service to (un)register
+ * @address: address family, IP address, and port to (un)register
+ * @netid: netid of transport protocol to (un)register
+ *
+ * Returns zero if the registration request was dispatched successfully
+ * and the rpcbind daemon returned success.  Otherwise, returns an errno
+ * value that reflects the nature of the error (request could not be
+ * dispatched, timed out, or rpcbind returned an error).
+ *
+ * RPC services invoke this function to advertise their contact
+ * information via the system's rpcbind daemon.  RPC services
+ * invoke this function once for each [program, version, address,
+ * netid] tuple they wish to advertise.
+ *
+ * Callers may also unregister RPC services that are no longer
+ * available by setting the port number in the passed-in address
+ * to zero.  Callers pass a netid of "" to unregister all
+ * transport netids associated with [program, version, address].
+ *
+ * This function uses rpcbind protocol version 4 to contact the
+ * local rpcbind daemon.  The local rpcbind daemon must support
+ * version 4 of the rpcbind protocol in order for these functions
+ * to register a service successfully.
+ *
+ * Supported netids include "udp" and "tcp" for UDP and TCP over
+ * IPv4, and "udp6" and "tcp6" for UDP and TCP over IPv6,
+ * respectively.
+ *
+ * The contents of @address determine the address family and the
+ * port to be registered.  The usual practice is to pass INADDR_ANY
+ * as the raw address, but specifying a non-zero address is also
+ * supported by this API if the caller wishes to advertise an RPC
+ * service on a specific network interface.
+ *
+ * Note that passing in INADDR_ANY does not create the same service
+ * registration as IN6ADDR_ANY.  The former advertises an RPC
+ * service on any IPv4 address, but not on IPv6.  The latter
+ * advertises the service on all IPv4 and IPv6 addresses.
+ */
+int rpcb_v4_register(const u32 program, const u32 version,
+                    const struct sockaddr *address, const char *netid)
+{
+       struct rpcbind_args map = {
+               .r_prog         = program,
+               .r_vers         = version,
+               .r_netid        = netid,
+               .r_owner        = RPCB_OWNER_STRING,
+       };
+       struct rpc_message msg = {
+               .rpc_argp       = &map,
+       };
+
+       switch (address->sa_family) {
+       case AF_INET:
+               return rpcb_register_netid4((struct sockaddr_in *)address,
+                                           &msg);
+       case AF_INET6:
+               return rpcb_register_netid6((struct sockaddr_in6 *)address,
+                                           &msg);
+       }
+
+       return -EAFNOSUPPORT;
 }
 
 /**
@@ -227,7 +430,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
                __func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
 
        rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
-                               sizeof(*sin), prot, 2, 0);
+                               sizeof(*sin), prot, RPCBVERS_2);
        if (IS_ERR(rpcb_clnt))
                return PTR_ERR(rpcb_clnt);
 
@@ -243,10 +446,10 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
 }
 EXPORT_SYMBOL_GPL(rpcb_getport_sync);
 
-static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, int version)
+static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc)
 {
        struct rpc_message msg = {
-               .rpc_proc = rpcb_next_version[version].rpc_proc,
+               .rpc_proc = proc,
                .rpc_argp = map,
                .rpc_resp = &map->r_port,
        };
@@ -271,6 +474,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
 void rpcb_getport_async(struct rpc_task *task)
 {
        struct rpc_clnt *clnt = task->tk_client;
+       struct rpc_procinfo *proc;
        u32 bind_version;
        struct rpc_xprt *xprt = task->tk_xprt;
        struct rpc_clnt *rpcb_clnt;
@@ -280,7 +484,6 @@ void rpcb_getport_async(struct rpc_task *task)
        struct sockaddr *sap = (struct sockaddr *)&addr;
        size_t salen;
        int status;
-       struct rpcb_info *info;
 
        dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
                task->tk_pid, __func__,
@@ -289,17 +492,16 @@ void rpcb_getport_async(struct rpc_task *task)
        /* Autobind on cloned rpc clients is discouraged */
        BUG_ON(clnt->cl_parent != clnt);
 
+       /* Put self on the wait queue to ensure we get notified if
+        * some other task is already attempting to bind the port */
+       rpc_sleep_on(&xprt->binding, task, NULL);
+
        if (xprt_test_and_set_binding(xprt)) {
-               status = -EAGAIN;       /* tell caller to check again */
                dprintk("RPC: %5u %s: waiting for another binder\n",
                        task->tk_pid, __func__);
-               goto bailout_nowake;
+               return;
        }
 
-       /* Put self on queue before sending rpcbind request, in case
-        * rpcb_getport_done completes before we return from rpc_run_task */
-       rpc_sleep_on(&xprt->binding, task, NULL);
-
        /* Someone else may have bound if we slept */
        if (xprt_bound(xprt)) {
                status = 0;
@@ -313,10 +515,12 @@ void rpcb_getport_async(struct rpc_task *task)
        /* Don't ever use rpcbind v2 for AF_INET6 requests */
        switch (sap->sa_family) {
        case AF_INET:
-               info = rpcb_next_version;
+               proc = rpcb_next_version[xprt->bind_index].rpc_proc;
+               bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
                break;
        case AF_INET6:
-               info = rpcb_next_version6;
+               proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
+               bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
                break;
        default:
                status = -EAFNOSUPPORT;
@@ -324,20 +528,19 @@ void rpcb_getport_async(struct rpc_task *task)
                                task->tk_pid, __func__);
                goto bailout_nofree;
        }
-       if (info[xprt->bind_index].rpc_proc == NULL) {
+       if (proc == NULL) {
                xprt->bind_index = 0;
                status = -EPFNOSUPPORT;
                dprintk("RPC: %5u %s: no more getport versions available\n",
                        task->tk_pid, __func__);
                goto bailout_nofree;
        }
-       bind_version = info[xprt->bind_index].rpc_vers;
 
        dprintk("RPC: %5u %s: trying rpcbind version %u\n",
                task->tk_pid, __func__, bind_version);
 
        rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot,
-                               bind_version, 0);
+                               bind_version);
        if (IS_ERR(rpcb_clnt)) {
                status = PTR_ERR(rpcb_clnt);
                dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
@@ -360,15 +563,15 @@ void rpcb_getport_async(struct rpc_task *task)
        map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
        map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
        map->r_owner = RPCB_OWNER_STRING;       /* ignored for GETADDR */
+       map->r_status = -EIO;
 
-       child = rpcb_call_async(rpcb_clnt, map, xprt->bind_index);
+       child = rpcb_call_async(rpcb_clnt, map, proc);
        rpc_release_client(rpcb_clnt);
        if (IS_ERR(child)) {
-               status = -EIO;
                /* rpcb_map_release() has freed the arguments */
                dprintk("RPC: %5u %s: rpc_run_task failed\n",
                        task->tk_pid, __func__);
-               goto bailout_nofree;
+               return;
        }
        rpc_put_task(child);
 
@@ -377,7 +580,6 @@ void rpcb_getport_async(struct rpc_task *task)
 
 bailout_nofree:
        rpcb_wake_rpcbind_waiters(xprt, status);
-bailout_nowake:
        task->tk_status = status;
 }
 EXPORT_SYMBOL_GPL(rpcb_getport_async);
@@ -416,9 +618,13 @@ static void rpcb_getport_done(struct rpc_task *child, void *data)
        dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n",
                        child->tk_pid, status, map->r_port);
 
-       rpcb_wake_rpcbind_waiters(xprt, status);
+       map->r_status = status;
 }
 
+/*
+ * XDR functions for rpcbind
+ */
+
 static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p,
                               struct rpcbind_args *rpcb)
 {
@@ -437,7 +643,7 @@ static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p,
                               unsigned short *portp)
 {
        *portp = (unsigned short) ntohl(*p++);
-       dprintk("RPC:      rpcb_decode_getport result %u\n",
+       dprintk("RPC:       rpcb_decode_getport result %u\n",
                        *portp);
        return 0;
 }
@@ -446,8 +652,8 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
                           unsigned int *boolp)
 {
        *boolp = (unsigned int) ntohl(*p++);
-       dprintk("RPC:      rpcb_decode_set result %u\n",
-                       *boolp);
+       dprintk("RPC:       rpcb_decode_set: call %s\n",
+                       (*boolp ? "succeeded" : "failed"));
        return 0;
 }
 
@@ -570,52 +776,60 @@ out_err:
 static struct rpc_procinfo rpcb_procedures2[] = {
        PROC(SET,               mapping,        set),
        PROC(UNSET,             mapping,        set),
-       PROC(GETADDR,           mapping,        getport),
+       PROC(GETPORT,           mapping,        getport),
 };
 
 static struct rpc_procinfo rpcb_procedures3[] = {
-       PROC(SET,               mapping,        set),
-       PROC(UNSET,             mapping,        set),
+       PROC(SET,               getaddr,        set),
+       PROC(UNSET,             getaddr,        set),
        PROC(GETADDR,           getaddr,        getaddr),
 };
 
 static struct rpc_procinfo rpcb_procedures4[] = {
-       PROC(SET,               mapping,        set),
-       PROC(UNSET,             mapping,        set),
+       PROC(SET,               getaddr,        set),
+       PROC(UNSET,             getaddr,        set),
+       PROC(GETADDR,           getaddr,        getaddr),
        PROC(GETVERSADDR,       getaddr,        getaddr),
 };
 
 static struct rpcb_info rpcb_next_version[] = {
-#ifdef CONFIG_SUNRPC_BIND34
-       { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] },
-       { 3, &rpcb_procedures3[RPCBPROC_GETADDR] },
-#endif
-       { 2, &rpcb_procedures2[RPCBPROC_GETPORT] },
-       { 0, NULL },
+       {
+               .rpc_vers       = RPCBVERS_2,
+               .rpc_proc       = &rpcb_procedures2[RPCBPROC_GETPORT],
+       },
+       {
+               .rpc_proc       = NULL,
+       },
 };
 
 static struct rpcb_info rpcb_next_version6[] = {
-#ifdef CONFIG_SUNRPC_BIND34
-       { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] },
-       { 3, &rpcb_procedures3[RPCBPROC_GETADDR] },
-#endif
-       { 0, NULL },
+       {
+               .rpc_vers       = RPCBVERS_4,
+               .rpc_proc       = &rpcb_procedures4[RPCBPROC_GETADDR],
+       },
+       {
+               .rpc_vers       = RPCBVERS_3,
+               .rpc_proc       = &rpcb_procedures3[RPCBPROC_GETADDR],
+       },
+       {
+               .rpc_proc       = NULL,
+       },
 };
 
 static struct rpc_version rpcb_version2 = {
-       .number         = 2,
+       .number         = RPCBVERS_2,
        .nrprocs        = RPCB_HIGHPROC_2,
        .procs          = rpcb_procedures2
 };
 
 static struct rpc_version rpcb_version3 = {
-       .number         = 3,
+       .number         = RPCBVERS_3,
        .nrprocs        = RPCB_HIGHPROC_3,
        .procs          = rpcb_procedures3
 };
 
 static struct rpc_version rpcb_version4 = {
-       .number         = 4,
+       .number         = RPCBVERS_4,
        .nrprocs        = RPCB_HIGHPROC_4,
        .procs          = rpcb_procedures4
 };