diff -ur --new-file old/linux/include/linux/atmsvc.h new/linux/include/linux/atmsvc.h --- old/linux/include/linux/atmsvc.h Mon Sep 9 19:42:00 1996 +++ new/linux/include/linux/atmsvc.h Mon Sep 9 19:42:31 1996 @@ -13,8 +13,8 @@ #define ATMSIGD_CTRL _IO('a',ATMIOC_SPECIAL) /* become ATM signaling demon control socket */ -enum atmsvc_msg_type { as_catch_null,as_bind,as_connect,as_accept,as_listen, - as_okay,as_error,as_indicate,as_close,as_itf_notify }; +enum atmsvc_msg_type { as_catch_null,as_bind,as_connect,as_accept,as_reject, + as_listen,as_okay,as_error,as_indicate,as_close,as_itf_notify }; struct atmsvc_msg { enum atmsvc_msg_type type; @@ -35,31 +35,7 @@ }; /* - * Message contents: - * - * Message Dir vcc listen_vcc reply aal pvc --svc-- local - * addr *xtp addr sap *xtp addr - * bind K->D X - - - - - X X - - - * - okay D->K X - - - - - X X - - - * connect K->D X - - X - - X X X X - * - okay D->K X - - - X X - - - X - * listen K->D X - - X - - X X X - - * - okay D->K X - - - - - - - - - - * indicate D->K - X - - X 1 X X X - - * accept K->D X X - - - - - - - - - * - okay D->K X - - - - - - - - X - * close K->D X - - - - - - - - - - * close D->K X - X - - - - - - - - * - * 1 same value as in svc.*xtp - * - * Note: we may have to get rid of the PVC part in indicate messages later, - * so it's a good idea not to depend on it too heavily. - */ - -/* - * In an as_itf_update message, only the fields type and pvc.sas_addr.itf are - * valid. + * Message contents: see ftp://lrcftp.epfl.ch/pub/linux/atm/docs/isp-*.tar.gz */ /* diff -ur --new-file old/linux/net/atm/atmarp.c new/linux/net/atm/atmarp.c --- old/linux/net/atm/atmarp.c Mon Sep 9 19:42:00 1996 +++ new/linux/net/atm/atmarp.c Mon Sep 9 19:42:31 1996 @@ -480,18 +480,10 @@ int clip_create(int number) /* remove by downing */ { - struct device *dev,*walk; + struct device *dev; - if (number != -1) { - for (walk = clip_devs; walk; walk = PRIV(walk)->next) - if (PRIV(walk)->number == number) return -EEXIST; - } - else { - number = 0; - for (walk = clip_devs; walk; walk = PRIV(walk)->next) - if (PRIV(walk)->number >= number) - number = PRIV(walk)->number+1; - } + number = ipcom_pick_number(number); + if (number < 0) return number; dev = kmalloc(sizeof(struct device)+sizeof(struct atmarp_priv), GFP_KERNEL); if (!dev) return -ENOMEM; diff -ur --new-file old/linux/net/atm/atmarp.h new/linux/net/atm/atmarp.h --- old/linux/net/atm/atmarp.h Mon Sep 9 19:42:00 1996 +++ new/linux/net/atm/atmarp.h Mon Sep 9 19:42:31 1996 @@ -42,7 +42,6 @@ }; -extern struct device *clip_devs; extern struct atm_vcc *atmarpd; /* ugly */ diff -ur --new-file old/linux/net/atm/clip.c new/linux/net/atm/clip.c --- old/linux/net/atm/clip.c Mon Sep 9 19:42:00 1996 +++ new/linux/net/atm/clip.c Mon Sep 9 19:42:31 1996 @@ -31,8 +31,7 @@ #endif - -static int pvc_num = 0; +struct clip_priv *old_clip_devs; /*static*/ void atm_push_clip(struct atm_vcc *vcc,struct sk_buff *skb) @@ -91,7 +90,6 @@ int atm_init_clip(struct atm_vcc *vcc) { struct device *dev; - int number; DPRINTK("atm_init_clip\n"); if (!suser()) return -EPERM; @@ -105,11 +103,14 @@ if (!dev) return -ENOMEM; memset(dev,0,sizeof(struct device)+sizeof(struct clip_priv)); dev->name = CLIP(dev)->name; - number = pvc_num++; - sprintf(dev->name,"atm%d",number); + CLIP(dev)->number = ipcom_pick_number(-1); + sprintf(dev->name,"atm%d",CLIP(dev)->number); dev->init = clip_init; CLIP(dev)->vcc = vcc; if (register_netdev(dev)) return -EIO; + /* if register_netdev can sleep, we race on ->number */ + CLIP(dev)->next = old_clip_devs; + old_clip_devs = CLIP(dev); DPRINTK("registered %s,0x%lx\n",dev->name,(unsigned long) vcc); - return number; + return CLIP(dev)->number; } diff -ur --new-file old/linux/net/atm/ipcommon.c new/linux/net/atm/ipcommon.c --- old/linux/net/atm/ipcommon.c Mon Sep 9 19:42:00 1996 +++ new/linux/net/atm/ipcommon.c Mon Sep 9 19:42:31 1996 @@ -13,6 +13,7 @@ #include "common.h" #include "ipcommon.h" +#include "atmarp.h" #if 0 @@ -178,4 +179,36 @@ dev->mtu = RFC1626_MTU; memset(&CLIP(dev)->stats,0,sizeof(struct enet_statistics)); +} + + +int ipcom_pick_number(int number) +{ +#ifdef CONFIG_ATM_ATMARP + struct device *atmarp; +#endif +#ifdef CONFIG_ATM_CLIP + struct clip_priv *clip; +#endif + + if (number != -1) { +#ifdef CONFIG_ATM_ATMARP + for (atmarp = clip_devs; atmarp; atmarp = PRIV(atmarp)->next) + if (PRIV(atmarp)->number == number) return -EEXIST; +#endif + } + else { + number = 0; + +#ifdef CONFIG_ATM_ATMARP + for (atmarp = clip_devs; atmarp; atmarp = PRIV(atmarp)->next) + if (PRIV(atmarp)->number >= number) + number = PRIV(atmarp)->number+1; +#endif +#ifdef CONFIG_ATM_CLIP + for (clip = old_clip_devs; clip; clip = clip->next) + if (clip->number >= number) number = clip->number+1; +#endif + } + return number; } diff -ur --new-file old/linux/net/atm/ipcommon.h new/linux/net/atm/ipcommon.h --- old/linux/net/atm/ipcommon.h Mon Sep 9 19:42:00 1996 +++ new/linux/net/atm/ipcommon.h Mon Sep 9 19:42:31 1996 @@ -15,18 +15,24 @@ extern const unsigned char llc_oui[6]; +extern struct device *clip_devs; #define CLIP(dev) ((struct clip_priv *) ((struct device *) (dev)+1)) struct clip_priv { - char name[8]; + char name[8]; /* interface name */ + int number; /* for convenience ... */ struct atm_vcc *vcc; struct enet_statistics stats; + struct clip_priv *next; /* next CLIP interface */ }; +extern struct clip_priv *old_clip_devs; + + static inline void ipcom_push(struct sk_buff *skb) { skb->mac.raw = skb->data; @@ -62,5 +68,6 @@ void ipcom_init(struct device *dev, int (*hard_start_xmit)(struct sk_buff *skb,struct device *dev), unsigned short extra_flags); +int ipcom_pick_number(int number); #endif diff -ur --new-file old/linux/net/atm/proc.c new/linux/net/atm/proc.c --- old/linux/net/atm/proc.c Mon Sep 9 19:42:01 1996 +++ new/linux/net/atm/proc.c Mon Sep 9 19:42:31 1996 @@ -22,6 +22,7 @@ #include "static.h" /* ugly */ #include "signaling.h" /* to get sigd - ugly too */ +#include "ipcommon.h" #include "atmarp.h" #ifdef CONFIG_ATM_LANE diff -ur --new-file old/linux/net/atm/svc.c new/linux/net/atm/svc.c --- old/linux/net/atm/svc.c Mon Sep 9 19:42:00 1996 +++ new/linux/net/atm/svc.c Mon Sep 9 19:42:31 1996 @@ -78,9 +78,8 @@ while ((skb = skb_dequeue(&vcc->listenq))) { vcc->flags &= ~ATM_VF_RELEASED; DPRINTK("LISTEN REL\n"); - sigd_enq(NULL,as_close,vcc,NULL,NULL); /* reject */ - while (!(vcc->flags & ATM_VF_RELEASED) && sigd) - sleep_on(&vcc->sleep); + sigd_enq(NULL,as_reject,vcc,NULL,NULL); /* @@@ should include + the reason */ dev_kfree_skb(skb,FREE_WRITE); } vcc->flags &= ~(ATM_VF_REGIS | ATM_VF_RELEASED); /* may retry later */ @@ -283,31 +282,35 @@ } /* should try to atm_connect now and possibly send a close on error */ + msg = (struct atmsvc_msg *) skb->data; + new_vcc->qos = msg->qos; + new_vcc->flags |= ATM_VF_HASQOS; + new_vcc->remote = msg->svc; + /* copy BLLI @@@ */ + new_vcc->remote.sas_addr.blli = NULL; + error = atm_connect(newsock,msg->pvc.sap_addr.itf, + msg->pvc.sap_addr.vpi,msg->pvc.sap_addr.vci); + dev_kfree_skb(skb,FREE_WRITE); + if (error) { + sigd_enq(NULL,as_reject,old_vcc,NULL,NULL); + /* @@@ should include the reason */ + return error == -EAGAIN ? -EBUSY : error; + } /* wait should be short, so we ignore the non-blocking flag */ new_vcc->reply = WAITING; sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL); while (new_vcc->reply == WAITING && sigd) sleep_on(&new_vcc->sleep); - if (!sigd) return -EUNATCH; + if (!sigd) { + atm_release_vcc(new_vcc,1); + return -EUNATCH; + } old_vcc->backlog_quota++; if (!new_vcc->reply) break; - dev_kfree_skb(skb,FREE_WRITE); - if (new_vcc->reply != -ERESTARTSYS) return new_vcc->reply; - } - if (!sigd) return -EUNATCH; - msg = (struct atmsvc_msg *) skb->data; - new_vcc->qos = msg->qos; - new_vcc->remote = msg->svc; - /* copy BLLI @@@ */ - new_vcc->remote.sas_addr.blli = NULL; - error = atm_connect(newsock,msg->pvc.sap_addr.itf,msg->pvc.sap_addr.vpi, - msg->pvc.sap_addr.vci); - dev_kfree_skb(skb,FREE_WRITE); - if (error) { - (void) svc_disconnect(ATM_SD(newsock)); - /* @@@ or should we try additional connections just until - we'd block ? (then we MUST return) */ - return error == -EAGAIN ? -EBUSY : error; + if (new_vcc->reply != -ERESTARTSYS) { + atm_release_vcc(new_vcc,1); + return new_vcc->reply; + } } newsock->state = SS_CONNECTED; return 0; diff -ur --new-file old/linux/net/ipv4/ip_forward.c new/linux/net/ipv4/ip_forward.c --- old/linux/net/ipv4/ip_forward.c Wed Aug 7 12:59:29 1996 +++ new/linux/net/ipv4/ip_forward.c Mon Sep 9 19:42:31 1996 @@ -39,6 +39,9 @@ #include <net/checksum.h> #include <linux/route.h> #include <net/route.h> +#ifdef CONFIG_AREQUIPA +#include <linux/arequipa.h> +#endif #ifdef CONFIG_IP_FORWARD #ifdef CONFIG_IP_MROUTE @@ -150,7 +153,11 @@ iph->check = checksum; } +#ifndef CONFIG_AREQUIPA if (iph->ttl <= 0) +#else + if (iph->ttl <= 0 || dev == arequipa_dev) +#endif { /* Tell the sender its packet died... */ icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev);