diff -ur --new-file old/atm/BUGS new/atm/BUGS --- old/atm/BUGS Fri Aug 21 00:15:16 1998 +++ new/atm/BUGS Wed Sep 23 19:29:03 1998 @@ -1,8 +1,8 @@ -Known bugs and restrictions in version 0.43 +Known bugs and restrictions in version 0.44 =========================================== - 2.1.117 kernel may not compile properly with sound enabled - - libresolve conflicts with libc on some systems + - ANS: libresolve conflicts with libc on some systems - ENI driver loses synchronization on some systems, leading to panics or hung VCs (these may be two distinct problems) - few if any drivers build properly as modules diff -ur --new-file old/atm/CHANGES new/atm/CHANGES --- old/atm/CHANGES Fri Aug 21 00:54:10 1998 +++ new/atm/CHANGES Thu Sep 24 19:26:47 1998 @@ -1,3 +1,48 @@ +Version 0.43 to 0.44 (24-SEP-1998) +==================== + +Bug fixes +--------- + + - CONNECT messages no longer contain the AAL type IE if EP ref is present and + non-zero (reported by Heikki Vatiainen) + - SSCOP: added mode for partial compatibility with Q.SAAL1 (to get rid of + warnings reported by Heikki Vatiainen and of interoperability problems with + Virata switches reported by Damian Gilmurray) + - ilmid now returns a valid response for atmfMyIpNmAddress (by Uwe Dannowski) + - configuration on-line help for CLIP didn't work because tag was different + from configuration variable + - atmsigd crashed when adding multiple local addresses on an interface + (reported by Heiko Krupp) + - atmaddr.8 said "ATMARP" in the header (reported by Hans Einsiedler) + - net/atm/misc.c didn't include linux/config.h and linux/module.h, causing + symbols to be missing when rebuilding the kernel after enabling modules + (reported by Thomas Parvais) + +New features +------------ + + - new maintenance utility tcpswc to control sw_tcp "switches" (description at + the end of switch/tcp/README) + - added support for setting the CLP bit (untested; see doc/README.CLP) + - added support for policing to the ATM qdisc (untested; see extra/tc/README) + - ilmid: added support for atmfAtmLayerUniVersion (by Uwe Dannowski) + +Other changes +------------- + + - updated the NICStAR driver to version 008b (by Rui Prior) + - new switch fabric function fab_option to pass configuration options + - atm2text now also supports unspecified and wildcard components in PVC + addresses + - added configuration option CONFIG_ATM_CLIP_NO_ICMP to discard packets for + which no ATMARP entry exists silently instead of sending an ICMP (this is an + ugly hack-around for the revalidation problem reported by Gerald Hanusch) + - various minor documentation updates + - atmarpd now sends InARP requests when active VC setup completes in order to + tell the peer our IP address(es) + + Version 0.42 to 0.43 (21-AUG-1998) ==================== diff -ur --new-file old/atm/README new/atm/README --- old/atm/README Thu Aug 20 16:26:58 1998 +++ new/atm/README Thu Sep 24 15:49:22 1998 @@ -1,4 +1,4 @@ -ATM on Linux, release 0.43 (alpha) by Werner Almesberger, EPFL ICA +ATM on Linux, release 0.44 (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 Wed Aug 12 20:35:04 1998 +++ new/atm/Rules.make Thu Sep 24 17:58:59 1998 @@ -35,6 +35,8 @@ # # STANDARDS += -DTHOMFLEX # +# Note: after changing STANDARDS, you need to rebuild at least the directories +# ilmid/, qgen/, sigd/, and sigd.new/ ifeq ($(TOPDIR),) TOPDIR=.. diff -ur --new-file old/atm/USAGE new/atm/USAGE --- old/atm/USAGE Fri Aug 21 01:02:14 1998 +++ new/atm/USAGE Thu Sep 24 18:47:31 1998 @@ -1,4 +1,4 @@ -Usage instructions - ATM on Linux, release 0.43 +Usage instructions - ATM on Linux, release 0.44 ------------------------------------------------- For updates of ATM on Linux, please check the Web page at @@ -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.43.tar.gz + ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.44.tar.gz - the Linux kernel, version 2.1.117, e.g. from ftp://ftp.kernel.org/pub/linux/kernel/v2.1/linux-2.1.117.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.43.tar.gz +tar xfz atm-0.44.tar.gz and the kernel source: @@ -85,19 +85,24 @@ Asynchronous Transfer Mode (ATM, EXPERIMENTAL) (CONFIG_ATM) Classical IP over ATM (CONFIG_ATM_CLIP) + Do NOT send ICMP if no neighbour (CONFIG_ATM_CLIP_NO_ICMP) LAN Emulation (LANE) support (CONFIG_ATM_LANE) + Multi-Protocol Over ATM (MPOA) support (CONFIG_ATM_MPOA) ATM over TCP (CONFIG_ATM_TCP) Efficient Networks ENI155P (CONFIG_ATM_ENI) Enable extended debugging (CONFIG_ATM_ENI_DEBUG) ZeitNet ZN1221/ZN1225 (CONFIG_ATM_ZATM) Enable extended debugging (CONFIG_ATM_ZATM_DEBUG) Enable usec resolution timestamps (CONFIG_ATM_ZATM_EXACT_TS) - IDT 77201 (NICStAR) (CONFIG_ATM_NICSTAR) Note that the file drivers/atm/nicstar.h contains a few configurable settings for the IDT 77201 driver. +Some drivers can also be used with certain compatible cards. The latest +information about compatibile cards can be found at +http://lrcwww.epfl.ch/linux-atm/info.html + Then build your kernel and reboot. @@ -153,8 +158,8 @@ --------- Now, as the final step, configure and build the ATM tools. Configuration is -only necessary if your switch uses UNI 3.1 or if it has certain bugs. The -configuration options are at the beginning of atm/Rules.make. +only necessary if your switch uses UNI 3.1 or 4.0, or if it has certain +bugs. The configuration options are at the beginning of atm/Rules.make. Then, build the ATM tools with: @@ -503,8 +508,8 @@ problems, it frequently terminates. This will (obviously) change in the future. -atmsigd also looks for a configuration file atmsigd.conf in the current -directory. +atmsigd also looks for a configuration file at the location specified with +the -c option. The default location is /etc/atmsigd.conf. ILMI demon @@ -531,9 +536,9 @@ -x disable inclusion of variable bindings in the ColdstartTrap. Some switches (e.g. the LS100) only work if this option is set. -If no interface number is specified, ilmid serves interface 0. atmsigd -should already be running when ilmid is started, Use the -b option to -make sure they're properly synchronized (see section "CLIP"). +If no interface number is specified, ilmid serves interface 0. You can +check whether address registration was successful with the atmaddr command +(see below). The agent supports only the address registration procedures specified in section 5.8 of the ATM Forum's UNI 3.1 specification. These procedures diff -ur --new-file old/atm/VERSION new/atm/VERSION --- old/atm/VERSION Fri Aug 21 00:53:48 1998 +++ new/atm/VERSION Thu Sep 24 18:48:35 1998 @@ -1 +1 @@ -0.43 +0.44 diff -ur --new-file old/atm/arpd/arp.c new/atm/arpd/arp.c --- old/atm/arpd/arp.c Tue Aug 11 16:09:36 1998 +++ new/atm/arpd/arp.c Wed Sep 23 20:16:11 1998 @@ -1007,8 +1007,9 @@ START_TIMER(entry,REPLY); arp_request(entry->itf,entry->ip); } - if (vcc->entry->state != as_valid) inarp_request(vcc->entry); - else if (set_ip(vcc->fd,vcc->entry->ip) < 0) + inarp_request(vcc->entry); + if (vcc->entry->state == as_valid) + if (set_ip(vcc->fd,vcc->entry->ip) < 0) diag(COMPONENT,DIAG_ERROR,"can't set IP (%s)",strerror(errno)); } diff -ur --new-file old/atm/atm.patch new/atm/atm.patch --- old/atm/atm.patch Fri Aug 21 01:08:48 1998 +++ new/atm/atm.patch Thu Sep 24 18:47:12 1998 @@ -20,8 +20,8 @@ if [ -f FS_MODULES ]; then inst_mod FS_MODULES fs; fi; \ if [ -f NLS_MODULES ]; then inst_mod NLS_MODULES fs; fi; \ --- ref/Documentation/Configure.help Wed Aug 19 23:37:58 1998 -+++ work/Documentation/Configure.help Fri Aug 21 00:52:27 1998 -@@ -3166,6 +3166,79 @@ ++++ work/Documentation/Configure.help Thu Sep 24 17:06:37 1998 +@@ -3166,6 +3166,93 @@ This is a backward compatibility option, choose Y for now. This option will be removed soon. @@ -46,11 +46,19 @@ + if you suspect problems with single-copy. + +Classical IP over ATM -+CONFIG_ATM_ATMARP ++CONFIG_ATM_CLIP + Classical IP over ATM for PVCs and SVCs, supporting InARP and ATMARP. + Typically you will either use LAN Emulation (LANE) or Classical IP to + communicate with other IP hosts on your ATM network. + ++Do NOT send ICMP if no neighbour ++CONFIG_ATM_CLIP_NO_ICMP ++ Normally, an ICMP host unreachable message is sent if a neighbour cannot ++ be reached because there is no VC to it in the kernel's ATMARP table. ++ This may cause problems when ATMARP table entries are briefly removed ++ during revalidation. If this configuration option is set to "yes", ++ packets to such neighbours are silently discarded instead. ++ +Application REQUested IP over ATM +CONFIG_AREQUIPA + Arequipa is a mechanism to create ATM connections under application @@ -98,6 +106,12 @@ + system time. Enabling this feature will add some general overhead for + timer synchronization and also per-packet overhead for time conversion. + ++IDT 77201 (NICStAR) ++CONFIG_ATM_NICSTAR ++ The NICStAR chipset family is used in a large number of ATM NICs for ++ 25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE ++ series. ++ SCSI support? CONFIG_SCSI If you want to use a SCSI hard disk, SCSI tape drive, SCSI CDROM or @@ -635,8 +649,8 @@ +#endif + --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/eni.c Fri Aug 21 00:52:28 1998 -@@ -0,0 +1,2143 @@ ++++ work/drivers/atm/eni.c Wed Sep 16 15:49:46 1998 +@@ -0,0 +1,2144 @@ +/* drivers/atm/eni.c - Efficient Networks ENI155P device driver */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -1688,7 +1702,8 @@ + (size/(ATM_CELL_PAYLOAD/4)); +/*printk("dsc = 0x%08lx\n",tx->send[tx->tx_pos]);*/ + tx->send[(tx->tx_pos+1) & (tx->words-1)] = (vcc->vci << -+ MID_SEG_VCI_SHIFT) | (aal5 ? 0 : (skb->data[3] & 0xf)); ++ MID_SEG_VCI_SHIFT) | (aal5 ? 0 : (skb->data[3] & 0xf)) | ++ (skb->atm.atm_options & ATM_ATMOPT_CLP ? MID_SEG_CLP : 0); + DPRINTK("size: %ld, len:%d\n",size,skb->len); + if (aal5) + tx->send[(tx->tx_pos+size-AAL5_TRAILER) & (tx->words-1)] = @@ -2781,7 +2796,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/eni.h Fri Aug 21 01:09:03 1998 ++++ work/drivers/atm/eni.h Thu Sep 17 17:08:54 1998 @@ -0,0 +1,114 @@ +/* drivers/atm/eni.h - Efficient Networks ENI155P device driver declarations */ + @@ -3166,8 +3181,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/nicstar.h Fri Aug 21 02:32:42 1998 -@@ -0,0 +1,748 @@ ++++ work/drivers/atm/nicstar.h Wed Sep 9 21:02:13 1998 +@@ -0,0 +1,753 @@ +/****************************************************************************** + * + * nicstar.h @@ -3254,7 +3269,9 @@ + +#define SCQFULL_TIMEOUT (5 * HZ) + -+#define PCR_TOLERANCE 1.0001 ++#define NS_POLL_PERIOD (HZ) ++ ++#define PCR_TOLERANCE (1.0001) + + + @@ -3902,6 +3919,9 @@ + u32 lg_addr; + struct sk_buff *rcbuf; /* Current raw cell buffer */ + u32 rawch; /* Raw cell queue head */ ++ unsigned intcnt; /* Interrupt counter */ ++ volatile int in_handler: 1; ++ volatile int in_poll: 1; +} ns_dev; + + @@ -3917,8 +3937,8 @@ + +#endif /* _LINUX_NICSTAR_H_ */ --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/nicstar.c Fri Aug 21 02:32:42 1998 -@@ -0,0 +1,2795 @@ ++++ work/drivers/atm/nicstar.c Wed Sep 23 20:17:51 1998 +@@ -0,0 +1,2883 @@ +/****************************************************************************** + * + * nicstar.c @@ -3953,6 +3973,7 @@ +#include +#include +#include ++#include +#include +#include +#include "nicstar.h" @@ -4058,6 +4079,7 @@ +static int ns_proc_read(struct atm_dev *dev, loff_t *pos, char *page); +static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg); +static void which_list(ns_dev *card, struct sk_buff *skb); ++static void ns_poll(unsigned long arg); + + +/* Global variables ***********************************************************/ @@ -4082,6 +4104,7 @@ + NULL, /* free_rx_skb */ + ns_proc_read /* proc_read */ +}; ++static struct timer_list ns_timer; + + +/* Functions*******************************************************************/ @@ -4135,6 +4158,12 @@ +#endif /* PHY_LOOPBACK */ + XPRINTK("nicstar: init_module() returned.\n"); + ++ ns_timer.next = NULL; ++ ns_timer.prev = NULL; ++ ns_timer.expires = jiffies + NS_POLL_PERIOD; ++ ns_timer.data = 0UL; ++ ns_timer.function = ns_poll; ++ add_timer(&ns_timer); + return 0; +} + @@ -4155,6 +4184,8 @@ + if (MOD_IN_USE) + printk("nicstar: module in use, remove delayed.\n"); + ++ del_timer(&ns_timer); ++ + for (i = 0; i < NS_MAX_CARDS; i++) + { + if (cards[i] == NULL) @@ -4705,7 +4736,10 @@ + card->hbpool.count++; + } + -+ ++ card->in_handler = 0; ++ card->in_poll = 0; ++ card->intcnt = 0; ++ + /* Configure NICStAR */ + if (card->rct_size == 4096) + ns_cfg_rctsize = NS_CFG_RCTSIZE_4096_ENTRIES; @@ -5023,8 +5057,23 @@ + ns_dev *card; + + card = (ns_dev *) dev_id; ++ card->intcnt++; + + PRINTK("nicstar%d: NICStAR generated an interrupt\n", card->index); ++ ++ if (card->in_handler) ++ { ++ printk("nicstar%d: Re-entering ns_irq_handler()???\n", card->index); ++ return; ++ } ++ card->in_handler = 1; ++ if (card->in_poll) ++ { ++ card->in_handler = 0; ++ printk("nicstar%d: Called irq handler while in ns_poll()!?\n", ++ card->index); ++ return; ++ } + + stat_r = readl(card->membase + STAT); + @@ -5033,9 +5082,7 @@ + { + TXPRINTK("nicstar%d: TSI interrupt\n", card->index); + process_tsq(card); -+ /* If there are no entries to process, clear the interrupt */ -+ if (readl(card->membase + TSQT) == (u32) virt_to_bus(card->tsq.next)) -+ writel(NS_STAT_TSIF, card->membase + STAT); ++ writel(NS_STAT_TSIF, card->membase + STAT); + } + + /* Incomplete CS-PDU has been transmitted */ @@ -5095,9 +5142,7 @@ + { + RXPRINTK("nicstar%d: End of CS-PDU received.\n", card->index); + process_rsq(card); -+ /* If there are no entries to process, clear the interrupt */ -+ if (readl(card->membase + RSQT) == (u32) virt_to_bus(card->rsq.next)) -+ writel(NS_STAT_EOPDU, card->membase + STAT); ++ writel(NS_STAT_EOPDU, card->membase + STAT); + } + + /* Raw cell received */ @@ -5190,7 +5235,8 @@ + process_rsq(card); + } + -+ XPRINTK("nicstar%d: end of interrupt service\n", card->index); ++ card->in_handler = 0; ++ PRINTK("nicstar%d: end of interrupt service\n", card->index); +} + + @@ -5209,6 +5255,7 @@ + warning. How I wish compilers were clever enough to + tell which variables can truly be used + uninitialized... */ ++ int inuse; /* tx or rx vc already in use by another vcc */ + + card = (ns_dev *) vcc->dev->dev_data; + PRINTK("nicstar%d: opening vpi.vci %d.%d \n", card->index, (int) vpi, vci); @@ -5227,103 +5274,113 @@ + vcc->vpi = vpi; + vcc->vci = vci; + vcc->dev_data = vc; ++ ++ inuse = 0; ++ if (vcc->qos.txtp.traffic_class != ATM_NONE && vc->tx) ++ inuse = 1; ++ if (vcc->qos.rxtp.traffic_class != ATM_NONE && vc->rx) ++ inuse += 2; ++ if (inuse) ++ { ++ printk("nicstar%d: %s vci already in use.\n", card->index, ++ inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx"); ++ return -EINVAL; ++ } ++ + vcc->flags |= ATM_VF_ADDR; + -+ /* Check requested cell rate and availability of SCD if CBR */ -+ if (vcc->qos.txtp.traffic_class == ATM_CBR) ++ /* NOTE: You are not allowed to modify an open connection's QOS. To change ++ that, remove the ATM_VF_PARTIAL flag checking. There may be other changes ++ needed to do that. */ ++ if (!(vcc->flags & ATM_VF_PARTIAL)) + { -+ if (vcc->qos.txtp.max_pcr == 0 && vcc->qos.txtp.pcr == 0 && -+ vcc->qos.txtp.min_pcr == 0) ++ scq_info *scq; ++ ++ vcc->flags |= ATM_VF_PARTIAL; ++ if (vcc->qos.txtp.traffic_class == ATM_CBR) + { -+ PRINTK("nicstar%d: trying to open a CBR vc with cell rate = 0 \n", -+ card->index); -+ vcc->flags &= ~(ATM_VF_ADDR); -+ return -EINVAL; -+ } ++ /* Check requested cell rate and availability of SCD */ ++ if (vcc->qos.txtp.max_pcr == 0 && vcc->qos.txtp.pcr == 0 && ++ vcc->qos.txtp.min_pcr == 0) ++ { ++ PRINTK("nicstar%d: trying to open a CBR vc with cell rate = 0 \n", ++ card->index); ++ vcc->flags &= ~(ATM_VF_ADDR | ATM_VF_PARTIAL); ++ return -EINVAL; ++ } + -+ tcr = atm_pcr_goal(&(vcc->qos.txtp)); -+ tcra = tcr >= 0 ? tcr : -tcr; ++ tcr = atm_pcr_goal(&(vcc->qos.txtp)); ++ tcra = tcr >= 0 ? tcr : -tcr; + -+ PRINTK("nicstar%d: target cell rate = %d.\n", card->index, -+ vcc->qos.txtp.max_pcr); ++ PRINTK("nicstar%d: target cell rate = %d.\n", card->index, ++ vcc->qos.txtp.max_pcr); + -+ tmpd = ((double) tcra) * ((double) NS_TST_NUM_ENTRIES) / -+ ((double) card->max_pcr); ++ tmpd = ((double) tcra) * ((double) NS_TST_NUM_ENTRIES) / ++ ((double) card->max_pcr); + -+ n = (int) tmpd; -+ if (tcr > 0) -+ { -+ if (tmpd > (double) n) n++; -+ } -+ else if (tcr < 0) -+ { -+ if (tmpd < (double) n) n--; -+ } -+ else /* tcr == 0 */ -+ { -+ if ((n = (card->tst_free_entries - NS_TST_RESERVED)) <= 0) -+ { -+ PRINTK("nicstar%d: no CBR bandwidth free.\n", card->index); -+ vcc->flags &= ~(ATM_VF_ADDR); -+ return -EINVAL; -+ } -+ } ++ n = (int) tmpd; ++ if (tcr > 0) ++ { ++ if (tmpd > (double) n) n++; ++ } ++ else if (tcr < 0) ++ { ++ if (tmpd < (double) n) n--; ++ } ++ else /* tcr == 0 */ ++ { ++ if ((n = (card->tst_free_entries - NS_TST_RESERVED)) <= 0) ++ { ++ PRINTK("nicstar%d: no CBR bandwidth free.\n", card->index); ++ vcc->flags &= ~(ATM_VF_ADDR | ATM_VF_PARTIAL); ++ return -EINVAL; ++ } ++ } + -+ if (n == 0) -+ { -+ printk("nicstar%d: selected bandwidth < granularity.\n", card->index); -+ vcc->flags &= ~(ATM_VF_ADDR); ++ if (n == 0) ++ { ++ printk("nicstar%d: selected bandwidth < granularity.\n", card->index); ++ vcc->flags &= ~(ATM_VF_ADDR | ATM_VF_PARTIAL); + return -EINVAL; -+ } ++ } + -+ if (vcc->qos.txtp.max_pcr > 0) -+ { -+ tmpd = (double) n * (double) card->max_pcr / -+ (double) NS_TST_NUM_ENTRIES; -+ if (tmpd > PCR_TOLERANCE * (double) vcc->qos.txtp.max_pcr) ++ if (vcc->qos.txtp.max_pcr > 0) + { -+ PRINTK("nicstar%d: target cell rate exceeded requested max_pcr.\n", -+ card->index); ++ tmpd = (double) n * (double) card->max_pcr / ++ (double) NS_TST_NUM_ENTRIES; ++ if (tmpd > PCR_TOLERANCE * (double) vcc->qos.txtp.max_pcr) ++ { ++ PRINTK("nicstar%d: target cell rate exceeded requested max_pcr.\n", ++ card->index); ++ } + } -+ } + -+ if (n > (card->tst_free_entries - NS_TST_RESERVED)) -+ { -+ PRINTK("nicstar%d: not enough free CBR bandwidth.\n", card->index); -+ vcc->flags &= ~(ATM_VF_ADDR); -+ return -EINVAL; -+ } -+ else -+ card->tst_free_entries -= n; ++ if (n > (card->tst_free_entries - NS_TST_RESERVED)) ++ { ++ PRINTK("nicstar%d: not enough free CBR bandwidth.\n", card->index); ++ vcc->flags &= ~(ATM_VF_ADDR | ATM_VF_PARTIAL); ++ return -EINVAL; ++ } ++ else ++ card->tst_free_entries -= n; + -+ XPRINTK("nicstar%d: writing %d tst entries.\n", card->index, n); -+ for (frscdi = 0; frscdi < NS_FRSCD_NUM; frscdi++) -+ { -+ if (card->scd2vc[frscdi] == NULL) -+ { -+ card->scd2vc[frscdi] = vc; -+ break; -+ } -+ } -+ if (frscdi == NS_FRSCD_NUM) -+ { -+ PRINTK("nicstar%d: no SCD available for CBR channel.\n", card->index); -+ card->tst_free_entries += n; -+ vcc->flags &= ~(ATM_VF_ADDR); -+ return -EBUSY; -+ } -+ } ++ XPRINTK("nicstar%d: writing %d tst entries.\n", card->index, n); ++ for (frscdi = 0; frscdi < NS_FRSCD_NUM; frscdi++) ++ { ++ if (card->scd2vc[frscdi] == NULL) ++ { ++ card->scd2vc[frscdi] = vc; ++ break; ++ } ++ } ++ if (frscdi == NS_FRSCD_NUM) ++ { ++ PRINTK("nicstar%d: no SCD available for CBR channel.\n", card->index); ++ card->tst_free_entries += n; ++ vcc->flags &= ~(ATM_VF_ADDR | ATM_VF_PARTIAL); ++ return -EBUSY; ++ } + -+ /* NOTE: You are not allowed to modify an open connection's QOS. To change -+ that, remove the ATM_VF_PARTIAL flag checking. There may be other changes -+ needed to do that. */ -+ if (!(vcc->flags & ATM_VF_PARTIAL)) -+ { -+ scq_info *scq; -+ -+ vcc->flags |= ATM_VF_PARTIAL; -+ if (vcc->qos.txtp.traffic_class == ATM_CBR) -+ { + vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE; + + scq = get_scq(CBR_SCQSIZE, vc->cbr_scd); @@ -5350,13 +5407,13 @@ + vc->scq = card->scq0; + } + -+ if (vcc->qos.txtp.traffic_class != ATM_NONE && !vc->tx) ++ if (vcc->qos.txtp.traffic_class != ATM_NONE) + { + vc->tx = 1; + vc->tx_vcc = vcc; + vc->tbd_count = 0; + } -+ if (vcc->qos.rxtp.traffic_class != ATM_NONE && !vc->rx) ++ if (vcc->qos.rxtp.traffic_class != ATM_NONE) + { + u32 status; + @@ -5388,7 +5445,6 @@ +{ + vc_map *vc; + ns_dev *card; -+ u32 u32d[4]; + u32 data; + int i; + @@ -5467,6 +5523,7 @@ + ns_scqe tsr; + u32 scdi, scqi; + u32 data; ++ int index; + + tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE); + scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE; @@ -5475,6 +5532,8 @@ + tsr.word_3 = 0x00000000; + tsr.word_4 = 0x00000000; + *scq->next = tsr; ++ index = (int) scqi; ++ scq->skb[index] = NULL; + if (scq->next == scq->last) + scq->next = scq->base; + else @@ -5486,11 +5545,6 @@ + restore_flags(flags); + } + -+ /* Re-initialize SCD to stop transmission */ -+ u32d[1] = ns_read_sram(card, vc->cbr_scd) & NS_SCD_BASE_MASK_FIX; -+ u32d[2] = 0x00000000; -+ ns_write_sram(card, vc->cbr_scd, u32d, 2); -+ + /* Free all TST entries */ + data = NS_TST_OPCODE_VARIABLE; + for (i = 0; i < NS_TST_NUM_ENTRIES; i++) @@ -5657,7 +5711,7 @@ + flags |= NS_TBD_EOPDU; + scqe.word_4 = *((u32 *) skb->data) & ~NS_TBD_VC_MASK; + /* Force the VPI/VCI to be the same as in VCC struct */ -+ scqe.word_4 |= (((u32) vcc->vpi) << NS_TBD_VPI_SHIFT & ++ scqe.word_4 |= (((u32) vcc->vpi) << NS_TBD_VPI_SHIFT | + ((u32) vcc->vci) << NS_TBD_VCI_SHIFT) & NS_TBD_VC_MASK; + } + @@ -5731,16 +5785,6 @@ + + if (vc->tbd_count >= MAX_TBD_PER_VC || scq->tbd_count >= MAX_TBD_PER_SCQ) + { -+ tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE); -+ if (scq_is_vbr) -+ scdi = NS_TSR_SCDISVBR; -+ else -+ scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE; -+ scqi = scq->next - scq->base; -+ tsr.word_2 = ns_tsr_mkword_2(scdi, scqi); -+ tsr.word_3 = 0x00000000; -+ tsr.word_4 = 0x00000000; -+ + if (scq->tail == scq->next) + { + save_flags(flags); cli(); @@ -5752,8 +5796,18 @@ + + if (!scq->full) + { ++ tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE); ++ if (scq_is_vbr) ++ scdi = NS_TSR_SCDISVBR; ++ else ++ scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE; ++ scqi = scq->next - scq->base; ++ tsr.word_2 = ns_tsr_mkword_2(scdi, scqi); ++ tsr.word_3 = 0x00000000; ++ tsr.word_4 = 0x00000000; ++ + *scq->next = tsr; -+ index = (int) (scq->next - scq->base); ++ index = (int) scqi; + scq->skb[index] = NULL; + XPRINTK("nicstar%d: TSR written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%x.\n", + card->index, tsr.word_1, tsr.word_2, tsr.word_3, tsr.word_4, @@ -5798,6 +5852,7 @@ + { + printk("nicstar%d: could not find VC from SCD index.\n", + card->index); ++ ns_tsi_init(card->tsq.next); + return; + } + scq = card->scd2vc[scdi]->scq; @@ -5944,11 +5999,11 @@ + break; + } + /* Rebuild the header */ -+ skb_push(sb, NS_AAL0_HEADER); + *((u32 *) sb->data) = rsqe->word_1 << 4 | + (ns_rsqe_clp(rsqe) ? 0x00000001 : 0x00000000); + if (i == 1 && ns_rsqe_eopdu(rsqe)) + *((u32 *) sb->data) |= 0x00000002; ++ skb_put(sb, NS_AAL0_HEADER); + memcpy(sb->tail, cell, ATM_CELL_PAYLOAD); + skb_put(sb, ATM_CELL_PAYLOAD); + sb->atm.vcc = vcc; @@ -6464,6 +6519,13 @@ + if (!left--) + return sprintf(page, "Iovec %5d %5d %5d %5d \n", card->iovpool.count, + card->iovnr.min, card->iovnr.init, card->iovnr.max); ++ if (!left--) ++ { ++ int retval; ++ retval = sprintf(page, "Interrupt counter: %u \n", card->intcnt); ++ card->intcnt = 0; ++ return retval; ++ } + /* Dump 25.6 Mbps PHY registers */ + if (card->max_pcr == IDT_25_PCR && !left--) + { @@ -6714,6 +6776,52 @@ + skb->list == &card->hbpool.queue ? "huge" : + skb->list == &card->iovpool.queue ? "iovec" : "unknown"); +} ++ ++ ++ ++static void ns_poll(unsigned long arg) ++{ ++ int i; ++ ns_dev *card; ++ unsigned long flags; ++ u32 stat_r, stat_w; ++ ++ PRINTK("nicstar: Entering ns_poll().\n"); ++ for (i = 0; i < num_cards; i++) ++ { ++ card = cards[i]; ++ save_flags(flags); cli(); ++ if (card->in_poll) ++ { ++ printk("nicstar: Re-entering ns_poll()???\n"); ++ continue; ++ } ++ card->in_poll = 1; ++ if (card->in_handler) ++ { ++ card->in_poll = 0; ++ printk("nicstar%d: ns_poll called while in interrupt handler!?\n", ++ card->index); ++ continue; ++ } ++ ++ stat_w = 0; ++ stat_r = readl(card->membase + STAT); ++ if (stat_r & NS_STAT_TSIF) ++ stat_w |= NS_STAT_TSIF; ++ if (stat_r & NS_STAT_EOPDU) ++ stat_w |= NS_STAT_EOPDU; ++ ++ process_tsq(card); ++ process_rsq(card); ++ ++ writel(card->membase + STAT, stat_w); ++ card->in_poll = 0; ++ restore_flags(flags); ++ } ++ mod_timer(&ns_timer, jiffies + NS_POLL_PERIOD); ++ PRINTK("nicstar: Leaving ns_poll().\n"); ++} --- /dev/null Tue Jan 1 05:00:00 1980 +++ work/drivers/atm/nicstarmac.h Fri Aug 21 02:32:42 1998 @@ -0,0 +1,14 @@ @@ -7374,7 +7482,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/suni.h Fri Aug 21 01:09:01 1998 ++++ work/drivers/atm/suni.h Thu Sep 17 17:08:52 1998 @@ -0,0 +1,210 @@ +/* drivers/atm/suni.h - PMC SUNI (PHY) declarations */ + @@ -8241,8 +8349,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/zatm.c Fri Aug 21 00:52:28 1998 -@@ -0,0 +1,1870 @@ ++++ work/drivers/atm/zatm.c Wed Sep 16 15:50:12 1998 +@@ -0,0 +1,1875 @@ +/* drivers/atm/zatm.c - ZeitNet ZN122x device driver */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -9084,7 +9192,8 @@ + mb(); + dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP | uPD98401_TXPD_SM + | (skb->atm.vcc->qos.aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : -+ 0); ++ 0 | (skb->atm.atm_options & ATM_ATMOPT_CLP ? ++ uPD98401_CLPM_1 : uPD98401_CLPM_0)); + EVENT("dsc (0x%lx)\n",(unsigned long) dsc,0); + } + else { @@ -9104,7 +9213,9 @@ + /* @@@ should check alignment */ + put = dsc+8; + dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP | -+ (skb->atm.vcc->aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0); ++ (skb->atm.vcc->aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 | ++ (skb->atm.atm_options & ATM_ATMOPT_CLP ? uPD98401_CLPM_1 : ++ uPD98401_CLPM_0)); + dsc[1] = 0; + dsc[2] = skb->atm.iovcnt*uPD98401_TXBD_SIZE; + dsc[3] = virt_to_bus(put); @@ -9142,9 +9253,11 @@ + "txing\n",vcc->dev->number); + return; + } ++#if 0 /* @@@ would fail on CLP */ +if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD_V | uPD98401_TXPD_DP | + uPD98401_TXPD_SM | uPD98401_TXPD_AAL5)) printk("@#*$!!!! (%08x)\n", + *ZATM_PRV_DSC(skb)); ++#endif + *ZATM_PRV_DSC(skb) = 0; /* mark as invalid */ + zatm_vcc->txing--; + if (vcc->pop) vcc->pop(vcc,skb); @@ -10114,7 +10227,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/zatm.h Fri Aug 21 01:09:07 1998 ++++ work/drivers/atm/zatm.h Thu Sep 17 17:08:58 1998 @@ -0,0 +1,136 @@ +/* drivers/atm/zatm.h - ZeitNet ZN122x device driver declarations */ + @@ -10310,7 +10423,7 @@ #ifdef CONFIG_VT console_map_init(); --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/arequipa.h Fri Aug 21 01:14:05 1998 ++++ work/include/linux/arequipa.h Thu Sep 17 17:11:46 1998 @@ -0,0 +1,63 @@ +/* arequipa.h - Arequipa interface definitions */ + @@ -10892,8 +11005,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atmdev.h Fri Aug 21 01:09:01 1998 -@@ -0,0 +1,309 @@ ++++ work/include/linux/atmdev.h Thu Sep 17 17:08:52 1998 +@@ -0,0 +1,311 @@ +/* atmdev.h - ATM device driver declarations */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -11051,6 +11164,8 @@ +#define ATM_PHY_SIG_UNKNOWN 1 /* carrier/light status is unknown */ +#define ATM_PHY_SIG_FOUND 2 /* carrier/light okay */ + ++#define ATM_ATMOPT_CLP 1 /* set CLP bit */ ++ + +struct atm_vcc { + unsigned short flags; /* VCC flags (ATM_VF_*) */ @@ -11657,7 +11772,7 @@ #define CAP_NET_ADMIN 12 --- ref/include/linux/if_arp.h Thu Aug 20 01:38:57 1998 -+++ work/include/linux/if_arp.h Fri Aug 21 01:07:19 1998 ++++ work/include/linux/if_arp.h Thu Sep 17 17:08:30 1998 @@ -35,6 +35,7 @@ #define ARPHRD_ARCNET 7 /* ARCnet */ #define ARPHRD_APPLETLK 8 /* APPLEtalk */ @@ -11677,7 +11792,7 @@ /* ARP ioctl request. */ --- ref/include/linux/pkt_sched.h Tue Apr 28 20:10:10 1998 -+++ work/include/linux/pkt_sched.h Fri Aug 21 00:52:29 1998 ++++ work/include/linux/pkt_sched.h Wed Sep 16 15:56:51 1998 @@ -274,4 +274,17 @@ #define TCA_CBQ_MAX TCA_CBQ_POLICE @@ -11689,7 +11804,7 @@ + TCA_ATM_FD, /* file/socket descriptor */ + TCA_ATM_PTR, /* pointer to descriptor - later */ + TCA_ATM_HDR, /* LL header */ -+ TCA_ATM_POLICE, /* policing - later */ ++ TCA_ATM_EXCESS, /* excess traffic class (0 for CLP) */ + TCA_ATM_ADDR /* PVC address (for output only) */ +}; + @@ -11697,8 +11812,8 @@ + #endif --- ref/include/linux/skbuff.h Thu Aug 20 01:38:56 1998 -+++ work/include/linux/skbuff.h Fri Aug 21 01:06:09 1998 -@@ -106,6 +106,16 @@ ++++ work/include/linux/skbuff.h Wed Sep 16 15:50:39 1998 +@@ -106,6 +106,17 @@ __u32 shapestamp; /* Stamp for shaper */ __u16 shapepend; /* Pending */ #endif @@ -11706,6 +11821,7 @@ + struct { + struct atm_vcc *vcc; /* ATM VCC */ + int iovcnt; /* 0 for "normal" operation */ ++ unsigned long atm_options; /* ATM layer options */ +#ifdef CONFIG_AREQUIPA + int generation; /* generation number */ +#endif @@ -11771,7 +11887,7 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/net/atmclip.h Fri Aug 21 01:12:51 1998 ++++ work/include/net/atmclip.h Thu Sep 17 17:10:41 1998 @@ -0,0 +1,62 @@ +/* net/atm/atmarp.h - RFC1577 ATM ARP */ + @@ -11836,8 +11952,8 @@ + +#endif --- ref/net/Config.in Mon Jun 8 19:02:34 1998 -+++ work/net/Config.in Fri Aug 21 00:52:29 1998 -@@ -23,6 +23,23 @@ ++++ work/net/Config.in Wed Sep 23 18:53:27 1998 +@@ -23,6 +23,26 @@ fi fi fi @@ -11850,6 +11966,9 @@ +# fi + if [ "$CONFIG_INET" = "y" ]; then + bool ' Classical IP over ATM' CONFIG_ATM_CLIP y ++ if [ "$CONFIG_ATM_CLIP" = "y" ]; then ++ bool ' Do NOT send ICMP if no neighbour' CONFIG_ATM_CLIP_NO_ICMP n ++ fi +# bool ' Application REQUested IP over ATM' CONFIG_AREQUIPA y + fi + tristate ' LAN Emulation (LANE) support' CONFIG_ATM_LANE y @@ -11987,18 +12106,13 @@ tc_filter_init(); #endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/sched/sch_atm.c Fri Aug 21 00:52:29 1998 -@@ -0,0 +1,550 @@ ++++ work/net/sched/sch_atm.c Thu Sep 24 19:35:30 1998 +@@ -0,0 +1,598 @@ +/* net/sched/sch_atm.c - ATM VC selection "queueing discipline" */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + -+/* -+ * NOTE: There are still essential parts (e.g. policing) missing. So don't -+ * depend too much on the existing interfaces ... -+ */ -+ +#include +#include +#include @@ -12012,7 +12126,8 @@ + + +extern struct socket *sockfd_lookup(int fd, int *err); /* @@@ fix this */ -+#define sockfd_put(sock) fput((sock)->file) ++#define sockfd_put(sock) fput((sock)->file) /* @@@ copied because it's ++ __inline__ in socket.c */ + + +#if 1 /* control */ @@ -12031,8 +12146,8 @@ +/* + * The ATM queuing discipline provides a framework for invoking classifiers + * (aka "filters"), which in turn select classes of this queuing discipline. -+ * Each class maps the flow(s) it is handling to a given VC. More than one -+ * class may use the same VC. ++ * Each class maps the flow(s) it is handling to a given VC. Multiple classes ++ * may share the same VC. + * + * When creating a class, VCs are specified by passing the number of the open + * socket descriptor by which the calling process references the VC. The kernel @@ -12044,11 +12159,9 @@ + * + * Known bugs: + * - sometimes messes up the IP stack -+ * - no policing yet -+ * - may panic if there's not enough space in an skb to add the CLIP header + * - any manipulations besides the few operations described in the README, are + * untested and likely to crash the system -+ * - takes a few dirty shortcuts on rtnetlink ++ * - should lock the flow while there is data in the queue (?) + */ + + @@ -12060,12 +12173,14 @@ + struct tcf_proto *filter_list; + struct atm_vcc *vcc; /* VCC; NULL if VCC is closed */ + struct socket *sock; /* for closing */ -+ unsigned long classid; /* x:y type ID */ ++ u32 classid; /* x:y type ID */ + int ref; /* reference count */ + struct tc_stats stats; + struct atm_flow_data *next; ++ struct atm_flow_data *excess; /* flow for excess traffic; ++ NULL to set CLP instead */ + int hdr_len; -+ unsigned char hdr[0]; /* header data */ ++ unsigned char hdr[0]; /* header data; MUST BE LAST */ +}; + +struct atm_qdisc_data { @@ -12110,8 +12225,7 @@ + struct atm_qdisc_data *p = PRIV(sch); + struct atm_flow_data *flow; + -+ DPRINTK("atm_tc_get(sch %p,[qdisc %p],classid %p)\n",sch,p, -+ (void *) classid); ++ DPRINTK("atm_tc_get(sch %p,[qdisc %p],classid %x)\n",sch,p,classid); + for (flow = PRIV(sch)->flows; flow; flow = flow->next) + if (flow->classid == classid) break; + if (flow) flow->ref++; @@ -12139,7 +12253,7 @@ + for (prev = &p->flows; *prev; prev = &(*prev)->next) + if (*prev == flow) break; + if (!*prev) { -+ printk(KERN_ERR "atm_tc_put: class %p not found\n",flow); ++ printk(KERN_CRIT "atm_tc_put: class %p not found\n",flow); + return; + } + *prev = flow->next; @@ -12160,6 +12274,7 @@ + * If flow == &p->link, the qdisc no longer works at this point and + * needs to be removed. (By the caller of atm_tc_put.) + */ ++ if (flow->excess) atm_tc_put(sch,(unsigned long) flow->excess); +} + + @@ -12168,6 +12283,7 @@ +{ + struct atm_qdisc_data *p = PRIV(sch); + struct atm_flow_data *flow = (struct atm_flow_data *) *arg; ++ struct atm_flow_data *excess; + struct rtattr *opt = tca[TCA_OPTIONS-1]; + struct rtattr *tb[TCA_ATM_MAX]; + struct socket *sock; @@ -12184,7 +12300,8 @@ + * ATM classes cannot be changed. In order to change properties of the + * ATM connection, that socket needs to be modified directly (via the + * native ATM API. In order to send a flow to a different VC, the old -+ * class needs to be removed and a new one added. ++ * class needs to be removed and a new one added. (This may be changed ++ * later.) + */ + if (flow) return -EBUSY; + if (opt == NULL || rtattr_parse(tb,TCA_ATM_MAX,RTA_DATA(opt), @@ -12201,6 +12318,14 @@ + hdr_len = RFC1483LLC_LEN; + hdr = NULL; /* default LLC/SNAP for IP */ + } ++ if (!tb[TCA_ATM_EXCESS-1]) excess = NULL; ++ else { ++ if (RTA_PAYLOAD(tb[TCA_ATM_EXCESS-1]) != sizeof(u32)) ++ return -EINVAL; ++ excess = (struct atm_flow_data *) atm_tc_get(sch, ++ *(u32 *) RTA_DATA(tb[TCA_ATM_EXCESS-1])); ++ if (!excess) return -ENOENT; ++ } + DPRINTK("atm_tc_change: type %d, payload %d, hdr_len %d\n", + opt->rta_type,RTA_PAYLOAD(opt),hdr_len); + if (!(sock = sockfd_lookup(fd,&error))) return error; /* f_count++ */ @@ -12249,6 +12374,7 @@ + DPRINTK("atm_tc_change: vcc %p\n",flow->vcc); + flow->classid = classid; + flow->ref = 1; ++ flow->excess = excess; + flow->next = p->link.next; + p->link.next = flow; + flow->hdr_len = hdr_len; @@ -12273,6 +12399,7 @@ + DPRINTK("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n",sch,p,flow); + if (!find_flow(PRIV(sch),flow)) return -EINVAL; + if (flow->filter_list || flow == &p->link) return -EBUSY; ++ if (flow->ref > 1) return -EBUSY; /* catch references via excess, etc.*/ + atm_tc_put(sch,arg); + return 0; +} @@ -12314,13 +12441,45 @@ + struct atm_qdisc_data *p = PRIV(sch); + struct atm_flow_data *flow; + struct tcf_result res; ++ int result; + + D2PRINTK("atm_tc_enqueue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p); -+ for (flow = p->link.next; flow; flow = flow->next) -+ if (flow->filter_list && tc_classify(skb,flow->filter_list, -+ &res) >= 0) break; ++ result = TC_POLICE_OK; /* be nice to gcc */ ++ if (TC_H_MAJ(skb->priority) != sch->handle || ++ !(flow = (struct atm_flow_data *) atm_tc_get(sch,skb->priority))) ++ for (flow = p->link.next; flow; flow = flow->next) ++ if (flow->filter_list) { ++ result = tc_classify(skb,flow->filter_list, ++ &res); ++ if (result >= 0) break; ++ } + if (!flow) flow = &p->link; -+ if (flow->q->enqueue(skb,flow->q) != 1) { ++ else { ++ if (flow->vcc) skb->atm.atm_options = flow->vcc->atm_options; ++#ifdef CONFIG_NET_CLS_POLICE ++ switch (result) { ++ case TC_POLICE_SHOT: ++ kfree_skb(skb); ++ break; ++ case TC_POLICE_RECLASSIFY: ++ if (flow->excess) flow = flow->excess; ++ else { ++ skb->atm.atm_options |= ATM_ATMOPT_CLP; ++ break; ++ } ++ /* fall through */ ++ case TC_POLICE_OK: ++ /* fall through */ ++ default: ++ break; ++ } ++ } ++#endif ++ if ( ++#ifdef CONFIG_NET_CLS_POLICE ++ result == TC_POLICE_SHOT || ++#endif ++ flow->q->enqueue(skb,flow->q) != 1) { + sch->stats.drops++; + if (flow) flow->stats.drops++; + return 0; @@ -12366,6 +12525,7 @@ + flow->hdr_len); + atomic_add(skb->truesize,&flow->vcc->tx_inuse); + skb->atm.iovcnt = 0; ++ /* atm.atm_options are already set by atm_tc_enqueue */ + (void) flow->vcc->dev->ops->send(flow->vcc,skb); + } + skb = p->link.q->dequeue(p->link.q); @@ -12471,6 +12631,13 @@ + pvc.sap_addr.vci = flow->vcc->vci; + RTA_PUT(skb,TCA_ATM_ADDR,sizeof(pvc),&pvc); + } ++ if (flow->excess) ++ RTA_PUT(skb,TCA_ATM_EXCESS,sizeof(u32),&flow->classid); ++ else { ++ static u32 zero = 0; ++ ++ RTA_PUT(skb,TCA_ATM_EXCESS,sizeof(zero),&zero); ++ } + rta->rta_len = skb->tail-b; + return skb->len; + @@ -12514,7 +12681,7 @@ + + atm_tc_enqueue, /* enqueue */ + atm_tc_dequeue, /* dequeue */ -+ atm_tc_enqueue, /* requeue */ ++ atm_tc_enqueue, /* requeue; we're cheating a little */ + atm_tc_drop, /* drop */ + + atm_tc_init, /* init */ @@ -12769,7 +12936,7 @@ + return total; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/addr.h Fri Aug 21 01:14:05 1998 ++++ work/net/atm/addr.h Thu Sep 17 17:11:46 1998 @@ -0,0 +1,18 @@ +/* net/atm/addr.h - Local ATM address registry */ + @@ -12790,13 +12957,14 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/clip.c Fri Aug 21 00:52:29 1998 -@@ -0,0 +1,645 @@ ++++ work/net/atm/clip.c Wed Sep 23 18:41:02 1998 +@@ -0,0 +1,649 @@ +/* clip.c - RFC1577 Classical IP over ATM */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ + + ++#include +#include +#include +#include /* for UINT_MAX */ @@ -13027,7 +13195,9 @@ + +static void clip_neigh_error(struct neighbour *neigh,struct sk_buff *skb) +{ ++#ifndef CONFIG_ATM_CLIP_NO_ICMP + icmp_send(skb,ICMP_DEST_UNREACH,ICMP_HOST_UNREACH,0); ++#endif + kfree_skb(skb); +} + @@ -13165,6 +13335,7 @@ + } + atomic_add(skb->truesize,&skb->atm.vcc->tx_inuse); + skb->atm.iovcnt = 0; ++ skb->atm.atm_options = skb->atm.vcc->atm_options; + entry->vccs->last_use = jiffies; + DPRINTK("skb(%p)->atm.vcc(%p)->dev(%p)\n",skb,skb->atm.vcc, + skb->atm.vcc->dev); @@ -13438,8 +13609,8 @@ + return 0; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/common.c Fri Aug 21 01:28:53 1998 -@@ -0,0 +1,916 @@ ++++ work/net/atm/common.c Wed Sep 16 15:52:34 1998 +@@ -0,0 +1,926 @@ +/* net/atm/common.c - ATM sockets (common part for PVC and SVC) */ + +/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ @@ -13906,6 +14077,7 @@ + if (!(vcc->flags & ATM_VF_READY)) return -EPIPE; + } + skb->atm.iovcnt = 0; ++ skb->atm.atm_options = vcc->atm_options; + if (copy_from_user(skb_put(skb,size),buff,size)) { + kfree_skb(skb); + return -EFAULT; @@ -14298,6 +14470,12 @@ + vcc->flags |= ATM_VF_HASQOS; + return 0; + } ++ case SO_SETCLP: ++ if (get_user(value,(unsigned long *) optval)) ++ return -EFAULT; ++ if (value) vcc->atm_options |= ATM_ATMOPT_CLP; ++ else vcc->atm_options &= ~ATM_ATMOPT_CLP; ++ return 0; + default: + if (level == SOL_SOCKET) return -EINVAL; + break; @@ -14328,6 +14506,9 @@ + if (!(vcc->flags & ATM_VF_HASQOS)) return -EINVAL; + return copy_to_user(optval,&vcc->qos,sizeof(vcc->qos)) ? + -EFAULT : 0; ++ case SO_SETCLP: ++ return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 : ++ 0,(unsigned long *) optval) ? -EFAULT : 0; + default: + if (level == SOL_SOCKET) return -EINVAL; + break; @@ -14461,7 +14642,7 @@ + skb_queue_head_init(from); +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/ipcommon.h Fri Aug 21 01:14:10 1998 ++++ work/net/atm/ipcommon.h Thu Sep 17 17:11:51 1998 @@ -0,0 +1,21 @@ +/* net/atm/ipcommon.h - Common items for all ways of doing IP over ATM */ + @@ -14485,13 +14666,15 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/misc.c Fri Aug 21 00:52:29 1998 -@@ -0,0 +1,182 @@ ++++ work/net/atm/misc.c Thu Sep 24 19:42:05 1998 +@@ -0,0 +1,184 @@ +/* net/atm/misc.c - Various functions for use by ATM drivers */ + -+/* Written 1995-1997 by Werner Almesberger, EPFL ICA */ ++/* Written 1995-1998 by Werner Almesberger, EPFL ICA */ + + ++#include ++#include +#include +#include +#include @@ -14670,8 +14853,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/lec.c Fri Aug 21 00:52:29 1998 -@@ -0,0 +1,1976 @@ ++++ work/net/atm/lec.c Wed Sep 16 16:16:16 1998 +@@ -0,0 +1,1977 @@ +/* + * lec.c: Lan Emulation driver + * Marko Kiiskila carnil@cs.tut.fi @@ -14878,6 +15061,7 @@ + } + atomic_add(skb->truesize, &send_vcc->tx_inuse); + skb->atm.iovcnt = 0; ++ skb->atm.atm_options = send_vcc->atm_options; + send_vcc->dev->ops->send(send_vcc, skb); + priv->stats.tx_packets++; + } @@ -16649,7 +16833,7 @@ +} + --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/lec.h Fri Aug 21 01:14:05 1998 ++++ work/net/atm/lec.h Thu Sep 17 17:11:46 1998 @@ -0,0 +1,143 @@ +/* + * @@ -16795,7 +16979,7 @@ +#endif _LEC_H_ + --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/lec_arpc.h Fri Aug 21 01:14:05 1998 ++++ work/net/atm/lec_arpc.h Thu Sep 17 17:11:46 1998 @@ -0,0 +1,112 @@ +/* + * Lec arp cache @@ -16910,8 +17094,8 @@ + +#endif --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/mpc.c Fri Aug 21 00:52:29 1998 -@@ -0,0 +1,1406 @@ ++++ work/net/atm/mpc.c Wed Sep 16 16:43:25 1998 +@@ -0,0 +1,1408 @@ +#include +#include +#include @@ -17406,6 +17590,8 @@ + } + + atomic_add(skb->truesize, &entry->shortcut->tx_inuse); ++ skb->atm.iovcnt = 0; /* just to be safe ... */ ++ skb->atm.atm_options = entry->shortcut->atm_options; + entry->shortcut->dev->ops->send(entry->shortcut, skb); + entry->packets_fwded++; + @@ -18319,7 +18505,7 @@ +#endif /* MODULE */ + --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/mpc.h Fri Aug 21 01:14:05 1998 ++++ work/net/atm/mpc.h Thu Sep 17 17:11:46 1998 @@ -0,0 +1,73 @@ +#ifndef _MPC_H_ +#define _MPC_H_ @@ -18933,7 +19119,7 @@ + return; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/mpoa_caches.h Fri Aug 21 01:14:05 1998 ++++ work/net/atm/mpoa_caches.h Thu Sep 17 17:11:46 1998 @@ -0,0 +1,87 @@ +#ifndef MPOA_CACHES_H +#define MPOA_CACHES_H @@ -20535,7 +20721,7 @@ +EXPORT_SYMBOL(shutdown_atm_dev); +EXPORT_SYMBOL(bind_vcc); --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/resources.h Fri Aug 21 01:14:05 1998 ++++ work/net/atm/resources.h Thu Sep 17 17:11:46 1998 @@ -0,0 +1,32 @@ +/* net/atm/resources.h - ATM-related resources */ + @@ -20825,7 +21011,7 @@ + return 0; +} --- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/net/atm/signaling.h Fri Aug 21 01:14:05 1998 ++++ work/net/atm/signaling.h Thu Sep 17 17:11:46 1998 @@ -0,0 +1,25 @@ +/* net/atm/signaling.h - ATM signaling */ + diff -ur --new-file old/atm/doc/README.CLP new/atm/doc/README.CLP --- old/atm/doc/README.CLP Thu Jan 1 01:00:00 1970 +++ new/atm/doc/README.CLP Wed Sep 16 19:25:05 1998 @@ -0,0 +1,22 @@ +Setting the CLP (Cell Loss Priority) bit +======================================== + +At the socket API: Enabled via the socket option SO_SETCLP (in SOL_ATM). +Default is off. + +Above the driver interface: before calling dev->ops->send on an skb, +vcc->atm_options must be copied into skb->atm.atm_options. This is +similar to the initialization of skb->atm.iovcnt. + +At the driver interface: Bit ATM_ATMOPT_CLP is set in skb->atm.atm_options +at the time dev->ops->send is called. + +A driver is not required to honor ATM_ATMOPT_CLP. + +ATM_ATMOPT_CLP may only be applied to AAL5 at the moment. It may or may +not work for AAL0. (In the future, attempting to set SO_SETCLP for AAL0 +may yield an error.) + +Drivers currently supporting CLP: ENI and ZATM. + +Note that CLP support is completely untested yet. diff -ur --new-file old/atm/doc/usage.tex new/atm/doc/usage.tex --- old/atm/doc/usage.tex Fri Aug 21 00:53:35 1998 +++ new/atm/doc/usage.tex Thu Sep 24 16:01:50 1998 @@ -1,7 +1,7 @@ %%def%:= %:\begin{verbatim} -%:Usage instructions - ATM on Linux, release 0.43 +%:Usage instructions - ATM on Linux, release 0.44 %:------------------------------------------------- %: %:\end{verbatim} @@ -38,14 +38,14 @@ \title{ATM on Linux \\ User's guide \\ - Release 0.43 (alpha)} + Release 0.44 (alpha)} \author{Werner Almesberger \\ {\tt Werner.Almesberger@epfl.ch} \\ \\ Institute for computer Communications and Applications (ICA) \\ EPFL, CH-1015 Lausanne, Switzerland} -\date{August 21, 1998} +\date{September 24, 1998} \begin{document} \maketitle @@ -76,12 +76,13 @@ %------------------------------------------------------------------------------ + \section{Installation} 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.43.tar.gz} + \url{ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.44.tar.gz} \item the Linux kernel, version 2.1.117, e.g. from \url{ftp://ftp.kernel.org/pub/linux/kernel/v2.1/linux-2.1.117.tar.gz} \item Perl, version 4 or 5 @@ -98,7 +99,7 @@ distribution: \begin{verbatim} -tar xfz atm-0.43.tar.gz +tar xfz atm-0.44.tar.gz \end{verbatim} and the kernel source: @@ -163,13 +164,16 @@ \begin{verbatim} Asynchronous Transfer Mode (ATM, EXPERIMENTAL) (CONFIG_ATM) Classical IP over ATM (CONFIG_ATM_CLIP) + Do NOT send ICMP if no neighbour (CONFIG_ATM_CLIP_NO_ICMP) LAN Emulation (LANE) support (CONFIG_ATM_LANE) + Multi-Protocol Over ATM (MPOA) support (CONFIG_ATM_MPOA) ATM over TCP (CONFIG_ATM_TCP) Efficient Networks ENI155P (CONFIG_ATM_ENI) Enable extended debugging (CONFIG_ATM_ENI_DEBUG) ZeitNet ZN1221/ZN1225 (CONFIG_ATM_ZATM) Enable extended debugging (CONFIG_ATM_ZATM_DEBUG) Enable usec resolution timestamps (CONFIG_ATM_ZATM_EXACT_TS) +IDT 77201 (NICStAR) (CONFIG_ATM_NICSTAR) \end{verbatim} %after ATM % Enable single-copy (CONFIG_MMU_HACKS) @@ -179,7 +183,6 @@ %after usec %Rolfs TI TNETA1570 (CONFIG_ATM_TNETA1570) % Enable extended debugging (CONFIG_ATM_TNETA1570_DEBUG) -IDT 77201 (NICStAR) (CONFIG_ATM_NICSTAR) %The ``MMU hacks'' add single-copy support for raw AAL5 on adapters whose @@ -193,6 +196,10 @@ Note that the file \path{drivers/atm/nicstar.h} contains a few configurable settings for the IDT 77201 driver. +Some drivers can also be used with certain compatible cards. The latest +information about compatibile cards can be found at +\url{http://lrcwww.epfl.ch/linux-atm/info.html} + Then build your kernel and reboot. @@ -250,8 +257,8 @@ \subsection{ATM tools} Now, as the final step, configure and build the ATM tools. Configuration is -only necessary if your switch uses UNI 3.1 or if it has certain bugs. The -configuration options are at the beginning of \path{atm/Rules.make}. +only necessary if your switch uses UNI 3.1 or 4.0, or if it has certain bugs. +The configuration options are at the beginning of \path{atm/Rules.make}. Then, build the ATM tools with: @@ -300,6 +307,7 @@ %------------------------------------------------------------------------------ + \section{Device setup} This section describes device-specific configuration operations, and general @@ -476,9 +484,9 @@ error insertions may be automatically switched off by the hardware. - %------------------------------------------------------------------------------ + \section{Native ATM PVCs} PVCs can be used for machines that are either connected back to back or @@ -563,8 +571,10 @@ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \end{verbatim}} + %------------------------------------------------------------------------------ + \section{Signaling} \subsection{ATM hosts file} @@ -632,8 +642,8 @@ problems, it frequently terminates. This will (obviously) change in the future. -\name{atmsigd} also looks for a configuration file \path{atmsigd.conf} in -the current directory. +\name{atmsigd} also looks for a configuration file at the location specified +with the \raw{-c} option. The default location is \path{/etc/atmsigd.conf}. \subsection{ILMI demon} @@ -666,9 +676,8 @@ \end{description} If no interface number is specified, \name{ilmid} serves interface 0. -\name{atmsigd} should already be running when \name{ilmid} is started, Use the -\raw{-b} option to make sure they're properly synchronized (see section -\ref{clip}). +You can check whether address registration was successful with the +\name{atmaddr} command (see below). The agent supports only the address registration procedures specified in section 5.8 of the ATM Forum's UNI 3.1 specification. These @@ -821,6 +830,7 @@ %------------------------------------------------------------------------------ + \section{IP over ATM} \label{ipoveratm} diff -ur --new-file old/atm/doc/usage.txt new/atm/doc/usage.txt --- old/atm/doc/usage.txt Fri Aug 21 01:02:14 1998 +++ new/atm/doc/usage.txt Thu Sep 24 18:47:31 1998 @@ -1,4 +1,4 @@ -Usage instructions - ATM on Linux, release 0.43 +Usage instructions - ATM on Linux, release 0.44 ------------------------------------------------- For updates of ATM on Linux, please check the Web page at @@ -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.43.tar.gz + ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.44.tar.gz - the Linux kernel, version 2.1.117, e.g. from ftp://ftp.kernel.org/pub/linux/kernel/v2.1/linux-2.1.117.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.43.tar.gz +tar xfz atm-0.44.tar.gz and the kernel source: @@ -85,19 +85,24 @@ Asynchronous Transfer Mode (ATM, EXPERIMENTAL) (CONFIG_ATM) Classical IP over ATM (CONFIG_ATM_CLIP) + Do NOT send ICMP if no neighbour (CONFIG_ATM_CLIP_NO_ICMP) LAN Emulation (LANE) support (CONFIG_ATM_LANE) + Multi-Protocol Over ATM (MPOA) support (CONFIG_ATM_MPOA) ATM over TCP (CONFIG_ATM_TCP) Efficient Networks ENI155P (CONFIG_ATM_ENI) Enable extended debugging (CONFIG_ATM_ENI_DEBUG) ZeitNet ZN1221/ZN1225 (CONFIG_ATM_ZATM) Enable extended debugging (CONFIG_ATM_ZATM_DEBUG) Enable usec resolution timestamps (CONFIG_ATM_ZATM_EXACT_TS) - IDT 77201 (NICStAR) (CONFIG_ATM_NICSTAR) Note that the file drivers/atm/nicstar.h contains a few configurable settings for the IDT 77201 driver. +Some drivers can also be used with certain compatible cards. The latest +information about compatibile cards can be found at +http://lrcwww.epfl.ch/linux-atm/info.html + Then build your kernel and reboot. @@ -153,8 +158,8 @@ --------- Now, as the final step, configure and build the ATM tools. Configuration is -only necessary if your switch uses UNI 3.1 or if it has certain bugs. The -configuration options are at the beginning of atm/Rules.make. +only necessary if your switch uses UNI 3.1 or 4.0, or if it has certain +bugs. The configuration options are at the beginning of atm/Rules.make. Then, build the ATM tools with: @@ -503,8 +508,8 @@ problems, it frequently terminates. This will (obviously) change in the future. -atmsigd also looks for a configuration file atmsigd.conf in the current -directory. +atmsigd also looks for a configuration file at the location specified with +the -c option. The default location is /etc/atmsigd.conf. ILMI demon @@ -531,9 +536,9 @@ -x disable inclusion of variable bindings in the ColdstartTrap. Some switches (e.g. the LS100) only work if this option is set. -If no interface number is specified, ilmid serves interface 0. atmsigd -should already be running when ilmid is started, Use the -b option to -make sure they're properly synchronized (see section "CLIP"). +If no interface number is specified, ilmid serves interface 0. You can +check whether address registration was successful with the atmaddr command +(see below). The agent supports only the address registration procedures specified in section 5.8 of the ATM Forum's UNI 3.1 specification. These procedures diff -ur --new-file old/atm/extra/tc/README new/atm/extra/tc/README --- old/atm/extra/tc/README Fri Jul 24 01:20:05 1998 +++ new/atm/extra/tc/README Wed Sep 16 15:49:51 1998 @@ -1,3 +1,6 @@ +Basic configuration +------------------- + 1. When configuring the kernel, select at least the following options under "Networking options": - kernel/User netlink socket @@ -63,3 +66,36 @@ Verify that the PVC has been removed: % cat /proc/atm/pvc + + +Policing (UNTESTED !) +-------- + +When adding policing, proceed as follows: + +1. Enable in "Networking options" the item "Ingres traffic policing" + +2. Specify policy along with the classifier (use u32 or rsvp) + +3. Decide on policing action. There are three choices: + + - drop packet + - send packet in different class (re-classify) + - send packet in same class, with CLP=1 + + Note that policing is only done once, so it's not possible to + re-classify a second time. Also note that dropping currently isn't + supported by tc. + +4. Set up the classifier and the class according to the choice made: + + Action Classifier/filter action Class + ---------- ------------------------ -------------- + drop drop (not yet supported) n/a + reclassify reclassify (default) excess CLASSID + CLP=1 reclassify (default) excess clp + + Example: + # ./tc filter add dev eth0 parent 1:1 protocol ip route \ + burst 100 rate 100 + # ./tc class add dev eth0 classid 1:1 atm pvc 0.100 excess 1:0 diff -ur --new-file old/atm/extra/tc/q_atm.c new/atm/extra/tc/q_atm.c --- old/atm/extra/tc/q_atm.c Thu Aug 13 13:35:14 1998 +++ new/atm/extra/tc/q_atm.c Wed Sep 16 15:50:24 1998 @@ -38,7 +38,7 @@ static void explain(void) { fprintf(stderr, "Usage: ... atm ( pvc ADDR | svc ADDR [ sap SAP ] ) " - "[ qos QOS ] [ hdr HEX... ]\n"); + "[ qos QOS ] [ hdr HEX... ] [ excess ( CLASSID | clp ) ] \n"); } @@ -49,6 +49,7 @@ struct atm_qos qos; struct atm_sap sap; unsigned char hdr[MAX_HDR_LEN]; + __u32 excess; struct rtattr *tail; int hdr_len = -1; int s; @@ -94,13 +95,14 @@ NEXT_ARG(); ptr = hdr; - for (walk = *argv; *walk; walk += 2) { + for (walk = *argv; *walk; walk++) { int tmp; if (ptr == hdr+MAX_HDR_LEN) { fprintf(stderr,"header is too long\n"); return -1; } + if (*walk == '.') continue; if (!isxdigit(walk[0]) || !walk[1] || !isxdigit(walk[1])) { explain(); @@ -108,9 +110,18 @@ } sscanf(walk,"%2x",&tmp); *ptr++ = tmp; + walk++; } hdr_len = ptr-hdr; } + else if (!strcmp(*argv,"excess")) { + NEXT_ARG(); + if (!strcmp(*argv,"clp")) excess = 0; + else if (get_tc_classid(&excess,*argv)) { + explain(); + return -1; + } + } else { explain(); return 1; @@ -140,6 +151,7 @@ tail = (struct rtattr *) (((void *) n)+NLMSG_ALIGN(n->nlmsg_len)); addattr_l(n,1024,TCA_OPTIONS,NULL,0); addattr_l(n,1024,TCA_ATM_FD,&s,sizeof(s)); + addattr_l(n,1024,TCA_ATM_EXCESS,&excess,sizeof(excess)); if (hdr_len != -1) addattr_l(n,1024,TCA_ATM_HDR,hdr,hdr_len); tail->rta_len = (((void *) n)+NLMSG_ALIGN(n->nlmsg_len))-(void *) tail; return 0; @@ -155,17 +167,45 @@ if (!opt) return 0; memset(tb, 0, sizeof(tb)); parse_rtattr(tb, TCA_ATM_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)); - if (!tb[TCA_ATM_ADDR]) return 0; - if (RTA_PAYLOAD(tb[TCA_ATM_ADDR]) < sizeof(struct sockaddr_atmpvc)) { - fprintf(stderr,"ATM: address too short\n"); - return 0; - } - if (atm2text(buffer,MAX_ATM_ADDR_LEN,RTA_DATA(tb[TCA_ATM_ADDR]), - A2T_PRETTY | A2T_NAME) < 0) fprintf(stderr,"atm2text error\n"); - printf("%s",buffer); + if (tb[TCA_ATM_ADDR]) + if (RTA_PAYLOAD(tb[TCA_ATM_ADDR]) < + sizeof(struct sockaddr_atmpvc)) + fprintf(stderr,"ATM: address too short\n"); + else { + if (atm2text(buffer,MAX_ATM_ADDR_LEN, + RTA_DATA(tb[TCA_ATM_ADDR]),A2T_PRETTY | A2T_NAME) < + 0) fprintf(stderr,"atm2text error\n"); + fprintf(f,"pvc %s",buffer); + } + if (tb[TCA_ATM_HDR]) { + int i; + + fprintf(f,"hdr"); + for (i = 0; i < RTA_PAYLOAD(tb[TCA_ATM_HDR]); i++) + fprintf(f,"%c%02x",i ? '.' : ' ', + ((unsigned char *) RTA_DATA(tb[TCA_ATM_HDR]))[i]); + if (!i) fprintf(f," ."); + } + if (tb[TCA_ATM_EXCESS]) { + __u32 excess; + + if (RTA_PAYLOAD(tb[TCA_ATM_EXCESS]) < sizeof(excess)) + fprintf(stderr,"ATM: excess class ID too short\n"); + else { + excess = *(__u32 *) RTA_DATA(tb[TCA_ATM_EXCESS]); + if (!excess) fprintf(f,"excess clp "); + else { + char buf[64]; + + print_tc_classid(buf,sizeof(buf),excess); + fprintf(f,"excess %s ",buf); + } + } + } return 0; } + static int atm_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) { return 0; @@ -182,4 +222,3 @@ atm_parse_class_opt, atm_print_opt }; - diff -ur --new-file old/atm/ilmid/Makefile new/atm/ilmid/Makefile --- old/atm/ilmid/Makefile Tue Aug 4 20:00:15 1998 +++ new/atm/ilmid/Makefile Thu Sep 24 18:00:31 1998 @@ -7,7 +7,7 @@ BOOTPGMS=ilmid include ../Rules.make -CFLAGS = $(CFLAGS_NOWARN) $(CFLAGS_OPT) $(CFLAGS_PRIVATE) +CFLAGS = $(CFLAGS_NOWARN) $(CFLAGS_OPT) $(CFLAGS_PRIVATE) $(STANDARDS) default: all diff -ur --new-file old/atm/ilmid/atmf_uni.c new/atm/ilmid/atmf_uni.c --- old/atm/ilmid/atmf_uni.c Wed Aug 5 17:29:33 1998 +++ new/atm/ilmid/atmf_uni.c Thu Sep 24 18:24:30 1998 @@ -35,10 +35,21 @@ AsnOid atmfPortIndex = {13, "\53\06\01\04\01\202\141\02\01\01\01\01\00"}; AsnOid atmfMyIpNmAddress = {11, "\53\06\01\04\01\202\141\02\01\02\00"}; +AsnOid atmfAtmLayerUniVersion = {13, "\53\06\01\04\01\202\141\02\02\01\01\11\00"}; AsnOid atmfNetPrefixStatus = {NETPREFIX_LEN, "\53\06\01\04\01\202\141\02\07\01\01\03"}; AsnInt atmfPortIndexValue = 0; -AsnOid atmfMyIpNmAddressValue = {4 , "\0\0\0\0"}; +IpAddress atmfMyIpNmAddressValue = {4 , NULL}; + +#ifdef UNI40 +AsnInt atmfAtmLayerUniVersionValue = 4; // version4point0(4) +#else +#if defined(UNI31) +AsnInt atmfAtmLayerUniVersionValue = 3; // version3point1(3) +#else +AsnInt atmfAtmLayerUniVersionValue = 2; // version3point0(2) +#endif +#endif static AsnOid atmNetPrefix = {0, NULL}; @@ -174,9 +185,3 @@ return NOERROR; } - - - - - - diff -ur --new-file old/atm/ilmid/atmf_uni.h new/atm/ilmid/atmf_uni.h --- old/atm/ilmid/atmf_uni.h Tue Apr 22 04:18:58 1997 +++ new/atm/ilmid/atmf_uni.h Thu Sep 24 18:00:31 1998 @@ -32,14 +32,17 @@ AsnOid atmfPortIndex; AsnOid atmfMyIpNmAddress; AsnOid atmfNetPrefixStatus; +AsnOid atmfAtmLayerUniVersion; AsnInt atmfPortIndexValue; -AsnOid atmfMyIpNmAddressValue; +IpAddress atmfMyIpNmAddressValue; +AsnInt atmfAtmLayerUniVersionValue; AsnOid *accessNetPrefix(void); void deleteNetPrefix(void); AsnInt getNetPrefix(VarBind *varbind, Variable *var); AsnInt getnextNetPrefix(VarBind *varbind, Variable *var); AsnInt setNetPrefix(VarBind *varbind, Variable *var); +AsnInt getMyIp(VarBind *varbind, Variable *var); #endif diff -ur --new-file old/atm/ilmid/mib.c new/atm/ilmid/mib.c --- old/atm/ilmid/mib.c Mon May 5 05:48:52 1997 +++ new/atm/ilmid/mib.c Thu Sep 24 18:17:18 1998 @@ -27,9 +27,13 @@ #include "util.h" #include "atmd.h" +#include /* gethostname() */ +#include /* gethostbyname() */ + #define COMPONENT "MIB" static Variable variables[] = +/* keep this sorted by the value of entry.name */ { { &sysDescr, getString, NULL, NULL, &sysDescrValue }, { &sysObjectID, getOid, NULL, NULL, &sysObjectIDValue }, @@ -39,7 +43,9 @@ { &sysLocation, getString, NULL, NULL, &sysLocationValue }, { &sysServices, getInteger, NULL, NULL, &sysServicesValue }, { &atmfPortIndex, getInteger, NULL, NULL, &atmfPortIndexValue }, - { &atmfMyIpNmAddress, getOid, NULL, NULL, &atmfMyIpNmAddressValue }, + { &atmfMyIpNmAddress, getIpAddr, NULL, NULL, &atmfMyIpNmAddressValue }, + { &atmfAtmLayerUniVersion, getInteger, NULL, NULL, + &atmfAtmLayerUniVersionValue }, { &atmfNetPrefixStatus, getNetPrefix, getnextNetPrefix, setNetPrefix, NULL }, { NULL } }; @@ -232,6 +238,116 @@ } +#include +#include +#include + +#include +#include +#include +#include +#include + + +#define MAX_ITFS 500 + +static const char *itf_types[] = { + "", /* fallback */ + "slip*","ppp*","eth*","atm*", /* candidates */ + "!lo", /* blacklist */ + NULL /* the end */ +}; +static uint32_t get_local_ip(void) +{ + struct ifconf ifc; + struct ifreq ifr[MAX_ITFS]; + const char **best; + uint32_t best_ip; + int s,i; + + s = socket(PF_INET,SOCK_DGRAM,0); + if (s < 0) { + perror("socket"); + return 0; + } + ifc.ifc_len = MAX_ITFS*sizeof(struct ifreq); + ifc.ifc_req = ifr; + if (ioctl(s,SIOCGIFCONF,&ifc) < 0) { + perror("SIOCGIFCONF"); + return 0; + } + best = itf_types; + best_ip = 0; + for (i = 0; i < ifc.ifc_len/sizeof(struct ifreq); i++) { + struct sockaddr_in *addr; + const char **walk; + uint32_t ip; + + addr = (struct sockaddr_in *) &ifr[i].ifr_addr; + if (addr->sin_family != AF_INET) continue; + ip = addr->sin_addr.s_addr; + if (!ip) continue; + if (ioctl(s,SIOCGIFFLAGS,&ifr[i]) < 0) { + perror("SIOCGIFFLAGS"); + continue; + } + if (ifr[i].ifr_flags & IFF_LOOPBACK) continue; + if (!(ifr[i].ifr_flags & IFF_UP)) continue; + for (walk = best+1; *walk; walk++) { + const char *pos,*wc,*end; + int not; + + if ((not = *(pos = *walk) == '!')) pos++; + if (*pos) { + int len; + + wc = strchr(pos,'*'); + end = wc ? wc : strchr(pos,0); + len = end-pos; + if (strncmp(ifr[i].ifr_name,pos,end-pos)) continue; + if (len < IFNAMSIZ && ifr[i].ifr_name[len]) + if (!wc || !isdigit(ifr[i].ifr_name[len])) continue; + } + if (not) break; + best = walk; + best_ip = ip; + } + } + return best_ip; +} + + +AsnInt getIpAddr(VarBind *varbind, Variable *var) +{ + if (!((IpAddress*) var->value)->octs) {/* not set */ + uint32_t ip; + ip = get_local_ip(); + if (ip) { + ((IpAddress*) var->value)->octs = alloc(4); + *((uint32_t *) ((IpAddress*) var->value)->octs) = ip; + } + } + if (!((IpAddress*) var->value)->octs) /* still not set */ + { + struct hostent* h; + char hostname[128]; + ((IpAddress*) var->value)->octs = alloc(4); + if (!gethostname(hostname, sizeof(hostname)-1)) + { + h = (struct hostent*) gethostbyname(hostname); + *((uint32_t *) ((IpAddress*) var->value)->octs) = + *((uint32_t *) h->h_addr_list[0]); + } + }; + varbind->value = Asn1Alloc(sizeof(ObjectSyntax)); + varbind->value->choiceId = OBJECTSYNTAX_APPLICATION_WIDE; + varbind->value->a.application_wide = Asn1Alloc(sizeof(ApplicationSyntax)); + varbind->value->a.application_wide->choiceId = APPLICATIONSYNTAX_ADDRESS; + varbind->value->a.application_wide->a.address = Asn1Alloc(sizeof(NetworkAddress)); + varbind->value->a.application_wide->a.address->choiceId = NETWORKADDRESS_INTERNET; + varbind->value->a.application_wide->a.address->a.internet = (IpAddress*) var->value; + return NOERROR; +} diff -ur --new-file old/atm/ilmid/mib.h new/atm/ilmid/mib.h --- old/atm/ilmid/mib.h Tue Apr 22 04:18:58 1997 +++ new/atm/ilmid/mib.h Thu Sep 24 18:00:32 1998 @@ -45,5 +45,6 @@ AsnInt getString(VarBind *varbind, Variable *var); AsnInt getOid(VarBind *varbind, Variable *var); AsnInt getInteger(VarBind *varbind, Variable *var); +AsnInt getIpAddr(VarBind *varbind, Variable *var); #endif diff -ur --new-file old/atm/ilmid/sysgroup.c new/atm/ilmid/sysgroup.c --- old/atm/ilmid/sysgroup.c Tue Apr 22 04:18:53 1997 +++ new/atm/ilmid/sysgroup.c Thu Sep 24 18:02:48 1998 @@ -33,7 +33,7 @@ AsnOid sysLocation = {8, "\53\06\01\02\01\01\06\00"}; AsnOid sysServices = {8, "\53\06\01\02\01\01\07\00"}; -AsnOcts sysDescrValue = {25, "ATM on Linux Version 0.30"}; +AsnOcts sysDescrValue = {25, "ATM on Linux Version " VERSION}; AsnOid sysObjectIDValue = {8, "\53\06\01\04\01\03\01\01"}; AsnOcts sysContactValue = {14, "root@localhost"}; AsnOcts sysNameValue = {23, "localhost.my.domain.com"}; diff -ur --new-file old/atm/lib/atm2text.c new/atm/lib/atm2text.c --- old/atm/lib/atm2text.c Sat Apr 11 12:52:37 1998 +++ new/atm/lib/atm2text.c Wed Sep 9 21:04:49 1998 @@ -17,8 +17,13 @@ char tmp; if (!*length) return FATAL; - if (!value) { - *(*buffer)++ = '0'; + if (value <= 0) { + if (!value) *(*buffer)++ = '0'; + else if (value == ATM_VCI_ANY) *(*buffer)++ = '*'; + else if (value == ATM_VCI_UNSPEC) *(*buffer)++ = '?'; + else return FATAL; + /* ATM_*_ANY and ATM_*_UNSPEC have all the same value, + respectively */ (*length)--; return 0; } diff -ur --new-file old/atm/lib/atmd.h new/atm/lib/atmd.h --- old/atm/lib/atmd.h Tue Jul 28 15:41:44 1998 +++ new/atm/lib/atmd.h Wed Sep 9 19:53:43 1998 @@ -123,7 +123,7 @@ * address. Returns a negative value on error. */ -int un_reply(int s,void *buf,int _size, +int un_reply(int s,void *buf,int size, int (*handler)(void *buf,int len,void *user),void *user); /* @@ -132,7 +132,7 @@ * 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 + * returns a negative value. Otherwise, it returns whatever was returned by the * handler function. */ diff -ur --new-file old/atm/maint/atmaddr.8 new/atm/maint/atmaddr.8 --- old/atm/maint/atmaddr.8 Mon Mar 11 13:09:39 1996 +++ new/atm/maint/atmaddr.8 Thu Sep 24 17:47:53 1998 @@ -1,4 +1,4 @@ -.TH ATMARP 8 "Mar 11, 1996" "Linux" "Maintenance Commands" +.TH ATMADDR 8 "Sep 24, 1998" "Linux" "Maintenance Commands" .SH NAME atmaddr \- list and maintain local ATM addresses .SH SYNOPSIS diff -ur --new-file old/atm/mkdist new/atm/mkdist --- old/atm/mkdist Fri Aug 21 01:02:50 1998 +++ new/atm/mkdist Thu Sep 24 18:48:08 1998 @@ -1,12 +1,12 @@ #!/bin/sh [ -r ./VERSION ] || exit 1 VERSION=`cat ./VERSION` -SRCDIR=$HOME/k/2117 +#SRCDIR=$HOME/k/2117 ARCHDIR=$HOME/l/arch -( - cd $SRCDIR +#( +# cd $SRCDIR # ./mkpatch -) +#) # cp $SRCDIR/atm.patch . cd doc make usage.txt @@ -18,7 +18,7 @@ atm/Makefile atm/Rules.make atm/mkdist atm/mkdiff atm/mkbindist \ atm/mkpatch atm/.kernel \ atm/doc/README atm/doc/usage.tex atm/doc/usage.txt atm/doc/url.sty \ - atm/doc/Makefile atm/doc/rlatex atm/doc/t2a.pl \ + atm/doc/Makefile atm/doc/rlatex atm/doc/t2a.pl atm/doc/README.CLP \ atm/man/Makefile atm/man/qos.7 atm/man/sap.7 \ atm/sigd/Makefile atm/sigd/atmsigd.c atm/sigd/cfg.l atm/sigd/cfg.y \ atm/sigd/io.h atm/sigd/io.c atm/sigd/kernel.c atm/sigd/proto.h \ @@ -128,6 +128,7 @@ atm/switch/debug/README atm/switch/debug/Makefile atm/switch/debug/debug.c \ atm/switch/debug/demo \ atm/switch/tcp/README atm/switch/tcp/Makefile atm/switch/tcp/tcpsw.c \ + atm/switch/tcp/tcpswc.h atm/switch/tcp/tcpswc.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/extra/tc/README atm/extra/tc/Makefile.patch atm/extra/tc/q_atm.c \ diff -ur --new-file old/atm/saal/sscf.c new/atm/saal/sscf.c --- old/atm/saal/sscf.c Fri Feb 9 17:36:05 1996 +++ new/atm/saal/sscf.c Wed Sep 9 15:21:27 1998 @@ -1,6 +1,6 @@ /* sscf.c - SSCF (Q.2130) protocol */ -/* Written 1995 by Werner Almesberger, EPFL-LRC */ +/* Written 1995,1998 by Werner Almesberger, EPFL-LRC/ICA */ #include "atmd.h" @@ -194,12 +194,13 @@ /* --- Invocation from user ------------------------------------------------ */ -void start_sscf(SSCF_DSC *dsc,SSCF_USER_OPS *ops,void *user_data) +void start_sscf(SSCF_DSC *dsc,SSCF_USER_OPS *ops,void *user_data, + SSCOP_MODE mode) { dsc->state = sscf_11; dsc->ops = ops; dsc->user = user_data; - start_sscop(&dsc->sscop,&sscf_ops,dsc); + start_sscop(&dsc->sscop,&sscf_ops,dsc,mode); dsc->sscop.cf_max_cc = SSCF_MaxCC; dsc->sscop.cf_max_pd = SSCF_MaxPD; dsc->sscop.cf_timer_cc = SSCF_Timer_CC; diff -ur --new-file old/atm/saal/sscf.h new/atm/saal/sscf.h --- old/atm/saal/sscf.h Fri Oct 6 11:33:07 1995 +++ new/atm/saal/sscf.h Wed Sep 23 19:49:35 1998 @@ -1,6 +1,6 @@ /* sscf.h - SSCF (Q.2130) user interface */ -/* Written 1995 by Werner Almesberger, EPFL-LRC */ +/* Written 1995,1998 by Werner Almesberger, EPFL-LRC/ICA */ #ifndef SSCF_H @@ -40,7 +40,8 @@ /* Attach/detach protocol */ -void start_sscf(SSCF_DSC *dsc,SSCF_USER_OPS *ops,void *user_data); +void start_sscf(SSCF_DSC *dsc,SSCF_USER_OPS *ops,void *user_data, + SSCOP_MODE _mode); /* gcc 2.7.2 firmly believes "mode" can shadow ... @%! */ void stop_sscf(SSCF_DSC *dsc); /* Connection control */ diff -ur --new-file old/atm/saal/sscop.c new/atm/saal/sscop.c --- old/atm/saal/sscop.c Wed Mar 4 16:40:59 1998 +++ new/atm/saal/sscop.c Mon Sep 14 17:38:25 1998 @@ -170,7 +170,8 @@ case SSCOP_BGN: case SSCOP_RS: case SSCOP_ER: - *trailer++ = SSCOP_TRAIL(0,0,dsc->vt_sq); + *trailer++ = dsc->mode == sscop_qsaal1 ? SSCOP_TRAIL(0,0,0) : + SSCOP_TRAIL(0,0,dsc->vt_sq); *trailer++ = SSCOP_TRAIL(type,pad,dsc->vr_mr); break; case SSCOP_BGAK: @@ -392,6 +393,7 @@ static int detect_retransmission(SSCOP_DSC *dsc,int sq) /* 20.50 */ { + if (dsc->mode == sscop_qsaal1) return 0; if (dsc->vr_sq == sq) return 1; dsc->vr_sq = sq; return 0; @@ -1670,7 +1672,8 @@ } -void start_sscop(SSCOP_DSC *dsc,SSCOP_USER_OPS *ops,void *user_data) +void start_sscop(SSCOP_DSC *dsc,SSCOP_USER_OPS *ops,void *user_data, + SSCOP_MODE mode) { static int initialize = 1; @@ -1681,6 +1684,7 @@ } dsc->ops = ops; dsc->user = user_data; + dsc->mode = mode; dsc->vt_sq = dsc->vr_sq = 0; /* 20.5 */ dsc->clear_buffers = 1; dsc->state = sscop_idle; diff -ur --new-file old/atm/saal/sscop.h new/atm/saal/sscop.h --- old/atm/saal/sscop.h Fri Feb 27 19:36:47 1998 +++ new/atm/saal/sscop.h Wed Sep 23 19:49:43 1998 @@ -12,6 +12,11 @@ #include "queue.h" +typedef enum { + sscop_qsaal1, /* emulate some properties of Q.SAAL1 as specified for + UNI 3.0 */ + sscop_q2110 /* follow Q.2110 by the letter */ +} SSCOP_MODE; typedef enum { sscop_idle,sscop_outconn,sscop_inconn,sscop_outdisc, sscop_outres,sscop_inres,sscop_outrec,sscop_recresp,sscop_inrec, @@ -22,6 +27,7 @@ struct _sscop_user_ops *ops; void *user; /* --- Configurable parameters ----------------------------------------- */ + SSCOP_MODE mode; int cf_max_cc,cf_max_pd,cf_max_stat; int cf_timer_cc,cf_timer_poll,cf_timer_noresp,cf_timer_keepalive, cf_timer_idle; @@ -97,7 +103,8 @@ /* Attach/detach protocol */ -void start_sscop(SSCOP_DSC *dsc,SSCOP_USER_OPS *ops,void *user_data); +void start_sscop(SSCOP_DSC *dsc,SSCOP_USER_OPS *ops,void *user_data, + SSCOP_MODE _mode); /* gcc 2.7.2 firmly believes "mode" can shadow ... @%! */ void stop_sscop(SSCOP_DSC *dsc); /* Connection control */ diff -ur --new-file old/atm/sigd/atmsigd.c new/atm/sigd/atmsigd.c --- old/atm/sigd/atmsigd.c Thu Aug 20 18:04:24 1998 +++ new/atm/sigd/atmsigd.c Mon Sep 14 17:38:43 1998 @@ -434,7 +434,13 @@ init_current_time(); if (mode != sm_switch) init_addr(); q_start(); - start_saal(&saal,&ops,NULL); + start_saal(&saal,&ops,NULL, +#ifdef UNI30 + sscop_qsaal1 +#else + sscop_q2110 +#endif + ); saal_estab_req(&saal,NULL,0); setup_signals(); if (background) { diff -ur --new-file old/atm/sigd/io.c new/atm/sigd/io.c --- old/atm/sigd/io.c Thu Aug 20 18:04:24 1998 +++ new/atm/sigd/io.c Wed Sep 23 20:02:07 1998 @@ -226,7 +226,7 @@ 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((struct sockaddr *) buffer+i, + 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) diff -ur --new-file old/atm/sigd/kernel.c new/atm/sigd/kernel.c --- old/atm/sigd/kernel.c Thu Aug 20 18:04:24 1998 +++ new/atm/sigd/kernel.c Mon Sep 7 15:37:16 1998 @@ -115,14 +115,16 @@ q_assign(&dsc,QF_msg_type,ATM_MSG_CONNECT); q_assign(&dsc,QF_call_ref,sock->call_ref); if (sock->ep_ref >= 0) q_assign(&dsc,QF_ep_ref,sock->ep_ref); - q_assign(&dsc,QF_aal_type,5); + if (sock->ep_ref <= 0) { /* no AAL parameters if ep_ref present and != 0 */ + q_assign(&dsc,QF_aal_type,5); #ifdef UNI30 - q_assign(&dsc,QF_aal_mode,1); /* Message mode - LANE seems to really want - this */ + q_assign(&dsc,QF_aal_mode,1); /* Message mode - LANE seems to really + want this */ #endif - q_assign(&dsc,QF_sscs_type,0); /* unspecified - LANE wants this */ - q_assign(&dsc,QF_fw_max_sdu,sock->qos.rxtp.max_sdu); - q_assign(&dsc,QF_bw_max_sdu,sock->qos.txtp.max_sdu); + q_assign(&dsc,QF_sscs_type,0); /* unspecified - LANE wants this */ + q_assign(&dsc,QF_fw_max_sdu,sock->qos.rxtp.max_sdu); + q_assign(&dsc,QF_bw_max_sdu,sock->qos.txtp.max_sdu); + } if ((size = q_close(&dsc)) >= 0) to_signaling(q_buffer,size); return 0; } diff -ur --new-file old/atm/sigd.new/atmsigd.c new/atm/sigd.new/atmsigd.c --- old/atm/sigd.new/atmsigd.c Fri Aug 21 00:07:18 1998 +++ new/atm/sigd.new/atmsigd.c Wed Sep 16 19:27:57 1998 @@ -458,7 +458,13 @@ q_start(); for (sig = entities; sig; sig = sig->next) { if (sig->mode != sm_switch) init_addr(sig); - start_saal(&sig->saal,&ops,sig); + start_saal(&sig->saal,&ops,sig, +#ifdef UNI30 + sscop_qsaal1 +#else + sscop_q2110 +#endif + ); saal_estab_req(&sig->saal,NULL,0); } setup_signals(); diff -ur --new-file old/atm/sigd.new/io.c new/atm/sigd.new/io.c --- old/atm/sigd.new/io.c Thu Aug 20 23:05:40 1998 +++ new/atm/sigd.new/io.c Wed Sep 23 19:45:35 1998 @@ -238,7 +238,7 @@ 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((struct sockaddr *) buffer+i, + 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_LOCAL_ADDRS-1) diff -ur --new-file old/atm/sigd.new/kernel.c new/atm/sigd.new/kernel.c --- old/atm/sigd.new/kernel.c Thu Aug 20 23:58:42 1998 +++ new/atm/sigd.new/kernel.c Wed Sep 16 19:29:12 1998 @@ -126,14 +126,16 @@ q_assign(&dsc,QF_msg_type,ATM_MSG_CONNECT); q_assign(&dsc,QF_call_ref,sock->call_ref); if (sock->ep_ref >= 0) q_assign(&dsc,QF_ep_ref,sock->ep_ref); - q_assign(&dsc,QF_aal_type,5); + if (sock->ep_ref <= 0) { /* no AAL parameters if ep_ref present and != 0 */ + q_assign(&dsc,QF_aal_type,5); #ifdef UNI30 - q_assign(&dsc,QF_aal_mode,1); /* Message mode - LANE seems to really want - this */ + q_assign(&dsc,QF_aal_mode,1); /* Message mode - LANE seems to really + want this */ #endif - q_assign(&dsc,QF_sscs_type,0); /* unspecified - LANE wants this */ - q_assign(&dsc,QF_fw_max_sdu,sock->qos.rxtp.max_sdu); - q_assign(&dsc,QF_bw_max_sdu,sock->qos.txtp.max_sdu); + q_assign(&dsc,QF_sscs_type,0); /* unspecified - LANE wants this */ + q_assign(&dsc,QF_fw_max_sdu,sock->qos.rxtp.max_sdu); + q_assign(&dsc,QF_bw_max_sdu,sock->qos.txtp.max_sdu); + } if ((size = q_close(&dsc)) >= 0) to_signaling(sock->sig,q_buffer,size); return 0; } diff -ur --new-file old/atm/switch/cfg.l new/atm/switch/cfg.l --- old/atm/switch/cfg.l Wed Jun 24 12:39:36 1998 +++ new/atm/switch/cfg.l Wed Sep 9 20:41:59 1998 @@ -27,6 +27,8 @@ %% BEGIN(N); +option { BEGIN(P); + token = TOK_OPTION; } command return TOK_COMMAND; socket { BEGIN(P); token = TOK_SOCKET; } diff -ur --new-file old/atm/switch/cfg.y new/atm/switch/cfg.y --- old/atm/switch/cfg.y Wed Jun 24 13:16:32 1998 +++ new/atm/switch/cfg.y Wed Sep 9 19:46:19 1998 @@ -10,6 +10,7 @@ #include "atm.h" +#include "fab.h" #include "sig.h" #include "route.h" @@ -27,7 +28,7 @@ %token TOK_COMMAND TOK_VPCI TOK_ITF TOK_DEFAULT -%token TOK_ROUTE TOK_STR TOK_SOCKET +%token TOK_ROUTE TOK_STR TOK_SOCKET TOK_OPTION %token TOK_NUM %token TOK_PVC @@ -36,7 +37,15 @@ %% all: + | option all | sig all + ; + +option: + TOK_OPTION TOK_STR + { + fab_option($1,$2); + } ; sig: diff -ur --new-file old/atm/switch/debug/debug.c new/atm/switch/debug/debug.c --- old/atm/switch/debug/debug.c Tue Aug 4 19:55:44 1998 +++ new/atm/switch/debug/debug.c Wed Sep 9 19:46:55 1998 @@ -26,6 +26,12 @@ static CALL *calls; +void fab_option(const char *name,const char *value) +{ + diag(COMPONENT,DIAG_FATAL,"unrecognized fabric option \"%s\"",name); +} + + void fab_start(void (*port_notify)(int number,int up)) { } diff -ur --new-file old/atm/switch/fab.h new/atm/switch/fab.h --- old/atm/switch/fab.h Wed Aug 12 12:09:26 1998 +++ new/atm/switch/fab.h Wed Sep 9 19:47:39 1998 @@ -30,6 +30,15 @@ /* --- Provided by fabric control ------------------------------------------ */ /* + * fab_option passes an option name/value pair from the configuration file to + * the fabric control. fab_option is invoked once for each "option" clause in + * the configuration file. All invocations of fab_option occur before + * fab_start. + */ + +void fab_option(const char *name,const char *value); + +/* * Initialize the fabric interface. The fabric control invokes port_notify * whenever a port is added to or removed from the switch. fab_start may * invoke port_notify before returning. port_notify(X,0) most not be invoked diff -ur --new-file old/atm/switch/tcp/Makefile new/atm/switch/tcp/Makefile --- old/atm/switch/tcp/Makefile Tue Aug 4 19:55:00 1998 +++ new/atm/switch/tcp/Makefile Wed Sep 9 20:12:18 1998 @@ -2,9 +2,12 @@ LIBDEPS=../../lib/libatmd.a ../libsw.a INCLUDES=-I../../qgen OBJS=tcpsw.o -SYSPGMS=sw_tcp +SYSPGMS=sw_tcp tcpswc include ../Rules.make + +tcpswc: tcpswc.o + $(CC) $(LDFLAGS) -o tcpswc tcpswc.o $(LIBS) $(LDLIBS) sw_tcp: $(OBJS) $(CC) $(LDFLAGS) -o sw_tcp $(OBJS) $(LIBS) $(LDLIBS) diff -ur --new-file old/atm/switch/tcp/README new/atm/switch/tcp/README --- old/atm/switch/tcp/README Thu Jun 25 13:54:51 1998 +++ new/atm/switch/tcp/README Wed Sep 9 21:19:03 1998 @@ -105,3 +105,13 @@ | +---------------+ | atmsigd 1.0.5 | | +---------------+ + +In order to control the switch with tcpswc, add the line + option control "" +to switch.conf, e.g. + option control "/var/run/tcpswc" + +Then invoke tcpswc as follows: + tcpswc show + +To add VCs, use add .. , to add VPs, use add ..? diff -ur --new-file old/atm/switch/tcp/tcpsw.c new/atm/switch/tcp/tcpsw.c --- old/atm/switch/tcp/tcpsw.c Tue Aug 4 19:56:13 1998 +++ new/atm/switch/tcp/tcpsw.c Wed Sep 9 21:11:54 1998 @@ -19,6 +19,7 @@ #include "uni.h" #include "../fab.h" #include "../dispatch.h" +#include "tcpswc.h" #define COMPONENT "FAB(tcp)" @@ -35,7 +36,7 @@ typedef struct _table { struct _link *out; /* output port */ uint16_t in_vpi; /* input VPI */ - int in_vci; /* input VCI */ + int in_vci; /* input VCI (may be ATM_VCI_ANY) */ uint16_t out_vpi; /* output VPI */ uint16_t out_vci; /* output VCI */ struct _table *next; @@ -60,6 +61,7 @@ static CALL *calls = NULL; static LINK *links = NULL; static void (*notify)(int number,int up); +static int s_control = -1; static LINK *find_link(int id) @@ -314,6 +316,74 @@ } +static int msg_handler(void *buf,int len,void *user) +{ + TCPSWC_MSG *msg = buf; + LINK *lnk; + TABLE *entry; + int i; + + if (len != sizeof(TCPSWC_MSG)) + diag(COMPONENT,DIAG_FATAL,"msg_handler: bad length (%d != %d)",len, + sizeof(TCPSWC_MSG)); + switch (msg->type) { + case tmt_get: + i = msg->n; + for (lnk = links; lnk; lnk = lnk->next) { + for (entry = lnk->table; i && entry; entry = entry->next) i--; + if (!i && entry) break; + } + if (!lnk || !entry) { + msg->n = -ENOENT; + break; + } + memset(&msg->in,0,sizeof(msg->in)); + msg->in.sap_family = AF_ATMPVC; + msg->in.sap_addr.itf = lnk->id; + msg->in.sap_addr.vpi = entry->in_vpi; + msg->in.sap_addr.vci = entry->in_vci; + memset(&msg->out,0,sizeof(msg->out)); + msg->out.sap_family = AF_ATMPVC; + msg->out.sap_addr.itf = entry->out->id; + msg->out.sap_addr.vpi = entry->out_vpi; + msg->out.sap_addr.vci = entry->out_vci; + memset(&msg->qos,0,sizeof(msg->qos)); + break; + case tmt_add: + msg->n = add_entry(&msg->in,&msg->out); + break; + case tmt_del: + msg->n = del_entry(&msg->in,&msg->out); + break; + default: + diag(COMPONENT,DIAG_FATAL,"msg_handler: unknown message type %d", + msg->type); + } + return sizeof(TCPSWC_MSG); +} + + +static void control_msg(int sock,void *dummy) +{ + TCPSWC_MSG msg; + + if (un_reply(sock,&msg,sizeof(msg),&msg_handler,NULL) < 0) + diag(COMPONENT,DIAG_ERROR,"un_reply: %s",strerror(errno)); +} + + +void fab_option(const char *name,const char *value) +{ + if (strcmp(name,"control")) + diag(COMPONENT,DIAG_FATAL,"unrecognized fabric option \"%s\"",name); + if (s_control != -1) + diag(COMPONENT,DIAG_FATAL,"control channel is already set"); + s_control = un_create(value,0600); + if (s_control < 0) + diag(COMPONENT,DIAG_FATAL,"un_create: %s",strerror(errno)); +} + + void fab_start(void (*port_notify)(int number,int up)) { struct sockaddr_in addr; @@ -330,6 +400,7 @@ if (listen(s_listen,5) < 0) diag(COMPONENT,DIAG_FATAL,"listen: %s",strerror(errno)); dsp_fd_add(s_listen,new_link,NULL); + if (s_control >= 0) dsp_fd_add(s_control,control_msg,NULL); } diff -ur --new-file old/atm/switch/tcp/tcpswc.c new/atm/switch/tcp/tcpswc.c --- old/atm/switch/tcp/tcpswc.c Thu Jan 1 01:00:00 1970 +++ new/atm/switch/tcp/tcpswc.c Wed Sep 9 21:12:14 1998 @@ -0,0 +1,110 @@ +/* tcpswc.c - ATMTCP switch control */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include +#include + +#include +#include + +#include "tcpswc.h" + + +static void dialog(int s,TCPSWC_MSG *msg) +{ + int size; + + size = write(s,msg,sizeof(*msg)); + if (size < 0) { + perror("write"); + exit(1); + } + if (size != sizeof(*msg)) { + fprintf(stderr,"bad write: %d != %d\n",size,sizeof(*msg)); + exit(1); + } + size = read(s,msg,sizeof(*msg)); + if (size < 0) { + perror("read"); + exit(1); + } + if (size != sizeof(*msg)) { + fprintf(stderr,"bad read: %d != %d\n",size,sizeof(*msg)); + exit(1); + } +} + + +static void usage(const char *name) +{ + fprintf(stderr,"usage: %s \n",name); + fprintf(stderr," commands: show\n"); + fprintf(stderr," add \n"); + fprintf(stderr," del \n"); + exit(1); +} + + +int main(int argc,const char **argv) +{ + char buffer[MAX_ATM_ADDR_LEN+1]; + TCPSWC_MSG msg; + int s; + + if (argc < 3) usage(*argv); + s = un_attach(argv[1]); + if (s < 0) { + perror(argv[1]); + return 1; + } + memset(&msg,0,sizeof(msg)); + if (!strcmp(argv[2],"show")) { + if (argc != 3) usage(*argv); + msg.type = tmt_get; + msg.n = 0; + while (1) { + dialog(s,&msg); + if (msg.type != tmt_get) { + fprintf(stderr,"unexpeced message type %d != %d\n",msg.type, + tmt_get); + } + if (msg.n < 0) return 0; + if (msg.in.sap_addr.vci != ATM_VCI_UNSPEC) printf("VC "); + else { + printf("VP "); + msg.out.sap_addr.vci = ATM_VCI_UNSPEC; + } + if (atm2text(buffer,sizeof(buffer),(struct sockaddr *) &msg.in, + A2T_PRETTY) < 0) strcpy(buffer,""); + printf("%s -> ",buffer); + if (atm2text(buffer,sizeof(buffer),(struct sockaddr *) &msg.out, + A2T_PRETTY) < 0) strcpy(buffer,""); + printf("%s\n",buffer); + msg.n++; + } + } + if (!strcmp(argv[2],"add")) msg.type = tmt_add; + else if (!strcmp(argv[2],"del")) msg.type = tmt_del; + else usage(*argv); + if (argc != 5) usage(*argv); + if (text2atm(argv[3],(struct sockaddr *) &msg.in,sizeof(msg.in), + T2A_PVC | T2A_UNSPEC | T2A_NAME) < 0) { + fprintf(stderr,"invalid PVC address: %s\n",argv[3]); + return 1; + } + if (text2atm(argv[4],(struct sockaddr *) &msg.out,sizeof(msg.out), + T2A_PVC | T2A_UNSPEC | T2A_NAME) < 0) { + fprintf(stderr,"invalid PVC address: %s\n",argv[4]); + return 1; + } + dialog(s,&msg); + if (msg.n < 0) { + fprintf(stderr,"%s\n",strerror(-msg.n)); + return 1; + } + return 0; +} diff -ur --new-file old/atm/switch/tcp/tcpswc.h new/atm/switch/tcp/tcpswc.h --- old/atm/switch/tcp/tcpswc.h Thu Jan 1 01:00:00 1970 +++ new/atm/switch/tcp/tcpswc.h Wed Sep 9 21:11:45 1998 @@ -0,0 +1,28 @@ +/* tcpswc.h - ATMTCP switch control interface */ + +/* Written 1998 by Werner Almesberger, EPFL ICA */ + + +#ifndef TCPSWC_H +#define TCPSWC_H + +#include + + +typedef enum { + tmt_invalid, /* catch uninitialized variables */ + tmt_get, /* get/return n-th entry */ + tmt_add, /* add one-way VC */ + tmt_del /* remove one-way VC */ +} TCPSWC_MSG_TYPE; + +typedef struct tcpswc_msg { + TCPSWC_MSG_TYPE type; /* message type */ + int n; /* index (for tmt_get) and error code + (for tmt_get, tmt_set, tmt_del) */ + struct sockaddr_atmpvc in; + struct sockaddr_atmpvc out; + struct atm_qos qos; /* currently unused */ +} TCPSWC_MSG; + +#endif .