The IP over ATM Mailing List Archive by date

Cell Relay Retreat>List Archive>month:1995-Feb> msg00143



[Date Prev][Date Next][Thread Prev][Thread Next]  
  [Date Index][Thread Index][Author Index][Subject Index]

Fixed-length format for (In)ATMARP?

  • From: Carl Marcinik <carlm@fore.com>
  • Date: Sun, 26 Feb 1995 18:03:03 -0500
  • CC: ip-atm@matmos.hpl.hp.com, atmiol@sun4.iol.unh.edu


Over the past few weeks questions and concerns have been raised with regard to 
the (In)ATMARP format. Vendors have interpreted and implemented RFC 1577 ATMARP
packet handling differently resulting in significant interoperabilty problems. 
(These problems have been somewhat temporarily alleviated by some vendors by 
being very loose in what they regard as a valid ATMARP packet). I have had the 
opportunity to discuss the issue with several individuals during this time 
(Maryann Perez - ISI, Uttam Shikarpur - DEC, Bryan Gleeson - Adaptec, David 
Cosby -IBM, Ron Pashby - UNH ATM Interoperability Lab, Fong Ching Liaw - 
FORE Systems, and others), all of whom have raised a number of valid concerns 
and points. The issue, it seems, basically boils down to a choice between 
supporting a fixed length format, a variable length format (as Mark originally 
intended), or something in between (basically the variable length format with 
allowance for padding out of a target protocol address with zeros). There has 
been a fair amount of support in favor of the fixed-length format expressed 
over the last week or so, but it is not at all clear that we have achieved 
consensus on the matter. However, I believe that it is *important* for many 
vendors who want to ship products based on 1577, or move forward in their 
development, that we come to some kind of consensus now rather than later 
(long before April, hopefully).

Support for the fixed-length format arises mainly because of its implementation 
advantages over the variable length format. It also seems to be more consistent
in its approach than the "in between" format (which, at least by my reading, 
would have still allowed zero-length target hardware addresses). However, the 
fixed-length format approach has at least a few issues that need to be resolved 
for ATMARP. One of these issues concerns the use of PVCs. If one side of a PVC 
is administratively configured with an ATM address and the other not, then, with
a fixed-length (In)ATMARP format, we would need a way to indicate that one or 
the other of the ATM addresses was not present. This could be accomplished by 
filling the appropriate field with zeroes or perhaps (as Craig suggested) by 
setting a bit (or reserved value) in the corresponding address length field. 
(From an implementation perspective it would be preferable not to have to check
a given field to determine if it contained all zeros just to know what to do 
with it.) Generally, with traditional ARP the ar$op field lets you know which
fields are valid. It would be nice of we could maintain some consistency in 
this regard without introducing any ambiguity.

A similar issue also exists WRT to the use of subaddresses. Currently, RFC 1577 
allows for the case of a "LIS implemented over a combination of [presumably 
private] ATM LANs and public ATM networks." Although it is not clear that this
scenario would ever exist for a Classical IP network, if it did, circumstances 
similar to the PVC case outlined above would arise (and would necessarily 
require a means, such as that described above, to ascertain the actual contents
of the packet).  Another issue concerns the use of the (native) E.164 address 
format. It is the intention of RFC 1577 that an ATM number carried in an ATMARP
packet map to a corresponding Called or Calling Party Number Information 
Element (IE). In the native E.164 case, the Called or Calling Party Number IE 
(as has been pointed out to me by Bryan Gleeson on several occassions) truly 
supports a variable length format (which could incidently include an odd number
of address octets). This is certainly one case where a variable length 
(In)ATMARP packet format would seem to be beneficial. A scheme could be devised
to compensate for this case in a fixed-length format, however, this could 
become awkward. 
 
It seems to me (and to some that I have discussed the issue with) that the 
chief advantage to be gained by adopting a fixed-length format for ATMARP is 
the ability to reuse a packet buffer on replys. Additionally, (as pointed out 
by Criag and others) a fixed length format facilitates ease of packet handling.
I believe it is possible, however, to achieve most (but certainly not all) of 
the benefit of the fixed-length packet format while still retaining the 
flexibilty offerred by the variable length scheme in accomodating the cases 
discussed above. This could be accomplished by treating source and target 
address fields as separate cases in an (In)ATMARP request. Since we know which 
addresses exist and which do not at a requesting station, we could require that
ONLY known addresses occupy space in a request packet as source addresses (with
the source address length fields set to values indicating the actual number of 
octets supplied in the corresponding address fields). ALL non-existent (i.e., 
null) source addresses (e.g., a subaddress in a private ATM network, a PVC with
no administratively configured ATM address) MUST be indicated as null addresses
by specifiying a value of zero (0) in the corresponding address length field.
ALL target address fields (ATM number, subaddress, protocol) in a request, 
however, MUST be padded out to their maximum values. If the target subaddress 
field were padded out to 20 octets and the target protocol address padded out 
to 4 octets, then it probably would not be necessary to also pad out the ATM 
number to twenty 20 octets although I don't see this as being a big deal (16 
octets should suffice since I don't believe that an E.164 address would require
more than 15 octets of space). This would reserve adequate space in the packet 
to allow the target station to form its reply without the need to allocate 
another packet buffer. BTW, it is not necessary for the octets in the padded 
target address fields to contain any particular value as long as the 
corresponding target address length fields are set to their maximum values.  

