INTERNET-DRAFT                                    Sumandra Majee (Cisco)
Expires: August 21, 2001                          Pearl Park (Nixxo)

                         IPv6 extension to RPC
                    draft-ietf-nfsv4-rpc-ipv6-00.txt




STATUS OF THIS MEMO

   This document is an Internet-Draft and is in full conformance with
   all provisions of Section 10 of RFC2026.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF), its areas, and its working groups.  Note that
   other groups may also distribute working documents as Internet-
   Drafts.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet- Drafts as reference
   material or to cite them other than as "work in progress."

   The list of current Internet-Drafts can be accessed at
   http://www.ietf.org/ietf/1id-abstracts.txt

   The list of Internet-Draft Shadow Directories can be accessed at
   http://www.ietf.org/shadow.html.

   This Internet Draft expires August 21, 2001.

ABSTRACT

   ONC+ RPC is a popular choice for developing various distributed
   software and services. NFS (network File system) is one example of
   that. This document describes the the various extensions and choices
   made in order to support IPv6 in ONC RPC. The goal is to keep the
   application porting effort to minimal or none depending on the
   complexity of the application. It describes the changes necessary
   for TI-RPC(Transport independent RPC) and TS-RPC(Socket based RPC).










draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 1]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


Table of Contents

    1.  Introduction ....................................................  3

    2.  Design Considerations ...........................................  3

    3.  Brief overview of RPC ...........................................  3

    4.  Transport Selection .............................................  4

    5.  ONC+ RPC API ....................................................  5
       5.1.  TI-RPC API .................................................  5
       5.2.  TS-RPC API .................................................  7
       5.3.  New Options ................................................ 10
       5.4.  Broadcast RPC API .......................................... 10

    6.  RPC Address lookup and registration service ..................... 11

    7.  Security Considerations ......................................... 12

    8.  Year 2000 considerations ........................................ 12

    9.  References ...................................................... 13

   10.  Acknowledgements ................................................ 13

   11.  Author's Addresses .............................................. 13
























draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 2]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


1.  Introduction

   ONC+ RPC is used to develop many different distributed application
   and services.  In most cases RPC uses TCP or UDP running over
   IP version 4 as the transport protocol.  This document describes
   the issues to make RPC work over IP version 6. There are
   two variants to RPC implementation, one is called TI-RPC (Transport
   Independent RPC) and the other one is TS-RPC (Socket based RPC).
   Even though TI-RPC is supposed to be transport independent, in
   practice it is exposed to IP address in many places. This memo
   describes the set of extensions and modification to RPC to enable
   RPC to work over IPv6.




2.  Design Considerations

   There are number of important consideration in designing changes to this well
   known API sets.


   1)  The API change should allow both source and binary compatibility
       for programs written to original API. Existing program should
       continue to operate as before when run using this new RPC over
       Ipv6. Existing application which are recompiled and run on system
       with RPC over IPv6 should continue to work. Existing binary
       should be able to use IPv6 wherever possible.

   2)  The RPC API function prototype should not be changed. This eases
       the porting effort and maintains compatibility.

   3)  Where possible, application should be able to use IPv6
       transparently without any change in application. Simply put an
       application should be able to inter operate with both IPv4 and
       IPv6 host and it need not know what type of host it is
       communicating with.


3.  Brief overview of RPC

   This section describes how RPC client and server program
   communicates.  The following steps outlines a typical RPC server.


   1)    Contact rpcbind/portmapper service to register the service. The
         service also receives a port number to bind to.




draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 3]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   2)    Bind the server address and port and listen to incoming
         requests.

   3)    Service the request and send reply.

   A typical RPC client takes the following steps.

   1)    Contact the portmapper or rpcbind of the server machine and
         then get the port number(address) for the particular RPC
         service it is interested in. Often times this step is preceded
         by a name lookup call to get remote server's address. At the
         end of this step client application gets a client handle which
         is subsequently used for all communications.

   2)    Connect to the remote server using the port number received
         from portmapper/rpcbind.

   3)    Send a RPC request (typically done via clnt_call() API) and
         process the response.



4.  Transport Selection

   One of the design goal is make application ignorant about type of
   host it is communicating with, that is IPv4 host or IPv6 host.  An
   IPv6 enabled client and server should communicate over IPv6
   automatically. Both TI-RPC and TS-RPC solves this in different ways.

   Transport selection in TI-RPC is governed by the NETPATH environment
   or by a configuration file (netconfig). There are two new entries for
   UDP/IPv6 and TCP/IPv6 in this configuration file and these two should
   be the first two entries in the configuration file. TI-RPC typically
   would try the first available transport so this ordering is important
   for IPv6 enabled client to use RPC over IPv6. The client should  fall
   back to IPv4 in the event it fails to communicate with the remote
   server using IPv6. The advantage of this approach is that an existing
   application developed using high level RPC API instantly works over
   IPv6. However an application may choose to use a certain transport by
   using a low level RPC API and communicating with selected device
   (UDP/IPv4, TCP/IPv4, UDP/IPv6 or TCP/IPv6).

   Socket based RPC depends on name lookup service to return IPv6
   address for the remote host in order to use IPv6 as transport. This
   is mostly done by using getipnodebyname() call from  the RPC library.
   However unlike TI-RPC this does not allow existing binaries to
   support IPv6 over RPC automatically.  The newly developed application
   should look for IPv6 address for host at first, failing that the RPC



draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 4]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   library should fall back to IPv4 address lookup for the host. TS-RPC
   does provide the ability to use specific transport e.g UDP/IPV4,
   UDP/IPV6 etc. by passing the appropriate  socket descriptor to the
   appropriate RPC API. The next section describes these issues in more
   detail.



5.  ONC+ RPC API

   The major effort in supporting IPv6 in RPC goes in client and server
   transport handle creation. These handles have intimate knowledge
   about host address and type and stores either a TLI end point file
   descriptor or socket descriptor. Subsequent calls use these handles
   to transfer data between client and server. The following section
   describes these APIs in more detail. or



5.1.  TI-RPC API

   TI-RPC has not modified any RPC API to support IPv6. The function
   parameters and their meaning remains same. To ease programming burden
   TI-RPC typically supplies a high level set of RPC APIs which takes
   care of most of the steps necessary. Some of the high level APIs are
   listed below.

         rpc_reg()
         rpc_call()
         callrpc()
         rpc_broadacast()


   These APIs are capable of selecting IPv6 automatically  by using IPv6
   specific "netid" and that enables most programs including old
   binaries to run over IPv6 without any porting effort.

   A client application typically calls clnt_create() to create a client
   handle to communicate with remote server. The API is shown below.


           CLIENT *
           clnt_create(const char *hostname, rpcprog_t prog,
                       rpcvers_t vers, const char *nettype)


   Clients typically uses nettype "udp" or "tcp". The system then
   consults the configuration file which list udp/ipv4, udp/ipv6 etc.



draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 5]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   and chooses the first match and creates the client handle.  It tries
   for all the netids in that particular class of netid until it
   succeeds. It is for that reason the IPv6 related netid entries should
   be placed before IPv4 specfic netids in the configuration file. It is
   then responsible for getting network specific(IPv4 or IPV6) address
   of the remote host using netdir_getbyname() with the currently chosen
   netid. After that it contact rpcbind service on the remote server
   over the chosen transport and seeks the universal address for the
   service.

   An application wishing to use udp creates client handle in the
   following way and RPC automatically tries UDP/IPv6 if the client is
   IPv6 enabled.

           clnt_create(server_name, rpc_prognum, rpc_progvers, "udp")

   A server routine similarly calls svc_create() to create server
   transport handles for all available transport which belongs to that
   particular netid class. In a dual host server this enables server to
   listen to requests coming via IPv4 or IPv6.  The prototype
   svc_create() is given below.

           int
           svc_create(dispatch, prognum, versnum, nettype)
               void (*dispatch)();     /* Dispatch function */
               rpcprog_t prognum;      /* Program number */
               rpcvers_t versnum;      /* Version number */
               const char *nettype;    /* Network id */



   There are several intermediate and expert level API for client handle
   creation which provides more control e.g selecting specific
   transport, selecting maximum timeout period, other transport specific
   parameter etc. Binary application using these set of APIs may not use
   IPv6 automatically.  be The following are low level client handle
   creation APIs,


           clnt_tp_create()
           clnt_tp_create_timed()
           clnt_tli_create()
           clnt_vc_create()
           clnt_dg_create()


   For example an application wishing to use tcp over IPv6 will use
   steps like below to create client transport handle,



draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 6]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   1)    Get the associated netconfig structure to TCP/IPv6 by using
         setnetconfig()/getnetconfig() or by getnetconfigent().

   2)    Get the universal address of the RPC program running on the
         remote server using rpcb_get().

   3)    Open the device associated with TCP/IPv6 and get a file
         descriptor for later TLI bind.

                  fd = t_open(nc_device,...)

         where nc_device points to the device for TCP/IPv6. After
         binding fd represents a TLI endpoint created to the remote
         server over TCP/IPv6.

   4)    Create the transport handle.

                  clnt_vc_create(fd, server_address, rpc_prognum, rpc_progvers,
                                  sendsz, rcvsz)


   The server_address is the remote server address expressed by netbuf
   structure. This creates the client handle subsequently used by
   clnt_call() to communicate with the remote server.

   Clearly this provides more control to a  program. However a
   sophisticated program might need to be ported in order to support
   IPv6.

   Low level server handle creation APIs are also available to server
   side RPC.


           svc_tp_create()
           svc_tli_create()
           svc_dg_create()
           svc_vc_create()
           svc_reg()


   TI-RPC makes the IPv6 support much easier to put with it's use of
   generic network address storage structure and use of network
   identifier to name a few.



5.2.  TS-RPC API




draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 7]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   IPv6 extensions to TS-RPC is more involved since it is exposed to
   socket address representation. There are no changes with TS-RPC APIs
   except the fact that TS-RPC APIs can take either IPv4 or IPv6 socket,
   and the allocated space for return value should be big enough to
   manage either IPv4 or IPv6 socket. Since the IPv4 socket interface
   remains intact, old applications do not need changes and operate over
   IPv4 protocol as before. In addition, they are able to inter operate
   with IPv6 enabled server program running over dual protocol host
   (both IPv4 and IPv6).

   The commonly used client handle creation API prototypes are shown
   below,


             CLIENT *
             clnt_create(char *rhost, rpcprog_t program, rpcvers_t version
                             char *protocol)
             rhost -> name of the remote server
             protocol -> "udp" or "tcp"


             CLIENT *
             clntudp_create( struct sockaddr_in *raddr, rpcprog_t program,
                             rpcvers_t version, struct timeval wait,
                             register int *sockp)
             raddr -> remote server's protocol address.


              CLIENT *
              clnttcp_create( struct sockaddr_in *raddr, rpcprog_t prog,
                      rpcvers_t vers, register int *sockp,
                      u_int sendsz, u_int recvsz)


   A RPC client wishing to communicate to remote program will first use
   clnt_create(), clntudp_create() or clnttcp_create()  API to get a
   client handle for further use.

   clnt_create() does a getipnodybyname() call to retrieve remote host's
   IPv6 address. In case of IPv4 only remote host it returns a mapped
   IPv4 address which is unmapped and converted to a sockaddr_in type
   storage. It then proceeds to create appropriate type (AF_INET or
   AF_INET6) of socket

   The API clntudp_create() provides more control to programmer.  In
   clntudp_create() the first argument raddr points to the remote
   server's address which could be either IPv6 address or IPv4 address,
   which means raddr may point to a sockaddr_in6 structure.  The routine



draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 8]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   must determine the address type by looking into the sin_family first.

            if (((struct sockaddr_in *)raddr)->sin_family == AF_INET6) {
                       ......
            }

   if *sockp is not defined i.e. (sockp == RPC_ANYSOCK) then a
   appropriate socket must be created. Again the socket type created is
   AF_INET6 if raddr points to a IPv6 protocol address. The next step
   for all types of clnt_create() is to contact the remote servers
   portmapper to get the port number for the remote service. Since
   portmapper protocol does not distinguish between IPv4 or IPv6 the
   returned port number might not be valid one for IPv4 client. This
   possesses a difficulty for UDP based communication. Suppose service A
   on server Y is only registered over UDP/IPv4 and listening to port
   23. Client X(IPv6 enabled) portmap request to Y for A will return 23.
   But subsequent clntudp_call() will fail because A is not listening
   over IPv6. To avoid this situation udp based clnt_create() shall send
   a NULL RPC call to the remote server(Y). If the remote server returns
   ICMP port unreachable error then clntudp_create() shall fail and RPC
   application is expected to retry using IPv4 address. However this
   retry is done automatically by clnt_create() and it returns a handle
   which can be used for IPv4 based UDP service.

   TCP based client handle creation routine using clnt_create() or
   clnttcp_create() is easier to implement. TCP connection to the server
   must fail when server port is not listening over particular
   transport. API clnt_create() will then fail over to TCP/IPv4 as
   described above. However clnttcp_create() will return error.

   It is recommended that applications use clnt_create() to create
   appropriate client handle and then use clnt_control() for finer
   control.

   All client handle creator API stores remote server address which is
   allocated and managed by RPC routines. This allocated space must be
   enough to store IPv6 address.  The suggested structure for this
   purpose is to use sockaddr_storage as defined in RFC2553[2].

   The server side APIs to create server transport handle are,


           svctcp_create()
           svcudp_create()


   Server side uses server transport handle(SVCXPRT) which is similar to
   client handle used by client side APIs. A RPC server created a



draft-ietf-nfsv4-rpc-ipv6-00.txt                                [Page 9]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   transport handle as one of the first initialization step. For example
   a server wishing to listen over TCP will create code fragment similar
   to this,


            SVCXPRT *xprt = svctcp_create(sock_fd, SENDSZ, RECVSZ)


   If the sock_fd is provided then this is simply stored in transport
   handle.

   However if user passes RPC_ANYSOCK which asks the library to pickup a
   socket descriptor for the application, then this API should create a
   AF_INET6 type socket if IPv6 is present and AF_INET type in case of
   IPv4 only. Recall that a AF_INET6 type of socket does listen to both
   IPv4 and IPv6 traffic and thus allows to service both types of
   client. Again server transport handle should allocate sizeof (struct
   sockaddr_storage) amount of space to provide enough space for both
   IPv4/IPv6 address type.



5.3.  New Options

   RPC has a client side API to change or retrieve client
   characteristics, including timeout, UDP retry timeout etc. RPC should
   take advantage of IPv6 by giving a new option to set flow label and
   traffic class. A pair of new options CLSET_TRAFFIC_CLASS and
   CLSET_FLOW_LABEL needs to be created to support this.


           clnt_control(clnt, CLSET_TRAFFIC_CLASS, info)


   Right now details about these are sketchy enough to define it in more
   thorough fashion. There may be need to support other options. In
   future it might be necessary to put control on server side too by
   using svc_control() API which is not defined in present RPC.



5.4.  Broadcast RPC API

   RPC has a notion of broadcast RPC call which allows a client program
   to call server program without knowing the remote server's address.
   If there are more than one server in the broadcast domain then client
   will get more than one answer. IPv6 does not have any concept of
   broadcast address similar to IPv4. IPv6 enabled RPC service must join



draft-ietf-nfsv4-rpc-ipv6-00.txt                               [Page 10]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   a well known multicast group, which is FF02::202. A IPv6 host is
   expected to remain in this group for it's entire life and should
   rejoin this group if the node leaves this multicast group for any
   reason. ONC RPC uses rpcbind or portmapper service to join this group
   early during boot phase.

   TI-RPC uses rpc_brodcast() function and TS-RPC uses clnt_broadcast()
   to brodcast RPC requests. The implementation to support IPv6 here is
   minimal.



