12.3. Protocol-Protocol Interface The interface between protocol modules uses the pr_usrreqs() routines as well as the pr_ctloutput() routine. The pr_usrreqs() and pr_ctloutput() routines are used by the socket layer to communicate with protocols. Although imposing a standard calling convention for all of a protocol's entry points might theoretically permit an arbitrary interconnection of protocol modules, it would be difficult in practice. Crossing of a protocol-family boundary for example, between IPv4 and IPX would require a network address to be converted from the format of the caller's domain to the format of the receiver's domain. Consequently, connection of protocols in different communication domains is not generally supported, and calling conventions for the routines listed in the preceding paragraph are typically standardized on a per-domain basis. (However, the system does support encapsulation of packets from one protocol into packets of a protocol in another family to tunnel one protocol through another.) In this section, we briefly examine the general framework and calling conventions of protocols. In Chapter 13, we examine specific protocols to see how they fit into this framework. pr_output Each protocol has a different calling convention for its output routine. This lack of standardization is one of the things that prevents protocol modules from being freely interchanged with each other in arbitrary stacks, such as is done in the STREAMS system [Ritchie, 1984]. Thus far this kind of standardization has not been considered necessary because each protocol stack tends to stand on its own without ever borrowing from others. An arbitrary stacking of protocol modules would also complicate the interpretation of network addresses in each module, since each would have to check to make sure that the address made some sense to them in their domain. The simplest example of a protocol output routine often uses a calling convention designed to send a single message on a connection; for example, int (*pr_output)( register struct inpcb *inp, struct mbuf *msg, struct sockaddr *addr struct mbuf *control, struct thread *td); would send a message contained in msg on a socket described by protocol control block inp. Special address and control information are passed in addr and control, respectively. pr_input Upper-level protocol input routines are usually called by the network software-interrupt task once the network-level protocol has located the protocol identifier. They have stricter conventions than do output routines because they are called via the protocol switch. Depending on the protocol family, they may receive a pointer to a control block identifying the connection, or they may have to locate the control block from information in the received packet. A typical calling convention is void (*pr_input)( struct mbuf *msg, int hlen); In this example, the incoming packet is passed to a transport protocol in an mbuf msg with the network protocol header still in place for the transport protocol to use, as well as the length of the header, hlen, so that the header can be removed. The protocol does the endpoint-level demultiplexing based on information in the network and transport headers. pr_ctlinput This routine passes control information (i.e., information that might be passed to the user but does not consist of data) upward from one protocol module to another. The common calling convention for this routine is void (*pr_ctlinput)( int cmd, struct sockaddr *addr, void* opaque); The cmd parameter is one of the values shown in Table 12.4. The addr parameter is the remote address to which the condition applies. Many of the requests have been derived from the Internet Control Message Protocol (ICMP) [Postel, 1981] and from error messages defined in the 1822 host (Internet Message Processor) convention [BBN, 1978]. Some protocols may pass additional parameters internally, such as local addresses or more specific information. Table 12.4. Control-input routine requests.Request | Description |
---|
PRC_IFDOWN | network interface transition to down | PRC_ROUTEDEAD | select new route if possible | PRC_IFUP | network interface has come back up | PRC_QUENCH | some receiver said to slow down | PRC_QUENCH2 | DEC congestion bit says slow down | PRC_MSGSIZE | message size forced packet to be dropped | PRC_HOSTDEAD | remote host is down | PRC_HOSTUNREACH | remote host is unreachable | PRC_UNREACH_NET | no route to network | PRC_UNREACH_HOST | no route to host | PRC_UNREACH_PROTOCOL | protocol not supported by destination | PRC_UNREACH_PORT | port number not in use at destination | PRC_UNREACH_SRCFAIL | source routing failed | PRC_REDIRECT_NET | routing redirect for a network | PRC_REDIRECT_HOST | routing redirect for a host | PRC_REDIRECT_TOSNET | routing redirect for type of service and network | PRC_REDIRECT_TOSHOST | routing redirect for type of service and host | PRC_TIMXCEED_INTRANS | packet lifetime expired in transit | PRC_TIMXCEED_REASS | lifetime expired on reassembly queue | PRC_PARAMPROB | header-parameter problem detected | PRC_UNREACH_ADMIN_PROHIB | packet administratively prohibited |
|