An (In)ATMARP reply would be treated the same as a request in that only known 
addresses at the receiving station would be included as source addresses in the
reply packet (with the source address length fields set to values indicating 
the actual number of octets supplied). All non-existent (i.e., null) source 
addresses would be indicated by a length of zero (0) in the corresponding 
source address length field. All target addresses contained in the reply (which
were included as source addresses in the request) would be returned exactly as 
they were received (in regard to length, order, etc.) with the exception that 
they would now occupy the proper location in the packet relative to the amount 
of space occupied by the source addresses. Therefore, no padding would be 
necessary in a (In)ATMARP reply packet. 
 
Following Craig's lead, I've included a few code fragments to show that this 
approach wouldn't be all that bad.


struct atm_arp {
        u_short ar_hrd;         /* hardware type */
        u_short ar_pro;         /* protocol type */
        u_char  ar_shtl;        /* type & length of source ATM number */
        u_char  ar_sstl;        /* type & length of source ATM subaddress */
        u_short ar_op;          /* operation code (req, repl, nak) */
        u_char  ar_spln;        /* length of source protocol addr */
        u_char  ar_thtl;        /* type & length of target ATM number */
        u_char  ar_tstl;        /* type & length of target ATM subaddress */
        u_char  ar_tpln;        /* length of target protocol address */
	u_char  ar_sha[1];	/* start of address fields */
/*
	u_char  ar_ssa[];
	u_char  ar_spa[];
	u_char  ar_tha[];
	u_char  ar_tsa[];
	u_char  ar_tpa[];
*/

};


/*
 * Client side ATMARP Request. Assume SVC with no subaddress.
 * For emphasis, use no length constants or variables.
 */

atm_arpwhohas(ac, addr)
    struct arpcom *ac;
    struct in_addr *addr;
{
    register struct mbuf *m;
    struct atm_arp *aa;

    . . .

    aa = mtod(m, struct atm_arp *);
    aa->ar_hrd  = htons(ARPHRD_ATMFORUM);
    aa->ar_pro  = htons(ETHERTYPE_IP);
    aa->ar_shtl = 20;
    aa->ar_sstl = 0;
    aa->ar_op   = htons(ARPOP_REQUEST);
    aa->ar_spln = 4;
    aa->ar_thtl = 20;
    aa->ar_tstl = 20;
    aa->ar_tpln = 4;
    bcopy(&ac->ac_atmaddr, aa->arp_sha, 20); /* source ATM number */
    bcopy(&ac->ac_ipaddr, aa->arp_sha + 20, 4); /* source protocol address */
    bcopy(addr, aa->arp_sha + 64); /* target protocol address */

    . . .

}


/*
 * Server side ATMARP Request handling only. Ignore ARP_REPLY, 
 * ARP_REQUEST for my IP address, and most verification details.  
 */

#define AR_LEN(n) ((n) & ~0xc0)

atm_in_arpinput(ac, m)
    struct arpcom *ac;
    struct mbuf *m;
{
     struct atm_arp *aa;
     struct in_addr itaddr;   /* IP target address */
     int tlen, slen;          /* target, source lengths */

     aa = mtod(m, struct atm_arp *);

     . . .

     tlen = AR_LEN(aa->ar_shtl) + AR_LEN(aa->ar_sstl) + aa->ar_spln;
     bcopy(&ar->sha[tlen + AR_LEN(aa->ar_thtl) + AR_LEN(aa->ar_tstl)], 
	&itaddr, sizeof(struct in_addr)); 

     . . .

     ARPTAB_LOOK(at, itaddr.s_addr);

     . . .
     
     if (at) {
          aa->ar_thtl = aa->ar_shtl;
          aa->ar_tstl = aa->ar_sstl);
          aa->ar_tpln = aa->ar_spln; /* probably not necessary, but ... */
 
          slen  = AR_LEN(aa->ar_shtl = at->at_atmaddr_tl);
          slen += AR_LEN(aa->ar_sstl = at->at_atmsubaddr_tl);
          slen += sizeof(struct in_addr);

          bcopy(aa->ar_sha, aa->ar_sha + slen, tlen); /* source -> target */ 
          bcopy(at->at_atmaddr, aa->ar_sha, (tlen = AR_LEN(aa->ar_shtl)));

          if (AR_LEN(aa->ar_sstl)) {
              bcopy(at->at_atmsubaddr, &aa->ar_sha[tlen], AR_LEN(aa->ar_sstl));
              tlen += AR_LEN(aa->ar_sstl);
          } 
     
          bcopy(&itaddr, &aa->ar_sha[tlen], sizeof(struct in_addr));
          aa->ar_op = ARPOP_REPLY;

          . . . 

     } else { /* send ARP_NAK */

          /* I'm not touching this issue, I've already said enough */

     }
     
     . . .
}


Comments (other than that my post is too long)? 

Carl Marcinik
FORE Systems