linux/net/sunrpc/rpcb_clnt.c
<<
>>
Prefs
   1/*
   2 * In-kernel rpcbind client supporting versions 2, 3, and 4 of the rpcbind
   3 * protocol
   4 *
   5 * Based on RFC 1833: "Binding Protocols for ONC RPC Version 2" and
   6 * RFC 3530: "Network File System (NFS) version 4 Protocol"
   7 *
   8 * Original: Gilles Quillard, Bull Open Source, 2005 <gilles.quillard@bull.net>
   9 * Updated: Chuck Lever, Oracle Corporation, 2007 <chuck.lever@oracle.com>
  10 *
  11 * Descended from net/sunrpc/pmap_clnt.c,
  12 *  Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  13 */
  14
  15#include <linux/module.h>
  16
  17#include <linux/types.h>
  18#include <linux/socket.h>
  19#include <linux/in.h>
  20#include <linux/in6.h>
  21#include <linux/kernel.h>
  22#include <linux/errno.h>
  23#include <net/ipv6.h>
  24
  25#include <linux/sunrpc/clnt.h>
  26#include <linux/sunrpc/sched.h>
  27#include <linux/sunrpc/xprtsock.h>
  28
  29#ifdef RPC_DEBUG
  30# define RPCDBG_FACILITY        RPCDBG_BIND
  31#endif
  32
  33#define RPCBIND_PROGRAM         (100000u)
  34#define RPCBIND_PORT            (111u)
  35
  36#define RPCBVERS_2              (2u)
  37#define RPCBVERS_3              (3u)
  38#define RPCBVERS_4              (4u)
  39
  40enum {
  41        RPCBPROC_NULL,
  42        RPCBPROC_SET,
  43        RPCBPROC_UNSET,
  44        RPCBPROC_GETPORT,
  45        RPCBPROC_GETADDR = 3,           /* alias for GETPORT */
  46        RPCBPROC_DUMP,
  47        RPCBPROC_CALLIT,
  48        RPCBPROC_BCAST = 5,             /* alias for CALLIT */
  49        RPCBPROC_GETTIME,
  50        RPCBPROC_UADDR2TADDR,
  51        RPCBPROC_TADDR2UADDR,
  52        RPCBPROC_GETVERSADDR,
  53        RPCBPROC_INDIRECT,
  54        RPCBPROC_GETADDRLIST,
  55        RPCBPROC_GETSTAT,
  56};
  57
  58#define RPCB_HIGHPROC_2         RPCBPROC_CALLIT
  59#define RPCB_HIGHPROC_3         RPCBPROC_TADDR2UADDR
  60#define RPCB_HIGHPROC_4         RPCBPROC_GETSTAT
  61
  62/*
  63 * r_owner
  64 *
  65 * The "owner" is allowed to unset a service in the rpcbind database.
  66 * We always use the following (arbitrary) fixed string.
  67 */
  68#define RPCB_OWNER_STRING       "rpcb"
  69#define RPCB_MAXOWNERLEN        sizeof(RPCB_OWNER_STRING)
  70
  71static void                     rpcb_getport_done(struct rpc_task *, void *);
  72static void                     rpcb_map_release(void *data);
  73static struct rpc_program       rpcb_program;
  74
  75struct rpcbind_args {
  76        struct rpc_xprt *       r_xprt;
  77
  78        u32                     r_prog;
  79        u32                     r_vers;
  80        u32                     r_prot;
  81        unsigned short          r_port;
  82        const char *            r_netid;
  83        const char *            r_addr;
  84        const char *            r_owner;
  85
  86        int                     r_status;
  87};
  88
  89static struct rpc_procinfo rpcb_procedures2[];
  90static struct rpc_procinfo rpcb_procedures3[];
  91static struct rpc_procinfo rpcb_procedures4[];
  92
  93struct rpcb_info {
  94        u32                     rpc_vers;
  95        struct rpc_procinfo *   rpc_proc;
  96};
  97
  98static struct rpcb_info rpcb_next_version[];
  99static struct rpcb_info rpcb_next_version6[];
 100
 101static const struct rpc_call_ops rpcb_getport_ops = {
 102        .rpc_call_done          = rpcb_getport_done,
 103        .rpc_release            = rpcb_map_release,
 104};
 105
 106static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
 107{
 108        xprt_clear_binding(xprt);
 109        rpc_wake_up_status(&xprt->binding, status);
 110}
 111
 112static void rpcb_map_release(void *data)
 113{
 114        struct rpcbind_args *map = data;
 115
 116        rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
 117        xprt_put(map->r_xprt);
 118        kfree(map);
 119}
 120
 121static const struct sockaddr_in rpcb_inaddr_loopback = {
 122        .sin_family             = AF_INET,
 123        .sin_addr.s_addr        = htonl(INADDR_LOOPBACK),
 124        .sin_port               = htons(RPCBIND_PORT),
 125};
 126
 127static const struct sockaddr_in6 rpcb_in6addr_loopback = {
 128        .sin6_family            = AF_INET6,
 129        .sin6_addr              = IN6ADDR_LOOPBACK_INIT,
 130        .sin6_port              = htons(RPCBIND_PORT),
 131};
 132
 133static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
 134                                          size_t addrlen, u32 version)
 135{
 136        struct rpc_create_args args = {
 137                .protocol       = XPRT_TRANSPORT_UDP,
 138                .address        = addr,
 139                .addrsize       = addrlen,
 140                .servername     = "localhost",
 141                .program        = &rpcb_program,
 142                .version        = version,
 143                .authflavor     = RPC_AUTH_UNIX,
 144                .flags          = RPC_CLNT_CREATE_NOPING,
 145        };
 146
 147        return rpc_create(&args);
 148}
 149
 150static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
 151                                    size_t salen, int proto, u32 version)
 152{
 153        struct rpc_create_args args = {
 154                .protocol       = proto,
 155                .address        = srvaddr,
 156                .addrsize       = salen,
 157                .servername     = hostname,
 158                .program        = &rpcb_program,
 159                .version        = version,
 160                .authflavor     = RPC_AUTH_UNIX,
 161                .flags          = (RPC_CLNT_CREATE_NOPING |
 162                                        RPC_CLNT_CREATE_NONPRIVPORT),
 163        };
 164
 165        switch (srvaddr->sa_family) {
 166        case AF_INET:
 167                ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
 168                break;
 169        case AF_INET6:
 170                ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT);
 171                break;
 172        default:
 173                return NULL;
 174        }
 175
 176        return rpc_create(&args);
 177}
 178
 179static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
 180                              u32 version, struct rpc_message *msg)
 181{
 182        struct rpc_clnt *rpcb_clnt;
 183        int result, error = 0;
 184
 185        msg->rpc_resp = &result;
 186
 187        rpcb_clnt = rpcb_create_local(addr, addrlen, version);
 188        if (!IS_ERR(rpcb_clnt)) {
 189                error = rpc_call_sync(rpcb_clnt, msg, 0);
 190                rpc_shutdown_client(rpcb_clnt);
 191        } else
 192                error = PTR_ERR(rpcb_clnt);
 193
 194        if (error < 0) {
 195                printk(KERN_WARNING "RPC: failed to contact local rpcbind "
 196                                "server (errno %d).\n", -error);
 197                return error;
 198        }
 199
 200        if (!result)
 201                return -EACCES;
 202        return 0;
 203}
 204
 205/**
 206 * rpcb_register - set or unset a port registration with the local rpcbind svc
 207 * @prog: RPC program number to bind
 208 * @vers: RPC version number to bind
 209 * @prot: transport protocol to register
 210 * @port: port value to register
 211 *
 212 * Returns zero if the registration request was dispatched successfully
 213 * and the rpcbind daemon returned success.  Otherwise, returns an errno
 214 * value that reflects the nature of the error (request could not be
 215 * dispatched, timed out, or rpcbind returned an error).
 216 *
 217 * RPC services invoke this function to advertise their contact
 218 * information via the system's rpcbind daemon.  RPC services
 219 * invoke this function once for each [program, version, transport]
 220 * tuple they wish to advertise.
 221 *
 222 * Callers may also unregister RPC services that are no longer
 223 * available by setting the passed-in port to zero.  This removes
 224 * all registered transports for [program, version] from the local
 225 * rpcbind database.
 226 *
 227 * This function uses rpcbind protocol version 2 to contact the
 228 * local rpcbind daemon.
 229 *
 230 * Registration works over both AF_INET and AF_INET6, and services
 231 * registered via this function are advertised as available for any
 232 * address.  If the local rpcbind daemon is listening on AF_INET6,
 233 * services registered via this function will be advertised on
 234 * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6
 235 * addresses).
 236 */
 237int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 238{
 239        struct rpcbind_args map = {
 240                .r_prog         = prog,
 241                .r_vers         = vers,
 242                .r_prot         = prot,
 243                .r_port         = port,
 244        };
 245        struct rpc_message msg = {
 246                .rpc_argp       = &map,
 247        };
 248
 249        dprintk("RPC:       %sregistering (%u, %u, %d, %u) with local "
 250                        "rpcbind\n", (port ? "" : "un"),
 251                        prog, vers, prot, port);
 252
 253        msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
 254        if (port)
 255                msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
 256
 257        return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
 258                                        sizeof(rpcb_inaddr_loopback),
 259                                        RPCBVERS_2, &msg);
 260}
 261
 262/*
 263 * Fill in AF_INET family-specific arguments to register
 264 */
 265static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
 266                                struct rpc_message *msg)
 267{
 268        struct rpcbind_args *map = msg->rpc_argp;
 269        unsigned short port = ntohs(address_to_register->sin_port);
 270        char buf[32];
 271
 272        /* Construct AF_INET universal address */
 273        snprintf(buf, sizeof(buf),
 274                        NIPQUAD_FMT".%u.%u",
 275                        NIPQUAD(address_to_register->sin_addr.s_addr),
 276                        port >> 8, port & 0xff);
 277        map->r_addr = buf;
 278
 279        dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
 280                "local rpcbind\n", (port ? "" : "un"),
 281                        map->r_prog, map->r_vers,
 282                        map->r_addr, map->r_netid);
 283
 284        msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
 285        if (port)
 286                msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
 287
 288        return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
 289                                        sizeof(rpcb_inaddr_loopback),
 290                                        RPCBVERS_4, msg);
 291}
 292
 293/*
 294 * Fill in AF_INET6 family-specific arguments to register
 295 */
 296static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
 297                                struct rpc_message *msg)
 298{
 299        struct rpcbind_args *map = msg->rpc_argp;
 300        unsigned short port = ntohs(address_to_register->sin6_port);
 301        char buf[64];
 302
 303        /* Construct AF_INET6 universal address */
 304        if (ipv6_addr_any(&address_to_register->sin6_addr))
 305                snprintf(buf, sizeof(buf), "::.%u.%u",
 306                                port >> 8, port & 0xff);
 307        else
 308                snprintf(buf, sizeof(buf), NIP6_FMT".%u.%u",
 309                                NIP6(address_to_register->sin6_addr),
 310                                port >> 8, port & 0xff);
 311        map->r_addr = buf;
 312
 313        dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
 314                "local rpcbind\n", (port ? "" : "un"),
 315                        map->r_prog, map->r_vers,
 316                        map->r_addr, map->r_netid);
 317
 318        msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
 319        if (port)
 320                msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
 321
 322        return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback,
 323                                        sizeof(rpcb_in6addr_loopback),
 324                                        RPCBVERS_4, msg);
 325}
 326
 327/**
 328 * rpcb_v4_register - set or unset a port registration with the local rpcbind
 329 * @program: RPC program number of service to (un)register
 330 * @version: RPC version number of service to (un)register
 331 * @address: address family, IP address, and port to (un)register
 332 * @netid: netid of transport protocol to (un)register
 333 *
 334 * Returns zero if the registration request was dispatched successfully
 335 * and the rpcbind daemon returned success.  Otherwise, returns an errno
 336 * value that reflects the nature of the error (request could not be
 337 * dispatched, timed out, or rpcbind returned an error).
 338 *
 339 * RPC services invoke this function to advertise their contact
 340 * information via the system's rpcbind daemon.  RPC services
 341 * invoke this function once for each [program, version, address,
 342 * netid] tuple they wish to advertise.
 343 *
 344 * Callers may also unregister RPC services that are no longer
 345 * available by setting the port number in the passed-in address
 346 * to zero.  Callers pass a netid of "" to unregister all
 347 * transport netids associated with [program, version, address].
 348 *
 349 * This function uses rpcbind protocol version 4 to contact the
 350 * local rpcbind daemon.  The local rpcbind daemon must support
 351 * version 4 of the rpcbind protocol in order for these functions
 352 * to register a service successfully.
 353 *
 354 * Supported netids include "udp" and "tcp" for UDP and TCP over
 355 * IPv4, and "udp6" and "tcp6" for UDP and TCP over IPv6,
 356 * respectively.
 357 *
 358 * The contents of @address determine the address family and the
 359 * port to be registered.  The usual practice is to pass INADDR_ANY
 360 * as the raw address, but specifying a non-zero address is also
 361 * supported by this API if the caller wishes to advertise an RPC
 362 * service on a specific network interface.
 363 *
 364 * Note that passing in INADDR_ANY does not create the same service
 365 * registration as IN6ADDR_ANY.  The former advertises an RPC
 366 * service on any IPv4 address, but not on IPv6.  The latter
 367 * advertises the service on all IPv4 and IPv6 addresses.
 368 */
 369int rpcb_v4_register(const u32 program, const u32 version,
 370                     const struct sockaddr *address, const char *netid)
 371{
 372        struct rpcbind_args map = {
 373                .r_prog         = program,
 374                .r_vers         = version,
 375                .r_netid        = netid,
 376                .r_owner        = RPCB_OWNER_STRING,
 377        };
 378        struct rpc_message msg = {
 379                .rpc_argp       = &map,
 380        };
 381
 382        switch (address->sa_family) {
 383        case AF_INET:
 384                return rpcb_register_netid4((struct sockaddr_in *)address,
 385                                            &msg);
 386        case AF_INET6:
 387                return rpcb_register_netid6((struct sockaddr_in6 *)address,
 388                                            &msg);
 389        }
 390
 391        return -EAFNOSUPPORT;
 392}
 393
 394/**
 395 * rpcb_getport_sync - obtain the port for an RPC service on a given host
 396 * @sin: address of remote peer
 397 * @prog: RPC program number to bind
 398 * @vers: RPC version number to bind
 399 * @prot: transport protocol to use to make this request
 400 *
 401 * Return value is the requested advertised port number,
 402 * or a negative errno value.
 403 *
 404 * Called from outside the RPC client in a synchronous task context.
 405 * Uses default timeout parameters specified by underlying transport.
 406 *
 407 * XXX: Needs to support IPv6
 408 */
 409int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
 410{
 411        struct rpcbind_args map = {
 412                .r_prog         = prog,
 413                .r_vers         = vers,
 414                .r_prot         = prot,
 415                .r_port         = 0,
 416        };
 417        struct rpc_message msg = {
 418                .rpc_proc       = &rpcb_procedures2[RPCBPROC_GETPORT],
 419                .rpc_argp       = &map,
 420                .rpc_resp       = &map.r_port,
 421        };
 422        struct rpc_clnt *rpcb_clnt;
 423        int status;
 424
 425        dprintk("RPC:       %s(" NIPQUAD_FMT ", %u, %u, %d)\n",
 426                __func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
 427
 428        rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
 429                                sizeof(*sin), prot, RPCBVERS_2);
 430        if (IS_ERR(rpcb_clnt))
 431                return PTR_ERR(rpcb_clnt);
 432
 433        status = rpc_call_sync(rpcb_clnt, &msg, 0);
 434        rpc_shutdown_client(rpcb_clnt);
 435
 436        if (status >= 0) {
 437                if (map.r_port != 0)
 438                        return map.r_port;
 439                status = -EACCES;
 440        }
 441        return status;
 442}
 443EXPORT_SYMBOL_GPL(rpcb_getport_sync);
 444
 445static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc)
 446{
 447        struct rpc_message msg = {
 448                .rpc_proc = proc,
 449                .rpc_argp = map,
 450                .rpc_resp = &map->r_port,
 451        };
 452        struct rpc_task_setup task_setup_data = {
 453                .rpc_client = rpcb_clnt,
 454                .rpc_message = &msg,
 455                .callback_ops = &rpcb_getport_ops,
 456                .callback_data = map,
 457                .flags = RPC_TASK_ASYNC,
 458        };
 459
 460        return rpc_run_task(&task_setup_data);
 461}
 462
 463/*
 464 * In the case where rpc clients have been cloned, we want to make
 465 * sure that we use the program number/version etc of the actual
 466 * owner of the xprt. To do so, we walk back up the tree of parents
 467 * to find whoever created the transport and/or whoever has the
 468 * autobind flag set.
 469 */
 470static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
 471{
 472        struct rpc_clnt *parent = clnt->cl_parent;
 473
 474        while (parent != clnt) {
 475                if (parent->cl_xprt != clnt->cl_xprt)
 476                        break;
 477                if (clnt->cl_autobind)
 478                        break;
 479                clnt = parent;
 480                parent = parent->cl_parent;
 481        }
 482        return clnt;
 483}
 484
 485/**
 486 * rpcb_getport_async - obtain the port for a given RPC service on a given host
 487 * @task: task that is waiting for portmapper request
 488 *
 489 * This one can be called for an ongoing RPC request, and can be used in
 490 * an async (rpciod) context.
 491 */
 492void rpcb_getport_async(struct rpc_task *task)
 493{
 494        struct rpc_clnt *clnt;
 495        struct rpc_procinfo *proc;
 496        u32 bind_version;
 497        struct rpc_xprt *xprt;
 498        struct rpc_clnt *rpcb_clnt;
 499        static struct rpcbind_args *map;
 500        struct rpc_task *child;
 501        struct sockaddr_storage addr;
 502        struct sockaddr *sap = (struct sockaddr *)&addr;
 503        size_t salen;
 504        int status;
 505
 506        clnt = rpcb_find_transport_owner(task->tk_client);
 507        xprt = clnt->cl_xprt;
 508
 509        dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
 510                task->tk_pid, __func__,
 511                clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
 512
 513        /* Put self on the wait queue to ensure we get notified if
 514         * some other task is already attempting to bind the port */
 515        rpc_sleep_on(&xprt->binding, task, NULL);
 516
 517        if (xprt_test_and_set_binding(xprt)) {
 518                dprintk("RPC: %5u %s: waiting for another binder\n",
 519                        task->tk_pid, __func__);
 520                return;
 521        }
 522
 523        /* Someone else may have bound if we slept */
 524        if (xprt_bound(xprt)) {
 525                status = 0;
 526                dprintk("RPC: %5u %s: already bound\n",
 527                        task->tk_pid, __func__);
 528                goto bailout_nofree;
 529        }
 530
 531        salen = rpc_peeraddr(clnt, sap, sizeof(addr));
 532
 533        /* Don't ever use rpcbind v2 for AF_INET6 requests */
 534        switch (sap->sa_family) {
 535        case AF_INET:
 536                proc = rpcb_next_version[xprt->bind_index].rpc_proc;
 537                bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
 538                break;
 539        case AF_INET6:
 540                proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
 541                bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
 542                break;
 543        default:
 544                status = -EAFNOSUPPORT;
 545                dprintk("RPC: %5u %s: bad address family\n",
 546                                task->tk_pid, __func__);
 547                goto bailout_nofree;
 548        }
 549        if (proc == NULL) {
 550                xprt->bind_index = 0;
 551                status = -EPFNOSUPPORT;
 552                dprintk("RPC: %5u %s: no more getport versions available\n",
 553                        task->tk_pid, __func__);
 554                goto bailout_nofree;
 555        }
 556
 557        dprintk("RPC: %5u %s: trying rpcbind version %u\n",
 558                task->tk_pid, __func__, bind_version);
 559
 560        rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot,
 561                                bind_version);
 562        if (IS_ERR(rpcb_clnt)) {
 563                status = PTR_ERR(rpcb_clnt);
 564                dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
 565                        task->tk_pid, __func__, PTR_ERR(rpcb_clnt));
 566                goto bailout_nofree;
 567        }
 568
 569        map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
 570        if (!map) {
 571                status = -ENOMEM;
 572                dprintk("RPC: %5u %s: no memory available\n",
 573                        task->tk_pid, __func__);
 574                goto bailout_release_client;
 575        }
 576        map->r_prog = clnt->cl_prog;
 577        map->r_vers = clnt->cl_vers;
 578        map->r_prot = xprt->prot;
 579        map->r_port = 0;
 580        map->r_xprt = xprt_get(xprt);
 581        map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
 582        map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
 583        map->r_owner = RPCB_OWNER_STRING;       /* ignored for GETADDR */
 584        map->r_status = -EIO;
 585
 586        child = rpcb_call_async(rpcb_clnt, map, proc);
 587        rpc_release_client(rpcb_clnt);
 588        if (IS_ERR(child)) {
 589                /* rpcb_map_release() has freed the arguments */
 590                dprintk("RPC: %5u %s: rpc_run_task failed\n",
 591                        task->tk_pid, __func__);
 592                return;
 593        }
 594
 595        xprt->stat.bind_count++;
 596        rpc_put_task(child);
 597        return;
 598
 599bailout_release_client:
 600        rpc_release_client(rpcb_clnt);
 601bailout_nofree:
 602        rpcb_wake_rpcbind_waiters(xprt, status);
 603        task->tk_status = status;
 604}
 605EXPORT_SYMBOL_GPL(rpcb_getport_async);
 606
 607/*
 608 * Rpcbind child task calls this callback via tk_exit.
 609 */
 610static void rpcb_getport_done(struct rpc_task *child, void *data)
 611{
 612        struct rpcbind_args *map = data;
 613        struct rpc_xprt *xprt = map->r_xprt;
 614        int status = child->tk_status;
 615
 616        /* Garbage reply: retry with a lesser rpcbind version */
 617        if (status == -EIO)
 618                status = -EPROTONOSUPPORT;
 619
 620        /* rpcbind server doesn't support this rpcbind protocol version */
 621        if (status == -EPROTONOSUPPORT)
 622                xprt->bind_index++;
 623
 624        if (status < 0) {
 625                /* rpcbind server not available on remote host? */
 626                xprt->ops->set_port(xprt, 0);
 627        } else if (map->r_port == 0) {
 628                /* Requested RPC service wasn't registered on remote host */
 629                xprt->ops->set_port(xprt, 0);
 630                status = -EACCES;
 631        } else {
 632                /* Succeeded */
 633                xprt->ops->set_port(xprt, map->r_port);
 634                xprt_set_bound(xprt);
 635                status = 0;
 636        }
 637
 638        dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n",
 639                        child->tk_pid, status, map->r_port);
 640
 641        map->r_status = status;
 642}
 643
 644/*
 645 * XDR functions for rpcbind
 646 */
 647
 648static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p,
 649                               struct rpcbind_args *rpcb)
 650{
 651        dprintk("RPC:       encoding rpcb request (%u, %u, %d, %u)\n",
 652                        rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
 653        *p++ = htonl(rpcb->r_prog);
 654        *p++ = htonl(rpcb->r_vers);
 655        *p++ = htonl(rpcb->r_prot);
 656        *p++ = htonl(rpcb->r_port);
 657
 658        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
 659        return 0;
 660}
 661
 662static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p,
 663                               unsigned short *portp)
 664{
 665        *portp = (unsigned short) ntohl(*p++);
 666        dprintk("RPC:       rpcb getport result: %u\n",
 667                        *portp);
 668        return 0;
 669}
 670
 671static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
 672                           unsigned int *boolp)
 673{
 674        *boolp = (unsigned int) ntohl(*p++);
 675        dprintk("RPC:       rpcb set/unset call %s\n",
 676                        (*boolp ? "succeeded" : "failed"));
 677        return 0;
 678}
 679
 680static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p,
 681                               struct rpcbind_args *rpcb)
 682{
 683        dprintk("RPC:       encoding rpcb request (%u, %u, %s)\n",
 684                        rpcb->r_prog, rpcb->r_vers, rpcb->r_addr);
 685        *p++ = htonl(rpcb->r_prog);
 686        *p++ = htonl(rpcb->r_vers);
 687
 688        p = xdr_encode_string(p, rpcb->r_netid);
 689        p = xdr_encode_string(p, rpcb->r_addr);
 690        p = xdr_encode_string(p, rpcb->r_owner);
 691
 692        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
 693
 694        return 0;
 695}
 696
 697static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p,
 698                               unsigned short *portp)
 699{
 700        char *addr;
 701        u32 addr_len;
 702        int c, i, f, first, val;
 703
 704        *portp = 0;
 705        addr_len = ntohl(*p++);
 706
 707        /*
 708         * Simple sanity check.  The smallest possible universal
 709         * address is an IPv4 address string containing 11 bytes.
 710         */
 711        if (addr_len < 11 || addr_len > RPCBIND_MAXUADDRLEN)
 712                goto out_err;
 713
 714        /*
 715         * Start at the end and walk backwards until the first dot
 716         * is encountered.  When the second dot is found, we have
 717         * both parts of the port number.
 718         */
 719        addr = (char *)p;
 720        val = 0;
 721        first = 1;
 722        f = 1;
 723        for (i = addr_len - 1; i > 0; i--) {
 724                c = addr[i];
 725                if (c >= '0' && c <= '9') {
 726                        val += (c - '0') * f;
 727                        f *= 10;
 728                } else if (c == '.') {
 729                        if (first) {
 730                                *portp = val;
 731                                val = first = 0;
 732                                f = 1;
 733                        } else {
 734                                *portp |= (val << 8);
 735                                break;
 736                        }
 737                }
 738        }
 739
 740        /*
 741         * Simple sanity check.  If we never saw a dot in the reply,
 742         * then this was probably just garbage.
 743         */
 744        if (first)
 745                goto out_err;
 746
 747        dprintk("RPC:       rpcb_decode_getaddr port=%u\n", *portp);
 748        return 0;
 749
 750out_err:
 751        dprintk("RPC:       rpcbind server returned malformed reply\n");
 752        return -EIO;
 753}
 754
 755#define RPCB_program_sz         (1u)
 756#define RPCB_version_sz         (1u)
 757#define RPCB_protocol_sz        (1u)
 758#define RPCB_port_sz            (1u)
 759#define RPCB_boolean_sz         (1u)
 760
 761#define RPCB_netid_sz           (1+XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
 762#define RPCB_addr_sz            (1+XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
 763#define RPCB_ownerstring_sz     (1+XDR_QUADLEN(RPCB_MAXOWNERLEN))
 764
 765#define RPCB_mappingargs_sz     RPCB_program_sz+RPCB_version_sz+        \
 766                                RPCB_protocol_sz+RPCB_port_sz
 767#define RPCB_getaddrargs_sz     RPCB_program_sz+RPCB_version_sz+        \
 768                                RPCB_netid_sz+RPCB_addr_sz+             \
 769                                RPCB_ownerstring_sz
 770
 771#define RPCB_setres_sz          RPCB_boolean_sz
 772#define RPCB_getportres_sz      RPCB_port_sz
 773
 774/*
 775 * Note that RFC 1833 does not put any size restrictions on the
 776 * address string returned by the remote rpcbind database.
 777 */
 778#define RPCB_getaddrres_sz      RPCB_addr_sz
 779
 780#define PROC(proc, argtype, restype)                                    \
 781        [RPCBPROC_##proc] = {                                           \
 782                .p_proc         = RPCBPROC_##proc,                      \
 783                .p_encode       = (kxdrproc_t) rpcb_encode_##argtype,   \
 784                .p_decode       = (kxdrproc_t) rpcb_decode_##restype,   \
 785                .p_arglen       = RPCB_##argtype##args_sz,              \
 786                .p_replen       = RPCB_##restype##res_sz,               \
 787                .p_statidx      = RPCBPROC_##proc,                      \
 788                .p_timer        = 0,                                    \
 789                .p_name         = #proc,                                \
 790        }
 791
 792/*
 793 * Not all rpcbind procedures described in RFC 1833 are implemented
 794 * since the Linux kernel RPC code requires only these.
 795 */
 796static struct rpc_procinfo rpcb_procedures2[] = {
 797        PROC(SET,               mapping,        set),
 798        PROC(UNSET,             mapping,        set),
 799        PROC(GETPORT,           mapping,        getport),
 800};
 801
 802static struct rpc_procinfo rpcb_procedures3[] = {
 803        PROC(SET,               getaddr,        set),
 804        PROC(UNSET,             getaddr,        set),
 805        PROC(GETADDR,           getaddr,        getaddr),
 806};
 807
 808static struct rpc_procinfo rpcb_procedures4[] = {
 809        PROC(SET,               getaddr,        set),
 810        PROC(UNSET,             getaddr,        set),
 811        PROC(GETADDR,           getaddr,        getaddr),
 812        PROC(GETVERSADDR,       getaddr,        getaddr),
 813};
 814
 815static struct rpcb_info rpcb_next_version[] = {
 816        {
 817                .rpc_vers       = RPCBVERS_2,
 818                .rpc_proc       = &rpcb_procedures2[RPCBPROC_GETPORT],
 819        },
 820        {
 821                .rpc_proc       = NULL,
 822        },
 823};
 824
 825static struct rpcb_info rpcb_next_version6[] = {
 826        {
 827                .rpc_vers       = RPCBVERS_4,
 828                .rpc_proc       = &rpcb_procedures4[RPCBPROC_GETADDR],
 829        },
 830        {
 831                .rpc_vers       = RPCBVERS_3,
 832                .rpc_proc       = &rpcb_procedures3[RPCBPROC_GETADDR],
 833        },
 834        {
 835                .rpc_proc       = NULL,
 836        },
 837};
 838
 839static struct rpc_version rpcb_version2 = {
 840        .number         = RPCBVERS_2,
 841        .nrprocs        = RPCB_HIGHPROC_2,
 842        .procs          = rpcb_procedures2
 843};
 844
 845static struct rpc_version rpcb_version3 = {
 846        .number         = RPCBVERS_3,
 847        .nrprocs        = RPCB_HIGHPROC_3,
 848        .procs          = rpcb_procedures3
 849};
 850
 851static struct rpc_version rpcb_version4 = {
 852        .number         = RPCBVERS_4,
 853        .nrprocs        = RPCB_HIGHPROC_4,
 854        .procs          = rpcb_procedures4
 855};
 856
 857static struct rpc_version *rpcb_version[] = {
 858        NULL,
 859        NULL,
 860        &rpcb_version2,
 861        &rpcb_version3,
 862        &rpcb_version4
 863};
 864
 865static struct rpc_stat rpcb_stats;
 866
 867static struct rpc_program rpcb_program = {
 868        .name           = "rpcbind",
 869        .number         = RPCBIND_PROGRAM,
 870        .nrvers         = ARRAY_SIZE(rpcb_version),
 871        .version        = rpcb_version,
 872        .stats          = &rpcb_stats,
 873};
 874
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.