diff -ur --new-file old/atm/CHANGES new/atm/CHANGES
--- old/atm/CHANGES	Tue Oct  6 13:18:50 1998
+++ new/atm/CHANGES	Fri Oct 30 19:52:05 1998
@@ -1,3 +1,39 @@
+Version 0.47 to 0.48 (30-OCT-1998)
+====================
+
+Bug fixes
+---------
+
+ - ilmid didn't recognize the -u option
+ - ATM_GETCIRANGE copied wrong amount of data (fix by Heikki Vatiainen)
+ - sch_atm didn't compile without policing enabled (reported by Calin Poenaru)
+ - BHLI octets: qgen/msg.fmt allowed nine instead of eight bytes for ISO and
+   user specified, include/linux/atmsap.h:ATM_MAX_HLI was 7 instead of 8 (by
+   Damian Gilmurray and Paisit Thamsakorn)
+ - MPOA: bug fixes and other changes, see atm/mpoa/CHANGELOG (by Heikki
+   Vatiainen)
+
+New features
+------------
+
+ - ilmid: new option -i to set local IP address (suggested by Andrew May)
+ - ilmid now also supports the MIB variables atmfAtmLayerMaxVpiBits and
+   atmfAtmLayerMaxVciBits (based on a patch by Uwe Dannowski)
+
+Other changes
+-------------
+
+ - ilmid: search for local IP address didn't consider LANE interfaces (lec*)
+ - consolidated most of the various calls to gethostbyname and friends into
+   text2ip (libatmd)
+ - corrected some glitches in net/sched/sch_atm.c (untested)
+ - removed debug/encopy, debug/endump, and debug/zndump from the distribution.
+   They were almost useless and caused problems with  make depend
+ - SYMFILES in qgen/Makefile now determines location of atmsap.h at run time to
+   avoid problems when kernel headers are not in /usr/include/linux (reported
+   by Uwe Dannowski)
+
+
 Version 0.46 to 0.47 (6-OCT-1998)
 ====================
 
