From: Andy P. <at...@us...> - 2002-04-09 16:20:50
|
Update of /cvsroot/linux-vax/kernel-2.4/net/atm In directory usw-pr-cvs1:/tmp/cvs-serv30559/atm Modified Files: Makefile addr.c addr.h clip.c common.c lec.c mpc.c mpoa_proc.c proc.c pvc.c resources.c signaling.c svc.c Added Files: pppoatm.c Log Message: synch 2.4.15 commit 18 --- NEW FILE --- /* net/atm/pppoatm.c - RFC2364 PPP over ATM/AAL5 */ /* Copyright 1999-2000 by Mitchell Blank Jr */ /* Based on clip.c; 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ /* And on ppp_async.c; Copyright 1999 Paul Mackerras */ /* And help from Jens Axboe */ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * This driver provides the encapsulation and framing for sending * and receiving PPP frames in ATM AAL5 PDUs. */ /* * One shortcoming of this driver is that it does not comply with * section 8 of RFC2364 - we are supposed to detect a change * in encapsulation and immediately abort the connection (in order * to avoid a black-hole being created if our peer loses state * and changes encapsulation unilaterally. However, since the * ppp_generic layer actually does the decapsulation, we need * a way of notifying it when we _think_ there might be a problem) * There's two cases: * 1. LLC-encapsulation was missing when it was enabled. In * this case, we should tell the upper layer "tear down * this session if this skb looks ok to you" * 2. LLC-encapsulation was present when it was disabled. Then * we need to tell the upper layer "this packet may be * ok, but if its in error tear down the session" * These hooks are not yet available in ppp_generic */ #include <linux/module.h> #include <linux/config.h> #include <linux/init.h> #include <linux/skbuff.h> #include <linux/atm.h> #include <linux/atmdev.h> #include <linux/ppp_defs.h> #include <linux/if_ppp.h> #include <linux/ppp_channel.h> #include <linux/atmppp.h> #if 0 #define DPRINTK(format, args...) \ printk(KERN_DEBUG "pppoatm: " format, ##args) #else #define DPRINTK(format, args...) #endif enum pppoatm_encaps { e_autodetect = PPPOATM_ENCAPS_AUTODETECT, e_vc = PPPOATM_ENCAPS_VC, e_llc = PPPOATM_ENCAPS_LLC, }; struct pppoatm_vcc { struct atm_vcc *atmvcc; /* VCC descriptor */ void (*old_push)(struct atm_vcc *, struct sk_buff *); void (*old_pop)(struct atm_vcc *, struct sk_buff *); /* keep old push/pop for detaching */ enum pppoatm_encaps encaps; int flags; /* SC_COMP_PROT - compress protocol */ struct ppp_channel chan; /* interface to generic ppp layer */ struct tasklet_struct wakeup_tasklet; }; /* * Header used for LLC Encapsulated PPP (4 bytes) followed by the LCP protocol * ID (0xC021) used in autodetection */ static const unsigned char pppllc[6] = { 0xFE, 0xFE, 0x03, 0xCF, 0xC0, 0x21 }; #define LLC_LEN (4) static inline struct pppoatm_vcc *atmvcc_to_pvcc(const struct atm_vcc *atmvcc) { return (struct pppoatm_vcc *) (atmvcc->user_back); } static inline struct pppoatm_vcc *chan_to_pvcc(const struct ppp_channel *chan) { return (struct pppoatm_vcc *) (chan->private); } /* * We can't do this directly from our _pop handler, since the ppp code * doesn't want to be called in interrupt context, so we do it from * a tasklet */ static void pppoatm_wakeup_sender(unsigned long arg) { ppp_output_wakeup((struct ppp_channel *) arg); } /* * This gets called every time the ATM card has finished sending our * skb. The ->old_pop will take care up normal atm flow control, * but we also need to wake up the device if we blocked it */ static void pppoatm_pop(struct atm_vcc *atmvcc, struct sk_buff *skb) { struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc); pvcc->old_pop(atmvcc, skb); /* * We don't really always want to do this since it's * really inefficient - it would be much better if we could * test if we had actually throttled the generic layer. * Unfortunately then there would be a nasty SMP race where * we could clear that flag just as we refuse another packet. * For now we do the safe thing. */ tasklet_schedule(&pvcc->wakeup_tasklet); } /* * Unbind from PPP - currently we only do this when closing the socket, * but we could put this into an ioctl if need be */ static void pppoatm_unassign_vcc(struct atm_vcc *atmvcc) { struct pppoatm_vcc *pvcc; pvcc = atmvcc_to_pvcc(atmvcc); atmvcc->push = pvcc->old_push; atmvcc->pop = pvcc->old_pop; tasklet_disable(&pvcc->wakeup_tasklet); ppp_unregister_channel(&pvcc->chan); atmvcc->user_back = NULL; kfree(pvcc); /* Gee, I hope we have the big kernel lock here... */ MOD_DEC_USE_COUNT; } /* Called when an AAL5 PDU comes in */ static void pppoatm_push(struct atm_vcc *atmvcc, struct sk_buff *skb) { struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc); DPRINTK("pppoatm push\n"); if (skb == NULL) { /* VCC was closed */ DPRINTK("removing ATMPPP VCC %p\n", pvcc); pppoatm_unassign_vcc(atmvcc); atmvcc->push(atmvcc, NULL); /* Pass along bad news */ return; } atm_return(atmvcc, skb->truesize); switch (pvcc->encaps) { case e_llc: if (skb->len < LLC_LEN || memcmp(skb->data, pppllc, LLC_LEN)) goto error; skb_pull(skb, LLC_LEN); break; case e_autodetect: if (pvcc->chan.ppp == NULL) { /* Not bound yet! */ kfree_skb(skb); return; } if (skb->len >= sizeof(pppllc) && !memcmp(skb->data, pppllc, sizeof(pppllc))) { pvcc->encaps = e_llc; skb_pull(skb, LLC_LEN); break; } if (skb->len >= (sizeof(pppllc) - LLC_LEN) && !memcmp(skb->data, &pppllc[LLC_LEN], sizeof(pppllc) - LLC_LEN)) { pvcc->encaps = e_vc; pvcc->chan.mtu += LLC_LEN; break; } DPRINTK("(unit %d): Couldn't autodetect yet " "(skb: %02X %02X %02X %02X %02X %02X)\n", pvcc->chan.unit, skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5]); goto error; case e_vc: break; } ppp_input(&pvcc->chan, skb); return; error: kfree_skb(skb); ppp_input_error(&pvcc->chan, 0); } /* * Called by the ppp_generic.c to send a packet - returns true if packet * was accepted. If we return false, then it's our job to call * ppp_output_wakeup(chan) when we're feeling more up to it. * Note that in the ENOMEM case (as opposed to the !atm_may_send case) * we should really drop the packet, but the generic layer doesn't * support this yet. We just return 'DROP_PACKET' which we actually define * as success, just to be clear what we're really doing. */ #define DROP_PACKET 1 static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb) { struct pppoatm_vcc *pvcc = chan_to_pvcc(chan); ATM_SKB(skb)->vcc = pvcc->atmvcc; DPRINTK("(unit %d): pppoatm_send (skb=0x%p, vcc=0x%p)\n", pvcc->chan.unit, skb, pvcc->atmvcc); if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT)) (void) skb_pull(skb, 1); switch (pvcc->encaps) { /* LLC encapsulation needed */ case e_llc: if (skb_headroom(skb) < LLC_LEN) { struct sk_buff *n; n = skb_realloc_headroom(skb, LLC_LEN); if (n != NULL && !atm_may_send(pvcc->atmvcc, n->truesize)) { kfree_skb(n); goto nospace; } kfree_skb(skb); if ((skb = n) == NULL) return DROP_PACKET; } else if (!atm_may_send(pvcc->atmvcc, skb->truesize)) goto nospace; memcpy(skb_push(skb, LLC_LEN), pppllc, LLC_LEN); break; case e_vc: if (!atm_may_send(pvcc->atmvcc, skb->truesize)) goto nospace; break; case e_autodetect: DPRINTK("(unit %d): Trying to send without setting encaps!\n", pvcc->chan.unit); kfree_skb(skb); return 1; } atomic_add(skb->truesize, &ATM_SKB(skb)->vcc->tx_inuse); ATM_SKB(skb)->iovcnt = 0; ATM_SKB(skb)->atm_options = ATM_SKB(skb)->vcc->atm_options; DPRINTK("(unit %d): atm_skb(%p)->vcc(%p)->dev(%p)\n", pvcc->chan.unit, skb, ATM_SKB(skb)->vcc, ATM_SKB(skb)->vcc->dev); return ATM_SKB(skb)->vcc->send(ATM_SKB(skb)->vcc, skb) ? DROP_PACKET : 1; nospace: /* * We don't have space to send this SKB now, but we might have * already applied SC_COMP_PROT compression, so may need to undo */ if ((pvcc->flags & SC_COMP_PROT) && skb_headroom(skb) > 0 && skb->data[-1] == '\0') (void) skb_push(skb, 1); return 0; } /* This handles ioctls sent to the /dev/ppp interface */ static int pppoatm_devppp_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg) { switch (cmd) { case PPPIOCGFLAGS: return put_user(chan_to_pvcc(chan)->flags, (int *) arg) ? -EFAULT : 0; case PPPIOCSFLAGS: return get_user(chan_to_pvcc(chan)->flags, (int *) arg) ? -EFAULT : 0; } return -ENOTTY; } static /*const*/ struct ppp_channel_ops pppoatm_ops = { start_xmit: pppoatm_send, ioctl: pppoatm_devppp_ioctl, }; static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, unsigned long arg) { struct atm_backend_ppp be; struct pppoatm_vcc *pvcc; int err; /* * Each PPPoATM instance has its own tasklet - this is just a * prototypical one used to initialize them */ static const DECLARE_TASKLET(tasklet_proto, pppoatm_wakeup_sender, 0); if (copy_from_user(&be, (void *) arg, sizeof be)) return -EFAULT; if (be.encaps != PPPOATM_ENCAPS_AUTODETECT && be.encaps != PPPOATM_ENCAPS_VC && be.encaps != PPPOATM_ENCAPS_LLC) return -EINVAL; MOD_INC_USE_COUNT; pvcc = kmalloc(sizeof(*pvcc), GFP_KERNEL); if (pvcc == NULL) { MOD_DEC_USE_COUNT; return -ENOMEM; } memset(pvcc, 0, sizeof(*pvcc)); pvcc->atmvcc = atmvcc; pvcc->old_push = atmvcc->push; pvcc->old_pop = atmvcc->pop; pvcc->encaps = (enum pppoatm_encaps) be.encaps; pvcc->chan.private = pvcc; pvcc->chan.ops = &pppoatm_ops; pvcc->chan.mtu = atmvcc->qos.txtp.max_sdu - PPP_HDRLEN - (be.encaps == e_vc ? 0 : LLC_LEN); pvcc->wakeup_tasklet = tasklet_proto; pvcc->wakeup_tasklet.data = (unsigned long) &pvcc->chan; if ((err = ppp_register_channel(&pvcc->chan)) != 0) { kfree(pvcc); return err; } atmvcc->user_back = pvcc; atmvcc->push = pppoatm_push; atmvcc->pop = pppoatm_pop; return 0; } /* * This handles ioctls actually performed on our vcc - we must return * -ENOIOCTLCMD for any unrecognized ioctl */ static int pppoatm_ioctl(struct atm_vcc *atmvcc, unsigned int cmd, unsigned long arg) { if (cmd != ATM_SETBACKEND && atmvcc->push != pppoatm_push) return -ENOIOCTLCMD; switch (cmd) { case ATM_SETBACKEND: { atm_backend_t b; if (get_user(b, (atm_backend_t *) arg)) return -EFAULT; if (b != ATM_BACKEND_PPP) return -ENOIOCTLCMD; if (!capable(CAP_NET_ADMIN)) return -EPERM; return pppoatm_assign_vcc(atmvcc, arg); } case PPPIOCGCHAN: return put_user(ppp_channel_index(&atmvcc_to_pvcc(atmvcc)-> chan), (int *) arg) ? -EFAULT : 0; case PPPIOCGUNIT: return put_user(ppp_unit_number(&atmvcc_to_pvcc(atmvcc)-> chan), (int *) arg) ? -EFAULT : 0; } return -ENOIOCTLCMD; } /* the following avoids some spurious warnings from the compiler */ #define UNUSED __attribute__((unused)) extern int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long); static int __init UNUSED pppoatm_init(void) { pppoatm_ioctl_hook = pppoatm_ioctl; return 0; } static void __exit UNUSED pppoatm_exit(void) { pppoatm_ioctl_hook = NULL; } module_init(pppoatm_init); module_exit(pppoatm_exit); MODULE_AUTHOR("Mitchell Blank Jr <mi...@sf...>"); MODULE_DESCRIPTION("RFC2364 PPP over ATM/AAL5"); Index: Makefile =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/Makefile,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- Makefile 14 Jan 2001 17:17:08 -0000 1.1.1.1 +++ Makefile 9 Apr 2002 16:20:45 -0000 1.2 @@ -7,16 +7,14 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -include ../../.config +O_TARGET := atm.o -O_TARGET= atm.o +export-objs := common.o atm_misc.o raw.o resources.o ipcommon.o proc.o -export-objs = common.o atm_misc.o raw.o resources.o ipcommon.o proc.o +list-multi := mpoa.o +mpoa-objs := mpc.o mpoa_caches.o mpoa_proc.o -multi-list = mpoa.o -mpoa-objs = mpc.o mpoa_caches.o mpoa_proc.o - -obj-$(CONFIG_ATM) = addr.o pvc.o signaling.o svc.o common.o atm_misc.o raw.o resources.o +obj-$(CONFIG_ATM) := addr.o pvc.o signaling.o svc.o common.o atm_misc.o raw.o resources.o ifeq ($(CONFIG_ATM_CLIP),y) obj-y += clip.o @@ -35,6 +33,7 @@ obj-$(CONFIG_ATM_LANE) += lec.o obj-$(CONFIG_ATM_MPOA) += mpoa.o +obj-$(CONFIG_PPPOATM) += pppoatm.o include $(TOPDIR)/Rules.make Index: addr.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/addr.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- addr.c 14 Jan 2001 17:17:09 -0000 1.1.1.1 +++ addr.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -52,25 +52,26 @@ sigd_enq(NULL,as_itf_notify,NULL,&pvc,NULL); } +/* + * This is called from atm_ioctl only. You must hold the lock as a caller + */ -void reset_addr(struct atm_dev *dev) +void atm_reset_addr(struct atm_dev *dev) { struct atm_dev_addr *this; down(&local_lock); - spin_lock (&atm_dev_lock); while (dev->local) { this = dev->local; dev->local = this->next; kfree(this); } up(&local_lock); - spin_unlock (&atm_dev_lock); notify_sigd(dev); } -int add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr) +int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr) { struct atm_dev_addr **walk; int error; @@ -96,7 +97,7 @@ } -int del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr) +int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr) { struct atm_dev_addr **walk,*this; int error; @@ -119,7 +120,7 @@ } -int get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size) +int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size) { struct atm_dev_addr *walk; int total; Index: addr.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/addr.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- addr.h 14 Jan 2001 17:17:09 -0000 1.1.1.1 +++ addr.h 9 Apr 2002 16:20:45 -0000 1.2 @@ -10,9 +10,9 @@ #include <linux/atmdev.h> -void reset_addr(struct atm_dev *dev); -int add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr); -int del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr); -int get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size); +void atm_reset_addr(struct atm_dev *dev); +int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr); +int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr); +int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size); #endif Index: clip.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/clip.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- clip.c 14 Jan 2001 17:17:12 -0000 1.1.1.1 +++ clip.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -571,7 +571,6 @@ /* compromise between decent burst-tolerance and protection */ /* against memory hogs. */ dev->flags = 0; - dev_init_buffers(dev); /* is this ever supposed to be used ? */ return 0; } @@ -686,8 +685,6 @@ static void atmarpd_close(struct atm_vcc *vcc) { - struct sk_buff *skb; - DPRINTK("atmarpd_close\n"); atmarpd = NULL; /* assumed to be atomic */ barrier(); @@ -696,7 +693,7 @@ if (skb_peek(&vcc->recvq)) printk(KERN_ERR "atmarpd_close: closing with requests " "pending\n"); - while ((skb = skb_dequeue(&vcc->recvq))) kfree_skb(skb); + skb_queue_purge(&vcc->recvq); DPRINTK("(done)\n"); } Index: common.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/common.c,v retrieving revision 1.1.1.2 retrieving revision 1.2 diff -u -r1.1.1.2 -r1.2 --- common.c 25 Feb 2001 23:14:57 -0000 1.1.1.2 +++ common.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -58,6 +58,11 @@ #endif #endif +#if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE) +int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long); +EXPORT_SYMBOL(pppoatm_ioctl_hook); +#endif + #include "resources.h" /* atm_find_dev */ #include "common.h" /* prototypes */ #include "protocols.h" /* atm_init_<transport> */ @@ -544,7 +549,7 @@ { struct atm_dev *dev; struct atm_vcc *vcc; - int *tmp_buf; + int *tmp_buf, *tmp_p; void *buf; int error,len,size,number, ret_val; @@ -598,14 +603,13 @@ ret_val = -ENOMEM; goto done; } + tmp_p = tmp_buf; for (dev = atm_devs; dev; dev = dev->next) - *tmp_buf++ = dev->number; - if (copy_to_user(buf,(char *) tmp_buf-size,size)) { - ret_val = -EFAULT; - goto done; - } - ret_val = put_user(size, - &((struct atm_iobuf *) arg)->length) ? -EFAULT : 0; + *tmp_p++ = dev->number; + ret_val = ((copy_to_user(buf, tmp_buf, size)) || + put_user(size, &((struct atm_iobuf *) arg)->length) + ) ? -EFAULT : 0; + kfree(tmp_buf); goto done; case SIOCGSTAMP: /* borrowed from IP */ if (!vcc->timestamp.tv_sec) { @@ -774,6 +778,13 @@ default: break; } +#if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE) + if (pppoatm_ioctl_hook) { + ret_val = pppoatm_ioctl_hook(vcc, cmd, arg); + if (ret_val != -ENOIOCTLCMD) + goto done; + } +#endif if (get_user(buf,&((struct atmif_sioc *) arg)->arg)) { ret_val = -EFAULT; goto done; @@ -867,7 +878,7 @@ ret_val = -EPERM; goto done; } - reset_addr(dev); + atm_reset_addr(dev); break; case ATM_ADDADDR: case ATM_DELADDR: @@ -883,13 +894,13 @@ goto done; } if (cmd == ATM_ADDADDR) - ret_val = add_addr(dev,&addr); + ret_val = atm_add_addr(dev,&addr); else - ret_val = del_addr(dev,&addr); + ret_val = atm_del_addr(dev,&addr); goto done; } case ATM_GETADDR: - size = get_addr(dev,buf,len); + size = atm_get_addr(dev,buf,len); if (size < 0) ret_val = size; else @@ -931,6 +942,8 @@ if (size) ret_val = put_user(size,&((struct atmif_sioc *) arg)->length) ? -EFAULT : 0; + else + ret_val = 0; done: spin_unlock (&atm_dev_lock); Index: lec.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/lec.c,v retrieving revision 1.1.1.2 retrieving revision 1.2 diff -u -r1.1.1.2 -r1.2 --- lec.c 25 Feb 2001 23:14:57 -0000 1.1.1.2 +++ lec.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -51,9 +51,9 @@ #define DPRINTK(format,args...) #endif -struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br, +extern struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br, unsigned char *addr); -void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent); +extern void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent); #define DUMP_PACKETS 0 /* 0 = None, @@ -281,6 +281,10 @@ dev->name, skb->len,skb->truesize); nb=(unsigned char*)kmalloc(64, GFP_ATOMIC); + if (nb == NULL) { + dev_kfree_skb(skb); + return 0; + } memcpy(nb,skb->data,skb->len); kfree(skb->head); skb->head = skb->data = nb; @@ -1796,6 +1800,10 @@ entry = lec_arp_find(priv, mac_addr); if (!entry) { entry = make_entry(priv, mac_addr); + if (!entry) { + lec_arp_unlock(priv); + return; + } entry->status = ESI_UNKNOWN; lec_arp_put(priv->lec_arp_tables, entry); /* Temporary, changes before end of function */ @@ -1890,6 +1898,10 @@ ioc_data->atm_addr[16],ioc_data->atm_addr[17], ioc_data->atm_addr[18],ioc_data->atm_addr[19]); entry = make_entry(priv, bus_mac); + if (entry == NULL) { + lec_arp_unlock(priv); + return; + } memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); memset(entry->mac_addr, 0, ETH_ALEN); entry->recv_vcc = vcc; @@ -1967,6 +1979,10 @@ /* Not found, snatch address from first data packet that arrives from this vcc */ entry = make_entry(priv, bus_mac); + if (!entry) { + lec_arp_unlock(priv); + return; + } entry->vcc = vcc; entry->old_push = old_push; memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); @@ -2177,3 +2193,4 @@ lec_arp_put(priv->lec_arp_tables,entry); lec_arp_unlock(priv); } +MODULE_LICENSE("GPL"); Index: mpc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/mpc.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- mpc.c 14 Jan 2001 17:17:34 -0000 1.1.1.1 +++ mpc.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -772,6 +772,8 @@ if (mpc == NULL) { dprintk("mpoa: mpoad_attach: allocating new mpc for itf %d\n", arg); mpc = alloc_mpc(); + if (mpc == NULL) + return -ENOMEM; mpc->dev_num = arg; mpc->dev = find_lec_by_itfnum(arg); /* NULL if there was no lec */ } @@ -1477,3 +1479,4 @@ return; } #endif /* MODULE */ +MODULE_LICENSE("GPL"); Index: mpoa_proc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/mpoa_proc.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- mpoa_proc.c 14 Jan 2001 17:17:38 -0000 1.1.1.1 +++ mpoa_proc.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -109,8 +109,6 @@ eg_cache_entry *eg_entry; struct timeval now; unsigned char ip_string[16]; - if(count < 0) - return -EINVAL; if(count == 0) return 0; page = get_free_page(GFP_KERNEL); @@ -173,9 +171,8 @@ char *page, c; const char *tmp; - if (nbytes < 0) return -EINVAL; if (nbytes == 0) return 0; - if (nbytes > PAGE_SIZE) nbytes = PAGE_SIZE-1; + if (nbytes >= PAGE_SIZE) nbytes = PAGE_SIZE-1; error = verify_area(VERIFY_READ, buff, nbytes); if (error) return error; Index: proc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/proc.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- proc.c 14 Jan 2001 17:17:40 -0000 1.1.1.1 +++ proc.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -495,7 +495,7 @@ unsigned long page; int length; - if (count < 0) return -EINVAL; + if (count == 0) return 0; page = get_free_page(GFP_KERNEL); if (!page) return -ENOMEM; dev = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip) @@ -524,7 +524,7 @@ info = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip) ->data; - if (count < 0) return -EINVAL; + if (count == 0) return 0; page = get_free_page(GFP_KERNEL); if (!page) return -ENOMEM; length = (*info)(*pos,(char *) page); @@ -561,7 +561,6 @@ dev->proc_entry->proc_fops = &proc_dev_atm_operations; dev->proc_entry->owner = THIS_MODULE; return 0; - kfree(dev->proc_entry); fail0: kfree(dev->proc_name); fail1: Index: pvc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/pvc.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- pvc.c 14 Jan 2001 17:17:41 -0000 1.1.1.1 +++ pvc.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -95,6 +95,7 @@ sendmsg: atm_sendmsg, recvmsg: atm_recvmsg, mmap: sock_no_mmap, + sendpage: sock_no_sendpage, }; Index: resources.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/resources.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- resources.c 14 Jan 2001 17:17:41 -0000 1.1.1.1 +++ resources.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -36,13 +36,18 @@ if (!dev) return NULL; memset(dev,0,sizeof(*dev)); dev->type = type; - dev->prev = last_dev; dev->signal = ATM_PHY_SIG_UNKNOWN; dev->link_rate = ATM_OC3_PCR; dev->next = NULL; + + spin_lock(&atm_dev_lock); + + dev->prev = last_dev; + if (atm_devs) last_dev->next = dev; else atm_devs = dev; last_dev = dev; + spin_unlock(&atm_dev_lock); return dev; } Index: signaling.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/signaling.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- signaling.c 14 Jan 2001 17:17:42 -0000 1.1.1.1 +++ signaling.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -211,14 +211,13 @@ static void sigd_close(struct atm_vcc *vcc) { - struct sk_buff *skb; struct atm_dev *dev; DPRINTK("sigd_close\n"); sigd = NULL; if (skb_peek(&vcc->recvq)) printk(KERN_ERR "sigd_close: closing with requests pending\n"); - while ((skb = skb_dequeue(&vcc->recvq))) kfree_skb(skb); + skb_queue_purge(&vcc->recvq); purge_vccs(nodev_vccs); spin_lock (&atm_dev_lock); Index: svc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/net/atm/svc.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- svc.c 14 Jan 2001 17:17:44 -0000 1.1.1.1 +++ svc.c 9 Apr 2002 16:20:45 -0000 1.2 @@ -408,6 +408,7 @@ sendmsg: atm_sendmsg, recvmsg: atm_recvmsg, mmap: sock_no_mmap, + sendpage: sock_no_sendpage, }; |