diff -ur --new-file old/atm/CHANGES new/atm/CHANGES --- old/atm/CHANGES Fri Mar 27 00:20:46 1998 +++ new/atm/CHANGES Thu Apr 23 21:20:44 1998 @@ -1,3 +1,50 @@ +Version 0.35 to 0.36 (23-APR-1998) +==================== + +Bug fixes +--------- + + - changed the numeric values of PF/AF_ATMPVC/SVC and SOL_ATM/AAL to avoid + conflicts with other allocations. This breaks binary compatibility with + ATM programs compiled under older kernels + - RESTART ACK was sent with the wrong class when acknowledging the restart of + the indicated virtual channel (fix by Mohsen Souissi) + - RELEASE was retransmitted forever (to avoid having to perform a RESTART), + although it's sufficient to retransmit once and then drop the connection + - esi.c checked the kernel version code without including linux/version.h + - CLIP changes magically fixed hangs on SICGIFCONF (reported by Wayne Salamon) + - atmsigd usually didn't set pvc.sap_family in ISP messages + +New features +------------ + + - added build-time option -DTHOMFLEX to send RESTART when SAAL comes up, which + works around a bug in some Thomson Thomflex 5000 switches (by Mohsen + Souissi) + - atmtcp: new option "-i itf" to request a specific interface number + - the "debug switch" (switch/debug/sw_debug) is now capable of successfully + signaling a UNI 3.x call (see switch/debug/README for details) + +Other changes +------------- + + - atm_equal can now also compare PVC addresses. The argument type has + therefore been changed from struct sockaddr_atmsvc * to struct sockaddr * + - moved driver-private data from skb->atm.* into skb->cb + - complete redesign of communication between atmarp(8) and atmarpd(8) (now + uses a UNIX domain socket; suggested by Alexey Kuznetsov) + - atmarp -a now also produces correct output if atmarpd is running with -d + - removed clip(8) + - moved atmarp(8) from atm/ip into atm/arpd, removed atm/ip + - /proc/atm/svc shows listening sockets again + - cleaned up a few cases where diag(...,DIAG_FATAL,...) was followed by an + "else" or a "return". + - atmsigd now uses Unix domain sockets (instead of named pipes) to communicate + with non-kernel ISP users (updated test/isp too) + - net/atm/resources.c:atm_dev_register can now be asked to assign a specific + interface number (-1 yields the old behaviour) + + Version 0.34 to 0.35 (27-MAR-1998) ==================== diff -ur --new-file old/atm/Makefile new/atm/Makefile --- old/atm/Makefile Mon Feb 16 16:34:17 1998 +++ new/atm/Makefile Sat Apr 11 12:45:10 1998 @@ -2,7 +2,7 @@ # "lib" must appear before anything else # "maint" must appear after "qgen" -DIRS=lib ip test debug qgen saal sigd maint arpd ilmid aqd man led lane #extra +DIRS=lib test debug qgen saal sigd maint arpd ilmid aqd man led lane #extra all: for n in $(DIRS); do $(MAKE) -C $$n || exit; done diff -ur --new-file old/atm/README new/atm/README --- old/atm/README Fri Mar 27 00:55:21 1998 +++ new/atm/README Thu Apr 23 20:55:09 1998 @@ -1,4 +1,4 @@ -ATM on Linux, release 0.35 (alpha) by Werner Almesberger, EPFL ICA +ATM on Linux, release 0.36 (alpha) by Werner Almesberger, EPFL ICA ============================================== Werner.Almesberger@epfl.ch This is experimental software. There are known major bugs and certainly diff -ur --new-file old/atm/Rules.make new/atm/Rules.make --- old/atm/Rules.make Thu Mar 26 23:07:08 1998 +++ new/atm/Rules.make Thu Apr 9 08:45:39 1998 @@ -26,6 +26,15 @@ # course makes our clearing procedure slightly non-conformant): # # STANDARDS += -DCISCO +# +# Some versions of the Thomson Thomflex 5000 won't do any signaling before they +# get a RESTART. Uncomment the next line to enable sending of a RESTART +# whenever SAAL comes up. Note that the RESTART ACKNOWLEDGE sent in response to +# the RESTART will yield a warning, because we don't implement the full RESTART +# state machine. +# +# STANDARDS += -DTHOMFLEX +# ifeq ($(TOPDIR),) TOPDIR=.. diff -ur --new-file old/atm/USAGE new/atm/USAGE --- old/atm/USAGE Fri Mar 27 01:07:35 1998 +++ new/atm/USAGE Thu Apr 23 20:57:29 1998 @@ -1,5 +1,5 @@ -Usage instructions - ATM on Linux, release 0.35 (alpha) ---------------------------------------------------------- +Usage instructions - ATM on Linux, release 0.36 +------------------------------------------------- For updates of ATM on Linux, please check the Web page at http://lrcwww.epfl.ch/linux-atm/ @@ -17,7 +17,7 @@ In order to install this package, you need - the package itself - ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.35.tar.gz + ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.36.tar.gz - the Linux kernel, version 2.1.90, e.g. from ftp://ftp.kernel.org/pub/linux/kernel/v2.1/linux-2.1.90.tar.gz - Perl, version 4 or 5 @@ -33,7 +33,7 @@ all the files listed above there. Then extract the ATM on Linux distribution: -tar xfz atm-0.35.tar.gz +tar xfz atm-0.36.tar.gz and the kernel source: @@ -56,8 +56,7 @@ esi, sonetdiag, saaldump, and zntune atm/test/ Test programs: align, aping, aread, awrite, br, bw, isp, ttcp_atm, window - atm/ip/ IP over ATM: atmarp - atm/arpd/ ATMARP demon: atmarpd + atm/arpd/ ATMARP tools and demon: atmarp, atmarpd atm/led/ LAN Emulation demon: led atm/lane/ LAN Emulation servers: bus, lecs, les atm/aqd/ Arequipa demon: aqpvc, arequipad diff -ur --new-file old/atm/VERSION new/atm/VERSION --- old/atm/VERSION Fri Mar 27 00:27:37 1998 +++ new/atm/VERSION Thu Apr 23 20:54:41 1998 @@ -1 +1 @@ -0.35 +0.36 diff -ur --new-file old/atm/arpd/Makefile new/atm/arpd/Makefile --- old/atm/arpd/Makefile Fri Mar 13 22:02:38 1998 +++ new/atm/arpd/Makefile Sat Apr 11 12:44:27 1998 @@ -3,8 +3,9 @@ #LIBS=-lfl # lex may want -ll here #INCLUDES= OBJS=atmarpd.o arp.o io.o itf.o table.o -BOOTPGMS=atmarpd -MAN8=atmarpd.8 +BOOTPGMS=atmarp atmarpd +MAN8=atmarp.8 atmarpd.8 +SYSHDR=atmarpd.h include ../Rules.make diff -ur --new-file old/atm/arpd/arp.c new/atm/arpd/arp.c --- old/atm/arpd/arp.c Wed Mar 25 20:30:39 1998 +++ new/atm/arpd/arp.c Tue Apr 14 11:37:40 1998 @@ -21,6 +21,7 @@ #include "atm.h" #include "atmd.h" +#include "atmarpd.h" #include "table.h" #include "itf.h" @@ -498,13 +499,15 @@ } if (!atmsvc_addr_in_use(*addr)) addr = NULL; if (entry->addr && addr && (entry->flags & ATF_PERM) && - !atm_equal(entry->addr,addr,0,0)) { + !atm_equal((struct sockaddr *) entry->addr,(struct sockaddr *) addr,0,0)) + { diag(COMPONENT,DIAG_ERROR,"ignoring attempt to change ATM address of " "permanent entry"); return; } if (entry->state == as_valid && entry->ip == ip && (!addr || (entry->addr - && atm_equal(entry->addr,addr,0,0)))) return; /* no news */ + && atm_equal((struct sockaddr *) entry->addr,(struct sockaddr *) addr,0, + 0)))) return; /* no news */ STOP_TIMER(entry); entry->ip = ip; if (!entry->itf) { @@ -835,68 +838,56 @@ } -int arp_ioctl(int itf_num,unsigned long cmd,struct atmarpreq *req) +int arp_ioctl(struct atmarp_req *req) { ITF *itf; char buffer[MAX_ATM_ADDR_LEN+1]; - uint32_t ip; unsigned char *ipp; - diag(COMPONENT,DIAG_DEBUG,"arp_ioctl 0x%08lx",cmd); - if (req->arp_pa.sa_family != AF_INET) { - diag(COMPONENT,DIAG_ERROR,"SIOCxARP: bad PA AF 0x%x", - req->arp_pa.sa_family); - return -EPFNOSUPPORT; - } - ip = ((struct sockaddr_in *) &req->arp_pa)->sin_addr.s_addr; - ipp = (unsigned char *) &ip; - if (!(itf = lookup_itf(itf_num))) { - diag(COMPONENT,DIAG_ERROR,"itf %d not found",itf_num); - return -EPROTO; - } - switch (cmd) { - case SIOCSARP: - if (req->arp_flags & ATF_DEFQOS) { - diag(COMPONENT,DIAG_DEBUG,"got SIOCSARP ATF_DEFQOS for itf %d", - itf_num); - itf->qos = req->arp_qos; - return 0; - } + diag(COMPONENT,DIAG_DEBUG,"arp_ioctl %d",req->type); + itf = lookup_itf_by_ip(req->ip); + if (!itf) return -EHOSTUNREACH; + if (!(req->ip & ~itf->netmask) && !(req->flags & ATF_ARPSRV) && + req->type != art_qos) return -EADDRNOTAVAIL; + ipp = (unsigned char *) &req->ip; + switch (req->type) { + case art_qos: + diag(COMPONENT,DIAG_DEBUG,"got art_qos for itf %d",itf->number); + itf->qos = req->qos; + return 0; + case art_set: if (atm2text(buffer,MAX_ATM_ADDR_LEN+1, - (struct sockaddr *) &req->arp_ha,pretty) < 0) { - diag(COMPONENT,DIAG_ERROR,"a2t fails on SIOCSARP"); + (struct sockaddr *) &req->addr,pretty) < 0) { + diag(COMPONENT,DIAG_ERROR,"a2t fails on art_set"); return -EINVAL; } - diag(COMPONENT,DIAG_DEBUG,"got SIOCSARP for itf %d, IP %d.%d.%d.%d" - ", ATM %s, flags 0x%x",itf_num,ipp[0],ipp[1],ipp[2],ipp[3],buffer, - req->arp_flags); - if (!req->arp_qos.txtp.traffic_class && - !req->arp_qos.rxtp.traffic_class) req->arp_qos = itf->qos; - switch (req->arp_ha.sas_family) { + diag(COMPONENT,DIAG_DEBUG,"got art_set for itf %d, IP %d.%d.%d.%d" + ", ATM %s, flags 0x%x",itf->number,ipp[0],ipp[1],ipp[2],ipp[3], + buffer,req->flags); + if (!req->qos.txtp.traffic_class && !req->qos.rxtp.traffic_class) + req->qos = itf->qos; + switch (req->addr.sas_family) { case AF_ATMPVC: - adjust_qos(itf,&req->arp_qos,req->arp_flags & ATF_NULL); - return ioctl_set_pvc(itf,((struct sockaddr_in *) - &req->arp_pa)->sin_addr.s_addr,(struct sockaddr_atmpvc *) - &req->arp_ha,&req->arp_qos,req->arp_flags); + adjust_qos(itf,&req->qos,req->flags & ATF_NULL); + return ioctl_set_pvc(itf,req->ip, + (struct sockaddr_atmpvc *) &req->addr,&req->qos, + req->flags); case AF_ATMSVC: - adjust_qos(itf,&req->arp_qos,0); - return ioctl_set_svc(itf,((struct sockaddr_in *) - &req->arp_pa)->sin_addr.s_addr,(struct sockaddr_atmsvc *) - &req->arp_ha,&req->arp_qos,req->arp_flags); + adjust_qos(itf,&req->qos,0); + return ioctl_set_svc(itf,req->ip, + (struct sockaddr_atmsvc *) &req->addr,&req->qos, + req->flags); default: /* not reached - atm2text complains before */ - diag(COMPONENT,DIAG_ERROR,"SIOCSARP: bad HA AF 0x%x", - req->arp_ha.sas_family); + diag(COMPONENT,DIAG_ERROR,"art_set: bad HA AF 0x%x", + req->addr.sas_family); return -EINVAL; } - case SIOCGARP: - diag(COMPONENT,DIAG_DEBUG,"got SIOCGARP for itf %d",itf_num); - return -ENOSYS; - case SIOCDARP: - diag(COMPONENT,DIAG_DEBUG,"got SIOCDARP for itf %d, IP %d.%d.%d.%d" - ,itf_num,ipp[0],ipp[1],ipp[2],ipp[3]); - return ioctl_delete(itf,ip,req->arp_flags); + case art_delete: + diag(COMPONENT,DIAG_DEBUG,"got art_delete for itf %d, IP " + "%d.%d.%d.%d",itf->number,ipp[0],ipp[1],ipp[2],ipp[3]); + return ioctl_delete(itf,req->ip,req->flags); default: - diag(COMPONENT,DIAG_ERROR,"unrecognized ioctl 0x%x",cmd); + diag(COMPONENT,DIAG_ERROR,"unrecognized type %d",req->type); return -EINVAL; } } diff -ur --new-file old/atm/arpd/arp.h new/atm/arpd/arp.h --- old/atm/arpd/arp.h Fri Feb 27 19:33:24 1998 +++ new/atm/arpd/arp.h Tue Apr 14 11:37:38 1998 @@ -9,6 +9,7 @@ #include #include +#include "atmarpd.h" #include "table.h" @@ -17,7 +18,7 @@ void vcc_detach(ENTRY *entry); void need_ip(int itf_num,uint32_t ip); void incoming_arp(VCC *vcc,struct atmarphdr *hdr,int len); -int arp_ioctl(int itf_num,unsigned long cmd,struct atmarpreq *req); +int arp_ioctl(struct atmarp_req *req); void vcc_connected(VCC *vcc); void vcc_failed(VCC *vcc); void disconnect_vcc(VCC *vcc); diff -ur --new-file old/atm/arpd/atmarp.8 new/atm/arpd/atmarp.8 --- old/atm/arpd/atmarp.8 Thu Jan 1 01:00:00 1970 +++ new/atm/arpd/atmarp.8 Sat Apr 11 12:43:50 1998 @@ -0,0 +1,95 @@ +.TH ATMARP 8 "Oct 10, 1996" "Linux" "Maintenance Commands" +.SH NAME +atmarp \- administer classical IP over ATM connections +.SH SYNOPSIS +.ad l +.B atmarp +.RB \-a +.br +.B atmarp +.RB \-c +.RB [[atm]\fInumber\fP] +.br +.B atmarp +.RB \-q +.RB \fIip_addr\fP +.RB \fIqos\fP +.br +.B atmarp +.RB \-s +.RB \fIip_addr\fP +.RB [\fIitf\fP.]\fIvpi\fP.\fIvci\fP +.RB [ qos\ \fIqos\fP ] +.RB [ temp ] +.RB [ pub ] +.RB [ null ] +.br +.B atmarp +.RB \-s +.RB \fIip_addr\fP +.RB \fIatm_addr\fP +.RB [ qos\ \fIqos\fP ] +.RB [ temp ] +.RB [ pub ] +.RB [ arpsrv ] +.br +.B atmarp +.RB \-d +.RB \fIip_addr\fP +.RB [ arpsrv ] +.ad b +.SH DESCRIPTION +\fBatmarp\fP is used to maintain the ATMARP table of the ATMARP demon. +The table can be listed, new PVC and SVC entries can be added, and existing +entries can be deleted. In addition to that, \fBatmarp\fP is also used to +create new IP over ATM interfaces. +.P +Note that the kernel has its own ATMARP table containing only entries +for destinations to which a connection exists. The table of \fBatmarpd\fP +can also contain currently unused entries. +.SH OPTIONS +.IP \fB\-a\fP +list the current ATMARP table. +.IP \fB\-c\fP +create the specified IP interface. If the interface number is omitted, +the operating system assigns the next free number and \fBatmarp\fP +prints the resulting interface name (e.g. `atm0') on standard output. +.IP \fB\-q\fP +sets the QOS to use as the default for all VCs generated for that IP +network (\fIip_addr\fP must be the address of the network). +.IP \fB\-s\fP +set up a PVC or create an SVC entry. The following options are recognized: +.RS +.IP \fBqos\fP\ \fIqos\fP +uses the specified quality of service (see qos(7) for the syntax). UBR at +link speed is used by default. +.IP \fBtemp\fP +does not mark the entry as permanent, i.e. it will time out and then be +removed. +.IP \fBpub\fP +publishes the entry (only relevant for ATMARP server). ATMARP requests for +entries not marked for publishing yield an ATMARP_NAK response. +.IP \fBnull\fP +uses NULL encapsulation instead of LLC/SNAP encapsulation on the PVC. This +option is not available for SVCs, because the LLC/SNAP header is required +to identify ATMARP packets. \fBnull\fP also implies that the entry is +permanent. +.IP \fBarpsrv\fP +identifies the entry pointing to the ATMARP server. Note that the node +acting as the ATMARP server must have no ATMARP server entry in its ATMARP +table. +.RE +.IP \fB\-d\fP +delete the specified ARP entry. In order to prevent accidental deletion of +the ATMARP server entry, the \fBarpsrv\fP flag must be specified when +deleting it. +.SH FILES +.PD 0 +.TP 25 +.B /var/run/atmarpd.table +ATMARP table +.SH AUTHOR +Werner Almesberger, EPFL LRC +.SH "SEE ALSO" +atmarpd(8), clip(8), qos(7) +.\"{{{}}} diff -ur --new-file old/atm/arpd/atmarp.c new/atm/arpd/atmarp.c --- old/atm/arpd/atmarp.c Thu Jan 1 01:00:00 1970 +++ new/atm/arpd/atmarp.c Wed Apr 15 19:42:41 1998 @@ -0,0 +1,212 @@ +/* atmarp.c - RFC1577 ATMARP control */ + +/* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "atm.h" +#include "atmd.h" +#include "atmarpd.h" + + +#define BUF_SIZE 4096 + + +static int send_request(struct atmarp_req *req) +{ + int s,len,reply; + + s = un_attach(ATMARP_SOCKET_PATH); + if (s < 0) { + perror("un_attach"); + exit(1); + } + if (write(s,req,sizeof(*req)) < 0) { + perror("write"); + exit(1); + } + len = read(s,&reply,sizeof(reply)); + if (len < 0) { + perror("read"); + exit(1); + } + if (len != sizeof(reply)) { + fprintf(stderr,"bad read: %d != %d\n",len,sizeof(reply)); + exit(1); + } + if (reply < 0) { + fprintf(stderr,"atmarp: %s\n",strerror(-reply)); + exit(1); + } + return reply; +} + + +static int print_table(void) +{ + char buffer[BUF_SIZE]; + int fd,size; + + if ((fd = open(ATMARP_DUMP_DIR "/" ATMARP_DUMP_FILE,O_RDONLY)) < 0) { + perror("open " ATMARP_DUMP_DIR "/" ATMARP_DUMP_FILE); + return 1; + } + while ((size = read(fd,buffer,BUF_SIZE))) { + if (size < 0) { + perror("read " ATMARP_DUMP_DIR "/" ATMARP_DUMP_FILE); + return 1; + } + if (write(0,buffer,size) < 0) { + perror("write stdout"); + return 1; + } + } + return 0; +} + + +static void usage(const char *name) +{ + fprintf(stderr,"usage: %s -a\n",name); + fprintf(stderr,"%6s %s -c [[atm]N]\n","",name); + fprintf(stderr,"%6s %s -q ip_addr qos_spec\n","",name); + fprintf(stderr,"%6s %s -s ip_addr [itf.]vpi.vci [pcr value] [qos spec] " + "[temp] [pub]\n%8s [null]\n","",name,""); + fprintf(stderr,"%6s %s -s ip_addr atm_addr [pcr value] [qos spec] [temp] " + "[pub] [arpsrv]\n","",name); + fprintf(stderr,"%6s %s -d ip_addr [arpsrv]\n","",name); + exit(1); +} + + +int main(int argc,char **argv) +{ + struct hostent *hostent; + struct atmarp_req req; + int c,i,num; + char *here,*end; + + req.type = 0; + while ((c = getopt(argc,argv,"acdqs")) != EOF) + switch (c) { + case 'a': + if (argc != optind || req.type) usage(argv[0]); + req.type = art_table; + /* (void) send_request(&req); @@@ fix this later */ + return print_table(); + case 'c': + if (req.type) usage(argv[0]); + req.type = art_create; + break; + case 'q': + if (req.type) usage(argv[0]); + req.type = art_qos; + break; + case 's': + if (req.type) usage(argv[0]); + req.type = art_set; + break; + case 'd': + if (req.type) usage(argv[0]); + req.type = art_delete; + break; + default: + usage(argv[0]); + } + switch (req.type) { + case art_create: + if (argc == optind) req.itf = -1; + else { + if (argc != optind+1) usage(argv[0]); + here = argv[optind]; + if (strlen(here) > 3 && !strncmp(here,"atm",3)) here += 3; + req.itf = strtoul(here,&end,10); + if (*end || (here[0] == '0' && here[1])) { + usage(argv[0]); + return 1; + } + } + num = send_request(&req); + if (req.itf == -1) printf("atm%d\n",num); + return 0; + case art_qos: + if (argc > optind+2) usage(argv[0]); + /* fall through */ + case art_set: + if (argc < optind+2) usage(argv[0]); + break; + case art_delete: + if (argc < optind+1) usage(argv[0]); + break; + default: + usage(argv[0]); + } + if (strspn(argv[optind],"0123456789.") == strlen(argv[optind])) { + if ((req.ip = inet_addr(argv[optind])) == -1) { + fprintf(stderr,"%s: invalid address\n",argv[optind]); + return 1; + } + } + else { + if (!(hostent = gethostbyname(argv[optind]))) { + fprintf(stderr,"%s: no such host\n",argv[optind]); + return 1; + } + if (hostent->h_addrtype != AF_INET) { + fprintf(stderr,"%s: unknown protocol family\n",argv[0]); + return 1; + } + memcpy(&req.ip,hostent->h_addr,hostent->h_length); + } + req.flags = ATF_PERM; + if (req.type == art_qos) + if (text2qos(argv[optind+1],&req.qos,0)) usage(argv[0]); + if (req.type == art_set) { + memset(&req.qos,0,sizeof(req.qos)); + for (i = optind+2; i < argc; i++) + if (!strcmp(argv[i],"temp")) req.flags &= ~ATF_PERM; + else if (!strcmp(argv[i],"pub")) req.flags |= ATF_PUBL; + else if (!strcmp(argv[i],"null")) req.flags |= ATF_NULL; + else if (!strcmp(argv[i],"arpsrv")) req.flags |= ATF_ARPSRV; + else if (!strcmp(argv[i],"qos")) { + if (++i >= argc) usage(argv[0]); + if (text2qos(argv[i],&req.qos,0)) usage(argv[0]); + } + else if (!strcmp(argv[i],"pcr")) { + if (++i >= argc) usage(argv[0]); + req.qos.txtp.traffic_class = req.qos.rxtp.traffic_class = + ATM_CBR; + req.qos.txtp.max_pcr = req.qos.rxtp.max_pcr = + strtol(argv[i],&end,0); + if (*end) usage(argv[0]); + } + else usage(argv[0]); + if (text2atm(argv[optind+1],(struct sockaddr *) &req.addr, + sizeof(req.addr),T2A_NAME) < 0) { + fprintf(stderr,"%s: invalid ATM address\n",argv[optind+1]); + return 1; + } + } + if (req.type == art_delete && optind+1 < argc) { + if (optind+2 < argc || strcmp(argv[optind+1],"arpsrv")) usage(argv[0]); + req.flags |= ATF_ARPSRV; + } + if (!req.qos.aal) req.qos.aal = ATM_AAL5; + send_request(&req); + return 0; +} diff -ur --new-file old/atm/arpd/atmarpd.c new/atm/arpd/atmarpd.c --- old/atm/arpd/atmarpd.c Fri Apr 4 21:53:45 1997 +++ new/atm/arpd/atmarpd.c Sat Apr 11 12:22:12 1998 @@ -1,6 +1,6 @@ /* atmarpd.c - ATMARP demon */ -/* Written 1995-1997 by Werner Almesberger, EPFL-LRC */ +/* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -13,6 +13,7 @@ #include "atm.h" #include "atmd.h" +#include "atmarpd.h" #include "io.h" #include "table.h" @@ -48,7 +49,7 @@ set_application("atmarpd"); set_verbosity(NULL,DIAG_INFO); - dump_dir = DUMP_DIR; + dump_dir = ATMARP_DUMP_DIR; background = 0; while ((c = getopt(argc,argv,"bdD:l:mnp")) != EOF) switch (c) { @@ -79,7 +80,7 @@ diag(COMPONENT,DIAG_INFO,"Linux ATM ARP, version " VERSION); if (chdir(dump_dir) < 0) diag(COMPONENT,DIAG_ERROR,"chdir %s: %s",dump_dir,strerror(errno)); - if (debug) (void) unlink(TMP_DUMP_FILE); /* avoid confusion */ + if (debug) (void) unlink(ATMARP_TMP_DUMP_FILE); /* avoid confusion */ open_all(); if (background) { pid_t pid; diff -ur --new-file old/atm/arpd/atmarpd.h new/atm/arpd/atmarpd.h --- old/atm/arpd/atmarpd.h Thu Jan 1 01:00:00 1970 +++ new/atm/arpd/atmarpd.h Sat Apr 11 13:01:13 1998 @@ -0,0 +1,43 @@ +/* atmarpd.h - ATMARP demon command interface */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + +#ifndef _ATMARPD_H +#define _ATMARPD_H + +#include + + +#define ATMARP_SOCKET_PATH "/dev/atmarp" /* it seems awfully silly to + put this socket into /dev, + but since that's what + syslogd and lpd are doing + too, ... */ + +#define ATMARP_DUMP_DIR "/var/run" /* ATMARP table file location */ +#define ATMARP_DUMP_FILE "atmarpd.table" /* ATMARP table file name */ +#define ATMARP_TMP_DUMP_FILE "~atmarpd.table"/* name during creation */ + +#define ATF_NULL 0x1000 /* use NULL encapsulation */ +#define ATF_ARPSRV 0x2000 /* entry describes ARP server */ + + +enum atmarp_req_type { + art_invalid, /* catch uninitialized structures */ + art_create, /* create an interface */ + art_qos, /* set the default QoS */ + art_set, /* create or change an entry */ + art_delete, /* delete an entry */ + art_table /* update the ATMARP table file */ +}; + +struct atmarp_req { + enum atmarp_req_type type; /* request type */ + int itf; /* interface number; art_create only */ + uint32_t ip; /* IP address */ + struct sockaddr_atmsvc addr; /* PVC or SVC address */ + int flags; /* ARP flags */ + struct atm_qos qos; /* requested QOS */ +}; + +#endif diff -ur --new-file old/atm/arpd/io.c new/atm/arpd/io.c --- old/atm/arpd/io.c Fri Feb 27 19:33:40 1998 +++ new/atm/arpd/io.c Thu Apr 16 10:27:20 1998 @@ -23,6 +23,7 @@ #include "atm.h" #include "atmd.h" +#include "atmarpd.h" #include "table.h" #include "arp.h" @@ -36,13 +37,13 @@ struct timeval now; -static int kernel,incoming,inet; +static int kernel,incoming,inet,unix_sock; /* ----- kernel interface -------------------------------------------------- */ -void open_all(void) +static void open_kernel(void) { struct sockaddr_atmsvc addr; struct atm_qos qos; @@ -70,77 +71,48 @@ if (listen(incoming,5) < 0) diag(COMPONENT,DIAG_FATAL,"listen: %s",strerror(errno)); } - else if (errno != EUNATCH) + else { + if (errno != EUNATCH) diag(COMPONENT,DIAG_FATAL,"bind: %s",strerror(errno)); - else { - diag(COMPONENT,DIAG_WARN,"SVCs are not available"); - (void) close(incoming); - incoming = -1; - } + diag(COMPONENT,DIAG_WARN,"SVCs are not available"); + (void) close(incoming); + incoming = -1; + } if ((inet = socket(PF_INET,SOCK_DGRAM,0)) < 0) diag(COMPONENT,DIAG_FATAL,"socket: %s",strerror(errno)); } -#if 1 -#define KERNEL_BUFFER_SIZE 500 -#else -#define KERNEL_BASE_LEN (sizeof(struct atmsvc_msg)-sizeof(struct atm_blli)) -#define KERNEL_BUFFER_SIZE (sizeof(struct atmsvc_msg)+(ATM_MAX_BLLI-1)* \ - sizeof(struct atm_blli)+1) -#endif - - static void recv_kernel(void) { - struct atmarp_ctrl *ctrl; - unsigned char buffer[KERNEL_BUFFER_SIZE]; + struct atmarp_ctrl ctrl; int size; - size = read(kernel,buffer,KERNEL_BUFFER_SIZE); + size = read(kernel,&ctrl,sizeof(ctrl)); if (size < 0) { diag(COMPONENT,DIAG_ERROR,"read kernel: %s",strerror(errno)); return; } - ctrl = (struct atmarp_ctrl *) buffer; - if (ctrl->magic != ATMARP_CTRL_MAGIC) { - diag(COMPONENT,DIAG_ERROR,"invalid magic number (0x%x) in kernel msg", - ctrl->magic); - return; - } - switch (ctrl->type) { + switch (ctrl.type) { case act_need: - need_ip(ctrl->itf_num,ctrl->arg); - break; - case act_create: - ctrl->type = act_complete; - ctrl->arg = itf_create(ctrl->itf_num); - if (write(kernel,ctrl,sizeof(*ctrl)) < 0) - diag(COMPONENT,DIAG_ERROR,"write reply: %s",strerror(errno)); + need_ip(ctrl.itf_num,ctrl.ip); break; case act_up: - itf_up(ctrl->itf_num); + itf_up(ctrl.itf_num); break; case act_down: - itf_down(ctrl->itf_num); + itf_down(ctrl.itf_num); break; case act_change: - itf_change(ctrl->itf_num); - case act_ioctl: - ctrl->type = act_complete; - ctrl->arg = arp_ioctl(ctrl->itf_num,ctrl->arg,(struct atmarpreq *) - ctrl->data); - if (write(kernel,ctrl,sizeof(*ctrl)) < 0) - diag(COMPONENT,DIAG_ERROR,"write reply: %s",strerror(errno)); - break; + itf_change(ctrl.itf_num); default: diag(COMPONENT,DIAG_ERROR,"invalid control msg type 0x%x", - ctrl->type); + ctrl.type); } } -void close_all(void) +static void close_kernel(void) { if (incoming >= 0) (void) close(incoming); (void) close(kernel); /* may get major complaints from the kernel ... */ @@ -148,6 +120,64 @@ } +/* ----- atmarp (maintenance) interface ------------------------------------ */ + + +static void open_unix(void) +{ + unix_sock = un_create(ATMARP_SOCKET_PATH,0600); + if (unix_sock < 0) + diag(COMPONENT,DIAG_FATAL,"un_create: %s",strerror(errno)); +} + + +static int got_unix(void *buf,int len,void *user) +{ + struct atmarp_req *req = buf; + int *reply = buf; + + if (len != sizeof(*req)) { + diag(COMPONENT,DIAG_ERROR,"bad unix read: %d != %d",len,sizeof(*req)); + return 0; + } + switch (req->type) { + case art_create: + *reply = ioctl(kernel,SIOCMKCLIP,req->itf); + if (*reply >= 0) itf_create(*reply); + break; + case art_qos: + case art_set: + case art_delete: + *reply = arp_ioctl(req); + break; + case art_table: + *reply = table_update(); + break; + default: + diag(COMPONENT,DIAG_ERROR,"invalid request msg type 0x%x", + req->type); + *reply = -EINVAL; + } + return sizeof(int); +} + + +static void recv_unix(void) +{ + struct atmarp_req req; + + if (un_reply(unix_sock,&req,sizeof(req),got_unix,NULL) < 0) + diag(COMPONENT,DIAG_ERROR,"un_reply: %s",strerror(errno)); +} + + +static void close_unix(void) +{ + (void) close(unix_sock); + (void) unlink(ATMARP_SOCKET_PATH); +} + + /* ----- common part ------------------------------------------------------- */ @@ -357,8 +387,11 @@ FD_ZERO(&rset); FD_ZERO(&cset); FD_SET(kernel,&rset); + FD_SET(unix_sock,&rset); if (incoming >= 0) FD_SET(incoming,&rset); - fds = (kernel > incoming ? kernel : incoming)+1; + fds = incoming+1; + if (kernel >= fds) fds = kernel+1; + if (unix_sock >= fds) fds = unix_sock+1; for (itf = itfs; itf; itf = itf->next) for (entry = itf->table; entry; entry = entry->next) for (vcc = entry->vccs; vcc; vcc = vcc->next) { @@ -403,6 +436,7 @@ diag(COMPONENT,DIAG_DEBUG,"----------"); gettimeofday(&now,NULL); if (FD_ISSET(kernel,&rset)) recv_kernel(); + if (FD_ISSET(unix_sock,&rset)) recv_unix(); if (incoming >= 0 && FD_ISSET(incoming,&rset)) accept_new(); for (itf = itfs; itf; itf = next_itf) { next_itf = itf->next; @@ -424,7 +458,7 @@ /* expire timers after handling messages to make sure we don't time out unnecessarily because of scheduling delays */ } - dump_all(); + table_changed(); } } @@ -485,4 +519,18 @@ if (result < 0) diag(COMPONENT,DIAG_ERROR,"getsockname: %s",strerror(errno)); return result; +} + + +void open_all(void) +{ + open_kernel(); + open_unix(); +} + + +void close_all(void) +{ + close_kernel(); + close_unix(); } diff -ur --new-file old/atm/arpd/itf.c new/atm/arpd/itf.c --- old/atm/arpd/itf.c Fri Feb 27 19:34:05 1998 +++ new/atm/arpd/itf.c Sat Apr 11 12:13:44 1998 @@ -43,10 +43,9 @@ } -int itf_create(int number) +void itf_create(int number) { diag(COMPONENT,DIAG_DEBUG,"ITF CREATE %d",number); - return 0; } diff -ur --new-file old/atm/arpd/itf.h new/atm/arpd/itf.h --- old/atm/arpd/itf.h Fri Feb 27 19:34:11 1998 +++ new/atm/arpd/itf.h Sat Apr 11 12:00:32 1998 @@ -12,7 +12,7 @@ ITF *lookup_itf(int number); ITF *lookup_itf_by_ip(uint32_t ip); -int itf_create(int number); +void itf_create(int number); void itf_up(int number); void itf_down(int number); void itf_change(int number); diff -ur --new-file old/atm/arpd/table.c new/atm/arpd/table.c --- old/atm/arpd/table.c Fri Feb 27 19:34:23 1998 +++ new/atm/arpd/table.c Wed Apr 15 17:26:45 1998 @@ -14,6 +14,7 @@ #include "atm.h" #include "atmd.h" +#include "atmarpd.h" #include "table.h" @@ -56,7 +57,8 @@ ENTRY *walk; for (walk = itf->table; walk; walk = walk->next) - if (walk->addr && atm_equal(walk->addr,addr,0,0)) break; + if (walk->addr && atm_equal((struct sockaddr *) walk->addr, + (struct sockaddr *) addr,0,0)) break; return walk; } @@ -66,11 +68,13 @@ ENTRY *walk; for (walk = unknown_incoming; walk; walk = walk->next) - if (walk->addr && atm_equal(walk->addr,addr,0,0)) break; + if (walk->addr && atm_equal((struct sockaddr *) walk->addr, + (struct sockaddr *) addr,0,0)) break; return walk; } +static int table_uptodate = 0; /* ATMARP table file is up to date */ static FILE *out_file = NULL; static int out_error = 0; @@ -82,7 +86,7 @@ va_start(ap,fmt); if (!out_file) vdiag(COMPONENT,DIAG_DEBUG,fmt,ap); else if (vfprintf(out_file,fmt,ap) < 0 || putc('\n',out_file) < 0) - out_error = 1; + out_error = errno; va_end(ap); } @@ -120,7 +124,7 @@ "???", "com", "PERM", "PUBL", /* 0x0001-0x0008 */ "trailers", "netmask", "dontpub", "magic", /* 0x0010-0x0080 */ "???", "???", "???", "???", /* 0x0100-0x0800 */ - "NULL", "ARPSRV", "DEFQOS" }; /* 0x1000-0x8000 */ + "NULL", "ARPSRV", "???" }; /* 0x1000-0x8000 */ /* lower case flags are not used by ATMARP */ ENTRY *entry; VCC *vcc; @@ -169,21 +173,41 @@ } -void dump_all(void) +static void dump_all(void) { ITF *itf; - if (!debug) { - out_file = fopen(TMP_DUMP_FILE,"w"); - out_error = 0; - } for (itf = itfs; itf; itf = itf->next) dump_itf(itf); output("----- Unknown incoming connections -----"); dump_entries(unknown_incoming); output("----- End of dump -----"); if (out_file) { - if (fclose(out_file) < 0) out_error = 1; - if (!out_error) rename(TMP_DUMP_FILE,DUMP_FILE); - unlink(TMP_DUMP_FILE); } +} + + +void table_changed(void) +{ + table_uptodate = 0; + table_update(); /* @@@ sigh, fix this later */ + if (debug) { + out_file = 0; + dump_all(); + } +} + + +int table_update(void) +{ + if (table_uptodate) return 0; + out_file = fopen(ATMARP_TMP_DUMP_FILE,"w"); + out_error = 0; + dump_all(); + if (fclose(out_file) < 0) out_error = errno; + if (!out_error) + if (rename(ATMARP_TMP_DUMP_FILE,ATMARP_DUMP_FILE) < 0) + out_error = errno; + else table_uptodate = 1; + unlink(ATMARP_TMP_DUMP_FILE); + return out_error; } diff -ur --new-file old/atm/arpd/table.h new/atm/arpd/table.h --- old/atm/arpd/table.h Fri Feb 27 19:34:46 1998 +++ new/atm/arpd/table.h Sat Apr 11 12:11:56 1998 @@ -7,16 +7,12 @@ #define TABLE_H #include +#include #include #include "atmd.h" -#define DUMP_DIR "/var/run" -#define DUMP_FILE "atmarpd.table" -#define TMP_DUMP_FILE "~atmarpd.table" - - typedef struct _vcc { int connecting; int active; /* indicate direction - for user entertainment only */ @@ -80,6 +76,7 @@ ENTRY *lookup_addr(const ITF *itf,const struct sockaddr_atmsvc *addr); ENTRY *lookup_incoming(const struct sockaddr_atmsvc *addr); -void dump_all(void); +void table_changed(void); +int table_update(void); #endif diff -ur --new-file old/atm/atm.patch new/atm/atm.patch --- old/atm/atm.patch Fri Mar 27 01:10:08 1998 +++ new/atm/atm.patch Thu Apr 23 21:22:22 1998 @@ -290,7 +290,7 @@ + return devs; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/atmtcp.c Wed Mar 18 21:09:25 1998 ++++ work/drivers/atm/atmtcp.c Thu Apr 16 13:44:31 1998 @@ -0,0 +1,226 @@ +/* drivers/atm/atmtcp.c - ATM over TCP "device" driver */ + @@ -502,12 +502,12 @@ +}; + + -+int atmtcp_attach(struct atm_vcc *vcc) ++int atmtcp_attach(struct atm_vcc *vcc,int itf) +{ + struct atm_dev *dev; + -+ dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,0); -+ if (!dev) return -ENOMEM; ++ dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,0); ++ if (!dev) return itf == -1 ? -EBUSY : -ENOMEM; + dev->ci_range.vpi_bits = MAX_VPI_BITS; + dev->ci_range.vci_bits = MAX_VCI_BITS; + dev->dev_data = vcc; @@ -519,8 +519,8 @@ + return dev->number; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/eni.c Wed Mar 18 21:08:35 1998 -@@ -0,0 +1,2148 @@ ++++ work/drivers/atm/eni.c Thu Apr 16 12:23:07 1998 +@@ -0,0 +1,2146 @@ +/* drivers/atm/eni.c - Efficient Networks ENI155P device driver */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -561,9 +561,6 @@ + * Show stoppers + * none + * -+ * Major -+ * - test ASIC Tonga support -+ * + * Minor + * - OAM support + * - fix bugs listed below @@ -871,7 +868,7 @@ + printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d has " + "mis-aligned RX data (0x%lx)\n",vcc->dev->number, + vcc->vci,paddr); -+ skb->atm.size = size+skip; ++ ENI_PRV_SIZE(skb) = size+skip; + /* PDU plus descriptor */ + skb->atm.vcc = vcc; + } @@ -957,7 +954,7 @@ + dma_wr = (dma_wr+1) & (NR_DMA_RX-1); + } + if (skb) { -+ skb->atm.pos = eni_vcc->descr+size+1; ++ ENI_PRV_POS(skb) = eni_vcc->descr+size+1; + skb_queue_tail(&eni_dev->rx_queue,skb); +eni_vcc->last = skb; +rx_enqueued++; @@ -976,7 +973,7 @@ + EVENT("discard (size=%ld)\n",size,0); + while (do_rx_dma(vcc,NULL,1,size,0)) EVENT("BUSY LOOP",0,0); + /* could do a full fallback, but that might be more expensive */ -+ if (eni_vcc->rxing) eni_vcc->last->atm.pos += size+1; ++ if (eni_vcc->rxing) ENI_PRV_POS(eni_vcc->last) += size+1; + else eni_vcc->rx_pos = (eni_vcc->rx_pos+size+1) & (eni_vcc->words-1); +} + @@ -1231,27 +1228,29 @@ + } + break; + } -+ EVENT("dequeued (size=%ld,pos=0x%lx)\n",skb->atm.size, -+ skb->atm.pos); ++ EVENT("dequeued (size=%ld,pos=0x%lx)\n",ENI_PRV_SIZE(skb), ++ ENI_PRV_POS(skb)); +rx_dequeued++; + vcc = skb->atm.vcc; + eni_vcc = ENI_VCC(vcc); + first = 0; + vci_dsc = eni_dev->vci+(vcc->vci << 2); -+ if (!EEPMOK(eni_vcc->rx_pos,skb->atm.size,(readl(vci_dsc+1) & -+ MID_VCI_READ) >> MID_VCI_READ_SHIFT,eni_vcc->words)) { ++ if (!EEPMOK(eni_vcc->rx_pos,ENI_PRV_SIZE(skb), ++ (readl(vci_dsc+1) & MID_VCI_READ) >> MID_VCI_READ_SHIFT, ++ eni_vcc->words)) { + EVENT("requeuing\n",0,0); + skb_queue_head(&eni_dev->rx_queue,skb); + break; + } + eni_vcc->rxing--; -+ eni_vcc->rx_pos = skb->atm.pos & (eni_vcc->words-1); ++ eni_vcc->rx_pos = ENI_PRV_POS(skb) & (eni_vcc->words-1); + if (!skb->len) kfree_skb(skb); + else { + EVENT("pushing (len=%ld)\n",skb->len,0); + if (vcc->qos.aal == ATM_AAL0) + *(unsigned long *) skb->data = + ntohl(*(unsigned long *) skb->data); ++ memset(skb->cb,0,sizeof(struct eni_skb_prv)); + vcc->push(vcc,skb); + pushed++; + } @@ -1585,8 +1584,8 @@ + writel(eni_dev->dma[i*2+1],eni_dev->tx_dma+dma_wr*2+1); + dma_wr = (dma_wr+1) & (NR_DMA_TX-1); + } -+ skb->atm.pos = tx->tx_pos; -+ skb->atm.size = size; ++ ENI_PRV_POS(skb) = tx->tx_pos; ++ ENI_PRV_SIZE(skb) = size; + ENI_VCC(vcc)->txing += size; + tx->tx_pos = (tx->tx_pos+size) & (tx->words-1); + DPRINTK("dma_wr set to %ld, tx_pos is now %ld\n",dma_wr,tx->tx_pos); @@ -1637,14 +1636,14 @@ + NULLCHECK(vcc); + tx = ENI_VCC(vcc)->tx; + NULLCHECK(ENI_VCC(vcc)->tx); -+ DPRINTK("dequeue_tx: next 0x%lx curr 0x%x\n",skb->atm.pos, ++ DPRINTK("dequeue_tx: next 0x%lx curr 0x%x\n",ENI_PRV_POS(skb), + readl(eni_dev->reg+MID_TX_DESCRSTART(tx->index))); -+ if (ENI_VCC(vcc)->txing < tx->words && skb->atm.pos == ++ if (ENI_VCC(vcc)->txing < tx->words && ENI_PRV_POS(skb) == + readl(eni_dev->reg+MID_TX_DESCRSTART(tx->index))) { + skb_queue_head(&eni_dev->tx_queue,skb); + break; + } -+ ENI_VCC(vcc)->txing -= skb->atm.size; ++ ENI_VCC(vcc)->txing -= ENI_PRV_SIZE(skb); + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb(skb); + vcc->stats->tx++; @@ -2401,7 +2400,7 @@ + u32 *dsc; + + if (skb->atm.vcc != vcc) continue; -+ dsc = tx->send+skb->atm.pos; ++ dsc = tx->send+ENI_PRV_POS(skb); + *dsc = (*dsc & ~(MID_SEG_RATE | MID_SEG_PR)) | + (tx->prescaler << MID_SEG_PR_SHIFT) | + (tx->resolution << MID_SEG_RATE_SHIFT); @@ -2444,8 +2443,8 @@ + +#else + -+static const struct atm_buffconst bctx = { 4,0,4,0,0,0 }; -+static const struct atm_buffconst bcrx = { 4,0,4,0,0,0 }; ++static const struct atm_buffconst bctx = { sizeof(int),0,sizeof(int),0,0,0 }; ++static const struct atm_buffconst bcrx = { sizeof(int),0,sizeof(int),0,0,0 }; + +#endif + if (level == SOL_AAL && (optname == SO_BCTXOPT || @@ -2482,8 +2481,7 @@ + dev_kfree_skb(skb); + return -EINVAL; + } -+ *(unsigned long *) skb->data = htonl(*(unsigned long *) -+ skb->data); ++ *(u32 *) skb->data = htonl(*(u32 *) skb->data); + } +submitted++; + skb->atm.vcc = vcc; @@ -2621,7 +2619,7 @@ + return -ENOMEM; + } + } -+ dev = atm_dev_register(DEV_LABEL,&ops,0); ++ dev = atm_dev_register(DEV_LABEL,&ops,-1,0); + if (!dev) break; + ENI_DEV(dev) = eni_dev; + eni_dev->asic = type; @@ -2670,11 +2668,11 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/eni.h Thu Mar 19 15:09:41 1998 -@@ -0,0 +1,105 @@ ++++ work/drivers/atm/eni.h Thu Apr 16 13:37:25 1998 +@@ -0,0 +1,114 @@ +/* drivers/atm/eni.h - Efficient Networks ENI155P device driver declarations */ + -+/* Written 1995-1997 by Werner Almesberger, EPFL LRC */ ++/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ + + +#ifndef DRIVER_ATM_ENI_H @@ -2776,6 +2774,15 @@ +#define ENI_DEV(d) ((struct eni_dev *) (d)->dev_data) +#define ENI_VCC(d) ((struct eni_vcc *) (d)->dev_data) + ++ ++struct eni_skb_prv { ++ unsigned long pos; /* position of next descriptor */ ++ int size; /* PDU size in reassembly buffer */ ++}; ++ ++#define ENI_PRV_SIZE(skb) (((struct eni_skb_prv *) (skb)->cb)->size) ++#define ENI_PRV_POS(skb) (((struct eni_skb_prv *) (skb)->cb)->pos) ++ +#endif --- /dev/null Tue Jan 1 05:00:00 1980 +++ work/drivers/atm/midway.h Wed Mar 18 21:01:27 1998 @@ -3350,7 +3357,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/suni.h Thu Mar 19 15:09:39 1998 ++++ work/drivers/atm/suni.h Thu Apr 16 13:37:20 1998 @@ -0,0 +1,219 @@ +/* drivers/atm/suni.h - PMC SUNI (PHY) declarations */ + @@ -4226,7 +4233,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/zatm.c Wed Mar 18 21:08:59 1998 ++++ work/drivers/atm/zatm.c Thu Apr 16 12:23:15 1998 @@ -0,0 +1,1870 @@ +/* drivers/atm/zatm.c - ZeitNet ZN122x device driver */ + @@ -5099,7 +5106,7 @@ + put[-2] |= uPD98401_TXBD_LAST; +#endif + } -+ skb->atm.pos = (unsigned long) dsc; ++ ZATM_PRV_DSC(skb) = dsc; + skb_queue_tail(&zatm_vcc->tx_queue,skb); + DPRINTK("QRP=0x%08lx\n",zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+ + uPD98401_TXVC_QRP)); @@ -5125,10 +5132,10 @@ + "txing\n",vcc->dev->number); + return; + } -+if (*(u32 *) skb->atm.pos != (uPD98401_TXPD_V | uPD98401_TXPD_DP | ++if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD_V | uPD98401_TXPD_DP | + uPD98401_TXPD_SM | uPD98401_TXPD_AAL5)) printk("@#*$!!!! (%08x)\n", -+ *(u32 *) skb->atm.pos); -+ *(u32 *) skb->atm.pos = 0; /* mark as invalid */ ++ *ZATM_PRV_DSC(skb)); ++ *ZATM_PRV_DSC(skb) = 0; /* mark as invalid */ + zatm_vcc->txing--; + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb(skb); @@ -6055,7 +6062,7 @@ + while (!pcibios_find_device(PCI_VENDOR_ID_ZEITNET,type ? + PCI_DEVICE_ID_ZEITNET_1225 : PCI_DEVICE_ID_ZEITNET_1221, + index,&zatm_dev->bus,&zatm_dev->dev_fn)) { -+ dev = atm_dev_register(DEV_LABEL,&ops,0); ++ dev = atm_dev_register(DEV_LABEL,&ops,-1,0); + if (!dev) break; + ZATM_DEV(dev) = zatm_dev; + zatm_dev->copper = type; @@ -6099,11 +6106,11 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/zatm.h Thu Mar 19 15:09:46 1998 -@@ -0,0 +1,129 @@ ++++ work/drivers/atm/zatm.h Thu Apr 16 13:37:29 1998 +@@ -0,0 +1,136 @@ +/* drivers/atm/zatm.h - ZeitNet ZN122x device driver declarations */ + -+/* Written 1995-1997 by Werner Almesberger, EPFL LRC */ ++/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ + + +#ifndef DRIVER_ATM_ZATM_H @@ -6229,6 +6236,13 @@ +#define ZATM_DEV(d) ((struct zatm_dev *) (d)->dev_data) +#define ZATM_VCC(d) ((struct zatm_vcc *) (d)->dev_data) + ++ ++struct zatm_skb_prv { ++ u32 *dsc; /* pointer to skb's descriptor */ ++}; ++ ++#define ZATM_PRV_DSC(skb) (((struct zatm_skb_prv *) (skb)->cb)->dsc) ++ +#endif --- /dev/null Tue Jan 1 05:00:00 1980 +++ work/drivers/atm/zeprom.h Wed Mar 18 21:01:27 1998 @@ -6288,7 +6302,7 @@ #ifdef CONFIG_VT console_map_init(); --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/arequipa.h Thu Mar 19 15:13:57 1998 ++++ work/include/linux/arequipa.h Tue Apr 14 17:02:26 1998 @@ -0,0 +1,63 @@ +/* arequipa.h - Arequipa interface definitions */ + @@ -6354,11 +6368,11 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atm.h Thu Mar 19 15:09:39 1998 -@@ -0,0 +1,254 @@ ++++ work/include/linux/atm.h Tue Apr 14 13:39:34 1998 +@@ -0,0 +1,233 @@ +/* atm.h - general ATM declarations */ + -+/* Written 1995-1997 by Werner Almesberger, EPFL LRC */ ++/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ + + +#ifndef _LINUX_ATM_H @@ -6369,6 +6383,7 @@ + * documentation. Do not change them. + */ + ++#include +#include +#include +#include @@ -6388,13 +6403,6 @@ +#define ATM_MAX_VPI_NNI 4096 /* maximum VPI at the NNI */ +#define ATM_MAX_VCI 65535 /* maximum VCI */ + -+/* -+ * The following items should be added to sys/socket.h aka linux/socket.h -+ */ -+ -+/* address families */ -+#define AF_ATMPVC 6 /* ATM PVCs */ -+#define AF_ATMSVC 7 /* ATM SVCs */ + +/* "protcol" values for the socket system call */ +#define ATM_NO_AAL 0 /* AAL not specified */ @@ -6405,27 +6413,12 @@ +#define ATM_AAL5 5 /* AAL5 (data) */ +#define ATM_SAAL 12 /* signaling AAL */ + -+/* -+ * UGLY - there should only be one protocol family (PF_ATM) for both -+ * address families. A quick glance at some kernel internals seems to -+ * suggest to me that doing it the "right" way might involve some -+ * swimming against the stream ... -+ */ -+ -+/* protocol families */ -+#define PF_ATMPVC AF_ATMPVC -+#define PF_ATMSVC AF_ATMSVC -+ +/* socket option name coding functions */ + -+#define __SO_ENCODE(l,n,t) (((l) << 24) | ((n) << 16) | sizeof(t)) -+#define __SO_LEVEL(c) ((c) >> 24) -+#define __SO_NUMBER(c) (((c) >> 16) & 0xff) -+#define __SO_SIZE(c) ((c) & 0xffff) -+ -+/* layers for getsockopt/setsockopt */ -+#define SOL_ATM 2 -+#define SOL_AAL 3 ++#define __SO_ENCODE(l,n,t) (((l) << 22) | ((n) << 16) | sizeof(t)) ++#define __SO_LEVEL(c) ((c) >> 22) ++#define __SO_NUMBER(c) (((c) >> 16) & 0x3f) ++#define __SO_SIZE(c) ((c) & 0x3fff) + +/* + * ATM layer @@ -6646,12 +6639,12 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atm_tcp.h Thu Mar 19 15:09:50 1998 ++++ work/include/linux/atm_tcp.h Thu Apr 16 12:22:44 1998 @@ -0,0 +1,30 @@ +/* atm_tcp.h - Driver-specific declarations of the ATMTCP driver (for use by + driver-specific utilities) */ + -+/* Written 1997 by Werner Almesberger, EPFL LRC */ ++/* Written 1997,1998 by Werner Almesberger, EPFL LRC/ICA */ + + +#ifndef LINUX_ATM_TCP_H @@ -6673,7 +6666,7 @@ + +#ifdef __KERNEL__ + -+int atmtcp_attach(struct atm_vcc *vcc); ++int atmtcp_attach(struct atm_vcc *vcc,int itf); + +#endif + @@ -6736,8 +6729,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atmarp.h Thu Mar 19 15:13:14 1998 -@@ -0,0 +1,104 @@ ++++ work/include/linux/atmarp.h Tue Apr 14 17:02:16 1998 +@@ -0,0 +1,64 @@ +/* atmarp.h - ATM ARP protocol and kernel-demon interface definitions */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -6746,12 +6739,7 @@ +#ifndef _LINUX_ATMARP_H +#define _LINUX_ATMARP_H + -+#ifdef __KERNEL__ /* @@@ glibc2 hack */ -+#include -+#else -+#include -+#endif -+ ++#include +#include +#include + @@ -6776,11 +6764,6 @@ +#define TL_E164 0x40 + + -+#define ATF_NULL 0x1000 /* use NULL encapsulation */ -+#define ATF_ARPSRV 0x2000 /* entry describes ARP server */ -+#define ATF_DEFQOS 0x4000 /* entry defines default QOS */ -+ -+ +#define MAX_ATMARP_SIZE (sizeof(struct atmarphdr)-1+2*(ATM_E164_LEN+ \ + ATM_ESA_LEN+4)) + @@ -6796,49 +6779,19 @@ +#define ATMARP_SETENTRY _IO('a',ATMIOC_CLIP+3) /* fill or hide ARP entry */ +#define ATMARP_ENCAP _IO('a',ATMIOC_CLIP+5) /* change encapsulation */ + -+/* -+ * ATMARP ioctl request. Mimics the structure of struct arpreq in -+ * include/linux/if_arp.h -+ */ -+ -+struct atmarpreq { -+ struct sockaddr arp_pa; /* protocol address */ -+ struct sockaddr dummy; /* hw addr in struct arpreq */ -+ int arp_flags; /* flags */ -+ struct sockaddr arp_netmask; /* netmask */ -+ char arp_dev[16]; /* device name */ -+ struct sockaddr_atmsvc arp_ha; /* PVC or SVC address */ -+ struct atm_qos arp_qos; /* requested QOS */ -+}; -+ -+ -+struct atmarp_arpsioc { -+ struct sockaddr pa; /* protocol address */ -+ int aa_len; /* size of ATM address */ -+ struct sockaddr_atmsvc aa; /* SVC address */ -+}; -+ -+ -+#define ATMARP_CTRL_MAGIC 0xac /* put this into the magic byte */ + +enum atmarp_ctrl_type { + act_invalid, /* catch uninitialized structures */ + act_need, /* need address resolution */ -+ act_create, /* interface has been created */ + act_up, /* interface is coming up */ + act_down, /* interface is going down */ -+ act_ioctl, /* ioctl follows */ -+ act_complete, /* demon indicates completion */ + act_change /* interface configuration has changed */ +}; + +struct atmarp_ctrl { -+ unsigned char magic; /* constant */ + enum atmarp_ctrl_type type; /* message type */ -+ volatile int *reply; /* reply address, NULL is asynch */ + int itf_num;/* interface number (if present) */ -+ unsigned long arg; /* argument, e.g. IP address */ -+ unsigned char data[1];/* optional data */ ++ uint32_t ip; /* IP address (act_need only) */ +}; + +#endif @@ -6867,7 +6820,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atmdev.h Thu Mar 19 15:09:39 1998 ++++ work/include/linux/atmdev.h Thu Apr 16 12:22:11 1998 @@ -0,0 +1,304 @@ +/* atmdev.h - ATM device driver declarations */ + @@ -7153,7 +7106,7 @@ + + +struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, -+ unsigned long flags); ++ int number,unsigned long flags); /* number == -1: pick first available */ +void atm_dev_deregister(struct atm_dev *dev); + + @@ -7215,7 +7168,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atmlec.h Thu Mar 19 15:13:57 1998 ++++ work/include/linux/atmlec.h Tue Apr 14 17:02:26 1998 @@ -0,0 +1,65 @@ +/* + * @@ -7447,7 +7400,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atmsvc.h Thu Mar 19 15:13:57 1998 ++++ work/include/linux/atmsvc.h Tue Apr 14 17:02:27 1998 @@ -0,0 +1,52 @@ +/* atmsvc.h - ATM signaling kernel-demon interface definitions */ + @@ -7502,7 +7455,7 @@ + +#endif --- ref/include/linux/if_arp.h Sat Mar 7 06:03:10 1998 -+++ work/include/linux/if_arp.h Wed Mar 18 22:15:50 1998 ++++ work/include/linux/if_arp.h Thu Apr 23 22:21:30 1998 @@ -35,6 +35,7 @@ #define ARPHRD_ARCNET 7 /* ARCnet */ #define ARPHRD_APPLETLK 8 /* APPLEtalk */ @@ -7522,23 +7475,19 @@ /* ARP ioctl request. */ --- ref/include/linux/skbuff.h Sat Mar 7 06:02:21 1998 -+++ work/include/linux/skbuff.h Wed Mar 18 22:14:41 1998 -@@ -117,6 +117,24 @@ ++++ work/include/linux/skbuff.h Thu Apr 23 22:20:05 1998 +@@ -117,6 +117,20 @@ __u32 shapestamp; /* Stamp for shaper */ __u16 shapepend; /* Pending */ #endif +#ifdef CONFIG_ATM + struct { -+ int size; /* PDU size (adapter too) */ -+ unsigned long pos; /* adapter data */ + struct atm_vcc *vcc; /* ATM VCC */ + int iovcnt; /* 0 for "normal" operation */ +#ifdef CONFIG_ATM_NICSTAR + void *recycle_buffer; /* set when buffer should be */ + /* recycled; points to vcc */ +#endif -+ int encap; /* non-zero if encapsulated */ -+ /* for ATMARP */ +#ifdef CONFIG_AREQUIPA + int generation; /* generation number */ +#endif @@ -7548,6 +7497,51 @@ }; /* These are just the default values. This is run time configurable. +--- ref/include/linux/socket.h Fri Mar 27 02:39:52 1998 ++++ work/include/linux/socket.h Thu Apr 23 22:19:50 1998 +@@ -138,7 +138,7 @@ + #define AF_APPLETALK 5 /* Appletalk DDP */ + #define AF_NETROM 6 /* Amateur Radio NET/ROM */ + #define AF_BRIDGE 7 /* Multiprotocol bridge */ +-#define AF_AAL5 8 /* Reserved for Werner's ATM */ ++#define AF_ATMPVC 8 /* ATM PVCs */ + #define AF_X25 9 /* Reserved for X.25 project */ + #define AF_INET6 10 /* IP version 6 */ + #define AF_ROSE 11 /* Amateur Radio X.25 PLP */ +@@ -150,6 +150,7 @@ + #define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */ + #define AF_PACKET 17 /* Packet family */ + #define AF_ASH 18 /* Ash */ ++#define AF_ATMSVC 20 /* ATM SVCs */ + #define AF_MAX 32 /* For now.. */ + + /* Protocol families, same as address families. */ +@@ -162,7 +163,7 @@ + #define PF_APPLETALK AF_APPLETALK + #define PF_NETROM AF_NETROM + #define PF_BRIDGE AF_BRIDGE +-#define PF_AAL5 AF_AAL5 ++#define PF_ATMPVC AF_ATMPVC + #define PF_X25 AF_X25 + #define PF_INET6 AF_INET6 + #define PF_ROSE AF_ROSE +@@ -174,6 +175,7 @@ + #define PF_ROUTE AF_ROUTE + #define PF_PACKET AF_PACKET + #define PF_ASH AF_ASH ++#define PF_ATMSVC AF_ATMSVC + + #define PF_MAX AF_MAX + +@@ -220,6 +222,8 @@ + #define SOL_DECNET 261 + #define SOL_X25 262 + #define SOL_PACKET 263 ++#define SOL_ATM 264 /* ATM layer (cell level) */ ++#define SOL_AAL 265 /* ATM Adaption Layer (packet level) */ + + /* IPX options */ + #define IPX_TYPE 1 --- /dev/null Tue Jan 1 05:00:00 1980 +++ work/include/linux/sonet.h Wed Mar 18 21:01:27 1998 @@ -0,0 +1,52 @@ @@ -7604,8 +7598,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/net/atmclip.h Thu Mar 26 21:59:40 1998 -@@ -0,0 +1,64 @@ ++++ work/include/net/atmclip.h Thu Apr 16 13:37:43 1998 +@@ -0,0 +1,62 @@ +/* net/atm/atmarp.h - RFC1577 ATM ARP */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -7667,8 +7661,6 @@ +int clip_setentry(struct atm_vcc *vcc,u32 ip); +int clip_encap(struct atm_vcc *vcc,int mode); + -+int clip_arp_ioctl(struct device *dev,unsigned int cmd,void *arg); -+ +#endif --- ref/net/Config.in Thu Feb 19 23:46:15 1998 +++ work/net/Config.in Wed Mar 18 21:01:27 1998 @@ -7745,7 +7737,7 @@ #ifdef NEED_LLC { "802.2LLC", llc_init }, /* 802.2 LLC */ --- ref/net/ipv4/arp.c Fri Mar 27 02:39:54 1998 -+++ work/net/ipv4/arp.c Wed Mar 18 21:01:27 1998 ++++ work/net/ipv4/arp.c Thu Apr 9 17:28:02 1998 @@ -115,6 +115,9 @@ #include #endif @@ -7769,31 +7761,6 @@ return (dst->neighbour != NULL); } -@@ -877,6 +884,24 @@ - default: - return -EINVAL; - } -+ -+#ifdef CONFIG_ATM_CLIP -+ if (!dev) { -+ struct rtable *rt; -+ -+ err = ip_route_output(&rt, -+ ((struct sockaddr_in *) &r.arp_pa)->sin_addr.s_addr, -+ 0, 1 /* local */, 0); -+ if (err) return err; -+ dev = rt->u.dst.dev; -+ ip_rt_put(rt); -+ } -+ -+ if (dev->type == ARPHRD_ATM) { -+ err = clip_arp_ioctl(dev, cmd, arg); -+ goto out; -+ } -+#endif - - if (r.arp_pa.sa_family != AF_INET) - return -EPFNOSUPPORT; --- /dev/null Tue Jan 1 05:00:00 1980 +++ work/net/atm/Makefile Wed Mar 18 21:01:27 1998 @@ -0,0 +1,52 @@ @@ -8012,7 +7979,7 @@ + return total; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/addr.h Thu Mar 19 15:13:57 1998 ++++ work/net/atm/addr.h Thu Apr 16 13:37:52 1998 @@ -0,0 +1,18 @@ +/* net/atm/addr.h - Local ATM address registry */ + @@ -8033,8 +8000,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/clip.c Fri Mar 27 02:00:54 1998 -@@ -0,0 +1,710 @@ ++++ work/net/atm/clip.c Tue Apr 14 13:09:44 1998 +@@ -0,0 +1,643 @@ +/* clip.c - RFC1577 Classical IP over ATM */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -8060,6 +8027,7 @@ +#include +#include /* for struct rtable and routing */ +#include /* ip_acct_output, etc. */ ++#include /* icmp_send */ +#include /* for HZ */ +#include /* for htons etc. */ +#include /* save/restore_flags */ @@ -8087,63 +8055,23 @@ +static int start_timer = 1; + + -+#define WAITING 1 /* see also signaling.h */ -+ -+ -+static int from_atmarpd(struct atm_vcc *vcc,struct sk_buff *skb) -+{ -+ struct atmarp_ctrl *ctrl; -+ -+ atomic_sub(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse); -+ ctrl = (struct atmarp_ctrl *) skb->data; -+ if (ctrl->magic != ATMARP_CTRL_MAGIC) { -+ printk(KERN_ALERT "from_atmarpd: bad magic 0x%x\n", -+ ctrl->magic); -+ return -EPROTO; -+ } -+ if (ctrl->type != act_complete) { -+ printk(KERN_ALERT "from_atmarpd: bad type 0x%x\n",ctrl->type); -+ return -EPROTO; -+ } -+ if (!ctrl->reply) { -+ printk(KERN_ALERT "from_atmarpd: no reply\n"); -+ return -EPROTO; -+ } -+ *ctrl->reply = ctrl->arg; -+ wake_up(&atmarpd_sleep); -+ dev_kfree_skb(skb); -+ return 0; -+} -+ -+ -+static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long arg, -+ void *data,int length) ++static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) +{ + struct atmarp_ctrl *ctrl; + struct sk_buff *skb; -+ int size,need_reply; -+ volatile int reply; + + DPRINTK("to_atmarpd(%d)\n",type); + if (!atmarpd) return -EUNATCH; -+ size = sizeof(struct atmarp_ctrl)+(data ? length : 0); -+ skb = alloc_skb(size,GFP_ATOMIC); ++ skb = alloc_skb(sizeof(struct atmarp_ctrl),GFP_ATOMIC); + if (!skb) return -ENOMEM; -+ ctrl = (struct atmarp_ctrl *) skb_put(skb,size); -+ need_reply = type == act_ioctl || type == act_create; -+ ctrl->magic = ATMARP_CTRL_MAGIC; ++ ctrl = (struct atmarp_ctrl *) skb_put(skb,sizeof(struct atmarp_ctrl)); + ctrl->type = type; -+ ctrl->reply = need_reply ? &reply : NULL; + ctrl->itf_num = itf; -+ ctrl->arg = arg; -+ if (data) memcpy(ctrl->data,data,length); -+ reply = WAITING; ++ ctrl->ip = ip; + atomic_add(skb->truesize+ATM_PDU_OVHD,&atmarpd->rx_inuse); + skb_queue_tail(&atmarpd->recvq,skb); + wake_up(&atmarpd->sleep); -+ if (!need_reply) return 0; -+ while (reply == WAITING && atmarpd) sleep_on(&atmarpd_sleep); -+ return atmarpd ? reply : -EUNATCH; ++ return 0; +} + + @@ -8307,8 +8235,7 @@ +static void clip_neigh_solicit(struct neighbour *neigh,struct sk_buff *skb) +{ + DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n",neigh,skb); -+ to_atmarpd(act_need,PRIV(neigh->dev)->number, -+ *(u32 *) neigh->primary_key,NULL,0); ++ to_atmarpd(act_need,PRIV(neigh->dev)->number,NEIGH2ENTRY(neigh)->ip); +} + + @@ -8333,7 +8260,7 @@ + +static int clip_constructor(struct neighbour *neigh) +{ -+ struct atmarp_entry *entry = (struct atmarp_entry *) neigh->primary_key; ++ struct atmarp_entry *entry = NEIGH2ENTRY(neigh); + struct device *dev = neigh->dev; + struct in_device *in_dev = dev->ip_ptr; + @@ -8347,7 +8274,7 @@ + neigh->ops->connected_output : neigh->ops->output; + entry->neigh = neigh; + entry->vccs = NULL; -+ entry->expires = jiffies+ATMARP_RETRY_DELAY*HZ; ++ entry->expires = jiffies-1; + return 0; +} + @@ -8427,8 +8354,10 @@ + } + entry = NEIGH2ENTRY(skb->dst->neighbour); + if (!entry->vccs) { -+ if (entry->expires < jiffies) /* should be resolved */ -+ to_atmarpd(act_need,PRIV(dev)->number,entry->ip,NULL,0); ++ if (entry->expires < jiffies) {/* should be resolved */ ++ entry->expires = jiffies+ATMARP_RETRY_DELAY*HZ; ++ to_atmarpd(act_need,PRIV(dev)->number,entry->ip); ++ } + if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS) + skb_queue_tail(&entry->neigh->arp_queue,skb); + else { @@ -8548,34 +8477,6 @@ +} + + -+int clip_arp_ioctl(struct device *dev,unsigned int cmd,void *arg) -+{ -+ struct atmarpreq req; -+ __u32 *ip; -+ -+ DPRINTK("clip_ioctl\n"); -+ if (copy_from_user(&req,arg,sizeof(struct atmarpreq))) return -EFAULT; -+ if (req.arp_pa.sa_family != AF_INET) return -EPFNOSUPPORT; -+ ip = &((struct sockaddr_in *) &req.arp_pa)->sin_addr.s_addr; -+#if 0 /* ??? fix later @@@ */ -+ if (!(*ip & ~dev->pa_mask) && !(req.arp_flags & (ATF_ARPSRV | -+ ATF_DEFQOS))) -+ return -EINVAL; -+#endif -+ switch (cmd) { -+ case SIOCSARP: -+ case SIOCDARP: -+ case SIOCGARP: -+ return to_atmarpd(act_ioctl,PRIV(dev)->number,cmd,&req, -+ sizeof(struct atmarpreq)); -+ /* @@@ get will need special treatment */ -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+ +static int clip_init(struct device *dev) +{ + DPRINTK("clip_init %s\n",dev->name); @@ -8593,7 +8494,7 @@ + dev->hard_header_len = RFC1483LLC_LEN; + dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); + dev->mtu = RFC1626_MTU; -+ return to_atmarpd(act_create,PRIV(dev)->number,0,NULL,0); ++ return 0; +} + + @@ -8640,16 +8541,15 @@ + switch (event) { + case NETDEV_UP: + DPRINTK("clip_device_event NETDEV_UP\n"); -+ (void) to_atmarpd(act_up,PRIV(dev)->number,0,NULL,0); ++ (void) to_atmarpd(act_up,PRIV(dev)->number,0); + break; + case NETDEV_DOWN: + DPRINTK("clip_device_event NETDEV_DOWN\n"); -+ (void) to_atmarpd(act_down,PRIV(dev)->number,0,NULL,0); ++ (void) to_atmarpd(act_down,PRIV(dev)->number,0); + break; + case NETDEV_CHANGE: + DPRINTK("clip_device_event NETDEV_CHANGE\n"); -+ (void) to_atmarpd(act_change,PRIV(dev)->number,0,NULL, -+ 0); ++ (void) to_atmarpd(act_change,PRIV(dev)->number,0); + break; + case NETDEV_REBOOT: + case NETDEV_REGISTER: @@ -8697,7 +8597,7 @@ + NULL, /* no ioctl */ + NULL, /* no getsockopt */ + NULL, /* no setsockopt */ -+ from_atmarpd, /* send */ ++ NULL, /* send */ + NULL, /* no sg_send */ + NULL, /* no send_oam */ + NULL, /* no phy_put */ @@ -8742,11 +8642,11 @@ + register_netdevice_notifier(&clip_dev_notifier); + for (dev = clip_devs; dev; dev = PRIV(dev)->next) + if (dev->flags & IFF_UP) -+ (void) to_atmarpd(act_up,PRIV(dev)->number,0,NULL,0); ++ (void) to_atmarpd(act_up,PRIV(dev)->number,0); + return 0; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/common.c Wed Mar 18 21:31:19 1998 ++++ work/net/atm/common.c Thu Apr 16 12:23:43 1998 @@ -0,0 +1,903 @@ +/* net/atm/common.c - ATM sockets (common part for PVC and SVC) */ + @@ -9416,7 +9316,7 @@ +#ifdef CONFIG_ATM_TCP + case SIOCSIFATMTCP: + if (!suser()) return -EPERM; -+ error = atmtcp_attach(vcc); ++ error = atmtcp_attach(vcc,(int) arg); + if (error >= 0) sock->state = SS_CONNECTED; + return error; +#endif @@ -9652,7 +9552,7 @@ + return atm_do_getsockopt(sock,level,optname,optval,len); +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/common.h Wed Mar 18 22:21:08 1998 ++++ work/net/atm/common.h Sun Apr 12 18:44:59 1998 @@ -0,0 +1,44 @@ +/* net/atm/common.h - ATM sockets (common part for PVC and SVC) */ + @@ -9754,7 +9654,7 @@ + skb_queue_head_init(from); +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/ipcommon.h Thu Mar 19 15:14:06 1998 ++++ work/net/atm/ipcommon.h Thu Apr 16 13:38:07 1998 @@ -0,0 +1,23 @@ +/* net/atm/ipcommon.h - Common items for all ways of doing IP over ATM */ + @@ -11868,7 +11768,7 @@ +} + --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/lec.h Thu Mar 19 15:13:57 1998 ++++ work/net/atm/lec.h Thu Apr 16 13:37:52 1998 @@ -0,0 +1,112 @@ +/* + * @@ -11983,7 +11883,7 @@ +#endif _LEC_H_ + --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/lec_arpc.h Thu Mar 19 15:13:57 1998 ++++ work/net/atm/lec_arpc.h Thu Apr 16 13:37:52 1998 @@ -0,0 +1,112 @@ +/* + * Lec arp cache @@ -12098,8 +11998,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/proc.c Thu Mar 26 21:57:46 1998 -@@ -0,0 +1,610 @@ ++++ work/net/atm/proc.c Tue Apr 14 13:11:23 1998 +@@ -0,0 +1,607 @@ +/* net/atm/proc.c - ATM /proc interface */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -12324,7 +12224,6 @@ + ip_len = sprintf(buf+off,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]); + off += ip_len; + while (ip_len++ < 16) buf[off++] = ' '; -+off += sprintf(buf+off,"[ref %d]",atomic_read(&entry->neigh->refcnt)); + if (!clip_vcc) + if (entry->expires > jiffies) strcpy(buf+off,"(resolving)\n"); + else sprintf(buf+off,"(expired, ref %d)\n", @@ -12392,14 +12291,7 @@ + if (!vcc->dev) sprintf(buf,"Unassigned "); + else sprintf(buf,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,vcc->vci); + here = strchr(buf,0); -+ here += sprintf(here,"%-10s ",vcc == sigd ? "Signaling" : -+#ifdef CONFIG_ATM_CLIP -+ vcc == atmarpd ? "ATMARPctrl" : -+#endif -+#ifdef CONFIG_AREQUIPA -+ vcc == aqd ? "Arequipa" : -+#endif -+ vcc_state(vcc)); ++ here += sprintf(here,"%-10s ",vcc_state(vcc)); + here += sprintf(here,"%s%s",vcc->remote.sas_addr.pub, + *vcc->remote.sas_addr.pub && *vcc->remote.sas_addr.prv ? "+" : ""); + if (*vcc->remote.sas_addr.prv) @@ -12531,6 +12423,11 @@ + svc_info(vcc,buf); + return strlen(buf); + } ++ for (vcc = nodev_vccs; vcc; vcc = vcc->next) ++ if (vcc->family == PF_ATMSVC && !left--) { ++ svc_info(vcc,buf); ++ return strlen(buf); ++ } + return 0; + } +#ifdef CONFIG_ATM_CLIP @@ -12973,8 +12870,8 @@ + return 0; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/resources.c Wed Mar 18 21:01:27 1998 -@@ -0,0 +1,174 @@ ++++ work/net/atm/resources.c Thu Apr 16 13:44:13 1998 +@@ -0,0 +1,183 @@ +/* net/atm/resources.c - Staticly allocated resources */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC */ @@ -13041,7 +12938,7 @@ + + +struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, -+ unsigned long flags) ++ int number,unsigned long flags) +{ + struct atm_dev *dev; + @@ -13051,8 +12948,17 @@ + type); + return NULL; + } -+ dev->number = 0; -+ while (atm_find_dev(dev->number)) dev->number++; ++ if (number != -1) { ++ if (atm_find_dev(number)) { ++ free_atm_dev(dev); ++ return NULL; ++ } ++ dev->number = number; ++ } ++ else { ++ dev->number = 0; ++ while (atm_find_dev(dev->number)) dev->number++; ++ } + dev->vccs = dev->last = NULL; + dev->dev_data = NULL; + barrier(); @@ -13150,7 +13056,7 @@ + } +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/resources.h Thu Mar 19 15:13:57 1998 ++++ work/net/atm/resources.h Thu Apr 16 13:37:52 1998 @@ -0,0 +1,29 @@ +/* net/atm/resources.h - ATM-related resources */ + @@ -13438,7 +13344,7 @@ + return 0; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/signaling.h Thu Mar 19 15:13:57 1998 ++++ work/net/atm/signaling.h Thu Apr 16 13:37:52 1998 @@ -0,0 +1,25 @@ +/* net/atm/signaling.h - ATM signaling */ + diff -ur --new-file old/atm/doc/usage.tex new/atm/doc/usage.tex --- old/atm/doc/usage.tex Fri Mar 27 00:54:58 1998 +++ new/atm/doc/usage.tex Thu Apr 23 20:55:55 1998 @@ -1,8 +1,8 @@ %%def%:= %:\begin{verbatim} -%:Usage instructions - ATM on Linux, release 0.35 (alpha) -%:--------------------------------------------------------- +%:Usage instructions - ATM on Linux, release 0.36 +%:------------------------------------------------- %: %:\end{verbatim} %%beginskip @@ -38,7 +38,7 @@ \title{ATM on Linux \\ User's guide \\ - Release 0.35 (alpha)} + Release 0.36 (alpha)} \author{Werner Almesberger \\ {\tt Werner.Almesberger@epfl.ch} \\ \\ @@ -81,7 +81,7 @@ In order to install this package, you need \begin{itemize} \item the package itself - \url{ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.35.tar.gz} + \url{ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.36.tar.gz} \item the Linux kernel, version 2.1.90, e.g. from \url{ftp://ftp.kernel.org/pub/linux/kernel/v2.1/linux-2.1.90.tar.gz} \item Perl, version 4 or 5 @@ -98,7 +98,7 @@ distribution: \begin{verbatim} -tar xfz atm-0.35.tar.gz +tar xfz atm-0.36.tar.gz \end{verbatim} and the kernel source: @@ -130,8 +130,7 @@ \item[\path{atm/test/}] Test programs: \name{align}, \name{aping}, \name{aread}, \name{awrite}, \name{br}, \name{bw}, \name{isp}, \name{ttcp\_atm}, \name{window} - \item[\path{atm/ip/}] IP over ATM: \name{atmarp} - \item[\path{atm/arpd/}] ATMARP demon: \name{atmarpd} + \item[\path{atm/arpd/}] ATMARP tools and demon: \name{atmarp}, \name{atmarpd} \item[\path{atm/led/}] LAN Emulation demon: \name{led} \item[\path{atm/lane/}] LAN Emulation servers: \name{bus}, \name{lecs}, \name{les} diff -ur --new-file old/atm/doc/usage.txt new/atm/doc/usage.txt --- old/atm/doc/usage.txt Fri Mar 27 01:07:35 1998 +++ new/atm/doc/usage.txt Thu Apr 23 20:57:29 1998 @@ -1,5 +1,5 @@ -Usage instructions - ATM on Linux, release 0.35 (alpha) ---------------------------------------------------------- +Usage instructions - ATM on Linux, release 0.36 +------------------------------------------------- For updates of ATM on Linux, please check the Web page at http://lrcwww.epfl.ch/linux-atm/ @@ -17,7 +17,7 @@ In order to install this package, you need - the package itself - ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.35.tar.gz + ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.36.tar.gz - the Linux kernel, version 2.1.90, e.g. from ftp://ftp.kernel.org/pub/linux/kernel/v2.1/linux-2.1.90.tar.gz - Perl, version 4 or 5 @@ -33,7 +33,7 @@ all the files listed above there. Then extract the ATM on Linux distribution: -tar xfz atm-0.35.tar.gz +tar xfz atm-0.36.tar.gz and the kernel source: @@ -56,8 +56,7 @@ esi, sonetdiag, saaldump, and zntune atm/test/ Test programs: align, aping, aread, awrite, br, bw, isp, ttcp_atm, window - atm/ip/ IP over ATM: atmarp - atm/arpd/ ATMARP demon: atmarpd + atm/arpd/ ATMARP tools and demon: atmarp, atmarpd atm/led/ LAN Emulation demon: led atm/lane/ LAN Emulation servers: bus, lecs, les atm/aqd/ Arequipa demon: aqpvc, arequipad diff -ur --new-file old/atm/ilmid/ilmid.c new/atm/ilmid/ilmid.c --- old/atm/ilmid/ilmid.c Thu Feb 12 16:57:48 1998 +++ new/atm/ilmid/ilmid.c Thu Apr 16 09:17:19 1998 @@ -308,8 +308,7 @@ pid = fork(); if(pid < 0) diag(COMPONENT, DIAG_FATAL, "fork: %s", strerror(errno)); - else if(pid > 0) - exit(0); + if(pid > 0) exit(0); } InitNibbleMem(512, 512); diff -ur --new-file old/atm/ilmid/io.c new/atm/ilmid/io.c --- old/atm/ilmid/io.c Thu Feb 26 21:23:21 1998 +++ new/atm/ilmid/io.c Thu Apr 9 14:49:32 1998 @@ -114,7 +114,8 @@ diag(COMPONENT, DIAG_FATAL, "ioctl ATM_GETADDR: %s", strerror(errno)); n = 0; - if (req.length && atm_equal(&addr, &ouraddr[0], ATM_ESA_LEN, 0)) { + if (req.length && atm_equal((struct sockaddr *) &addr, + (struct sockaddr *) &ouraddr[0], ATM_ESA_LEN, 0)) { diag(COMPONENT, DIAG_INFO, "Primary ATM Address did not change"); n = 1; } diff -ur --new-file old/atm/ip/Makefile new/atm/ip/Makefile --- old/atm/ip/Makefile Tue Apr 22 12:38:25 1997 +++ new/atm/ip/Makefile Thu Jan 1 01:00:00 1970 @@ -1,4 +0,0 @@ -BOOTPGMS=atmarp #clip -MAN8=atmarp.8 #clip.8 - -include ../Rules.make diff -ur --new-file old/atm/ip/atmarp.8 new/atm/ip/atmarp.8 --- old/atm/ip/atmarp.8 Fri Oct 11 00:05:06 1996 +++ new/atm/ip/atmarp.8 Thu Jan 1 01:00:00 1970 @@ -1,95 +0,0 @@ -.TH ATMARP 8 "Oct 10, 1996" "Linux" "Maintenance Commands" -.SH NAME -atmarp \- administer classical IP over ATM connections -.SH SYNOPSIS -.ad l -.B atmarp -.RB \-a -.br -.B atmarp -.RB \-c -.RB [[atm]\fInumber\fP] -.br -.B atmarp -.RB \-q -.RB \fIip_addr\fP -.RB \fIqos\fP -.br -.B atmarp -.RB \-s -.RB \fIip_addr\fP -.RB [\fIitf\fP.]\fIvpi\fP.\fIvci\fP -.RB [ qos\ \fIqos\fP ] -.RB [ temp ] -.RB [ pub ] -.RB [ null ] -.br -.B atmarp -.RB \-s -.RB \fIip_addr\fP -.RB \fIatm_addr\fP -.RB [ qos\ \fIqos\fP ] -.RB [ temp ] -.RB [ pub ] -.RB [ arpsrv ] -.br -.B atmarp -.RB \-d -.RB \fIip_addr\fP -.RB [ arpsrv ] -.ad b -.SH DESCRIPTION -\fBatmarp\fP is used to maintain the ATMARP table of the ATMARP demon. -The table can be listed, new PVC and SVC entries can be added, and existing -entries can be deleted. In addition to that, \fBatmarp\fP is also used to -create new IP over ATM interfaces. -.P -Note that the kernel has its own ATMARP table containing only entries -for destinations to which a connection exists. The table of \fBatmarpd\fP -can also contain currently unused entries. -.SH OPTIONS -.IP \fB\-a\fP -list the current ATMARP table. -.IP \fB\-c\fP -create the specified IP interface. If the interface number is omitted, -the operating system assigns the next free number and \fBatmarp\fP -prints the resulting interface name (e.g. `atm0') on standard output. -.IP \fB\-q\fP -sets the QOS to use as the default for all VCs generated for that IP -network (\fIip_addr\fP must be the address of the network). -.IP \fB\-s\fP -set up a PVC or create an SVC entry. The following options are recognized: -.RS -.IP \fBqos\fP\ \fIqos\fP -uses the specified quality of service (see qos(7) for the syntax). UBR at -link speed is used by default. -.IP \fBtemp\fP -does not mark the entry as permanent, i.e. it will time out and then be -removed. -.IP \fBpub\fP -publishes the entry (only relevant for ATMARP server). ATMARP requests for -entries not marked for publishing yield an ATMARP_NAK response. -.IP \fBnull\fP -uses NULL encapsulation instead of LLC/SNAP encapsulation on the PVC. This -option is not available for SVCs, because the LLC/SNAP header is required -to identify ATMARP packets. \fBnull\fP also implies that the entry is -permanent. -.IP \fBarpsrv\fP -identifies the entry pointing to the ATMARP server. Note that the node -acting as the ATMARP server must have no ATMARP server entry in its ATMARP -table. -.RE -.IP \fB\-d\fP -delete the specified ARP entry. In order to prevent accidental deletion of -the ATMARP server entry, the \fBarpsrv\fP flag must be specified when -deleting it. -.SH FILES -.PD 0 -.TP 25 -.B /var/run/atmarpd.table -ATMARP table -.SH AUTHOR -Werner Almesberger, EPFL LRC -.SH "SEE ALSO" -atmarpd(8), clip(8), qos(7) -.\"{{{}}} diff -ur --new-file old/atm/ip/atmarp.c new/atm/ip/atmarp.c --- old/atm/ip/atmarp.c Thu Feb 26 20:07:38 1998 +++ new/atm/ip/atmarp.c Thu Jan 1 01:00:00 1970 @@ -1,205 +0,0 @@ -/* atmarp.c - RFC1577 ATMARP control */ - -/* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* struct ifreq */ -#include - -#include -#include -#include -#include - -#include "atm.h" - - -#define DUMP_DIR "/var/run" -#define BUF_SIZE 4096 - - -static int print_table(void) -{ - char buffer[BUF_SIZE]; - int fd,size; - - if ((fd = open(DUMP_DIR "/atmarpd.table",O_RDONLY)) < 0) { - perror("open " DUMP_DIR "/atmarpd.table"); - return 1; - } - while ((size = read(fd,buffer,BUF_SIZE))) { - if (size < 0) { - perror("read " DUMP_DIR "/atmarpd.table"); - return 1; - } - if (write(0,buffer,size) < 0) { - perror("write stdout"); - return 1; - } - } - return 0; -} - - -static void usage(const char *name) -{ - fprintf(stderr,"usage: %s -a\n",name); - fprintf(stderr,"%6s %s -c [[atm]N]\n","",name); - fprintf(stderr,"%6s %s -q ip_addr qos_spec\n","",name); - fprintf(stderr,"%6s %s -s ip_addr [itf.]vpi.vci [pcr value] [qos spec] " - "[temp] [pub]\n%8s [null]\n","",name,""); - fprintf(stderr,"%6s %s -s ip_addr atm_addr [pcr value] [qos spec] [temp] " - "[pub] [arpsrv]\n","",name); - fprintf(stderr,"%6s %s -d ip_addr [arpsrv]\n","",name); - exit(1); -} - - -int main(int argc,char **argv) -{ - struct hostent *hostent; - struct atmarpreq req; - int c,op,s,i,req_num,num; - const char *qos; - char *here,*end; - - op = 0; - qos = NULL; - while ((c = getopt(argc,argv,"acdqs")) != EOF) - switch (c) { - case 'a': - if (argc != optind) usage(argv[0]); - return print_table(); - case 'c': - if (op) usage(argv[0]); - op = SIOCMKCLIP; - break; - case 'q': - if (op) usage(argv[0]); - op = SIOCSARP; - qos = ""; /* non-NULL */ - break; - case 's': - if (op) usage(argv[0]); - op = SIOCSARP; - break; - case 'd': - if (op) usage(argv[0]); - op = SIOCDARP; - break; - default: - usage(argv[0]); - } - switch (op) { - case SIOCMKCLIP: - if (argc == optind) req_num = -1; - else { - if (argc != optind+1) usage(argv[0]); - here = argv[optind]; - if (strlen(here) > 3 && !strncmp(here,"atm",3)) here += 3; - req_num = strtoul(here,&end,10); - if (*end || (here[0] == '0' && here[1])) { - usage(argv[0]); - return 1; - } - } - if ((s = socket(PF_ATMSVC,SOCK_DGRAM,0)) < 0) { - perror("socket"); - return 1; - } - if ((num = ioctl(s,op,req_num)) < 0) { - perror("ioctl SIOCMKCLIP"); - return 1; - } - if (req_num == -1) printf("atm%d\n",num); - return 0; - case SIOCSARP: - if (argc < optind+2) usage(argv[0]); - if (qos && argc > optind+2) usage(argv[0]); - break; - case SIOCDARP: - if (argc < optind+1) usage(argv[0]); - break; - default: - usage(argv[0]); - } - ((struct sockaddr_in *) &req.arp_pa)->sin_family = AF_INET; - if (strspn(argv[optind],"0123456789.") == strlen(argv[optind])) { - if ((((struct sockaddr_in *) &req.arp_pa)->sin_addr.s_addr = - inet_addr(argv[optind])) == -1) { - fprintf(stderr,"%s: invalid address\n",argv[optind]); - return 1; - } - } - else { - if (!(hostent = gethostbyname(argv[optind]))) { - fprintf(stderr,"%s: no such host\n",argv[optind]); - return 1; - } - if (hostent->h_addrtype != AF_INET) { - fprintf(stderr,"%s: unknown protocol family\n",argv[0]); - return 1; - } - memcpy(&((struct sockaddr_in *) &req.arp_pa)->sin_addr,hostent->h_addr, - hostent->h_length); - } - req.arp_flags = ATF_PERM; - if (op == SIOCSARP && qos) { - req.arp_flags |= ATF_DEFQOS; - if (text2qos(argv[optind+1],&req.arp_qos,0)) usage(argv[0]); - } - if (op == SIOCSARP && !qos) { - memset(&req.arp_qos,0,sizeof(req.arp_qos)); - for (i = optind+2; i < argc; i++) - if (!strcmp(argv[i],"temp")) req.arp_flags &= ~ATF_PERM; - else if (!strcmp(argv[i],"pub")) req.arp_flags |= ATF_PUBL; - else if (!strcmp(argv[i],"null")) req.arp_flags |= ATF_NULL; - else if (!strcmp(argv[i],"arpsrv")) req.arp_flags |= ATF_ARPSRV; - else if (!strcmp(argv[i],"qos")) { - if (++i >= argc) usage(argv[0]); - if (text2qos(argv[i],&req.arp_qos,0)) usage(argv[0]); - } - else if (!strcmp(argv[i],"pcr")) { - if (++i >= argc) usage(argv[0]); - req.arp_qos.txtp.traffic_class = - req.arp_qos.rxtp.traffic_class = ATM_CBR; - req.arp_qos.txtp.max_pcr = req.arp_qos.rxtp.max_pcr = - strtol(argv[i],&end,0); - if (*end) usage(argv[0]); - } - else usage(argv[0]); - if (text2atm(argv[optind+1],(struct sockaddr *) &req.arp_ha, - sizeof(req.arp_ha),T2A_NAME) < 0) { - fprintf(stderr,"%s: invalid ATM address\n",argv[optind+1]); - return 1; - } - } - if (op == SIOCDARP && optind+1 < argc) { - if (optind+2 < argc || strcmp(argv[optind+1],"arpsrv")) usage(argv[0]); - req.arp_flags |= ATF_ARPSRV; - } - if (!req.arp_qos.aal) req.arp_qos.aal = ATM_AAL5; - if ((s = socket(AF_INET,SOCK_DGRAM,0)) < 0) { - perror("socket"); - return 1; - } -#if LINUX_VERSION_CODE >= 0x20100 - *req.arp_dev = 0; -#endif - if (ioctl(s,op,&req) < 0) { - perror("ioctl SIOCxARP"); - return 1; - } - return 0; -} diff -ur --new-file old/atm/ip/clip.8 new/atm/ip/clip.8 --- old/atm/ip/clip.8 Thu Nov 23 15:43:51 1995 +++ new/atm/ip/clip.8 Thu Jan 1 01:00:00 1970 @@ -1,32 +0,0 @@ -.TH CLIP 8 "Nov 23, 1995" "Linux" "Maintenance Commands" -.SH NAME -clip \- set up Classical IP over ATM connections -.SH SYNOPSIS -.ad l -.B clip -.RB [ \-0 ] -.RB [\fIitf\fP.]\fIvpi\fP.\fIvci\fP -.RB [ \fIpcr\fB ] -.ad b -.SH DESCRIPTION -.B clip -sets up an ATM connection and attaches it to the Classical IP over ATM -protocol stack. The PVC connection endpoint is identified by the interface -number (default is zero), the VPI, and the VCI. -.PP -By default, maximum bandwidth (without reservation) is used for the connection. -If the peak cell rate (\fIpcr\fP) is specified, bandwidth is allocated -accordingly. -.SH OPTIONS -.IP \fB\-0\fP -use null encapsulation instead of LLC-SNAP encapsulation. -.SH BUGS -.B clip -should print the name of the interface it creates. Since it will be -replaced by some "real" ATMARP interface soon, this shouldn't bother -too many people. -.SH AUTHOR -Werner Almesberger, EPFL LRC -.SH "SEE ALSO" -atmdiag(8), atmdump(8), sonetdiag(8) -.\"{{{}}} diff -ur --new-file old/atm/ip/clip.c new/atm/ip/clip.c --- old/atm/ip/clip.c Tue Mar 11 11:55:38 1997 +++ new/atm/ip/clip.c Thu Jan 1 01:00:00 1970 @@ -1,79 +0,0 @@ -/* clip.c - CLassical IP over ATM control (to be replaced by ATMARP) */ - -/* Written 1995-1997 by Werner Almesberger, EPFL-LRC */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static void usage(const char *name) -{ - fprintf(stderr,"usage: %s [ -0 ] [itf.]vpi.vci [ pcr ]\n",name); - exit(1); -} - - -int main(int argc,char **argv) -{ - struct sockaddr_atmpvc addr; - struct atm_qos qos; - const char *name; - int s,null,itf; - - name = argv[0]; - null = 0; - if (argc > 1 && *argv[1] == '-') - if (strcmp(argv[1],"-0")) usage(name); - else { - null = 1; - argc--; - argv++; - } - if (argc != 2 && argc != 3) usage(name); - if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) { - perror("socket"); - return 1; - } - memset(&addr,0,sizeof(addr)); - if (text2atm(argv[1],(struct sockaddr *) &addr,sizeof(addr),T2A_PVC) < 0) - usage(argv[0]); - memset(&qos,0,sizeof(qos)); - qos.aal = ATM_AAL5; - if (argc != 3) qos.txtp.traffic_class = ATM_UBR; - else { - qos.txtp.traffic_class = ATM_CBR; - qos.txtp.min_pcr = atoi(argv[2]); - } - qos.rxtp.traffic_class = ATM_UBR; - qos.txtp.max_sdu = qos.rxtp.max_sdu = RFC1626_MTU+ - (null ? 0 : RFC1483LLC_LEN); - if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) { - perror("setsockopt SO_ATMQOS"); - return 1; - } - if (bind(s,(struct sockaddr *) &addr,sizeof(addr)) < 0) { - perror("bind"); - return 1; - } - if ((itf = ioctl(s,CLIP_PVC,0)) < 0) { - perror("ioctl CLIP_PVC"); - return 1; - } - if (null) - if (ioctl(s,CLIP_NULENCAP,0) < 0) { - perror("ioctl CLIP_NULENCAP"); - return 1; - } - printf("atm%d\n",itf); - return 0; -} diff -ur --new-file old/atm/lib/Makefile new/atm/lib/Makefile --- old/atm/lib/Makefile Thu Mar 5 16:14:49 1998 +++ new/atm/lib/Makefile Wed Apr 15 19:34:38 1998 @@ -5,7 +5,7 @@ else ATM_OBJS += ans.o endif -ATMD_OBJS=common.o diag.o timer.o +ATMD_OBJS=common.o diag.o timer.o unix.o AQ_OBJS=arequipa.o PGMS=#test GENLIBS=libatm.a libatmd.a libarequipa.a diff -ur --new-file old/atm/lib/atm.h new/atm/lib/atm.h --- old/atm/lib/atm.h Thu Mar 5 16:15:36 1998 +++ new/atm/lib/atm.h Tue Apr 14 13:39:15 1998 @@ -10,6 +10,19 @@ #include +/* + * For glibc. gcc won't complain unless we define something else than what + * is in sys/socket.h + */ + +#define AF_ATMPVC 20 +#define AF_ATMSVC 21 +#define PF_ATMPVC AF_ATMPVC +#define PF_ATMSVC AF_ATMSVC +#define SOL_ATM 264 +#define SOL_AAL 265 + + #define HOSTS_ATM "/etc/hosts.atm" /* text2atm flags */ @@ -30,7 +43,7 @@ /* atm_equal flags */ #define AXE_WILDCARD 1 /* allow wildcard match */ -#define AXE_PRVOPT 2 /* private part is optional */ +#define AXE_PRVOPT 2 /* private part of SVC address is optional */ /* text2qos flags */ #define T2Q_DEFAULTS 1 /* structure contains default values */ @@ -61,8 +74,8 @@ int text2atm(const char *text,struct sockaddr *addr,int length,int flags); int atm2text(char *buffer,int length,const struct sockaddr *addr,int flags); -int atm_equal(const struct sockaddr_atmsvc *a,const struct sockaddr_atmsvc *b, - int len,int flags); +int atm_equal(const struct sockaddr *a,const struct sockaddr *b,int len, + int flags); int sdu2cell(int s,int sizes,const int *sdu_size,int *num_sdu); diff -ur --new-file old/atm/lib/atm2text.c new/atm/lib/atm2text.c --- old/atm/lib/atm2text.c Wed Mar 18 21:38:47 1998 +++ new/atm/lib/atm2text.c Sat Apr 11 12:52:37 1998 @@ -149,8 +149,7 @@ ((const struct sockaddr_atmpvc *) addr)->sap_addr.vci != ((struct sockaddr_atmpvc *) &temp)->sap_addr.vci) continue; } - else if (!atm_equal((const struct sockaddr_atmsvc *) addr, - (struct sockaddr_atmsvc *) &temp,0,0)) continue; + else if (!atm_equal(addr,(struct sockaddr *) &temp,0,0)) continue; while ((here = strtok(NULL,"\t\n "))) if (strlen(here) < length) { strcpy(buffer,here); diff -ur --new-file old/atm/lib/atmd.h new/atm/lib/atmd.h --- old/atm/lib/atmd.h Fri Feb 27 19:38:40 1998 +++ new/atm/lib/atmd.h Thu Apr 16 10:23:59 1998 @@ -1,4 +1,4 @@ -/* atmd.h - Functions useful for demons */ +/* atmd.h - Functions useful for demons (and some other ATM tools) */ /* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ @@ -85,5 +85,43 @@ struct timeval *next_timer(void); void pop_timer(TIMER *timer); void expire_timers(void); + + +/*--------------------------- Unix domain sockets ---------------------------*/ + +int un_create(const char *path,mode_t mode); + +/* + * Creates a Unix domain DGRAM socket, binds it to the specified path, and + * returns the socket descriptor. Returns a negative value on error. + */ + +int un_attach(const char *path); + +/* + * Creates a Unix domain DGRAM socket and connects it to the specified path. + * The local side is bound to an ephemeral address. Returns the socket + * descriptor on success, a negative value otherwise. + */ + +int un_recv_connect(int s,void *buf,int size); + +/* + * Performs a recv(s,buf,size,0) and connects the socket to the sender's + * address. Returns a negative value on error. + */ + +int un_reply(int s,void *buf,int _size, + int (*handler)(void *buf,int len,void *user),void *user); + +/* + * Receives a message from the socket into the buffer provided by the caller, + * invokes handler for processing and optionally sends back a reply. If the + * handler returns a negative value or zero, no reply is sent. If the handler + * returns a positive value, this is interpreted as the length of the reply to + * send. The data is taken from the buffer. If any system call fails, un_reply + * returns a negative value. Otherwise, is returns whatever was returned by the + * handler function. + */ #endif diff -ur --new-file old/atm/lib/atmequal.c new/atm/lib/atmequal.c --- old/atm/lib/atmequal.c Wed Mar 18 21:38:56 1998 +++ new/atm/lib/atmequal.c Thu Apr 9 14:47:50 1998 @@ -10,13 +10,25 @@ #include "atm.h" -int atm_equal(const struct sockaddr_atmsvc *a,const struct sockaddr_atmsvc *b, - int len,int flags) +static int atm_equal_pvc(const struct sockaddr_atmpvc *a, + const struct sockaddr_atmpvc *b,int flags) +{ + int wc = flags & AXE_WILDCARD; + +#define EQ(field,any) \ + (a->sap_addr.field == b->sap_addr.field || \ + (wc && (a->sap_addr.field == any || b->sap_addr.field == any))) + return EQ(itf,ATM_ITF_ANY) && EQ(vpi,ATM_VPI_ANY) && EQ(vci,ATM_VCI_ANY); +#undef EQ +} + + +static int atm_equal_svc(const struct sockaddr_atmsvc *a, + const struct sockaddr_atmsvc *b,int len,int flags) { const unsigned char *a_prv,*b_prv; int len_a,len_b; - assert(a->sas_family == AF_ATMSVC && b->sas_family == AF_ATMSVC); if (!(flags & AXE_WILDCARD)) len = ATM_ESA_LEN*8; assert(len >= 0 && len <= ATM_ESA_LEN*8); if (*a->sas_addr.prv && *b->sas_addr.prv) { @@ -56,4 +68,17 @@ if (len_a != len_b && !(flags & AXE_WILDCARD)) return 0; return !strncmp(a->sas_addr.pub,b->sas_addr.pub,len_a < len_b ? len_a : len_b); +} + + +int atm_equal(const struct sockaddr *a,const struct sockaddr *b,int len, + int flags) +{ + assert((a->sa_family == AF_ATMPVC && b->sa_family == AF_ATMPVC) || + (a->sa_family == AF_ATMSVC && b->sa_family == AF_ATMSVC)); + if (a->sa_family == AF_ATMPVC) + return atm_equal_pvc((const struct sockaddr_atmpvc *) a, + (const struct sockaddr_atmpvc *) b,flags); + return atm_equal_svc((const struct sockaddr_atmsvc *) a, + (const struct sockaddr_atmsvc *) b,len,flags); } diff -ur --new-file old/atm/lib/unix.c new/atm/lib/unix.c --- old/atm/lib/unix.c Thu Jan 1 01:00:00 1970 +++ new/atm/lib/unix.c Thu Apr 16 15:42:46 1998 @@ -0,0 +1,90 @@ +/* unix.c - Unix domain socket communication */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "atmd.h" + + +static int mkaddr(const char *path,struct sockaddr_un *addr) +{ + addr->sun_family = AF_UNIX; + strcpy(addr->sun_path,path); + return (char *) &addr->sun_path[strlen(path)]-(char *) addr; +} + + +int un_create(const char *path,mode_t mode) +{ + struct sockaddr_un addr; + mode_t old_umask; + int size; + int s; + + s = socket(PF_UNIX,SOCK_DGRAM,0); + if (s < 0) return s; + (void) unlink(path); + size = mkaddr(path,&addr); + old_umask = umask(~mode); + if (bind(s,(struct sockaddr *) &addr,size) < 0) return -1; + (void) umask(old_umask); + return s; +} + + +int un_attach(const char *path) +{ + struct sockaddr_un addr; + int size; + int s; + + s = socket(PF_UNIX,SOCK_DGRAM,0); + if (s < 0) return s; + size = mkaddr("",&addr); + if (bind(s,(struct sockaddr *) &addr,size) < 0) return -1; + size = mkaddr(path,&addr); + if (connect(s,(struct sockaddr *) &addr,size) < 0) return -1; + return s; +} + + +int un_recv_connect(int s,void *buf,int size) +{ + struct sockaddr_un addr; + int addr_size; + int len; + + addr_size = sizeof(addr); + len = recvfrom(s,buf,size,0,(struct sockaddr *) &addr,&addr_size); + if (len < 0) return len; + if (connect(s,(struct sockaddr *) &addr,addr_size) < 0) return -1; + return len; +} + + +int un_reply(int s,void *buf,int size, + int (*handler)(void *buf,int len,void *user),void *user) +{ + struct sockaddr_un addr; + int addr_size; + int len,sent; + + addr_size = sizeof(addr); + len = recvfrom(s,buf,size,0,(struct sockaddr *) &addr,&addr_size); + if (len < 0) return len; + len = handler(buf,len,user); + if (len <= 0) return len; + sent = sendto(s,buf,len,0,(struct sockaddr *) &addr,addr_size); + if (sent < 0 || sent == len) return sent; + errno = EMSGSIZE; /* ugly */ + return -1; +} diff -ur --new-file old/atm/maint/atmtcp.8 new/atm/maint/atmtcp.8 --- old/atm/maint/atmtcp.8 Thu May 29 09:09:48 1997 +++ new/atm/maint/atmtcp.8 Thu Apr 16 11:29:14 1998 @@ -1,15 +1,17 @@ -.TH ATMTCP 8 "May 29, 1997" "Linux" "Maintenance Commands" +.TH ATMTCP 8 "Apr 16, 1998" "Linux" "Maintenance Commands" .SH NAME atmtcp \- set up ATM over TCP connections .SH SYNOPSIS .ad l .B atmtcp .RB [ -b ] +.RB [ -i \fIitf\fB ] .B \-l .RB [ \fIlclport\fB ] .br .B atmtcp .RB [ -b ] +.RB [ -i \fIitf\fB ] .B \-c .I host .RB [ \fIrmtport\fB ] @@ -27,6 +29,9 @@ .SH OPTIONS .IP \fB\-b\fP Run in background (i.e. in a forked child process) after initializing. +.IP \fB\-i\ \fIitf\fP +create the interface with the specified number instead of picking the first +available number. \fBatmtcp\fP fails if the requested interface already exists. .IP \fB\-l\fP listen for an incoming connection. Only one connection is accepted. .IP \fB\-c\ \fIhost\fP @@ -41,7 +46,7 @@ .B atmtcp will force all VCs to be closed and the virtual ATM device to be removed. .SH AUTHOR -Werner Almesberger, EPFL LRC +Werner Almesberger, EPFL ICA .SH "SEE ALSO" atmdiag(8), clip(8), sonetdiag(8) .\"{{{}}} diff -ur --new-file old/atm/maint/atmtcp.c new/atm/maint/atmtcp.c --- old/atm/maint/atmtcp.c Wed Mar 4 08:24:02 1998 +++ new/atm/maint/atmtcp.c Thu Apr 16 11:26:48 1998 @@ -114,8 +114,8 @@ static void usage(const char *name) { - fprintf(stderr,"%s [ -b ] -l [ ]\n",name); - fprintf(stderr,"%s [ -b ] -c [ ]\n",name); + fprintf(stderr,"%s [ -b ] [ -i itf ] -l [ ]\n",name); + fprintf(stderr,"%s [ -b ] [ -i itf ] -c [ ]\n",name); exit(1); } @@ -129,10 +129,24 @@ name = argv[0]; background = 0; - if (argc > 2 && !strcmp(argv[1],"-b")) { - background = 1; - argc--; - argv++; + itf = -1; + while (argc > 2) { + if (!strcmp(argv[1],"-b")) { + if (background) usage(name); + background = 1; + argc--; + argv++; + } + else if (!strcmp(argv[1],"-i")) { + char *end; + + if (itf != -1) usage(name); + itf = strtoul(argv[2],&end,10); + if (*end) usage(name); + argc -= 2; + argv += 2; + } + else break; } if (argc < 2) usage(name); listen_mode = !strcmp(argv[1],"-l"); @@ -159,7 +173,7 @@ perror("socket"); return 1; } - if ((itf = ioctl(s_krn,SIOCSIFATMTCP,0)) < 0) { + if ((itf = ioctl(s_krn,SIOCSIFATMTCP,itf)) < 0) { perror("ioctl SIOCSIFATMTCP"); return 1; } diff -ur --new-file old/atm/maint/esi.c new/atm/maint/esi.c --- old/atm/maint/esi.c Wed Sep 24 08:43:49 1997 +++ new/atm/maint/esi.c Tue Apr 7 14:01:42 1998 @@ -1,6 +1,9 @@ /* esi.c - Get or set End System Identifier (ESI) */ -/* Written 1997 by Werner Almesberger, EPFL LRC */ +/* Written 1997,1998 by Werner Almesberger, EPFL LRC/ICA */ + + +#include #if LINUX_VERSION_CODE < 0x20100 diff -ur --new-file old/atm/mkdist new/atm/mkdist --- old/atm/mkdist Fri Mar 27 01:07:15 1998 +++ new/atm/mkdist Thu Apr 16 12:31:43 1998 @@ -36,8 +36,9 @@ atm/qgen/qgen.c atm/qgen/ql.l atm/qgen/ql.y atm/qgen/qlib.h \ atm/qgen/qlib.c atm/qgen/uni.h atm/qgen/qtest.c atm/qgen/msg.fmt \ atm/arpd/Makefile atm/arpd/arp.c atm/arpd/arp.h atm/arpd/atmarpd.c \ - atm/arpd/io.c atm/arpd/io.h atm/arpd/itf.c atm/arpd/itf.h \ - atm/arpd/table.c atm/arpd/table.h atm/arpd/atmarpd.8 \ + atm/arpd/atmarpd.h atm/arpd/io.c atm/arpd/io.h atm/arpd/itf.c \ + atm/arpd/itf.h atm/arpd/table.c atm/arpd/table.h atm/arpd/atmarpd.8 \ + atm/arpd/atmarp.c atm/arpd/atmarp.8 \ atm/ilmid/COPYRIGHT atm/ilmid/Makefile \ atm/ilmid/rfc1155_smi.c atm/ilmid/rfc1155_smi.h \ atm/ilmid/rfc1157_snmp.c atm/ilmid/rfc1157_snmp.h \ @@ -69,7 +70,6 @@ atm/test/bw.c atm/test/ttcp.c atm/test/aping.c atm/test/window.c \ atm/test/align.c atm/test/isp.c atm/test/isp.h atm/test/ispl.l \ atm/test/ispl.y atm/test/mkerrnos.pl atm/test/README.isp \ - atm/ip/Makefile atm/ip/atmarp.c atm/ip/clip.c atm/ip/clip.8 atm/ip/atmarp.8 \ atm/debug/Makefile atm/debug/ed.c atm/debug/encopy.c atm/debug/endump.c \ atm/debug/peek.pl atm/debug/zndump.c atm/debug/znth.c atm/debug/delay.c \ atm/debug/aqtest.c atm/debug/svctor.c \ @@ -80,7 +80,7 @@ atm/lib/text2qos.c atm/lib/qos2text.c atm/lib/qosequal.c \ atm/lib/sap2text.c atm/lib/text2sap.c atm/lib/sapequal.c atm/lib/misc.c \ atm/lib/atmres.h atm/lib/ans.c atm/lib/rtf2e164_cc.pl \ - atm/lib/stdint.h \ + atm/lib/stdint.h atm/lib/unix.c \ atm/led/USAGE atm/led/COPYRIGHT.DEC atm/led/COPYRIGHT.TUT \ atm/led/lec.h atm/led/lec_arp.h atm/led/lec_ctrl.h atm/led/emask.h \ atm/led/le_disp.h atm/led/g_event.h \ @@ -108,9 +108,11 @@ atm/lane/units.h \ atm/aqd/Makefile atm/aqd/arequipad.c atm/aqd/io.h atm/aqd/io.c \ atm/aqd/arequipad.8 atm/aqd/aqpvc.c atm/aqd/aqpvc.8 \ - atm/switch/Makefile atm/switch/Rules.make atm/switch/fab.h \ - atm/switch/io.h atm/switch/io.c atm/switch/proto.h atm/switch/proto.c \ - atm/switch/relay.c atm/switch/debug/Makefile atm/switch/debug/debug.c \ + atm/switch/Makefile atm/switch/Rules.make atm/switch/cfg.l atm/switch/cfg.y \ + atm/switch/fab.h atm/switch/proto.h atm/switch/proto.c atm/switch/relay.c \ + atm/switch/route.h atm/switch/route.c atm/switch/sig.h atm/switch/sig.c \ + atm/switch/dispatch.h atm/switch/dispatch.c \ + atm/switch/debug/README atm/switch/debug/Makefile atm/switch/debug/debug.c \ atm/extra/extra.html atm/extra/Makefile atm/extra/tcpdump-3.0.4-1.patch \ atm/extra/bind-4.9.5-REL.patch atm/extra/hosts2ans.pl \ atm/config/README atm/config/Makefile atm/config\ diff -ur --new-file old/atm/sigd/atmsigd.c new/atm/sigd/atmsigd.c --- old/atm/sigd/atmsigd.c Thu Feb 12 12:20:01 1998 +++ new/atm/sigd/atmsigd.c Thu Apr 16 09:13:45 1998 @@ -284,7 +284,7 @@ fprintf(stderr,"usage: %s [ -b ] [ -c config_file ] [ -d ] " "[ -D dump_dir ]\n" " [ -l logfile ] [ -n ] [ -N [ -A ] ] [ -q qos ] [ -t trace_length ]\n" - " [ [itf.]vpi.vci [ input output ] ]\n",name); + " [ [itf.]vpi.vci [ socket_path ] ]\n",name); exit(1); } @@ -306,10 +306,8 @@ if (c == 'c') config_file = optarg; if (!(yyin = fopen(config_file,"r"))) diag(COMPONENT,DIAG_WARN,"%s not found. - Using defaults.",config_file); - else if (yyparse()) { + else if (yyparse()) diag(COMPONENT,DIAG_FATAL,"Error in config file. - Aborting."); - return 1; - } /* process all other options but -c */ optind = 0; while ((c = getopt(argc,argv,"Abc:dD:l:nNP:q:t:")) != EOF) @@ -365,10 +363,9 @@ sizeof(signaling_pvc),T2A_PVC) < 0) diag(COMPONENT,DIAG_FATAL,"text2atm \"%s\": failed",argv[optind]); optind++; - if (optind == argc-2) { - open_input(argv[optind]); - open_output(argv[optind+1]); - optind += 2; + if (optind == argc-1) { + open_unix(argv[optind]); + optind++; } } if (optind != argc) usage(argv[0]); diff -ur --new-file old/atm/sigd/io.c new/atm/sigd/io.c --- old/atm/sigd/io.c Wed Nov 5 00:22:43 1997 +++ new/atm/sigd/io.c Thu Apr 16 10:27:29 1998 @@ -1,6 +1,6 @@ /* io.c - I/O operations */ -/* Written 1995-1997 by Werner Almesberger, EPFL-LRC */ +/* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -34,7 +34,9 @@ struct sockaddr_atmpvc signaling_pvc; -static int kernel_in = -1,kernel_out,signaling; +static int kernel = -1,signaling; +static int need_connect = 0; /* non-zero if connection to kernel isn't + bi-directional yet */ /* ----- kernel interface -------------------------------------------------- */ @@ -56,21 +58,12 @@ } -void open_input(const char *name) +void open_unix(const char *path) { - kernel_in = open(name,O_RDWR); /* actually read-only, but that'd block */ - if (kernel_in >= 0) return; - perror(name); - exit(1); -} - - -void open_output(const char *name) -{ - kernel_out = open(name,O_RDWR); /* actually write-only */ - if (kernel_out >= 0) return; - perror(name); - exit(1); + kernel = un_create(path,0600); + if (kernel < 0) + diag(COMPONENT,DIAG_FATAL,"un_create %s: %s",path,strerror(errno)); + need_connect = 1; } @@ -79,7 +72,11 @@ static unsigned char buffer[sizeof(struct atmsvc_msg)+1]; int size; - size = read(kernel_in,buffer,sizeof(buffer)); + if (!need_connect) size = read(kernel,buffer,sizeof(buffer)); + else { + size = un_recv_connect(kernel,buffer,sizeof(buffer)); + need_connect = 0; + } if (size < 0) { diag(COMPONENT,DIAG_ERROR,"read kernel: %s",strerror(errno)); return; @@ -100,7 +97,7 @@ as_name[msg->type],msg->reply,msg->vcc,msg->listen_vcc); /* should be "IO" ... */ trace_kernel("TO KERNEL",msg); - wrote = write(kernel_out,msg,sizeof(*msg)); + wrote = write(kernel,msg,sizeof(*msg)); if (wrote == sizeof(*msg)) return; if (wrote < 0) { perror("kernel write"); @@ -113,9 +110,7 @@ static void close_kernel(void) { - (void) close(kernel_in); /* may get major complaints from the kernel ... */ - (void) close(kernel_out); /* fails if kernel_in == kernel_out, but that's - okay */ + (void) close(kernel); /* may get major complaints from the kernel ... */ } @@ -230,7 +225,8 @@ addrs = req.length/sizeof(struct sockaddr_atmsvc); for (i = 0; i < addrs; i++) { for (from = local_addr; from->state != ls_unused; from++) - if (from->itf == itf && atm_equal(buffer+i,&from->addr,0,0)) break; + if (from->itf == itf && atm_equal((struct sockaddr *) buffer+i, + (struct sockaddr *) &from->addr,0,0)) break; if (from->state != ls_unused) from->state = ls_same; else if (to == local_addr+MAX_ADDRS-1) diag(COMPONENT,DIAG_WARN,"local address table overflow"); @@ -251,8 +247,8 @@ int open_all(void) { - if (kernel_in == -1) kernel_in = kernel_out = open_kernel(); - if (kernel_in < 0) return -1; + if (kernel == -1) kernel = open_kernel(); + if (kernel < 0) return -1; signaling = open_signaling(); if (signaling < 0) { close_kernel(); @@ -282,9 +278,9 @@ int fds,ret; FD_ZERO(&perm); - FD_SET(kernel_in,&perm); + FD_SET(kernel,&perm); FD_SET(signaling,&perm); - fds = kernel_in > signaling ? kernel_in+1 : signaling+1; + fds = kernel > signaling ? kernel+1 : signaling+1; gettimeofday(&now,NULL); while (1) { set = perm; @@ -303,7 +299,7 @@ else { diag(COMPONENT,DIAG_DEBUG,"----------"); gettimeofday(&now,NULL); - if (FD_ISSET(kernel_in,&set)) recv_kernel(); + if (FD_ISSET(kernel,&set)) recv_kernel(); if (FD_ISSET(signaling,&set)) recv_signaling(); expire_timers(); /* expire timers after handling messges to make sure we don't diff -ur --new-file old/atm/sigd/io.h new/atm/sigd/io.h --- old/atm/sigd/io.h Thu Oct 30 20:08:36 1997 +++ new/atm/sigd/io.h Wed Apr 15 19:57:26 1998 @@ -1,6 +1,6 @@ /* io.h - I/O operations */ -/* Written 1995-1997 by Werner Almesberger, EPFL-LRC */ +/* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ #ifndef IO_H @@ -25,8 +25,7 @@ int open_all(void); -void open_input(const char *name); -void open_output(const char *name); +void open_unix(const char *name); void init_current_time(void); void poll_loop(void); void close_all(void); diff -ur --new-file old/atm/sigd/kernel.c new/atm/sigd/kernel.c --- old/atm/sigd/kernel.c Fri Mar 13 20:29:20 1998 +++ new/atm/sigd/kernel.c Thu Apr 16 09:14:48 1998 @@ -206,8 +206,10 @@ LOCAL_ADDR *walk; for (walk = local_addr; walk->state != ls_unused; walk++) - if (walk->state == ls_same && atm_equal(&walk->addr, - &msg->svc,(ATM_ESA_LEN-1)*8,AXE_WILDCARD)) break; + if (walk->state == ls_same && + atm_equal((struct sockaddr *) &walk->addr, + (struct sockaddr *) &msg->svc,(ATM_ESA_LEN-1)*8, + AXE_WILDCARD)) break; if(*msg->svc.sas_addr.pub) diag(COMPONENT,DIAG_DEBUG,"binding to E.164 address " "%s\n",msg->svc.sas_addr.pub); @@ -370,10 +372,8 @@ diag(COMPONENT,DIAG_FATAL,"No CI allocator (use -A)"); return; } - if (net && allocate_ci) { + if (net && allocate_ci) diag(COMPONENT,DIAG_FATAL,"CI allocation role conflict"); - return; - } sock->pvc = msg->pvc; if (send_call_proceeding(sock)) diag(COMPONENT,DIAG_FATAL,"s_c_p failed"); diff -ur --new-file old/atm/sigd/policy.c new/atm/sigd/policy.c --- old/atm/sigd/policy.c Mon Nov 3 22:40:18 1997 +++ new/atm/sigd/policy.c Thu Apr 9 14:51:34 1998 @@ -1,6 +1,6 @@ /* policy.c - Access control policies */ -/* Written 1997 by Werner Almesberger, EPFL-LRC */ +/* Written 1997,1998 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -38,7 +38,8 @@ for (rule = rules; rule; rule = rule->next) { count++; if (!(rule->type & direction)) continue; - if (!atm_equal(addr,&rule->addr,rule->mask,AXE_PRVOPT | + if (!atm_equal((struct sockaddr *) addr, + (struct sockaddr *) &rule->addr,rule->mask,AXE_PRVOPT | (rule->mask == -1 ? 0 : AXE_WILDCARD))) continue; rule->hits++; if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) addr, diff -ur --new-file old/atm/sigd/sap.c new/atm/sigd/sap.c --- old/atm/sigd/sap.c Thu Mar 5 16:24:25 1998 +++ new/atm/sigd/sap.c Thu Apr 9 14:51:56 1998 @@ -53,7 +53,8 @@ struct atm_sap *res_sap,const struct atm_qos *old_qos, const struct atm_qos *new_qos,struct atm_qos *res_qos) { - if (atmsvc_addr_in_use(*old_addr) && !atm_equal(old_addr,new_addr,0,0)) + if (atmsvc_addr_in_use(*old_addr) && + !atm_equal((struct sockaddr *) old_addr,(struct sockaddr *) new_addr,0,0)) return 0; if (res_qos) *res_qos = *new_qos; if (old_qos->txtp.max_sdu && new_qos->rxtp.max_sdu && diff -ur --new-file old/atm/sigd/timeout.c new/atm/sigd/timeout.c --- old/atm/sigd/timeout.c Wed Mar 18 22:13:35 1998 +++ new/atm/sigd/timeout.c Tue Apr 7 13:59:17 1998 @@ -56,10 +56,9 @@ diag(COMPONENT,DIAG_WARN,"Trouble: T308_2 has expired"); if (sock->state != ss_wait_rel && sock->state != ss_rel_req) complain(sock,"T308_2"); - /* should initiate restart procedure now ... but we retry forver instead */ - send_release(sock,ATM_CV_TIMER_EXP,308); /* @@@ ? */ sock->conn_timer = NULL; - START_TIMER(sock,T308_2); + if (sock->state == ss_rel_req) send_close(sock); + free_sock(sock); } diff -ur --new-file old/atm/sigd/uni.c new/atm/sigd/uni.c --- old/atm/sigd/uni.c Fri Mar 13 21:11:54 1998 +++ new/atm/sigd/uni.c Thu Apr 16 16:13:47 1998 @@ -51,6 +51,7 @@ (void) q_close(&dsc); return vci; } + sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = signaling_pvc.sap_addr.itf; sock->pvc.sap_addr.vpi = 0; sock->pvc.sap_addr.vci = vci; @@ -115,6 +116,7 @@ int vpci; vpci = q_fetch(&in_dsc,QF_vpi); + this->pvc.sap_family = AF_ATMPVC; this->pvc.sap_addr.itf = get_itf(&vpci); this->pvc.sap_addr.vpi = vpci; this->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); @@ -238,7 +240,7 @@ q_assign(&dsc,QF_call_ref,0); if (!vpi && !vci) q_assign(&dsc,QF_rst_class,ATM_RST_ALL_VC); else { - q_assign(&dsc,QF_rst_class,ATM_RST_ALL_VC); + q_assign(&dsc,QF_rst_class,ATM_RST_IND_VC); q_assign(&dsc,QF_vpi,vpi); q_assign(&dsc,QF_vci,vci); } @@ -318,6 +320,7 @@ int vpci; vpci = q_fetch(&in_dsc,QF_vpi); + sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); @@ -339,6 +342,7 @@ int vpci; vpci = q_fetch(&in_dsc,QF_vpi); + sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); @@ -531,6 +535,7 @@ int vpci; vpci = q_fetch(&in_dsc,QF_vpi); + sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); @@ -633,6 +638,27 @@ SOCKET *curr; trace_msg("SAAL came up"); +#ifdef THOMFLEX + /* + * Some versions of the Thomson Thomflex 5000 won't do any signaling before + * they get a RESTART. Whenever SAAL comes up, this may indicate that the + * switch got booted, so we send that RESTART. We also have to clear all + * pending connections, which isn't that nice ... Note that the rest of the + * RESTART state machine is not implemented, so the RESTART ACKNOWLEDGE + * will yield a warning. + */ + { + Q_DSC dsc; + int size; + + clear_all_calls(); + q_create(&dsc,q_buffer,MAX_Q_MSG); + q_assign(&dsc,QF_msg_type,QMSG_RESTART); + q_assign(&dsc,QF_call_ref,0); + q_assign(&dsc,QF_rst_class,ATM_RST_ALL_VC); + if ((size = q_close(&dsc)) >= 0) to_signaling(q_buffer,size); + } +#endif if (!t309) return; stop_timer(t309); t309 = NULL; diff -ur --new-file old/atm/switch/Makefile new/atm/switch/Makefile --- old/atm/switch/Makefile Wed Mar 25 20:29:14 1998 +++ new/atm/switch/Makefile Thu Apr 16 09:06:13 1998 @@ -1,8 +1,14 @@ -SW_OBJS=io.o proto.o relay.o +SW_OBJS=dispatch.o proto.o relay.o route.o sig.o lex.yy.o y.tab.o -all: libsw.a +all: libsw.a include ../Rules.make -libsw.a: $(SW_OBJS) - ar rcs libsw.a $(SW_OBJS) +lex.yy.c: cfg.l y.tab.h ../lib/atm.h + $(LEX) cfg.l + +y.tab.c y.tab.h: cfg.y ../lib/atmd.h route.h sig.h + $(YACC) -d cfg.y + +libsw.a: $(SW_OBJS) + ar rcs libsw.a $(SW_OBJS) diff -ur --new-file old/atm/switch/Rules.make new/atm/switch/Rules.make --- old/atm/switch/Rules.make Wed Mar 25 20:26:34 1998 +++ new/atm/switch/Rules.make Thu Apr 16 09:29:54 1998 @@ -1,3 +1,5 @@ TOPDIR=../.. include $(TOPDIR)/Rules.make + +LIBS += -lfl # lex may want -ll here diff -ur --new-file old/atm/switch/cfg.l new/atm/switch/cfg.l --- old/atm/switch/cfg.l Thu Jan 1 01:00:00 1970 +++ new/atm/switch/cfg.l Wed Apr 15 23:21:32 1998 @@ -0,0 +1,66 @@ +%{ +/* cfg.l - switch configuration language */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include + +#include "atm.h" + +#include "y.tab.h" + + +static int lineno = 1; +static int token; /* f@#%ing flex doesn't grok return after BEGIN */ + + +void yyerror(const char *s); + +%} + +%s N +%s P + +%% + BEGIN(N); + +command return TOK_COMMAND; +socket { BEGIN(P); + token = TOK_SOCKET; } +vpci return TOK_VPCI; +itf return TOK_ITF; +route { BEGIN(P); + token = TOK_ROUTE; } +default return TOK_DEFAULT; +\"[^"\t\n ]*\" { yylval.str = strdup(yytext+1); + *strrchr(yylval.str,'"') = 0; + return TOK_STR; } +[0-9]+ { char *end; + yylval.num = strtoul(yytext,&end,10); + if (*end) yyerror("invalid number"); + return TOK_NUM; } +[0-9]+\.[0-9]+(\.[0-9]+)? { + if (text2atm(yytext,(struct sockaddr *) &yylval.pvc, + sizeof(yylval.pvc),T2A_PVC) < 0) yyerror("invalid VC"); + return TOK_PVC; } +