diff -ur --new-file old/atm/README new/atm/README
--- old/atm/README	Tue Oct  6 13:12:59 1998
+++ new/atm/README	Thu Oct  8 18:03:39 1998
@@ -1,4 +1,4 @@
-ATM on Linux, release 0.47 (alpha)        by Werner Almesberger, EPFL ICA
+ATM on Linux, release 0.48 (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/USAGE new/atm/USAGE
--- old/atm/USAGE	Tue Oct  6 13:13:49 1998
+++ new/atm/USAGE	Thu Oct  8 18:10:58 1998
@@ -1,4 +1,4 @@
-Usage instructions  -  ATM on Linux, release 0.47
+Usage instructions  -  ATM on Linux, release 0.48
 -------------------------------------------------
 
 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.47.tar.gz  
+    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.48.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.47.tar.gz
+tar xfz atm-0.48.tar.gz
 
 and the kernel source:
 
diff -ur --new-file old/atm/VERSION new/atm/VERSION
--- old/atm/VERSION	Tue Oct  6 13:13:06 1998
+++ new/atm/VERSION	Thu Oct  8 17:26:11 1998
@@ -1 +1 @@
-0.47
+0.48
diff -ur --new-file old/atm/arpd/atmarp.c new/atm/arpd/atmarp.c
--- old/atm/arpd/atmarp.c	Tue Jul 28 16:02:48 1998
+++ new/atm/arpd/atmarp.c	Thu Oct  8 16:09:20 1998
@@ -117,7 +117,6 @@
 
 int main(int argc,char **argv)
 {
-    struct hostent *hostent;
     struct atmarp_req req;
     int c,i,num;
     char *here,*end;
@@ -184,23 +183,8 @@
 	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.ip = text2ip(argv[optind],NULL,T2I_NAME | T2I_ERROR);
+    if (req.ip == INADDR_NONE) return 1;
     req.flags = ATF_PERM;
     if (req.type == art_qos)
 	if (text2qos(argv[optind+1],&req.qos,0)) usage(argv[0]);
diff -ur --new-file old/atm/atm.patch new/atm/atm.patch
--- old/atm/atm.patch	Mon Oct  5 19:22:26 1998
+++ new/atm/atm.patch	Fri Oct 30 20:03:50 1998
@@ -2984,7 +2984,7 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/drivers/atm/eni.h	Thu Oct  1 17:09:22 1998
++++ work/drivers/atm/eni.h	Fri Oct 30 20:09:44 1998
 @@ -0,0 +1,115 @@
 +/* drivers/atm/eni.h - Efficient Networks ENI155P device driver declarations */
 + 
@@ -3370,7 +3370,7 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/drivers/atm/nicstar.h	Thu Oct  1 17:09:30 1998
++++ work/drivers/atm/nicstar.h	Wed Oct  7 15:02:19 1998
 @@ -0,0 +1,753 @@
 +/******************************************************************************
 + *
@@ -10558,7 +10558,7 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/drivers/atm/suni.h	Thu Oct  1 17:09:20 1998
++++ work/drivers/atm/suni.h	Fri Oct 30 20:09:41 1998
 @@ -0,0 +1,210 @@
 +/* drivers/atm/suni.h - PMC SUNI (PHY) declarations */
 + 
@@ -13303,7 +13303,7 @@
 + 
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/drivers/atm/zatm.h	Thu Oct  1 17:09:26 1998
++++ work/drivers/atm/zatm.h	Fri Oct 30 20:09:47 1998
 @@ -0,0 +1,137 @@
 +/* drivers/atm/zatm.h - ZeitNet ZN122x device driver declarations */
 +
@@ -13500,7 +13500,7 @@
  #ifdef CONFIG_VT
  	console_map_init();
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/include/linux/arequipa.h	Thu Oct  1 17:13:53 1998
++++ work/include/linux/arequipa.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,63 @@
 +/* arequipa.h - Arequipa interface definitions */
 + 
@@ -13566,7 +13566,7 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/include/linux/atm.h	Fri Aug 21 00:52:28 1998
++++ work/include/linux/atm.h	Fri Oct 30 20:09:41 1998
 @@ -0,0 +1,239 @@
 +/* atm.h - general ATM declarations */
 + 
@@ -14082,7 +14082,7 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/include/linux/atmdev.h	Thu Oct  1 17:09:20 1998
++++ work/include/linux/atmdev.h	Fri Oct 30 20:09:41 1998
 @@ -0,0 +1,324 @@
 +/* atmdev.h - ATM device driver declarations */
 + 
@@ -14451,7 +14451,7 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/include/linux/atmlec.h	Fri Aug 21 00:52:28 1998
++++ work/include/linux/atmlec.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,70 @@
 +/*
 + * 
@@ -14524,7 +14524,7 @@
 +};
 +#endif /* _ATMLEC_H_ */
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/include/linux/atmmpc.h	Mon Oct  5 13:18:01 1998
++++ work/include/linux/atmmpc.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,99 @@
 +#ifndef _ATMMPC_H_
 +#define _ATMMPC_H_
@@ -14573,7 +14573,7 @@
 +                in_ctrl_info in_info;
 +                eg_ctrl_info eg_info;
 +        } content;
-+        struct atm_qos qos;            /* only used with content.in_info */
++        struct atm_qos qos;       
 +} k_message;
 +
 +struct llc_snap_hdr { /* RFC 1483 LLC/SNAP encapsulation for routed IP PDUs */
@@ -14626,7 +14626,7 @@
 +#endif /* _ATMMPC_H_ */
 +
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/include/linux/atmsap.h	Fri Aug 21 00:52:28 1998
++++ work/include/linux/atmsap.h	Fri Oct 30 18:49:44 1998
 @@ -0,0 +1,161 @@
 +/* atmsap.h - ATM Service Access Point addressing definitions */
 +
@@ -14725,7 +14725,7 @@
 + * SAP structures
 + */
 +
-+#define ATM_MAX_HLI	7	/* maximum high-layer information length */
++#define ATM_MAX_HLI	8	/* maximum high-layer information length */
 +
 +
 +struct atm_blli {
@@ -14790,7 +14790,7 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/include/linux/atmsvc.h	Fri Aug 21 00:52:28 1998
++++ work/include/linux/atmsvc.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,52 @@
 +/* atmsvc.h - ATM signaling kernel-demon interface definitions */
 + 
@@ -14845,7 +14845,7 @@
 +
 +#endif
 --- ref/include/linux/capability.h	Thu Aug 20 01:38:43 1998
-+++ work/include/linux/capability.h	Fri Aug 21 00:55:14 1998
++++ work/include/linux/capability.h	Sun Oct 11 23:59:08 1998
 @@ -121,6 +121,7 @@
  #define CAP_LINUX_IMMUTABLE  9
  
@@ -14863,7 +14863,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	Thu Oct  1 17:09:00 1998
++++ work/include/linux/if_arp.h	Mon Oct 12 00:00:25 1998
 @@ -35,6 +35,7 @@
  #define	ARPHRD_ARCNET	7		/* ARCnet			*/
  #define	ARPHRD_APPLETLK	8		/* APPLEtalk			*/
@@ -14903,7 +14903,7 @@
 +
  #endif
 --- ref/include/linux/skbuff.h	Thu Aug 20 01:38:56 1998
-+++ work/include/linux/skbuff.h	Thu Oct  1 17:08:53 1998
++++ work/include/linux/skbuff.h	Sun Oct 11 23:59:14 1998
 @@ -106,6 +106,25 @@
  	__u32		shapestamp;		/* Stamp for shaper    */
  	__u16		shapepend;		/* Pending */
@@ -14986,7 +14986,7 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/include/net/atmclip.h	Thu Oct  1 17:12:48 1998
++++ work/include/net/atmclip.h	Fri Oct 30 20:10:05 1998
 @@ -0,0 +1,62 @@
 +/* net/atm/atmarp.h - RFC1577 ATM ARP */
 + 
@@ -15206,8 +15206,8 @@
  	tc_filter_init();
  #endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/sched/sch_atm.c	Thu Oct  1 17:06:05 1998
-@@ -0,0 +1,601 @@
++++ work/net/sched/sch_atm.c	Thu Oct 29 16:29:26 1998
+@@ -0,0 +1,611 @@
 +/* net/sched/sch_atm.c - ATM VC selection "queueing discipline" */
 +
 +/* Written 1998 by Werner Almesberger, EPFL ICA */
@@ -15305,6 +15305,17 @@
 +}
 +
 +
++static __inline__ struct atm_flow_data *lookup_flow(struct Qdisc *sch,
++    u32 classid)
++{
++	struct atm_flow_data *flow;
++
++        for (flow = PRIV(sch)->flows; flow; flow = flow->next)
++		if (flow->classid == classid) break;
++	return flow;
++}
++
++
 +static int atm_tc_graft(struct Qdisc *sch,unsigned long arg,
 +    struct Qdisc *new,struct Qdisc **old)
 +{
@@ -15316,6 +15327,7 @@
 +	if (!find_flow(p,flow)) return -EINVAL;
 +	if (!new) new = &noop_qdisc;
 +	*old = xchg(&flow->q,new);
++	if (*old) qdisc_reset(*old);
 +        return 0;
 +}
 +
@@ -15323,11 +15335,10 @@
 +static unsigned long atm_tc_get(struct Qdisc *sch,u32 classid)
 +{
 +	struct atm_qdisc_data *p = PRIV(sch);
-+        struct atm_flow_data *flow;
++	struct atm_flow_data *flow;
 +
 +	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;
++	flow = lookup_flow(sch,classid);
 +        if (flow) flow->ref++;
 +	DPRINTK("atm_tc_get: flow %p\n",flow);
 +	return (unsigned long) flow;
@@ -15539,7 +15550,7 @@
 +static int atm_tc_enqueue(struct sk_buff *skb,struct Qdisc *sch)
 +{
 +	struct atm_qdisc_data *p = PRIV(sch);
-+	struct atm_flow_data *flow;
++	struct atm_flow_data *flow = NULL ; /* @@@ */
 +	struct tcf_result res;
 +	int result;
 +
@@ -15551,7 +15562,10 @@
 +			if (flow->filter_list) {
 +				result = tc_classify(skb,flow->filter_list,
 +				    &res);
-+				if (result >= 0) break;
++				if (result < 0) continue;
++				flow = (struct atm_flow_data *) res.class;
++				if (!flow) flow = lookup_flow(sch,res.classid);
++				break;
 +			}
 +	if (!flow) flow = &p->link;
 +	else {
@@ -15576,8 +15590,8 @@
 +			default:
 +				break;
 +		}
-+	}
 +#endif
++	}
 +	if (
 +#ifdef CONFIG_NET_CLS_POLICE
 +	    result == TC_POLICE_SHOT ||
@@ -15690,10 +15704,6 @@
 +	DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n",sch,p);
 +	/* races ? */
 +	while ((flow = p->flows)) {
-+		struct tcf_proto *filter;
-+
-+		for (filter = flow->filter_list; filter; filter = filter->next)
-+			filter->ops->destroy(filter);
 +		if (flow->ref > 1)
 +			printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow,
 +			    flow->ref);
@@ -16039,7 +16049,7 @@
 +	return total;
 +}
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/addr.h	Thu Oct  1 17:13:53 1998
++++ work/net/atm/addr.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,18 @@
 +/* net/atm/addr.h - Local ATM address registry */
 +
@@ -16715,7 +16725,7 @@
 +	return 0;
 +}
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/common.c	Thu Oct  1 16:32:39 1998
++++ work/net/atm/common.c	Thu Oct 29 16:03:28 1998
 @@ -0,0 +1,926 @@
 +/* net/atm/common.c - ATM sockets (common part for PVC and SVC) */
 +
@@ -17448,7 +17458,7 @@
 +			if (error) return error;
 +			break;
 +		case ATM_GETCIRANGE:
-+			size = sizeof(sizeof(struct atm_cirange));
++			size = sizeof(struct atm_cirange);
 +			if (copy_to_user(buf,&dev->ci_range,size))
 +				return -EFAULT;
 +			break;
@@ -17644,7 +17654,7 @@
 +	return atm_do_getsockopt(sock,level,optname,optval,len);
 +}
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/common.h	Fri Aug 21 01:14:05 1998
++++ work/net/atm/common.h	Mon Oct 12 00:09:43 1998
 @@ -0,0 +1,46 @@
 +/* net/atm/common.h - ATM sockets (common part for PVC and SVC) */
 + 
@@ -17748,7 +17758,7 @@
 +	skb_queue_head_init(from);
 +}
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/ipcommon.h	Thu Oct  1 17:13:58 1998
++++ work/net/atm/ipcommon.h	Fri Oct 30 20:10:16 1998
 @@ -0,0 +1,21 @@
 +/* net/atm/ipcommon.h - Common items for all ways of doing IP over ATM */
 +
@@ -19954,7 +19964,7 @@
 +}
 +
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/lec.h	Thu Oct  1 17:13:53 1998
++++ work/net/atm/lec.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,143 @@
 +/*
 + *
@@ -20100,7 +20110,7 @@
 +#endif _LEC_H_
 +
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/lec_arpc.h	Thu Oct  1 17:13:53 1998
++++ work/net/atm/lec_arpc.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,112 @@
 +/*
 + * Lec arp cache
@@ -20215,8 +20225,8 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/mpc.c	Mon Oct  5 13:19:34 1998
-@@ -0,0 +1,1455 @@
++++ work/net/atm/mpc.c	Fri Oct 30 19:58:28 1998
+@@ -0,0 +1,1485 @@
 +#include <linux/kernel.h>
 +#include <linux/string.h>
 +#include <linux/timer.h>
@@ -20282,6 +20292,7 @@
 +
 +static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry);
 +
++static void send_set_mps_ctrl_addr(char *addr, struct mpoa_client *mpc);
 +static void mpoad_close(struct atm_vcc *vcc);
 +static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb);
 +
@@ -20370,12 +20381,18 @@
 + */
 +
 +/*
-+ * Returns the new entry. Note the use of the 2nd argument
++ * Overwrites the old entry or makes a new one.
 + */
 +struct atm_mpoa_qos *atm_mpoa_add_qos(uint32_t dst_ip, struct atm_qos *qos)
 +{
 +        struct atm_mpoa_qos *entry;
 +
++        entry = atm_mpoa_search_qos(dst_ip);
++        if (entry != NULL) {
++                entry->qos = *qos;
++                return entry;
++        }
++
 +        entry = kmalloc(sizeof(struct atm_qos), GFP_KERNEL);
 +        if (entry == NULL) {
 +                printk("mpoa: atm_mpoa_add_qos: out of memory\n");
@@ -20577,8 +20594,6 @@
 +{
 +        uint32_t type;
 +        uint8_t length, mpoa_device_type, number_of_mps_macs;
-+        struct k_message *mesg;
-+        struct sk_buff *skb;
 +        uint8_t *end_of_tlvs;
 +        struct mpoa_client *mpc;
 +        
@@ -20660,17 +20675,7 @@
 +                printk("this MPS has %d MAC addresses\n", number_of_mps_macs);
 +                
 +                /* ok, now we can go and tell our daemon the control address of MPS */
-+                skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC);
-+                if (skb == NULL) {
-+                        printk("mpoa: (%s) lane2_assoc_ind: alloc_skb()\n", dev->name);
-+                        return;
-+                }
-+                memcpy (mpc->mps_ctrl_addr, tlvs, ATM_ESA_LEN);
-+
-+                mesg  = (struct k_message *)skb->data;
-+                mesg->type = SET_MPS_CTRL_ADDR;
-+                memcpy(mesg->MPS_ctrl, tlvs, ATM_ESA_LEN);
-+                msg_to_mpoad(mesg, mpc);
++                send_set_mps_ctrl_addr(tlvs, mpc);
 +                
 +                tlvs += 20; if (mpoa_device_type == MPS_AND_MPC) tlvs += 20;
 +                /* collect the MPS MAC addresses */
@@ -21033,13 +21038,43 @@
 +        mpc->mpoad_vcc = vcc;
 +        bind_vcc(vcc, &mpc_dev);
 +        vcc->flags |= ATM_VF_READY | ATM_VF_META;
-+        if (mpc->dev)
++
++        if (mpc->dev) {
++                char empty[ATM_ESA_LEN];
++                memset(empty, 0, ATM_ESA_LEN);
++                
 +                start_mpc(mpc, mpc->dev);
-+        MOD_INC_USE_COUNT;
++                /* set address if mpcd e.g. gets killed and restarted.
++                 * If we do not do it now we have to wait for the next LE_ARP
++                 */
++                if ( memcmp(mpc->mps_ctrl_addr, empty, ATM_ESA_LEN) != 0 )
++                        send_set_mps_ctrl_addr(mpc->mps_ctrl_addr, mpc);
++        }
 +
++        MOD_INC_USE_COUNT;
 +        return arg;
 +}
 +
++static void send_set_mps_ctrl_addr(char *addr, struct mpoa_client *mpc)
++{
++        struct sk_buff *skb;
++        struct k_message *mesg;
++
++        skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC);
++        if (skb == NULL) {
++                printk("mpoa: (%s) lane2_assoc_ind: alloc_skb()\n", mpc->dev->name);
++                return;
++        }
++        memcpy (mpc->mps_ctrl_addr, addr, ATM_ESA_LEN);
++        
++        mesg  = (struct k_message *)skb->data;
++        mesg->type = SET_MPS_CTRL_ADDR;
++        memcpy(mesg->MPS_ctrl, addr, ATM_ESA_LEN);
++        msg_to_mpoad(mesg, mpc);
++
++        return;
++}
++
 +static void mpoad_close(struct atm_vcc *vcc)
 +{
 +        unsigned long flags;
@@ -21323,23 +21358,28 @@
 +	 * in egress cache. If none found, ask daemon to create one.
 +	 */
 +	eg_entry = client->eg_ops->search_by_src_ip(dst_ip, client);
-+	if (eg_entry != NULL) {
-+		ip = (unsigned char *)&dst_ip;
-+		entry->shortcut = eg_entry->shortcut;
-+		dprintk("mpoa: (%s) using egress SVC to reach %d.%d.%d.%d\n",
-+			client->dev->name, ip[0], ip[1], ip[2], ip[3]);
-+
++	if (eg_entry != NULL && eg_entry->shortcut) {
++	  /* FIXME: Is it enough to just look at the max_pcr-value? */
++	        if(eg_entry->shortcut->qos.txtp.traffic_class == ATM_UBR || (eg_entry->shortcut->qos.txtp.traffic_class == ATM_CBR && eg_entry->shortcut->qos.txtp.max_pcr > 0)){
++		          entry->shortcut = eg_entry->shortcut;
++			  ip = (unsigned char *)&dst_ip;
++			  dprintk("mpoa: (%s) using egress SVC to reach %d.%d.%d.%d\n", client->dev->name, ip[0], ip[1], ip[2], ip[3]);
++		}
 +	}
-+
++	
 +	/* It is possible that there was an egress entry with no valid shortcut */
 +	if (entry->shortcut == NULL) {
 +		msg->type = OPEN_INGRESS_SVC;
 +                qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
-+                if (qos != NULL) {
++                if (qos != NULL && qos->qos.txtp.traffic_class & msg->qos.txtp.traffic_class) {
 +                        msg->qos = qos->qos;
 +                        printk("mpoa: (%s) MPOA_res_reply_rcvd: trying to get a CBR shortcut\n",
 +                               client->dev->name);
 +                }
++		else{
++		        if(qos)printk("mpoa: (%s) requested qos-parameters not supported by the other end\n",client->dev->name);
++			memset(&msg->qos,0,sizeof(struct atm_qos));
++		}
 +		msg_to_mpoad(msg, client);
 +	}
 +
@@ -21673,7 +21713,7 @@
 +
 +
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/mpc.h	Mon Oct  5 13:19:34 1998
++++ work/net/atm/mpc.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,89 @@
 +#ifndef _MPC_H_
 +#define _MPC_H_
@@ -22325,7 +22365,7 @@
 +        return;
 +}
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/mpoa_caches.h	Mon Oct  5 13:19:34 1998
++++ work/net/atm/mpoa_caches.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,90 @@
 +#ifndef MPOA_CACHES_H
 +#define MPOA_CACHES_H
@@ -22418,8 +22458,8 @@
 +
 +#endif
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/mpoa_proc.c	Mon Oct  5 13:19:34 1998
-@@ -0,0 +1,393 @@
++++ work/net/atm/mpoa_proc.c	Fri Oct 30 19:58:49 1998
+@@ -0,0 +1,388 @@
 +#include <linux/config.h>
 +
 +#ifdef CONFIG_PROC_FS
@@ -22679,7 +22719,7 @@
 +static int parse_qos(const char *buff, int len)
 +{
 +        /* possible lines look like this
-+         * add 130.230.54.142 tx=max_pcr,pcr,min_pcr,max_cdv,max_sdu rx=max_pcr,pcr,min_pcr,max_cdv,max_sd
++         * add 130.230.54.142 tx=max_pcr,max_cdv,max_sdu rx=max_pcr,max_cdv,max_sdu
 +         */
 +        
 +        int pos, i;
@@ -22690,12 +22730,12 @@
 +	struct atm_qos qos; 
 +	int value[5];
 +        
-+	pos = 0;
++        memset(&qos, 0, sizeof(struct atm_qos));
 +        strncpy(cmd, buff, 3);
-+	if( strncmp(cmd,"add", 3) &&  strncmp(cmd,"del", 3))
++        if( strncmp(cmd,"add", 3) &&  strncmp(cmd,"del", 3))
 +	        return 0;  /* not add or del */
 +
-+	pos += 4;
++	pos = 4;
 +        /* next parse ip */
 +        prev = buff + pos;
 +        for (i = 0; i < 3; i++) {
@@ -22716,11 +22756,13 @@
 +                
 +	if(!strncmp(cmd, "del", 3))
 +	         return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
++
++        /* next transmit values */
 +	tmp = strstr(buff, "tx=");
 +	if(tmp == NULL) return 0;
 +	tmp += 3;
 +	prev = tmp;
-+	for( i = 0; i < 4; i++){
++	for( i = 0; i < 2; i++){
 +	         tmp = strchr(prev, ',');
 +		 if (tmp == NULL) return 0;
 +		 memset(temp, '\0', 256);
@@ -22736,16 +22778,15 @@
 +        value[i] = (int)simple_strtoul(temp, NULL, 0);
 +	qos.txtp.traffic_class = ATM_CBR;
 +	qos.txtp.max_pcr = value[0];
-+        qos.txtp.pcr = value[1];
-+	qos.txtp.min_pcr = value[2];
-+	qos.txtp.max_cdv = value[3];
-+	qos.txtp.max_sdu = value[4];
++	qos.txtp.max_cdv = value[1];
++	qos.txtp.max_sdu = value[2];
 +
++        /* next receive values */
 +	tmp = strstr(buff, "rx=");
 +	if(tmp == NULL) return 0;
 +	tmp += 3;
 +	prev = tmp;
-+	for( i = 0; i < 4; i++){
++	for( i = 0; i < 2; i++){
 +	         tmp = strchr(prev, ',');
 +		 if (tmp == NULL) return 0;
 +		 memset(temp, '\0', 256);
@@ -22761,19 +22802,13 @@
 +        value[i] = (int)simple_strtoul(temp, NULL, 0);
 +	qos.rxtp.traffic_class = ATM_CBR;
 +	qos.rxtp.max_pcr = value[0];
-+        qos.rxtp.pcr = value[1];
-+	qos.rxtp.min_pcr = value[2];
-+	qos.rxtp.max_cdv = value[3];
-+	qos.rxtp.max_sdu = value[4];
-+	dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d,%d,%d,%d rx=%d,%d,%d,%d,%d\n",
++	qos.rxtp.max_cdv = value[1];
++	qos.rxtp.max_sdu = value[2];
++	dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d,%d rx=%d,%d,%d\n",
 +		qos.txtp.max_pcr,
-+		qos.txtp.pcr,
-+		qos.txtp.min_pcr,
 +		qos.txtp.max_cdv,
 +		qos.txtp.max_sdu,
 +		qos.rxtp.max_pcr,
-+		qos.rxtp.pcr,
-+		qos.rxtp.min_pcr,
 +		qos.rxtp.max_cdv,
 +		qos.rxtp.max_sdu
 +		);
@@ -23930,7 +23965,7 @@
 +EXPORT_SYMBOL(shutdown_atm_dev);
 +EXPORT_SYMBOL(bind_vcc);
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/resources.h	Thu Oct  1 17:13:53 1998
++++ work/net/atm/resources.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,32 @@
 +/* net/atm/resources.h - ATM-related resources */
 +
@@ -24220,7 +24255,7 @@
 +	return 0;
 +}
 --- /dev/null	Tue Jan  1 05:00:00 1980
-+++ work/net/atm/signaling.h	Thu Oct  1 17:13:53 1998
++++ work/net/atm/signaling.h	Fri Oct 30 20:10:11 1998
 @@ -0,0 +1,25 @@
 +/* net/atm/signaling.h - ATM signaling */
 + 
diff -ur --new-file old/atm/debug/encopy.c new/atm/debug/encopy.c
--- old/atm/debug/encopy.c	Thu Sep 14 11:37:12 1995
+++ new/atm/debug/encopy.c	Thu Jan  1 01:00:00 1970
@@ -1,63 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <netinet/in.h>
-
-#include "/usr/src/linux/drivers/atm/midway.h"
-
-
-#define MEM_DEV		"/dev/mem"
-#define BASE_ADDR	0xff400000
-
-
-static void usage(const char *name)
-{
-    fprintf(stderr,"usage: %s [ -s ] [ addr ]\n",name);
-    exit(1);
-}
-
-
-int main(int argc,char **argv)
-{
-    unsigned long buffer[MAP_MAX_SIZE/4];
-    unsigned char *base;
-    unsigned long addr;
-    char *name,*end;
-    int fd,size,swap,i;
-
-    name = argv[0];
-    swap = 0;
-    if (argc > 1 && *argv[1] == '-') {
-	if (strcmp(argv[1],"-s")) usage(name);
-	swap = 1;
-	argv++;
-	argc--;
-    }
-    addr = BASE_ADDR;
-    if (argc > 1) {
-	addr = strtoul(argv[1],&end,16);
-	if (*end) usage(name);
-    }
-    if ((fd = open(MEM_DEV,O_RDWR,0)) < 0) {
-	perror("open");
-	return 1;
-    }
-    base = mmap(0L,MAP_MAX_SIZE,PROT_READ | PROT_WRITE,MAP_FILE | MAP_SHARED,
-      fd,(off_t) addr);
-    if (base == (unsigned char *) -1) {
-	perror("mmap " MEM_DEV);
-	return 1;
-    }
-    if (swap) {
-	memcpy(buffer,base,MAP_MAX_SIZE);
-	for (i = 0; i < MAP_MAX_SIZE/4; i++) buffer[i] = ntohl(buffer[i]);
-	base = (char *) buffer;
-    }
-    size = write(1,base,MAP_MAX_SIZE);
-    fprintf(stderr,"%d 0x%x\n",size,size);
-    return 0;
-}
diff -ur --new-file old/atm/debug/endump.c new/atm/debug/endump.c
--- old/atm/debug/endump.c	Thu Apr 17 17:58:00 1997
+++ new/atm/debug/endump.c	Thu Jan  1 01:00:00 1970
@@ -1,283 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include "/usr/src/linux/drivers/atm/suni.h"
-#include "/usr/src/linux/drivers/atm/midway.h"
-#include "/usr/src/linux/drivers/atm/tonga.h"
-
-
-#define MEM_DEV		"/dev/mem"
-#define BASE_ADDR	0xff400000
-
-
-struct descr {
-    const char *name;
-    char shift;	/* -1 = flag */
-    unsigned long mask; /* 0 = label */
-    const char *table;
-};
-
-struct descr midway_regs[] = {
-    { "Midway Reset/ID",	0, 			0,			NULL },
-    { "Daughter board",		0,			DAUGTHER_ID,		NULL },
-    { "UTOPIA type", 		-1,			MID_CON_V6,		"non-pipelined UTOPIA\0UTOPIA" },
-    { "PHY type",		-1,			MID_CON_SUNI,		"UTOPIA\0SUNI" },
-    { "PHY interface",		-1,			MID_CON_TI,		"Normal\0SABRE" },
-    { "Mother board",		MID_MOTHER_SHIFT,	MID_MOTHER_ID,		NULL },
-    { "Midway version",		MID_SHIFT,		MID_ID,			NULL },
-    { "",			0,			0,			NULL },
-    { "Interrupt Status",	0,			0,			NULL },
-    { "Statistics overflow",	-1,			MID_STAT_OVFL,		NULL },
-    { "SUNI",			-1,			MID_SUNI_INT,		NULL },
-    { "Service list",		-1,			MID_SERVICE,		NULL },
-    { "TX DMA complete",	-1,			MID_TX_DMA_COMPLETE,	NULL },
-    { "RX DMA complete",	-1,			MID_RX_DMA_COMPLETE,	NULL },
-    { "ERR ACK",		-1,			MID_DMA_ERR_ACK,	NULL },
-    { "LERR ACK",		-1,			MID_DMA_LERR_ACK,	NULL },
-    { "TX DMA ident mismatch",	-1,			MID_TX_IDENT_MISM,	NULL },
-    { "TX DMA overflow",	-1,			MID_TX_DMA_OVFL,	NULL },
-    { "TX 0 complete",		-1,			MID_TX_COMPLETE_0,	NULL },
-    { "TX 1 complete",		-1,			MID_TX_COMPLETE_1,	NULL },
-    { "TX 2 complete",		-1,			MID_TX_COMPLETE_2,	NULL },
-    { "TX 3 complete",		-1,			MID_TX_COMPLETE_3,	NULL },
-    { "TX 4 complete",		-1,			MID_TX_COMPLETE_4,	NULL },
-    { "TX 5 complete",		-1,			MID_TX_COMPLETE_5,	NULL },
-    { "TX 6 complete",		-1,			MID_TX_COMPLETE_6,	NULL },
-    { "TX 7 complete",		-1,			MID_TX_COMPLETE_7,	NULL },
-    { "Interrupt Enable",	0,			0,			NULL },
-    { "Statistics overflow",	-1,			MID_STAT_OVFL,		NULL },
-    { "SUNI",			-1,			MID_SUNI_INT,		NULL },
-    { "Service list",		-1,			MID_SERVICE,		NULL },
-    { "TX DMA complete",	-1,			MID_TX_DMA_COMPLETE,	NULL },
-    { "RX DMA complete",	-1,			MID_RX_DMA_COMPLETE,	NULL },
-    { "ERR ACK",		-1,			MID_DMA_ERR_ACK,	NULL },
-    { "LERR ACK",		-1,			MID_DMA_LERR_ACK,	NULL },
-    { "TX DMA ident mismatch",	-1,			MID_TX_IDENT_MISM,	NULL },
-    { "TX DMA overflow",	-1,			MID_TX_DMA_OVFL,	NULL },
-    { "TX 0 complete",		-1,			MID_TX_COMPLETE_0,	NULL },
-    { "TX 1 complete",		-1,			MID_TX_COMPLETE_1,	NULL },
-    { "TX 2 complete",		-1,			MID_TX_COMPLETE_2,	NULL },
-    { "TX 3 complete",		-1,			MID_TX_COMPLETE_3,	NULL },
-    { "TX 4 complete",		-1,			MID_TX_COMPLETE_4,	NULL },
-    { "TX 5 complete",		-1,			MID_TX_COMPLETE_5,	NULL },
-    { "TX 6 complete",		-1,			MID_TX_COMPLETE_6,	NULL },
-    { "TX 7 complete",		-1,			MID_TX_COMPLETE_7,	NULL },
-    { "Master Control/Status",	0,			0,			NULL },
-    { "Wait 500us",		-1,			MID_WAIT_500US,		NULL },
-    { "Wait 1ms",		-1,			MID_WAIT_1MS,		NULL },
-    { "RX enabled",		-1,			MID_RX_ENABLE,		NULL },
-    { "TX enabled",		-1,			MID_TX_ENABLE,		NULL },
-    { "DMA enabled",		-1,			MID_DMA_ENABLE,		NULL },
-    { "TX DMA overflow handling",-1,			MID_TX_LOCK_MODE,	"Streaming\0Lock" },
-    { "Interrupt level",	MID_INT_SEL_SHIFT,	MID_INT_SELECT,		NULL },
-    { "Statistics",		0,			0,			NULL },
-    { "Overflow",		0,			MID_OVFL_TRASH,		NULL },
-    { "Trashed",		MID_VCI_TRASH_SHIFT,	MID_VCI_TRASH,		NULL },
-    { "Pointers",		0,			0,			NULL },
-    { "Service write pointer",	0,			0xffffffff,		NULL },
-    { "",			0,			0,			NULL },
-    { "DMA address",		0,			0xffffffff,		NULL },
-    { "",			0,			0,			NULL },
-    { "DMA RX write",		0,			0xffffffff,		NULL },
-    { "",			0,			0,			NULL },
-    { "DMA RX read",		0,			0xffffffff,		NULL },
-    { "",			0,			0,			NULL },
-    { "DMA TX write",		0,			0xffffffff,		NULL },
-    { "",			0,			0,			NULL },
-    { "DMA TX read",		0,			0xffffffff,		NULL },
-    { NULL,			0,			0,			NULL }
-};
-
-struct descr tx_place[] = {
-    { "Location",		0,			MID_LOCATION,		NULL },
-    { "Size",			MID_SIZE_SHIFT,		MID_SIZE,		 "1kB\0002kB\0004kB\0008kB\00016kB\00032kB\00064kB\000128kB" },
-    { NULL,			0,			0,			NULL }
-};
-
-struct descr tx_rdptr[] = {
-    { "Read pointer",		0,			0xffffffff,		NULL },
-    { NULL,			0,			0,			NULL }
-};
-
-struct descr tx_descrstart[] = {
-    { "Descriptor start",	0,			0xffffffff,		NULL },
-    { NULL,			0,			0,			NULL }
-};
-
-struct descr vci[] = {
-    { "In service",		-1,			MID_VCI_IN_SERVICE,	NULL },
-    { "Size",			MID_VCI_SIZE_SHIFT,	MID_VCI_SIZE,		"1kB\0002kB\0004kB\0008kB\00016kB\00032kB\00064kB\000128kB" },
-    { "Location",		MID_VCI_LOCATION_SHIFT,	MID_VCI_LOCATION,	NULL },
-    { "PTI mode",		-1,			MID_VCI_PTI_MODE,	"Trash\0Preserve" },
-    { "Mode",			MID_VCI_MODE_SHIFT,	MID_VCI_MODE,		"Trash\0non AAL5\0AAL5\0???" },
-    { "",			0,			0,			NULL },
-    { "Read pointer",		MID_VCI_READ_SHIFT,	MID_VCI_READ,		NULL },
-    { "Descriptor start",	MID_VCI_DESCR_SHIFT,	MID_VCI_DESCR,		NULL },
-    { "",			0,			0,			NULL },
-    { "Cell count",		MID_VCI_COUNT_SHIFT,	MID_VCI_COUNT,		NULL },
-    { "State",			MID_VCI_STATE_SHIFT,	MID_VCI_STATE,		"Idle\0Reassembling\0???\0Trashing" },
-    { "Write pointer",		MID_VCI_WRITE_SHIFT,	MID_VCI_WRITE,		NULL },
-    { "",			0,			0,			NULL },
-    { "CRC",			0,			0xffffffff,		NULL },
-    { NULL,			0,			0,			NULL }
-};
-
-struct descr rx_dma[] = {
-    { "Type",			0,			MID_DMA_TYPE,
-	"Word\0(Byte)\0(HWord)\0JK\0004W\0008W\00016W\0002W\000???\000???\000???\000???\0004WM\0008WM\00016WM\0002WM" },
-    { "End",			-1,			MID_DMA_END,		NULL },
-    { "VCI",			MID_DMA_VCI_SHIFT,	MID_DMA_VCI,		NULL },
-    { "Count",			MID_DMA_COUNT_SHIFT,	MID_DMA_COUNT,		NULL },
-    { "",			0,			0,			NULL },
-    { "Host address",		0,			0xffffffff,		NULL },
-    { NULL,			0,			0,			NULL }
-};
-
-struct descr tx_dma[] = {
-    { "Type",			0,			MID_DMA_TYPE,
-	"Word\0Byte\0HWord\0JK\0004W\0008W\00016W\0002W\000???\000???\000???\000???\0004WM\0008WM\00016WM\0002WM" },
-    { "End",			-1,			MID_DMA_END,		NULL },
-    { "Chan",			MID_DMA_CHAN_SHIFT,	MID_DMA_CHAN,		NULL },
-    { "Count",			MID_DMA_COUNT_SHIFT,	MID_DMA_COUNT,		NULL },
-    { "",			0,			0,			NULL },
-    { "Host address",		0,			0xffffffff,		NULL },
-    { NULL,			0,			0,			NULL }
-};
-
-
-static void process(unsigned long *base,struct descr *list)
-{
-    int ind,fetch;
-    unsigned long value,eff;
-    const char *here;
-
-    if (!list->mask) {
-	ind = -1;
-	fetch = 0;
-    }
-    else {
-	ind = 0;
-	fetch = 1;
-    }
-    value = 0; /* for GCC ... */
-    while (list->name) {
-	if (!list->mask) {
-	    ind++;
-	    fetch = 1;
-	    if (*list->name) printf("%s[%d]\n",list->name,ind);
-	}
-	else {
-	    printf("  %-30s",list->name);
-	    if (fetch) {value = base[ind];
-/*printf("  [%d] = 0x%lx\n",ind,value);*/
-}
-	    fetch = 0;
-	    if (list->shift == -1) eff = !!(value & list->mask);
-	    else eff = (value & list->mask) >> list->shift;
-	    if (!list->table) printf("0x%08lx %10ld\n",eff,eff);
-	    else {
-		for (here = list->table; eff; eff--)
-		    here = strchr(here,0)+1;
-		printf("%s\n",here);
-	    }
-
-	}
-	list++;
-    }
-}
-
-
-static void dump_registers(unsigned long *base)
-{
-    int i;
-
-    process(base,midway_regs);
-    for (i = 0; i < NR_CHAN; i++) {
-	printf("TX %d\n",i);
-	process(base+0x10+4*i,tx_place);
-	process(base+0x11+4*i,tx_rdptr);
-	process(base+0x12+4*i,tx_descrstart);
-	
-    }
-}
-
-
-static void dump_vcis(unsigned long *base)
-{
-    int i;
-
-    printf("VCI %p\