6.  RPC Address lookup and registration service

   RPC service uses well known address (portmap and/or rpcbind) lookup
   service to resolve remote server address given the RPC program and
   version number[2]. There are three versions of a lookup service all
   of which uses the same RPC program number (100000) and well known
   port (111). Versions 3 and 4 are known as rpcbind and version 2 is
   known as portmap which is widely used. Both portmapper and rpcbind
   should listen over IPv4 and IPv6 based transports in order to service
   IPv6 as well as IPv4 hosts.

   A TI-RPC RPC server typically registers itself with RPCBIND running
   on the system.  The program passes program number, version number and
   network identifier ( "netid"). TI-RPC uses two new network
   identifiers ("udp6" and "tcp6") to add IPv6 support in RPCBIND. A
   client application looking for server "universal address" sends
   program number, version number and network identifier. In the case of
   IPv6 client program it sends this request with IPv6 specific netid
   ("udp6" or "tcp6"). The server actually ignores the "netid" and
   infers that from the network identifier of the transport the request
   arrived. The universal address for IPv6 enabled service is
   represented by concatenating IPv6 address followed by port numbers.
   Examples are given below.

             2::a8:a00:20ff:fe8c:9403:0.23 - listening on port 23
             ::.23.34 - listening on port 2334


   RPCBIND is able distinguish between IPv6 and IPv4 with the help
   network protocol family("inet6" versus "inet"). RFC 1833 currently
   does not list "inet6" and this issue should be addressed. RPCBIND
   should be the preferred address lookup service over much widely used
   portmapper service.

   The portmapper support for IPv6 is bit restricted. RPC server
   registering with portmapper passes on program number, version number



draft-ietf-nfsv4-rpc-ipv6-00.txt                               [Page 11]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


   and protocol number "prot". RFC 1833 which describes BINDING protocol
   for ONC RPC has defined two protocols, IPPROTO_UDP(#6) and
   IPPROTO_TCP(#17). This does not differentiate between UDP/TCP running
   over IPv4 and IPv6. Thus portmapper is restricted to use same port
   number while binding a service over both IPv4 and IPv6. Section 5.2
   already describes the method by which clients solves the problem.



7.  Security Considerations

   RPC has provisions for several different security mechanism which are
   different from security mechanism and purposes of IPv6.



8.  Year 2000 considerations

   There are no issues for this memo concerning the year 2000 issue
   regarding the date.































draft-ietf-nfsv4-rpc-ipv6-00.txt                               [Page 12]


INTERNET-DRAFT          IPv6 extensions to RPC        February 21, 2001


9.  References


   [1]   Srinivasan, R., "Remote Procedure Call Protocol Version 2",
         RFC-1831, Sun Microsystems, 1995.

   [2]   Deering, S., Hinden, R., "Internet Protocol, Version 6 (IPv6),
         Specification", RFC 2460, Dec. 1998.

   [3]   "ONC+ Developer's Guide, SUN Microsystems,
         http://docs.sun.com:80/ab2/coll.45.10/ONCDG/@Ab2TocView?"

   [4]   Gilligan, R. E., Thomson, S., Bound, J., Stevens, W., "Basic
         Socket Interface Extensions for IPv6", RFC 2553, March 1999.


10.  Acknowledgements

   Linda Wu started the work to extend TI-RPC over IPv6. The following
   provided comments during the writeup.  Alex Chiu, Mike Eisler and
   Erik Nordmark.


11.  Author's Addresses

    Sumandra Majee
    Cisco Systems, Inc.
    170 West Tasman Drive
    San Jose, CA 95134
    Phone: +1 (650) 786-4221

    E-mail: smajee@cisco.com


    Pearl Park
    Nixxo Technologies, Inc.
    2855 Zanker Road
    San Jose, CA 95134
    Phone: +1 (408) 468-1517

    E-mail: ppark@nixxotech.com










draft-ietf-nfsv4-rpc-ipv6-00.txt                               [Page 13]