[^\t\n ]+ { BEGIN(N); + yylval.str = strdup(yytext); + if (!yylval.str) { + perror("strdup"); + exit(1); + } + return token; } +\n?[\t ]* lineno += *yytext == '\n'; +#[^\n]*\n lineno++; +. return *yytext; + +%% + +void yyerror(const char *s) +{ + fprintf(stderr,"line %d: %s near \"%s\"\n",lineno,s,yytext); + exit(1); +} diff -ur --new-file old/atm/switch/cfg.y new/atm/switch/cfg.y --- old/atm/switch/cfg.y Thu Jan 1 01:00:00 1970 +++ new/atm/switch/cfg.y Thu Apr 16 10:31:23 1998 @@ -0,0 +1,90 @@ +%{ +/* cfg.y - switch configuration language */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include + +#include "atm.h" + +#include "sig.h" +#include "route.h" + + +static int itf; +static SIGNALING_ENTITY *sig; + +%} + +%union { + int num; + char *str; + struct sockaddr_atmpvc pvc; +}; + + +%token TOK_COMMAND TOK_VPCI TOK_ITF TOK_DEFAULT +%token TOK_ROUTE TOK_STR TOK_SOCKET +%token TOK_NUM +%token TOK_PVC + +%% + +all: + | sig all + ; + +sig: + opt_command TOK_SOCKET '{' + { + itf = 0; + } + opt_itf + { + sig = sig_vc($2,itf); + } + routes '}' + ; + +opt_command: + | TOK_COMMAND TOK_STR + { + if (system($2)) yyerror("command failed"); + } + ; + +opt_itf: + | TOK_ITF TOK_NUM + { + itf = $2; + } + ; + +routes: + | route routes + | TOK_DEFAULT + { + put_route(NULL,0,sig); + } + routes + ; + +route: + TOK_ROUTE + { + struct sockaddr_atmsvc addr; + char *mask; + + mask = strchr($1,'/'); + if (mask) *mask++ = 0; + if (text2atm($1,(struct sockaddr *) &addr,sizeof(addr), + T2A_SVC | T2A_WILDCARD | T2A_NAME | T2A_LOCAL) < 0) { + yyerror("invalid address"); + return; + } + put_route(&addr,mask ? strtol(mask,NULL,10) : INT_MAX,sig); + } + ; diff -ur --new-file old/atm/switch/debug/Makefile new/atm/switch/debug/Makefile --- old/atm/switch/debug/Makefile Wed Mar 25 20:38:24 1998 +++ new/atm/switch/debug/Makefile Wed Apr 15 23:23:45 1998 @@ -1,4 +1,4 @@ -LIBS=-latmd -lsw -L.. +LIBS=-lsw -latmd -L.. LIBDEPS=../../lib/libatmd.a ../libsw.a OBJS=debug.o SYSPGMS=sw_debug diff -ur --new-file old/atm/switch/debug/README new/atm/switch/debug/README --- old/atm/switch/debug/README Thu Jan 1 01:00:00 1970 +++ new/atm/switch/debug/README Thu Apr 16 18:12:01 1998 @@ -0,0 +1,97 @@ +This is a little sample configuration with two terminals connected to a +switch. All of the are on the same host and atmtcp takes care of the +"wiring". The terminals are controlled by the isp program. (We can't use +the real kernel with multiple terminals on the same machine. At least +not yet.) + +Note that no data transfer or such is possible yet. This is only +signaling. + + +This is the example setup: + + +-------+ +------+ +-------+ + | isp | |switch| | isp | + |atmsigd|-----| |-----|atmsigd| + +-------+ +------+ +-------+ + + +Preparation (only once): + + # atmtcp -b -i 1 -l 8412 + # atmtcp -b -i 2 -c localhost 8412 + # atmtcp -b -i 3 -l 8434 + # atmtcp -b -i 4 -c localhost 8434 + +Start the "network" (no privileges required): + + % atmsigd -b 1.0.105 /tmp/1 + % atmsigd -b -N -A 2.0.105 /tmp/2 + % atmsigd -b -N -A 3.0.105 /tmp/3 + % atmsigd -b 4.0.105 /tmp/4 + % ./sw_debug -d + % isp /tmp/4 <4.isp + % isp /tmp/1 <1.isp + + +In more detail: + + + +------------------------------------------+ + | ./sw_debug | + +------------------------------------------+ + | | + /tmp/2 /tmp/3 + | | + +------------------------------+ +------------------------------+ + | atmsigd -N -A 2.0.105 /tmp/2 | | atmsigd -N -A 3.0.105 /tmp/3 | + +------------------------------+ +------------------------------+ + | | + itf 2 itf 3 + | | + +-------------------------------+ +-------------------------------+ + | atmtcp -i 2 -c localhost 8412 | | atmtcp -i 3 -l 8434 | + +-------------------------------+ +-------------------------------+ + | atmtcp -i 1 -l 8412 | | atmtcp -i 4 -c localhost 8434 | + +-------------------------------+ +-------------------------------+ + | | + itf 1 itf 4 + | | + +------------------------+ +------------------------+ + | atmsigd 1.0.105 /tmp/1 | | atmsigd 4.0.105 /tmp/4 | + +------------------------+ +------------------------+ + | | + /tmp/1 /tmp/4 + | | ++-------------------+ +-------------------+ +| isp /tmp/1 <1.isp | | isp /tmp/4 <4.isp | ++-------------------+ +-------------------+ + + +--- switch.conf -------------------------------------------------------------- + +socket /tmp/2 { + itf 2 + route +1 +} +socket /tmp/3 { + itf 3 + default +} + +--- 1.isp -------------------------------------------------------------------- + +send connect vcc=1 svc=+234 local=+123 qos=ubr,aal5 +receive okay vcc=1 +send close vcc=1 +receive close vcc=1 + +--- 4.isp -------------------------------------------------------------------- + +send listen vcc=1 svc=+234 qos=ubr,aal5 +receive okay vcc=1 +receive indicate listen_vcc=1 +send accept vcc=2 listen_vcc=1 +receive okay vcc=2 +receive close vcc=2 +send close vcc=2 diff -ur --new-file old/atm/switch/debug/debug.c new/atm/switch/debug/debug.c --- old/atm/switch/debug/debug.c Mon Mar 23 13:24:46 1998 +++ new/atm/switch/debug/debug.c Thu Apr 16 15:29:35 1998 @@ -46,6 +46,32 @@ } +static int vci_exists(int vci,int threshold) +{ + CALL *call; + int found; + + found = 0; + for (call = calls; call; call = PRV(call)->next) + if (call->in.pvc.sap_addr.vci == vci || + call->out.pvc.sap_addr.vci == vci) + if (++found > threshold) return 1; + return 0; +} + + +static int check_ci(struct sockaddr_atmpvc *pvc) +{ + int vci; + + if (pvc->sap_addr.vpi == ATM_VPI_ANY) pvc->sap_addr.vpi = 0; + /* that was easy :-) */ + for (vci = 32; pvc->sap_addr.vci == ATM_VCI_ANY; vci++) + if (!vci_exists(vci,0)) pvc->sap_addr.vci = vci; + return !vci_exists(vci,1); +} + + void fab_op(CALL *call,int op,const struct atm_qos *qos, void (*callback)(CALL *call,int okay,void *user),void *user) { @@ -61,5 +87,9 @@ op & _RM_SHIFT(RM_OUT_RX) ? " OUT_RX" : "", op & _RM_SHIFT(RM_PATH_TX) ? " PATH_TX" : "", op & _RM_SHIFT(RM_PATH_RX) ? " PATH_RX" : ""); + if (op & (RM_RSV(RM_IN) | RM_CLAIM(RM_IN))) + if (!check_ci(&call->in.pvc)) callback(call,0,user); + if (op & (RM_RSV(RM_OUT) | RM_CLAIM(RM_OUT))) + if (!check_ci(&call->out.pvc)) callback(call,0,user); callback(call,1,user); } diff -ur --new-file old/atm/switch/dispatch.c new/atm/switch/dispatch.c --- old/atm/switch/dispatch.c Thu Jan 1 01:00:00 1970 +++ new/atm/switch/dispatch.c Thu Apr 16 09:09:20 1998 @@ -0,0 +1,113 @@ +/* dispatch.c - Event dispatcher */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include +#include +#include +#include + +#include "atmd.h" +#include "dispatch.h" + + +typedef struct _fd_entry { + int fd; + void (*callback)(int fd,void *user); + void *user; + struct _fd_entry *next; +} FD_ENTRY; + +static FD_ENTRY *fd_idle = NULL,*fd_active = NULL; +static int fds = 0; +static fd_set r_set; + + +void dsp_fd_add(int fd,void (*callback)(int fd,void *user),void *user) +{ + FD_ENTRY *entry; + + for (entry = fd_idle; entry; entry = entry->next) + if (entry->fd == fd) break; + if (!entry) + for (entry = fd_active; entry; entry = entry->next) + if (entry->fd == fd) break; + if (entry) { + fprintf(stderr,"dsp_fd_add: duplicate fd %d\n",fd); + exit(1); + } + if (fd >= fds) fds = fd+1; + FD_SET(fd,&r_set); + entry = alloc_t(FD_ENTRY); + entry->fd = fd; + entry->callback = callback; + entry->user = user; + entry->next = fd_idle; + fd_idle = entry; +} + + +void dsp_fd_remove(int fd) +{ + FD_ENTRY **walk,*next; + + FD_CLR(fd,&r_set); + for (walk = &fd_idle; *walk; walk = &(*walk)->next) { + if ((*walk)->fd != fd) continue; + next = (*walk)->next; + free(*walk); + *walk = next; + return; + } + for (walk = &fd_active; *walk; walk = &(*walk)->next) { + if ((*walk)->fd != fd) continue; + next = (*walk)->next; + free(*walk); + *walk = next; + return; + } + fprintf(stderr,"dsp_fd_remove: fd %d not found\n",fd); + exit(1); +} + + +void dsp_init(void) +{ + FD_ZERO(&r_set); +} + + +void dsp_poll(void) +{ + FD_ENTRY **walk,*next,*entry; + fd_set r_poll; + int num; + + while (!fd_active) { + r_poll = r_set; + num = select(fds+1,&r_poll,NULL,NULL,NULL); + if (num < 0) { + if (errno != EINTR) perror("select"); + continue; + } + for (walk = &fd_idle; num;) { + next = (*walk)->next; + if (!FD_ISSET((*walk)->fd,&r_poll)) { + walk = &(*walk)->next; + continue; + } + (*walk)->next = fd_active; + fd_active = *walk; + *walk = next; + num--; + } + } + entry = fd_active; + fd_active = entry->next; + entry->next = fd_idle; + fd_idle = entry; + entry->callback(entry->fd,entry->user); +} diff -ur --new-file old/atm/switch/dispatch.h new/atm/switch/dispatch.h --- old/atm/switch/dispatch.h Thu Jan 1 01:00:00 1970 +++ new/atm/switch/dispatch.h Thu Apr 16 09:06:06 1998 @@ -0,0 +1,37 @@ +/* dispatch.h - Event dispatcher */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#ifndef DISPATCH_H +#define DISPATCH_H + +/* + * Add a file descriptor to probe for reading in the central dispatcher. If + * the FD if readable, the callback function is invoked. The dispatcher does + * not attempt to read itself. + */ + +void dsp_fd_add(int fd,void (*callback)(int fd,void *user),void *user); + +/* + * Remove a file descriptor from the central dispatcher. This function can be + * invoked from within a callback function. + */ + +void dsp_fd_remove(int fd); + +/* + * Initialize the dispatcher. + */ + +void dsp_init(void); + +/* + * Wait until one of the file descriptors becomes readable and execute the + * callback function. dsp_poll only handles one event at a time. + */ + +void dsp_poll(void); + +#endif diff -ur --new-file old/atm/switch/fab.h new/atm/switch/fab.h --- old/atm/switch/fab.h Mon Mar 23 13:19:42 1998 +++ new/atm/switch/fab.h Thu Apr 16 08:25:34 1998 @@ -27,23 +27,6 @@ #define RM_CLAIM(what) _RM_SHIFT(what) -/* --- Provided by the relay core ------------------------------------------ */ - -/* - * Add a file descriptor to probe for reading in the central dispatcher. If - * the FD if readable, the callback function is invoked. The dispatcher does - * not attempt to read itself. - */ - -void sw_fd_add(int fd,void (*callback)(int fd,void *user),void *user); - -/* - * Remove a file descriptor from the central dispatcher. This function can be - * invoked from within a callback function. - */ - -void sw_fd_remove(int fd); - /* --- Provided by fabric control ------------------------------------------ */ /* diff -ur --new-file old/atm/switch/io.c new/atm/switch/io.c --- old/atm/switch/io.c Mon Feb 16 18:44:27 1998 +++ new/atm/switch/io.c Thu Jan 1 01:00:00 1970 @@ -1,44 +0,0 @@ -/* io.c - I/O operations */ - -/* Written 1997-1998 by Roman Pletka, EPFL-LRC */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "atm.h" -#include "atmd.h" - -/*#include "proto.h"*/ -#include "io.h" - -#define COMPONENT "IO" - -void to_sigd(long id,struct atmsvc_msg *msg) { - int err; - err = write(id,msg,sizeof(*msg)); - if (err == sizeof(*msg)) return; - if (err < 0) { - perror("write"); - } -} - -void to_rm(long id,struct atmsvc_msg *msg) { - int err; - err = write(id,msg,sizeof(*msg)); - if (err == sizeof(*msg)) return; - if (err < 0) { - perror("write"); - } -} diff -ur --new-file old/atm/switch/io.h new/atm/switch/io.h --- old/atm/switch/io.h Mon Feb 16 18:44:40 1998 +++ new/atm/switch/io.h Thu Jan 1 01:00:00 1970 @@ -1,13 +0,0 @@ -/* io.h - I/O operations */ - -/* Written 1997-1998 by Roman Pletka, EPFL-LRC */ - -#ifndef IO_H -#define IO_H - -#include -#include - -void to_sigd(long id,struct atmsvc_msg *msg); -void to_rm(long id,struct atmsvc_msg *msg); -#endif diff -ur --new-file old/atm/switch/proto.c new/atm/switch/proto.c --- old/atm/switch/proto.c Fri Mar 27 00:19:33 1998 +++ new/atm/switch/proto.c Thu Apr 16 08:22:34 1998 @@ -11,7 +11,8 @@ #include #include "atmd.h" -#include "io.h" +#include "sig.h" +#include "fab.h" #include "proto.h" @@ -34,213 +35,148 @@ static const char *sources[4] = {"CALLER","CALLED","RM"}; -static CALL *calls = NULL; - - -CALL *new_call(unsigned long id) +CALL *new_call(void) { CALL *call; call = alloc_t(CALL); memset(call,0,sizeof(CALL)); call->state = cs_invalid; - call->in.id = id; - call->out.id = 0; - call->listen = NULL; - call->next = calls; - calls = call; + fab_init(call); return call; } void free_call(CALL *call) { - - call->state = cs_invalid; - free(call); - printf("Call 0x%p killed\n",call); - /* because call is not in a double linked chain, the next-pointer - in the previous element will not point to the next element! - But this chain is only for debbuging (except at startup) we neglect - this fact... */ + fab_destroy(call); + call->state = cs_invalid; + free(call); + printf("Call 0x%p killed\n",call); } void new_state(CALL *call,STATE state) { - call->state = state; - print_state(call); + call->state = state; + print_state(call); } -void send_sigd(unsigned long vcc, - unsigned long listen_vcc, - enum atmsvc_msg_type type, - int reply, - const struct sockaddr_atmpvc *pvc, - const struct sockaddr_atmsvc *svc, - const struct sockaddr_atmsvc *local, - const struct atm_sap *sap, - const struct atm_qos *qos) -{ - struct atmsvc_msg *msg; - - msg = alloc_t(struct atmsvc_msg); - msg->vcc = vcc; - msg->listen_vcc = listen_vcc; - msg->type = type; - msg->reply = reply; - if (pvc) msg->pvc = *pvc; - else memset(&msg->pvc,0,sizeof(msg->pvc)); - if (sap) msg->sap = *sap; - else memset(&msg->sap,0,sizeof(msg->sap)); - if (qos) msg->qos = *qos; - else memset(&msg->qos,0,sizeof(msg->qos)); - if (local) msg->local = *local; - else memset(&msg->local,0,sizeof(msg->local)); - if (svc) msg->svc = *svc; - else memset(&msg->svc,0,sizeof(msg->svc)); - to_sigd(vcc,msg); - free(msg); -} - -void send_listen(void) +void send_listen(SIGNALING_ENTITY *sig) { - CALL *call; struct atmsvc_msg msg; - for (call = calls; call; call = call->next) { - memset(&msg,0,sizeof(msg)); - /* compose the message */ - msg.type = as_listen; - msg.vcc = (unsigned long) call; - msg.svc.sas_family = AF_ATMSVC; - msg.qos.aal = ATM_AAL5; - msg.qos.txtp.traffic_class = msg.qos.rxtp.traffic_class = ATM_ANYCLASS; - /* msg.sap ; */ - call->listen = call; - to_sigd(call->in.id,&msg); - new_state(call,cs_null); - } + memset(&msg,0,sizeof(msg)); + /* compose the message */ + msg.type = as_listen; + msg.vcc = (unsigned long) sig; + msg.svc.sas_family = AF_ATMSVC; + msg.qos.aal = ATM_AAL5; + msg.qos.txtp.traffic_class = msg.qos.rxtp.traffic_class = ATM_ANYCLASS; + /* msg.sap ; */ + sig_send(sig,&msg); } + void send_identify(CALL *call) { - struct atmsvc_msg msg; + struct atmsvc_msg msg; - /* this is always sent to caller */ - memset(&msg,0,sizeof(msg)); + /* this is always sent to caller */ + memset(&msg,0,sizeof(msg)); - /* compose the message */ - msg.type = as_identify; - msg.vcc = (unsigned long) call; - msg.listen_vcc = (unsigned long) call->listen; + /* compose the message */ + msg.type = as_identify; + msg.vcc = (unsigned long) call | CALLER; + msg.listen_vcc = (unsigned long) call->in.sig; - /* We have to complete the message (vci,vpi..) */ - msg.pvc = call->in.pvc; - to_sigd(call->in.id,&msg); + /* We have to complete the message (vci,vpi..) */ + msg.pvc = call->in.pvc; + sig_send(call->in.sig,&msg); } + void send_connect(CALL *call) { - struct atmsvc_msg msg; + struct atmsvc_msg msg; - /* this is always sent to called */ - memset(&msg,0,sizeof(msg)); - /* compose the message */ - msg.type = as_connect; - msg.vcc = (unsigned long) call | CALLED; /* some kind of magic... */ - msg.local = call->in.svc; - msg.qos = call->in.qos; - msg.svc = call->out.svc; - msg.sap = call->sap; - /* we have to give VCI/VPI */ - msg.pvc = call->out.pvc; - to_sigd(call->out.id,&msg); + /* this is always sent to called */ + memset(&msg,0,sizeof(msg)); + /* compose the message */ + msg.type = as_connect; + msg.vcc = (unsigned long) call | CALLED; /* some kind of magic... */ + msg.local = call->in.svc; + msg.qos = call->in.qos; + msg.svc = call->out.svc; + msg.sap = call->sap; + /* we have to give VCI/VPI */ + msg.pvc = call->out.pvc; + sig_send(call->out.sig,&msg); } + void send_reject(CALL *call, int err_code) { - struct atmsvc_msg msg; + struct atmsvc_msg msg; - /* this is always sent to called */ - memset(&msg,0,sizeof(msg)); - msg.type = as_reject; - msg.vcc = (unsigned long) call; - msg.reply = err_code; - /* msg.listen_vcc = call->in.id; */ - to_sigd(call->in.id,&msg); -} - -void send_reject_not_id(CALL *call, int err_code) -{ - struct atmsvc_msg msg; - - /* this is always sent to called */ - memset(&msg,0,sizeof(msg)); - msg.type = as_reject; - msg.vcc = (unsigned long) call->listen; - msg.reply = err_code; - /* msg.listen_vcc = call->in.id; */ - to_sigd(call->in.id,&msg); + /* this is always sent to caller */ + memset(&msg,0,sizeof(msg)); + msg.type = as_reject; + msg.vcc = (unsigned long) call | CALLER; + msg.reply = err_code; + sig_send(call->in.sig,&msg); } -void send_close(CALL *call,int dest) + +void send_reject_not_id(SIGNALING_ENTITY *sig, int err_code) { - unsigned long id; - struct atmsvc_msg msg; + struct atmsvc_msg msg; - memset(&msg,0,sizeof(msg)); - msg.type = as_close; - msg.vcc = (unsigned long) call | dest; /* dest: CALLER or CALLED */ - id = dest == CALLER ? id = call->in.id : call->out.id; - /* msg.reply = ??!! */ - to_sigd(id,&msg); + /* this is always sent to caller */ + memset(&msg,0,sizeof(msg)); + msg.type = as_reject; + msg.listen_vcc = (unsigned long) sig; + msg.reply = err_code; + sig_send(sig,&msg); } -void send_accept(CALL *call) + +void send_close(CALL *call,int dest) { - struct atmsvc_msg msg; + struct atmsvc_msg msg; - memset(&msg,0,sizeof(msg)); - msg.type = as_accept; - msg.vcc = (unsigned long) call; - /* msg.listen_vcc = call->in.id; */ - to_sigd(call->in.id,&msg); + memset(&msg,0,sizeof(msg)); + msg.type = as_close; + msg.vcc = (unsigned long) call | dest; /* dest: CALLER or CALLED */ + /* msg.reply = ??!! */ + sig_send(dest == CALLER ? call->in.sig : call->out.sig,&msg); } -void send_free_rm(long id, CALL *call) + +void send_accept(CALL *call) { - /* here we send an as_close msg */ - struct atmsvc_msg msg; + struct atmsvc_msg msg; - memset(&msg,0,sizeof(msg)); - msg.type = as_close; - msg.vcc = (unsigned long) call | RM; - to_rm(id,&msg); + memset(&msg,0,sizeof(msg)); + msg.type = as_accept; + msg.vcc = (unsigned long) call | CALLER; + sig_send(call->in.sig,&msg); } + /*****************************************************************************/ /* Demultiplexing with magic number: caller - called - rm */ /*****************************************************************************/ + CALL *demux_in(unsigned long *srce, struct atmsvc_msg *msg) { /* The multiplexing informations are in the 3 least significant bits of the call pointer. We can do this, because the compiler aligns memory reservation to pointers with 3 ls-bits = 0. */ - CALL *call; - - if ((msg->type == as_identify) || (msg->type == as_indicate)) { - call = (struct _call *) (msg->listen_vcc); - *srce = CALLER; - return call; - } /* all identify msgs come from a listening call */ - else { - call = (struct _call *) (msg->vcc & ~3); *srce = (unsigned long) (msg->vcc & 3); - return call; - } + return (CALL *) (msg->vcc & ~3); } /*****************************************************************************/ @@ -257,7 +193,7 @@ call , cs_states[call->state]); } void print_call(CALL *call) { - printf(" Call 0x%p in state %s, caller-id:%ld, called-id:%ld\n", + printf(" Call 0x%p in state %s, caller-id:%p, called-id:%p\n", call, cs_states[call->state], - call->in.id, call->out.id); + call->in.sig, call->out.sig); } diff -ur --new-file old/atm/switch/proto.h new/atm/switch/proto.h --- old/atm/switch/proto.h Mon Mar 23 11:02:37 1998 +++ new/atm/switch/proto.h Thu Apr 16 08:22:13 1998 @@ -15,6 +15,8 @@ #include "atmsap.h" #include "atmd.h" +#include "sig.h" + typedef enum { /* call states */ cs_invalid, cs_null, cs_listening, @@ -28,27 +30,23 @@ } STATE; typedef struct _party { - unsigned long id; - struct sockaddr_atmpvc pvc; /* itf and CI */ - struct sockaddr_atmsvc svc; /* remote address */ - struct atm_qos qos; /* QOS parameters */ + SIGNALING_ENTITY *sig; /* signaling entity */ + struct sockaddr_atmpvc pvc; /* itf and CI */ + struct sockaddr_atmsvc svc; /* remote address */ + struct atm_qos qos; /* QOS parameters */ } PARTY; typedef struct _call { - STATE state; - unsigned long caller_id,called_id; /* file descriptors to pipes */ - PARTY in; /* caller data */ - PARTY out; /* called data */ - - struct atm_sap sap; /* SAP (BHLI and BLLI) */ - - int error; /* error code for close */ - /* --- switch fabric control data -------------------------------------- */ - void *fab; - /* --- some meta-information ------------------------------------------- */ - struct _call *next; /* next call (for debugging) */ - struct _call *listen; /* pointer to corresponding listening - "call" (more like a socket) */ + STATE state; + unsigned long caller_id,called_id; /* file descriptors to pipes */ + PARTY in; /* caller data */ + PARTY out; /* called data */ + + struct atm_sap sap; /* SAP (BHLI and BLLI) */ + + int error; /* error code for close */ + /* --- switch fabric control data -------------------------------------- */ + void *fab; } CALL; /* @@ -57,32 +55,25 @@ */ -#define SEND_ERROR(vcc,code) \ - send_sigd(vcc,0L,as_error,code,NULL,NULL,NULL,NULL,NULL) - -void send_sigd(unsigned long vcc,unsigned long listen_vcc, - enum atmsvc_msg_type type,int reply,const struct sockaddr_atmpvc *pvc, - const struct sockaddr_atmsvc *svc,const struct sockaddr_atmsvc *local, - const struct atm_sap *sap,const struct atm_qos *qos); void send_identify(CALL *call); -void send_listen(void); +void send_listen(SIGNALING_ENTITY *sig); void send_connect(CALL *call); void send_reject(CALL *call, int err_code); -void send_reject_not_id(CALL *call, int err_code); +void send_reject_not_id(SIGNALING_ENTITY *sig, int err_code); void send_close(CALL *call,int dest); void send_accept(CALL *call); -CALL *new_call(unsigned long id); +CALL *new_call(void); void free_call(CALL *call); void new_state(CALL *call,STATE state); -void send_free_rm(long id, CALL *call); - CALL *demux_in(unsigned long *srce, struct atmsvc_msg *msg); /* some debugging functions */ void print_msg(struct atmsvc_msg *msg, CALL *call,unsigned long source); void print_state(CALL *call); void print_call(CALL *call); + +int from_sigd(SIGNALING_ENTITY *sig,struct atmsvc_msg *msg); #endif diff -ur --new-file old/atm/switch/relay.c new/atm/switch/relay.c --- old/atm/switch/relay.c Mon Mar 23 10:58:35 1998 +++ new/atm/switch/relay.c Thu Apr 16 15:50:54 1998 @@ -4,383 +4,288 @@ /* Modified 1998 by Werner Almesberger, EPFL ICA */ -#include /* perror */ +#include #include -#include /* select,open */ -#include -#include /* open */ -#include /* open */ -#include /* select */ -#include /* select */ +#include +#include -#include "io.h" +#include "atmd.h" +#include "fab.h" +#include "dispatch.h" +#include "sig.h" +#include "route.h" #include "proto.h" -/*#include "atmsvc.h"*/ +#define COMPONENT "RELAY" +#define CONFIG_FILE "switch.conf" -#define MAX_ITF 10 /* limit max number of interfaces */ +extern int yyparse(void); +extern FILE *yyin; -static int in,out[MAX_ITF],rm; +static void from_fab(CALL *call,int okay,void *user) +{ + printf("%p: fab returns %d\n",call,okay); + print_call(call); + + switch (call->state) { + case cs_indicated: + if (okay) { + /* send connect to called and enter state cs_rm_accepted */ + send_identify(call); + send_connect(call); + new_state(call,cs_rm_accepted); + } + else { + /* send as_reject to caller and enter state cs_invalid */ + send_reject_not_id(call->in.sig,-EREMOTEIO); /* @@@ */ + new_state(call,cs_invalid); + free_call(call); + } + break; + case cs_called_accepted: + if (okay) { + /* send accept to caller */ + send_accept(call); + new_state(call,cs_rm_accepted2); + } + else { + /* send reject to caller and close to called */ + send_reject(call,-EREMOTEIO); + send_close(call,CALLED); + new_state(call, cs_rejected); + } + break; + case cs_rejecting: + if (!okay) free_call(call); + else { + /* free resources */ + new_state(call, cs_free_rm); + fab_op(call,RM_FREE,NULL,from_fab,NULL); + } + break; + case cs_free_rm: + if (!okay) printf("Error: RM couldn't free resources\n"); + free_call(call); + break; + default: + diag(COMPONENT,DIAG_FATAL,"invalid state for fab callback"); + break; + } +} -static void from_sigd(struct atmsvc_msg *msg) +static void from_caller(CALL *call,struct atmsvc_msg *msg) { - CALL *call; - CALL *old_call; - unsigned long source; - - /* Choose right call and source (caller/called/rm)*/ - call = demux_in(&source, msg); - print_msg(msg,call,source); - print_call(call); - - switch (call->state) { - case cs_null: - if (source == CALLER) { - switch(msg->type) { - case as_okay: /* enter cs_listening state */ - new_state(call,cs_listening); - break; - case as_error: /* sigd says "no" */ - printf("sigd not ready for listening\n"); - /* kill the listening "call" ??!! */ - break; - default: - printf("Error: Socket\n"); - abort(); - break; - } - } - break; - case cs_listening: - if (source == CALLER && msg->type == as_indicate) { - /* now work starts... */ - old_call = call; - call = new_call(old_call->in.id); /* fd to out pipe */ - /* save data in call: pvc,local,qos,sap */ - call->in.pvc = msg->pvc; /* maybe it's in the msg */ - call->in.qos = msg->qos; - call->out.svc = msg->local; - call->in.svc = msg->svc; - call->sap = msg->sap; - call->listen = old_call; - - msg->vcc = msg->listen_vcc; - /* ask for vci,vpi... */ - msg->vcc = (unsigned long) call | RM; /* some kind of magic... */ - to_rm(rm,msg); /* forwards indicate as it is */ - new_state(call,cs_indicated); + switch (call->state) { + case cs_rm_accepted2: + /* msg from: caller(error,okay) or called(close) */ + switch(msg->type) { + case as_okay: /* complete the call */ + new_state(call, cs_connected); + return; + case as_error: + /* send close called */ + send_close(call, CALLED); + new_state(call, cs_caller_error); + return; + default: + break; + } + break; + case cs_connected: + if (msg->type != as_close) break; + send_close(call, CALLER); + send_close(call, CALLED); + new_state(call, cs_caller_closed); + return; + case cs_called_closed: + switch(msg->type) { + case as_error: + new_state(call, cs_free_rm); + fab_op(call,RM_FREE,NULL,from_fab,NULL); + break; + case as_okay: + send_close(call, CALLER); + new_state(call, cs_caller_closing); + break; + default: + break; + } + break; + case cs_called_closed2: + case cs_caller_closing: + if (msg->type != as_close) break; + new_state(call, cs_free_rm); + fab_op(call,RM_FREE,NULL,from_fab,NULL); + return; + default: + break; } - else { - if (msg->type == as_close) { - /* close the listening "call" */ - send_close(call, CALLER); - new_state(call, cs_will_close); - } - } - break; - case cs_indicated: - if (source == RM) { - switch(msg->type) { - case as_okay: - /* find fd/itf->out.id for called from msg */ - call->out.id = out[msg->pvc.sap_addr.itf]; - call->out.pvc = call->in.pvc = msg->pvc; /* @@@@ hmm, that looks wrong*/ - /* send connect to called and enter state cs_rm_accepted */ - send_identify(call); - send_connect(call); - new_state(call,cs_rm_accepted); - break; - case as_error: - /* send as_reject to caller - and enter state cs_invalid */ - send_reject_not_id(call,msg->reply); - new_state(call,cs_invalid); - free_call(call); - break; - default: - abort(); - break; - } + diag(COMPONENT,DIAG_FATAL,"invalid combination"); +} + + +static void from_called(CALL *call,struct atmsvc_msg *msg) +{ + switch (call->state) { + case cs_rm_accepted: + switch(msg->type) { + case as_okay: + /* save msg content in call */ + call->out.qos = msg->qos; + new_state(call,cs_called_accepted); + fab_op(call,RM_CLAIM(_RM_ANY),NULL,from_fab,NULL); + return; + case as_error: + send_reject(call,msg->reply); + new_state(call,cs_invalid); + free_call(call); + return; + default: + break; + } + break; + case cs_rm_accepted2: + /* msg from: caller(error,okay) or called(close) */ + if (msg->type != as_close) break; + /* send close to called */ + send_close(call, CALLED); + new_state(call, cs_called_closed); + return; + case cs_rejected: + /* wait for close msg from called */ + if (msg->type != as_close) break; + free_call(call); + return; + case cs_called_accepted: + if (msg->type != as_close) break; + /* send reject to caller and send close to called */ + send_reject(call, msg->reply); + send_close(call,CALLED); + new_state(call,cs_rejecting); + return; + case cs_connected: + if (msg->type != as_close) break; + send_close(call, CALLER); + send_close(call, CALLED); + new_state(call, cs_called_closed2); + return; + case cs_caller_error: + case cs_caller_closed: + if (msg->type != as_close) break; + new_state(call, cs_free_rm); + fab_op(call,RM_FREE,NULL,from_fab,NULL); + return; + default: + break; } + diag(COMPONENT,DIAG_FATAL,"invalid combination"); +} + + +static void from_listening(SIGNALING_ENTITY *sig,struct atmsvc_msg *msg) +{ + SIGNALING_ENTITY *out; + CALL *call; + + /* try to find a route */ + out = find_route(&msg->svc,&msg->local,&msg->qos); + if (!out) { + send_reject_not_id(sig,-EHOSTUNREACH); + return; + } + /* now work starts... */ + call = new_call(); + /* set up caller side */ + call->in.sig = sig; + if (atmpvc_addr_in_use(msg->pvc)) call->in.pvc = msg->pvc; else { - printf("Error: in state cs_indicated. Msg from %ld != RM expected.\n", - source); - abort(); - } - break; - case cs_rm_accepted: - if (source == CALLED) { - switch(msg->type) { - case as_okay: - /* send claim */ - msg->vcc = (unsigned long) call | RM; /* some kind of magic... */ - /* save msg content in call */ - call->out.qos = msg->qos; - to_rm(rm,msg); /* claim ??!! */ - new_state(call,cs_called_accepted); - break; - case as_error: - send_reject(call,msg->reply); - new_state(call,cs_invalid); - free_call(call); - break; - default: - abort(); - break; - } - } + call->in.pvc.sap_addr.itf = sig->itf; + call->in.pvc.sap_addr.vpi = ATM_VPI_ANY; + call->in.pvc.sap_addr.vci = ATM_VCI_ANY; + } + call->in.pvc.sap_family = AF_ATMPVC; + call->in.svc = msg->svc; + call->in.qos = msg->qos; + /* set up what little we know about the called side */ + call->out.sig = out; + call->out.pvc.sap_family = AF_ATMPVC; + call->out.pvc.sap_addr.itf = out->itf; + call->out.pvc.sap_addr.vpi = ATM_VPI_ANY; + call->out.pvc.sap_addr.vci = ATM_VCI_ANY; + call->out.svc = msg->local; + call->sap = msg->sap; + new_state(call,cs_indicated); + fab_op(call,RM_RSV(_RM_ANY),&msg->qos,from_fab,NULL); +} + + +int from_sigd(SIGNALING_ENTITY *sig,struct atmsvc_msg *msg) +{ + if (msg->type == as_indicate) from_listening(sig,msg); else { - printf("Error: in state cs_rm_accepted. " - "Msg from %ld != CALLED expected.\n", - source); - abort(); - } - break; - case cs_rm_accepted2: - /* msg from: caller(error,okay) or called(close) */ - switch (source) { - case CALLER: - switch(msg->type) { - case as_okay: /* complete the call */ - new_state(call, cs_connected); - break; - case as_error: - /* send close called */ - send_close(call, CALLED); - new_state(call, cs_caller_error); - break; - default: - abort(); - break; - } - break; - case CALLED: - if (msg->type == as_close) { - /* send close to called */ - send_close(call, CALLED); - new_state(call, cs_called_closed); - } - else abort(); - break; - default: - abort(); - break; - } - break; - case cs_rejected: - /* wait for close msg from called */ - if (source == CALLED) { - if (msg->type == as_close){ - new_state(call,cs_invalid); - free_call(call); - } - } - else abort(); - /* else error */ - break; - case cs_called_accepted: - if (source == CALLED) { - if (msg->type == as_close){ - /* send reject to caller and send close to called */ - send_reject(call, msg->reply); - send_close(call,CALLED); - new_state(call,cs_rejecting); - } - } - if (source == RM) { - switch(msg->type) { - case as_okay: - /* send accept to caller */ - send_accept(call); - new_state(call,cs_rm_accepted2); - break; - case as_error: - /* send reject to caller and close to called */ - send_reject(call,msg->reply); - send_close(call,CALLED); - new_state(call, cs_rejected); - break; - default: - abort(); - break; - } - } - break; - case cs_connected: - if (msg->type == as_close) { - if (source == CALLER) { - send_close(call, CALLER); - send_close(call, CALLED); - new_state(call, cs_caller_closed); - } - else if (source == CALLED) { - send_close(call, CALLER); - send_close(call, CALLED); - new_state(call, cs_called_closed2); - } - } - /* else error */ - else abort(); - break; - case cs_rejecting: - if (source == RM ) { - switch(msg->type) { - case as_error: - free_call(call); - break; - case as_okay: - /* free resources */ - send_free_rm(rm,call); - new_state(call, cs_free_rm); - break; - default: - abort(); - break; - } - } - break; - case cs_called_closed: - if (source == CALLER) { - switch(msg->type) { - case as_error: - send_free_rm(rm, call); - new_state(call, cs_free_rm); - break; - case as_okay: - send_close(call, CALLER); - new_state(call, cs_caller_closing); - break; - default: - abort(); - break; - } - } - case cs_called_closed2: - if (source == CALLER && msg->type == as_close) { - send_free_rm(rm, call); - new_state(call, cs_free_rm); - } - /* else error */ - break; - case cs_caller_error: - if (source == CALLED && msg->type == as_close) { - send_free_rm(rm, call); - new_state(call, cs_free_rm); - break; - } - case cs_caller_closing: - if (source == CALLER && msg->type == as_close) { - send_free_rm(rm, call); - new_state(call, cs_free_rm); - } - else abort(); - break; - case cs_caller_closed: - if (source == CALLED && msg->type == as_close) { - send_free_rm(rm, call); - new_state(call, cs_free_rm); - } - else abort(); - /* else error */ - break; - case cs_free_rm: - if (source == RM) { - switch(msg->type) { - case as_error: - free_call(call); - printf("Error: RM couldn't free resources\n"); - break; - case as_okay: - free_call(call); - break; - default: - abort(); - break; - } - } - else abort(); - break; - case cs_will_close: - if (source == CALLER) { - switch (msg->type) { - case as_close: - free_call(call); - break; - case as_indicate: - send_reject_not_id(call, 0); - new_state(call, cs_call_indicated); - free_call(call); - break; - default: - abort(); - break; - } + CALL *call; + unsigned long source; + + call = demux_in(&source,msg); + print_msg(msg,call,source); + print_call(call); + switch (source) { + case CALLER: + from_caller(call,msg); + break; + case CALLED: + from_called(call,msg); + break; + default: + diag(COMPONENT,DIAG_FATAL,"unrecognized source %d\n",source); + } } - break; - default: - abort(); - break; - } + return 0; } + /*****************************************************************************/ /* M A I N */ /*****************************************************************************/ -int main(int argc, char *argv[]) -{ - static unsigned char buffer[sizeof(struct atmsvc_msg)]; - int nb_itf; - int i; - if (argc < 5) { - printf("Usage: %s in rm [out1 out_2 ...]\n",argv[0]); - exit(1); - } - if ((argc+1) > MAX_ITF) { - printf("%s: Too many interfaces (%d > %d)",argv[0],argc-1,MAX_ITF); +static void usage(const char *name) +{ + fprintf(stderr,"usage: %s [ -c config_file ] [ -d ]\n",name); exit(1); - } - - nb_itf = argc-3; - - /* open all pipes and send listen */ - if ((in = open(argv[1],O_RDWR)) < 0) { /* actually read-only */ - perror(argv[1]); - return 1; - } - if ((rm = open(argv[2],O_RDWR)) < 0) { /* actually read-only */ - perror(argv[2]); - return 1; - } - - for(i=0;i + +#include "atm.h" +#include "atmd.h" +#include "route.h" + + +#define COMPONENT "ROUTE" + + +typedef struct _route { + struct sockaddr_atmsvc addr; + int mask; + SIGNALING_ENTITY *sig; + struct _route *next; +} ROUTE; + + +static ROUTE *routes = NULL; + + +void put_route(struct sockaddr_atmsvc *addr,int addr_mask, + SIGNALING_ENTITY *sig) +{ + ROUTE *route; + + for (route = routes; route; route = route->next) + if (route->mask == addr_mask && + (!addr_mask || atm_equal((struct sockaddr *) addr, + (struct sockaddr *) &route->addr,addr_mask, + AXE_PRVOPT | (addr_mask == INT_MAX ? 0 : AXE_WILDCARD)))) + diag(COMPONENT,DIAG_FATAL,"duplicate route"); + route = alloc_t(ROUTE); + if (addr) route->addr = *addr; + route->mask = addr_mask; + route->sig = sig; + route->next = routes; + routes = route; +} + + +SIGNALING_ENTITY *find_route(struct sockaddr_atmsvc *from, + struct sockaddr_atmsvc *to,struct atm_qos *qos) +{ + ROUTE *best,*route; + int best_len; + + best = NULL; + best_len = -1; + for (route = routes; route; route = route->next) + if (route->mask > best_len && (!route->mask || + atm_equal((struct sockaddr *) to,(struct sockaddr *) &route->addr, + route->mask, + AXE_PRVOPT | (route->mask == INT_MAX ? 0 : AXE_WILDCARD)))) { + if (route->mask == INT_MAX) return route->sig; + best_len = route->mask; + best = route; + } + return best->sig; +} diff -ur --new-file old/atm/switch/route.h new/atm/switch/route.h --- old/atm/switch/route.h Thu Jan 1 01:00:00 1970 +++ new/atm/switch/route.h Wed Apr 15 21:00:48 1998 @@ -0,0 +1,19 @@ +/* route.h - ATM switch routing database */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#ifndef ROUTE_H +#define ROUTE_H + +#include "atm.h" +#include "sig.h" + + +void put_route(struct sockaddr_atmsvc *addr,int addr_mask, + SIGNALING_ENTITY *sig); +SIGNALING_ENTITY *find_route(struct sockaddr_atmsvc *from, + struct sockaddr_atmsvc *to,struct atm_qos *qos); + + +#endif diff -ur --new-file old/atm/switch/sig.c new/atm/switch/sig.c --- old/atm/switch/sig.c Thu Jan 1 01:00:00 1970 +++ new/atm/switch/sig.c Thu Apr 16 10:22:10 1998 @@ -0,0 +1,76 @@ +/* sig.c - signaling entity handling */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include + +#include "atmd.h" + +#include "dispatch.h" +#include "proto.h" +#include "sig.h" + + +#define COMPONENT "SIG" + + +static int sig_check_listen(SIGNALING_ENTITY *sig,struct atmsvc_msg *msg) +{ + return msg->type == as_okay ? 0 : msg->reply; +} + + +static int sig_recv(SIGNALING_ENTITY *sig, + int (*handler)(SIGNALING_ENTITY *sig,struct atmsvc_msg *msg)) +{ + char buf[sizeof(struct atmsvc_msg)+1]; + int len; + + len = read(sig->s,buf,sizeof(buf)); + if (len == sizeof(struct atmsvc_msg)) + return handler(sig,(struct atmsvc_msg *) buf); + if (len < 0) + diag(COMPONENT,DIAG_ERROR,"read isp msg: %s",strerror(errno)); + else diag(COMPONENT,DIAG_ERROR,"bad isp msg: %d != %d",len, + sizeof(struct atmsvc_msg)); + return -1; +} + + +static void sig_data(int fd,void *sig) +{ + (void) sig_recv(sig,from_sigd); +} + + +SIGNALING_ENTITY *sig_vc(const char *path,int itf) +{ + SIGNALING_ENTITY *sig; + int error; + + sig = alloc_t(SIGNALING_ENTITY); + sig->s = un_attach(path); + if (sig->s < 0) + diag(COMPONENT,DIAG_FATAL,"un_attach %s: %s",path,strerror(errno)); + sig->itf = itf; + send_listen(sig); + error = sig_recv(sig,sig_check_listen); + if (!error) dsp_fd_add(sig->s,sig_data,sig); + else diag(COMPONENT,DIAG_FATAL,"listen failed: %s",strerror(error)); + return sig; +} + + +void sig_send(SIGNALING_ENTITY *sig,struct atmsvc_msg *msg) +{ + int len; + + len = write(sig->s,msg,sizeof(*msg)); + if (len == sizeof(*msg)) return; + if (len < 0) diag(COMPONENT,DIAG_ERROR,"write isp msg: %s",strerror(errno)); + else diag(COMPONENT,DIAG_ERROR,"bad isp msg write: %d != %d",len, + sizeof(*msg)); +} diff -ur --new-file old/atm/switch/sig.h new/atm/switch/sig.h --- old/atm/switch/sig.h Thu Jan 1 01:00:00 1970 +++ new/atm/switch/sig.h Wed Apr 15 20:50:09 1998 @@ -0,0 +1,24 @@ +/* sig.h - signaling entity handling */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#ifndef SIG_H +#define SIG_H + +#include + +#include "atm.h" + + +typedef struct _signaling_entity { + int s; /* socket */ + /*struct sockaddr_atmpvc pvc; signaling VC; not yet used */ + short itf; /* interface we manage */ +} SIGNALING_ENTITY; + + +SIGNALING_ENTITY *sig_vc(const char *path,int itf); +void sig_send(SIGNALING_ENTITY *sig,struct atmsvc_msg *msg); + +#endif diff -ur --new-file old/atm/test/Makefile new/atm/test/Makefile --- old/atm/test/Makefile Thu Mar 5 21:29:52 1998 +++ new/atm/test/Makefile Thu Apr 16 10:07:12 1998 @@ -11,8 +11,9 @@ ttcp.o: # dummy touch ttcp.o -isp: $(ISP_OBJS) ../lib/libatm.a - $(CC) $(LDFLAGS) -o isp $(ISP_OBJS) $(LDLIBS) -lfl +isp: $(ISP_OBJS) ../lib/libatm.a ../lib/libatmd.a + $(CC) $(LDFLAGS) -o isp $(ISP_OBJS) $(LDLIBS) -latmd \ + -lfl lex.yy.c: ispl.l y.tab.h $(LEX) ispl.l diff -ur --new-file old/atm/test/isp.c new/atm/test/isp.c --- old/atm/test/isp.c Thu Mar 5 22:31:27 1998 +++ new/atm/test/isp.c Thu Apr 16 11:07:53 1998 @@ -12,6 +12,7 @@ #include #include +#include #include #include "isp.h" @@ -20,16 +21,17 @@ extern int yyparse(void); int quiet = 0; +int verbose = 0; VAR *variables = NULL; -static int input,output; +static int sock; void send_msg(const struct atmsvc_msg *msg) { int wrote; - wrote = write(output,msg,sizeof(*msg)); + wrote = write(sock,msg,sizeof(*msg)); if (wrote == sizeof(*msg)) return; if (wrote < 0) perror("write"); else fprintf(stderr,"bad write: %d != %d\n",wrote,sizeof(*msg)); @@ -41,7 +43,7 @@ { int got; - got = read(input,msg,sizeof(*msg)); + got = read(sock,msg,sizeof(*msg)); if (got == sizeof(*msg)) return; if (got < 0) perror("read"); else fprintf(stderr,"bad read: %d != %d\n",got,sizeof(*msg)); @@ -147,16 +149,16 @@ } -void dump_msg(const struct atmsvc_msg *msg) +void dump_msg(const char *prefix,const struct atmsvc_msg *msg) { int fields; if (msg->type >= MSG_TYPES) { - printf("Unknown message type %d\n",msg->type); + printf("%s: unknown message type %d\n",prefix,msg->type); return; } fields = types[msg->type].fields; - printf("Type: %s\n",types[msg->type].name); + printf("%s: %s\n",prefix,types[msg->type].name); FIELD(F_VCC, " vcc = "); FIELD(F_LISTEN_VCC, " listen_vcc = "); FIELD(F_REPLY, " reply = "); @@ -290,12 +292,12 @@ if (a.u.num == b.u.num) return; break; case vt_svc: - if (atm_equal(&a.u.svc,&b.u.svc,0,0)) return; + if (atm_equal((struct sockaddr *) &a.u.svc, + (struct sockaddr *) &b.u.svc,0,0)) return; break; case vt_pvc: - if (a.u.pvc.sap_addr.itf == b.u.pvc.sap_addr.itf && - a.u.pvc.sap_addr.vpi == b.u.pvc.sap_addr.vpi && - a.u.pvc.sap_addr.vci == b.u.pvc.sap_addr.vci) return; + if (atm_equal((struct sockaddr *) &a.u.pvc, + (struct sockaddr *) &b.u.pvc,0,0)) return; break; case vt_qos: if (qos_equal(&a.u.qos,&b.u.qos)) return; @@ -422,21 +424,23 @@ const char *name; name = *argv; - if (argc > 3 && !strcmp(argv[1],"-q")) { + if (argc > 2 && !strcmp(argv[1],"-q")) { quiet = 1; argc--; argv++; } - if (argc != 3) { - fprintf(stderr,"usage: %s [-q] input output\n",name); - return 1; + if (argc > 2 && !strcmp(argv[1],"-v")) { + verbose = 1; + argc--; + argv++; } - if ((input = open(argv[1],O_RDWR)) < 0) { /* actually read-only */ - perror(argv[1]); + if (argc != 2 || (quiet && verbose)) { + fprintf(stderr,"usage: %s [-q | -v] socket\n",name); return 1; } - if ((output = open(argv[2],O_RDWR)) < 0) { /* actually write-only */ - perror(argv[2]); + sock = un_attach(argv[1]); + if (sock < 0) { + perror(argv[1]); return 1; } return yyparse(); diff -ur --new-file old/atm/test/isp.h new/atm/test/isp.h --- old/atm/test/isp.h Thu Mar 5 20:41:58 1998 +++ new/atm/test/isp.h Thu Apr 16 11:08:04 1998 @@ -44,7 +44,7 @@ } VAR; -extern int quiet; +extern int quiet,verbose; extern VAR *variables; @@ -63,6 +63,6 @@ void send_msg(const struct atmsvc_msg *msg); void recv_msg(struct atmsvc_msg *msg); -void dump_msg(const struct atmsvc_msg *msg); +void dump_msg(const char *prefix,const struct atmsvc_msg *msg); #endif diff -ur --new-file old/atm/test/ispl.y new/atm/test/ispl.y --- old/atm/test/ispl.y Thu Mar 5 22:03:15 1998 +++ new/atm/test/ispl.y Thu Apr 16 11:06:29 1998 @@ -54,11 +54,12 @@ values { send_msg(&msg); + if (verbose) dump_msg("SENT",&msg); } | TOK_RECEIVE { recv_msg(&msg); - if (!quiet) dump_msg(&msg); + if (!quiet) dump_msg("RECV",&msg); } opt_recv | TOK_WAIT number .