cck%cunixc@COLUMBIA.EDU.UUCP (12/09/86)
Bill Schilit found the following problem with the udp code. Basically, the Kinetics gateway running the udp code cannot send or receive full size ip encapsulated AppleTalk packets. Problem: Kinetics gateway doesn't seem to forward full sized or nearly full sized appletalk packets from the Appletalk to Ethernet. Analysis: TBSZ in ie.h only accounts for 630 bytes. With all ip, udp, and ethernet headers added in, we need 645 bytes. Solution: Assume MAXDATA refers only to AppleTalk data. Increase TBSZ byte ETHER_HEADERS=(sizeof(udp header) + sizeof(ip header) + sizeof(ethernet header)) to account for additional data. Note: this take buffer to 672 bytes which is more than adequate. [Alternatively, set TBSZ to 645 (603 maximum appletalk data + 42 for udp encapsulation), but this isn't as conservative.] Problem: Kinetics gateway doesn't seem to receive full sized udp encapsulated appletalk packets from the ethernet. Analysis: RBSZ does not account for udp encapsulation data (e.g. ETHER_HEADERS). Solution: Increase RBSZ by ETHER_HEADERS. In addition, note that in pbuf, only MAXDATA (630) bytes are available in the data portion of pbuf. To account for this, we must start the pbuf offset back ETHER_HEADERS size (e.g. start reading data into header portion of pbuf) in ieframein. An alternative analysis is to consider MAXDATA undersized at 630 bytes and bump it to 645 bytes. Unfortunately, this requires we recompile "lap.s" which is in PROM on the Kinetics box. (It isn't even clear that we really would want to do this). Two files need to be modified to correct this problem: ie.h and ie.c. Context difference follow and can be applied using patch or by hand. Bill Schilit and Charlie C. Kim Columbia University ------ie.c.diff------ *** /tmp/,RCSt1006968 Mon Dec 8 19:12:59 1986 --- ie.c Mon Dec 8 19:12:50 1986 *************** *** 7,20 **** * (c) 1986, Kinetics, Inc. * May be used but not sold without permission. * ! * $Header: ie.c,v 1.1 86/12/08 12:50:25 bill Exp $ */ #include "gw.h" #include "fp/pbuf.h" - #include "ie.h" #include "ether.h" #include "ab.h" #include "fp/cmdmacro.h" extern char broadcastaddr[]; --- 7,21 ---- * (c) 1986, Kinetics, Inc. * May be used but not sold without permission. * ! * $Header: ie.c,v 1.4 86/12/08 19:12:41 cck Exp $ */ #include "gw.h" #include "fp/pbuf.h" #include "ether.h" #include "ab.h" + #include "inet.h" + #include "ie.h" #include "fp/cmdmacro.h" extern char broadcastaddr[]; *************** *** 291,299 **** /* get a buffer from the free list */ K_PGET(PT_ENET,pp); ! free = MAXDATA; if (pp) ! pp->p_off = cp = pp->p_data; for (rbdp = OTOA(struct r_bd *, rfdp->fd_rbd) ; rbdp->rbd.bd_count & SWAB(BD_F); rbdp = OTOA(struct r_bd *, rbdp->rbd.bd_next)) { --- 292,300 ---- /* get a buffer from the free list */ K_PGET(PT_ENET,pp); ! free = MAXDATA + ETHER_HEADERS; if (pp) ! pp->p_off = cp = (pp->p_data - ETHER_HEADERS); for (rbdp = OTOA(struct r_bd *, rfdp->fd_rbd) ; rbdp->rbd.bd_count & SWAB(BD_F); rbdp = OTOA(struct r_bd *, rbdp->rbd.bd_next)) { *************** *** 327,333 **** #endif STATS if (pp) { K_SPLIMP(&pri); ! pp->p_len = MAXDATA - free; p_if(pp) = &ifie; /* enqueue a buffer to the rec'd packet queue */ K_PENQNP(pq,pp); --- 328,334 ---- #endif STATS if (pp) { K_SPLIMP(&pri); ! pp->p_len = (MAXDATA+ETHER_HEADERS) - free; p_if(pp) = &ifie; /* enqueue a buffer to the rec'd packet queue */ K_PENQNP(pq,pp); *************** *** 356,363 **** --- 357,370 ---- K_PDEQNP(sendq,p); bcopy(p->p_off, &tbd[0].t_buf[0], p->p_len); + #ifdef notdef if (p->p_len < 64) p->p_len = 64; + #else + /* shouldn't count crc bytes */ + if (p->p_len < 60) + p->p_len = 60; + #endif tbd[0].tbd.bd_count = SWAB(p->p_len | BD_EOF); /* put the buffer back on the free list */ ------------------------ 30 ----------------------- ------ie.h.diff------ *** /tmp/,RCSt1005763 Mon Dec 8 18:57:35 1986 --- ie.h Mon Dec 8 18:55:52 1986 *************** *** 7,13 **** * (c) 1986, Kinetics, Inc. * May be used but not sold without permission. * ! * $Header: ie.h,v 1.1 86/12/08 13:54:48 cck Exp $ */ /* --- 7,13 ---- * (c) 1986, Kinetics, Inc. * May be used but not sold without permission. * ! * $Header: ie.h,v 1.2 86/12/08 18:55:47 cck Exp $ */ /* *************** *** 48,56 **** --- 48,70 ---- #define BD_EL 0x8000 /* end of list */ /* + * ETHER_HEADERS defines the length of ethernet header plus ip header plus + * udp header for ip encapsulated packets. Theoretically, pkts can't + * be any bigger anyway. + * + */ + #define ETHER_HEADERS (sizeof(struct ip)+sizeof(struct udp)+ \ + sizeof(struct ether_header)) + + /* * transmit buffer */ + #ifdef notdef #define TBSZ MAXDATA + #else + /* must also account for ip data */ + # define TBSZ (MAXDATA+ETHER_HEADERS) + #endif struct t_bd { struct bd tbd; /* the buffer descriptor */ char t_buf[TBSZ]; /* the transmit data */ *************** *** 59,65 **** --- 73,84 ---- /* * receive buffer */ + #ifdef notdef #define RBSZ 640 /* receive buffer size */ + #else + /* must also account for ip data */ + #define RBSZ (MAXDATA+ETHER_HEADERS) + #endif struct r_bd { struct bd rbd; /* the buffer descriptor */ char r_buf[RBSZ]; /* the received data */ ------------------------ 30 -----------------------
cck%cunixc@COLUMBIA.EDU.UUCP (12/09/86)
Oh, I should also mention that one diff to ie.c makes the minimum ethernet packet 60 bytes vs. 64 bytes. Sometimes people put 64 in to account for the CRC bytes, but this isn't right with the 286 controller (well, changing this to 60 makes it do the right thing - send out 60 bytes min. sized pkts - in particular arp). Charlie C. Kim User Services Group Columbia University