|
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,
};
|