Commit faa3c778 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.5

into home.osdl.org:/home/torvalds/v2.5/linux
parents 0b021260 fb582038
......@@ -66,7 +66,7 @@ static int atmtcp_send_control(struct atm_vcc *vcc,int type,
*(struct atm_vcc **) &new_msg->vcc = vcc;
old_test = test_bit(flag,&vcc->flags);
out_vcc->push(out_vcc,skb);
add_wait_queue(&vcc->sleep,&wait);
add_wait_queue(vcc->sk->sk_sleep, &wait);
while (test_bit(flag,&vcc->flags) == old_test) {
mb();
out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
......@@ -78,7 +78,7 @@ static int atmtcp_send_control(struct atm_vcc *vcc,int type,
schedule();
}
current->state = TASK_RUNNING;
remove_wait_queue(&vcc->sleep,&wait);
remove_wait_queue(vcc->sk->sk_sleep, &wait);
return error;
}
......@@ -90,7 +90,7 @@ static int atmtcp_recv_control(const struct atmtcp_control *msg)
vcc->vpi = msg->addr.sap_addr.vpi;
vcc->vci = msg->addr.sap_addr.vci;
vcc->qos = msg->qos;
vcc->reply = msg->result;
vcc->sk->sk_err = -msg->result;
switch (msg->type) {
case ATMTCP_CTRL_OPEN:
change_bit(ATM_VF_READY,&vcc->flags);
......@@ -103,7 +103,7 @@ static int atmtcp_recv_control(const struct atmtcp_control *msg)
msg->type);
return -EINVAL;
}
wake_up(&vcc->sleep);
wake_up(vcc->sk->sk_sleep);
return 0;
}
......@@ -134,7 +134,7 @@ static int atmtcp_v_open(struct atm_vcc *vcc,short vpi,int vci)
clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
if (error) return error;
return vcc->reply;
return -vcc->sk->sk_err;
}
......@@ -257,7 +257,7 @@ static void atmtcp_c_close(struct atm_vcc *vcc)
walk = atm_sk(s);
if (walk->dev != atmtcp_dev)
continue;
wake_up(&walk->sleep);
wake_up(walk->sk->sk_sleep);
}
read_unlock(&vcc_sklist_lock);
}
......
......@@ -162,22 +162,12 @@ static void eql_timer(unsigned long param)
static char version[] __initdata =
"Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)\n";
static int __init eql_init(struct net_device *dev)
static void __init eql_setup(struct net_device *dev)
{
static unsigned int version_printed;
equalizer_t *eql;
equalizer_t *eql = dev->priv;
SET_MODULE_OWNER(dev);
if (version_printed++ == 0)
printk(version);
dev->priv = kmalloc(sizeof (equalizer_t), GFP_KERNEL);
if (dev->priv == NULL)
return -ENOMEM;
memset(dev->priv, 0, sizeof (equalizer_t));
eql = dev->priv;
init_timer(&eql->timer);
eql->timer.data = (unsigned long) dev->priv;
eql->timer.expires = jiffies + EQL_DEFAULT_RESCHED_IVAL;
......@@ -203,8 +193,6 @@ static int __init eql_init(struct net_device *dev)
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 5; /* Hands them off fast */
return 0;
}
static int eql_open(struct net_device *dev)
......@@ -598,23 +586,28 @@ static int eql_s_master_cfg(struct net_device *dev, master_config_t *mcp)
return -EINVAL;
}
static struct net_device dev_eql;
static struct net_device *dev_eql;
static int __init eql_init_module(void)
{
strcpy(dev_eql.name, "eql");
dev_eql.init = eql_init;
if (register_netdev(&dev_eql) != 0) {
printk("eql: register_netdev() returned non-zero.\n");
return -EIO;
}
return 0;
int err;
printk(version);
dev_eql = alloc_netdev(sizeof(equalizer_t), "eql", eql_setup);
if (!dev_eql)
return -ENOMEM;
err = register_netdev(dev_eql);
if (err)
kfree(dev_eql);
return err;
}
static void __exit eql_cleanup_module(void)
{
kfree(dev_eql.priv);
unregister_netdev(&dev_eql);
unregister_netdev(dev_eql);
kfree(dev_eql);
}
module_init(eql_init_module);
......
......@@ -252,6 +252,7 @@ enum {
ATM_VF_SESSION, /* VCC is p2mp session control descriptor */
ATM_VF_HASSAP, /* SAP has been set */
ATM_VF_CLOSE, /* asynchronous close - treat like VF_RELEASED*/
ATM_VF_WAITING, /* waiting for reply from sigd */
};
......@@ -291,14 +292,11 @@ struct atm_vcc {
void *dev_data; /* per-device data */
void *proto_data; /* per-protocol data */
struct k_atm_aal_stats *stats; /* pointer to AAL stats group */
wait_queue_head_t sleep; /* if socket is busy */
struct sock *sk; /* socket backpointer */
/* SVC part --- may move later ------------------------------------- */
short itf; /* interface number */
struct sockaddr_atmsvc local;
struct sockaddr_atmsvc remote;
void (*callback)(struct atm_vcc *vcc);
int reply; /* also used by ATMTCP */
/* Multipoint part ------------------------------------------------- */
struct atm_vcc *session; /* session VCC descriptor */
/* Other stuff ----------------------------------------------------- */
......
......@@ -29,6 +29,7 @@
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/device.h>
#include <linux/percpu.h>
#include <asm/atomic.h>
#include <asm/cache.h>
......@@ -544,10 +545,9 @@ struct softnet_data
struct sk_buff *completion_queue;
struct net_device backlog_dev; /* Sorry. 8) */
} ____cacheline_aligned;
};
extern struct softnet_data softnet_data[NR_CPUS];
DECLARE_PER_CPU(struct softnet_data,softnet_data);
#define HAVE_NETIF_QUEUE
......@@ -555,12 +555,12 @@ static inline void __netif_schedule(struct net_device *dev)
{
if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
unsigned long flags;
int cpu;
struct softnet_data *sd;
local_irq_save(flags);
cpu = smp_processor_id();
dev->next_sched = softnet_data[cpu].output_queue;
softnet_data[cpu].output_queue = dev;
sd = &__get_cpu_var(softnet_data);
dev->next_sched = sd->output_queue;
sd->output_queue = dev;
raise_softirq_irqoff(NET_TX_SOFTIRQ);
local_irq_restore(flags);
}
......@@ -605,13 +605,13 @@ static inline int netif_running(const struct net_device *dev)
static inline void dev_kfree_skb_irq(struct sk_buff *skb)
{
if (atomic_dec_and_test(&skb->users)) {
int cpu;
struct softnet_data *sd;
unsigned long flags;
local_irq_save(flags);
cpu = smp_processor_id();
skb->next = softnet_data[cpu].completion_queue;
softnet_data[cpu].completion_queue = skb;
sd = &__get_cpu_var(softnet_data);
skb->next = sd->completion_queue;
sd->completion_queue = skb;
raise_softirq_irqoff(NET_TX_SOFTIRQ);
local_irq_restore(flags);
}
......@@ -769,12 +769,10 @@ static inline int netif_rx_schedule_prep(struct net_device *dev)
static inline void __netif_rx_schedule(struct net_device *dev)
{
unsigned long flags;
int cpu;
local_irq_save(flags);
cpu = smp_processor_id();
dev_hold(dev);
list_add_tail(&dev->poll_list, &softnet_data[cpu].poll_list);
list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
if (dev->quota < 0)
dev->quota += dev->weight;
else
......@@ -798,13 +796,11 @@ static inline int netif_rx_reschedule(struct net_device *dev, int undo)
{
if (netif_rx_schedule_prep(dev)) {
unsigned long flags;
int cpu;
dev->quota += undo;
local_irq_save(flags);
cpu = smp_processor_id();
list_add_tail(&dev->poll_list, &softnet_data[cpu].poll_list);
list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
__raise_softirq_irqoff(NET_RX_SOFTIRQ);
local_irq_restore(flags);
return 1;
......
......@@ -887,7 +887,6 @@ extern int sysctl_ip_vs_cache_bypass;
extern int sysctl_ip_vs_expire_nodest_conn;
extern int sysctl_ip_vs_sync_threshold[2];
extern int sysctl_ip_vs_nat_icmp_send;
extern atomic_t ip_vs_dropentry;
extern struct ip_vs_stats ip_vs_stats;
extern struct ip_vs_service *
......@@ -902,7 +901,6 @@ extern struct ip_vs_dest *
ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport);
extern int ip_vs_use_count_inc(void);
extern void ip_vs_use_count_dec(void);
extern void update_defense_level(void);
extern int ip_vs_control_init(void);
extern void ip_vs_control_cleanup(void);
......
......@@ -16,9 +16,12 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary
#include <linux/ip.h>
#include <asm/uaccess.h>
#include <net/arp.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/atmbr2684.h>
#include "common.h"
#include "ipcommon.h"
/*
......@@ -768,8 +771,6 @@ static struct file_operations br2684_proc_operations = {
extern struct proc_dir_entry *atm_proc_root; /* from proc.c */
extern int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
/* the following avoids some spurious warnings from the compiler */
#define UNUSED __attribute__((unused))
......@@ -779,14 +780,14 @@ static int __init UNUSED br2684_init(void)
if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL)
return -ENOMEM;
p->proc_fops = &br2684_proc_operations;
br2684_ioctl_hook = br2684_ioctl;
br2684_ioctl_set(br2684_ioctl);
return 0;
}
static void __exit UNUSED br2684_exit(void)
{
struct br2684_dev *brdev;
br2684_ioctl_hook = NULL;
br2684_ioctl_set(NULL);
remove_proc_entry("br2684", atm_proc_root);
while (!list_empty(&br2684_devs)) {
brdev = list_entry_brdev(br2684_devs.next);
......
......@@ -67,7 +67,7 @@ static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip)
ctrl->ip = ip;
atm_force_charge(atmarpd,skb->truesize);
skb_queue_tail(&atmarpd->sk->sk_receive_queue, skb);
wake_up(&atmarpd->sleep);
atmarpd->sk->sk_data_ready(atmarpd->sk, skb->len);
return 0;
}
......
......@@ -129,14 +129,34 @@ EXPORT_SYMBOL(atm_clip_ops_set);
#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);
static DECLARE_MUTEX(pppoatm_ioctl_mutex);
static int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
void pppoatm_ioctl_set(int (*hook)(struct atm_vcc *, unsigned int, unsigned long))
{
down(&pppoatm_ioctl_mutex);
pppoatm_ioctl_hook = hook;
up(&pppoatm_ioctl_mutex);
}
#ifdef CONFIG_PPPOATM_MODULE
EXPORT_SYMBOL(pppoatm_ioctl_set);
#endif
#endif
#if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
static DECLARE_MUTEX(br2684_ioctl_mutex);
static int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
void br2684_ioctl_set(int (*hook)(struct atm_vcc *, unsigned int, unsigned long))
{
down(&br2684_ioctl_mutex);
br2684_ioctl_hook = hook;
up(&br2684_ioctl_mutex);
}
#ifdef CONFIG_ATM_BR2684_MODULE
EXPORT_SYMBOL(br2684_ioctl_hook);
EXPORT_SYMBOL(br2684_ioctl_set);
#endif
#endif
......@@ -215,6 +235,37 @@ static void vcc_sock_destruct(struct sock *sk)
kfree(sk->sk_protinfo);
}
static void vcc_def_wakeup(struct sock *sk)
{
read_lock(&sk->sk_callback_lock);
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up(sk->sk_sleep);
read_unlock(&sk->sk_callback_lock);
}
static inline int vcc_writable(struct sock *sk)
{
struct atm_vcc *vcc = atm_sk(sk);
return (vcc->qos.txtp.max_sdu +
atomic_read(&sk->sk_wmem_alloc)) <= sk->sk_sndbuf;
}
static void vcc_write_space(struct sock *sk)
{
read_lock(&sk->sk_callback_lock);
if (vcc_writable(sk)) {
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up_interruptible(sk->sk_sleep);
sk_wake_async(sk, 2, POLL_OUT);
}
read_unlock(&sk->sk_callback_lock);
}
int vcc_create(struct socket *sock, int protocol, int family)
{
......@@ -227,7 +278,9 @@ int vcc_create(struct socket *sock, int protocol, int family)
sk = sk_alloc(family, GFP_KERNEL, 1, NULL);
if (!sk)
return -ENOMEM;
sock_init_data(NULL, sk);
sock_init_data(sock, sk);
sk->sk_state_change = vcc_def_wakeup;
sk->sk_write_space = vcc_write_space;
vcc = atm_sk(sk) = kmalloc(sizeof(*vcc), GFP_KERNEL);
if (!vcc) {
......@@ -238,7 +291,6 @@ int vcc_create(struct socket *sock, int protocol, int family)
memset(vcc, 0, sizeof(*vcc));
vcc->sk = sk;
vcc->dev = NULL;
vcc->callback = NULL;
memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc));
memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc));
vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */
......@@ -249,8 +301,6 @@ int vcc_create(struct socket *sock, int protocol, int family)
vcc->push_oam = NULL;
vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
vcc->atm_options = vcc->aal_options = 0;
init_waitqueue_head(&vcc->sleep);
sk->sk_sleep = &vcc->sleep;
sk->sk_destruct = vcc_sock_destruct;
sock->sk = sk;
return 0;
......@@ -300,9 +350,9 @@ int vcc_release(struct socket *sock)
void vcc_release_async(struct atm_vcc *vcc, int reply)
{
set_bit(ATM_VF_CLOSE, &vcc->flags);
vcc->reply = reply;
vcc->sk->sk_err = -reply;
wake_up(&vcc->sleep);
clear_bit(ATM_VF_WAITING, &vcc->flags);
vcc->sk->sk_state_change(vcc->sk);
}
......@@ -475,7 +525,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
vcc = ATM_SD(sock);
if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
test_bit(ATM_VF_CLOSE,&vcc->flags))
return vcc->reply;
return -sk->sk_err;
if (!test_bit(ATM_VF_READY, &vcc->flags))
return 0;
......@@ -532,7 +582,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
vcc = ATM_SD(sock);
if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
test_bit(ATM_VF_CLOSE, &vcc->flags)) {
error = vcc->reply;
error = -sk->sk_err;
goto out;
}
if (!test_bit(ATM_VF_READY, &vcc->flags)) {
......@@ -549,7 +599,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
}
/* verify_area is done by net/socket.c */
eff = (size+3) & ~3; /* align to word boundary */
prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
error = 0;
while (!(skb = alloc_tx(vcc,eff))) {
if (m->msg_flags & MSG_DONTWAIT) {
......@@ -563,16 +613,16 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
}
if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
test_bit(ATM_VF_CLOSE,&vcc->flags)) {
error = vcc->reply;
error = -sk->sk_err;
break;
}
if (!test_bit(ATM_VF_READY,&vcc->flags)) {
error = -EPIPE;
break;
}
prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
}
finish_wait(&vcc->sleep, &wait);
finish_wait(sk->sk_sleep, &wait);
if (error)
goto out;
skb->dev = NULL; /* for paths shared with net_device interfaces */
......@@ -591,29 +641,38 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
}
unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait)
unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
{
struct sock *sk = sock->sk;
struct atm_vcc *vcc;
unsigned int mask;
vcc = ATM_SD(sock);
poll_wait(file,&vcc->sleep,wait);
poll_wait(file, sk->sk_sleep, wait);
mask = 0;
if (skb_peek(&vcc->sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
test_bit(ATM_VF_CLOSE,&vcc->flags))
vcc = ATM_SD(sock);
/* exceptional events */
if (sk->sk_err)
mask = POLLERR;
if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
test_bit(ATM_VF_CLOSE, &vcc->flags))
mask |= POLLHUP;
if (sock->state != SS_CONNECTING) {
if (vcc->qos.txtp.traffic_class != ATM_NONE &&
vcc->qos.txtp.max_sdu +
atomic_read(&vcc->sk->sk_wmem_alloc) <= vcc->sk->sk_sndbuf)
mask |= POLLOUT | POLLWRNORM;
}
else if (vcc->reply != WAITING) {
mask |= POLLOUT | POLLWRNORM;
if (vcc->reply) mask |= POLLERR;
}
/* readable? */
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
/* writable? */
if (sock->state == SS_CONNECTING &&
test_bit(ATM_VF_WAITING, &vcc->flags))
return mask;
if (vcc->qos.txtp.traffic_class != ATM_NONE &&
vcc_writable(vcc->sk))
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
return mask;
}
......@@ -859,19 +918,22 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
default:
break;
}
error = -ENOIOCTLCMD;
#if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
if (pppoatm_ioctl_hook) {
down(&pppoatm_ioctl_mutex);
if (pppoatm_ioctl_hook)
error = pppoatm_ioctl_hook(vcc, cmd, arg);
if (error != -ENOIOCTLCMD)
goto done;
}
up(&pppoatm_ioctl_mutex);
if (error != -ENOIOCTLCMD)
goto done;
#endif
#if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
if (br2684_ioctl_hook) {
down(&br2684_ioctl_mutex);
if (br2684_ioctl_hook)
error = br2684_ioctl_hook(vcc, cmd, arg);
if (error != -ENOIOCTLCMD)
goto done;
}
up(&br2684_ioctl_mutex);
if (error != -ENOIOCTLCMD)
goto done;
#endif
error = atm_dev_ioctl(cmd, arg);
......
......@@ -17,7 +17,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
int size, int flags);
int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
int total_len);
unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait);
unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval,
int optlen);
......@@ -26,6 +26,9 @@ int vcc_getsockopt(struct socket *sock, int level, int optname, char *optval,
void atm_shutdown_dev(struct atm_dev *dev);
void pppoatm_ioctl_set(int (*hook)(struct atm_vcc *, unsigned int, unsigned long));
void br2684_ioctl_set(int (*hook)(struct atm_vcc *, unsigned int, unsigned long));
int atmpvc_init(void);
void atmpvc_exit(void);
int atmsvc_init(void);
......
......@@ -134,7 +134,7 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
priv = (struct lec_priv *)dev->priv;
atm_force_charge(priv->lecd, skb2->truesize);
skb_queue_tail(&priv->lecd->sk->sk_receive_queue, skb2);
wake_up(&priv->lecd->sleep);
priv->lecd->sk->sk_data_ready(priv->lecd->sk, skb2->len);
}
return;
......@@ -513,7 +513,7 @@ lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
memcpy(skb2->data, mesg, sizeof(struct atmlec_msg));
atm_force_charge(priv->lecd, skb2->truesize);
skb_queue_tail(&priv->lecd->sk->sk_receive_queue, skb2);
wake_up(&priv->lecd->sleep);
priv->lecd->sk->sk_data_ready(priv->lecd->sk, skb2->len);
}
if (f != NULL) br_fdb_put_hook(f);
#endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
......@@ -598,13 +598,13 @@ send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
atm_force_charge(priv->lecd, skb->truesize);
skb_queue_tail(&priv->lecd->sk->sk_receive_queue, skb);
wake_up(&priv->lecd->sleep);
priv->lecd->sk->sk_data_ready(priv->lecd->sk, skb->len);
if (data != NULL) {
DPRINTK("lec: about to send %d bytes of data\n", data->len);
atm_force_charge(priv->lecd, data->truesize);
skb_queue_tail(&priv->lecd->sk->sk_receive_queue, data);
wake_up(&priv->lecd->sleep);
priv->lecd->sk->sk_data_ready(priv->lecd->sk, skb->len);
}
return 0;
......@@ -686,7 +686,7 @@ lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
if (memcmp(skb->data, lec_ctrl_magic, 4) ==0) { /* Control frame, to daemon*/
DPRINTK("%s: To daemon\n",dev->name);
skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
wake_up(&vcc->sleep);
vcc->sk->sk_data_ready(vcc->sk, skb->len);
} else { /* Data frame, queue to protocol handlers */
unsigned char *dst;
......
......@@ -669,7 +669,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb)
dprintk("mpoa: (%s) mpc_push: control packet arrived\n", dev->name);
/* Pass control packets to daemon */
skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
wake_up(&vcc->sleep);
vcc->sk->sk_data_ready(vcc->sk, skb->len);
return;
}
......@@ -947,7 +947,7 @@ int msg_to_mpoad(struct k_message *mesg, struct mpoa_client *mpc)
memcpy(skb->data, mesg, sizeof(struct k_message));
atm_force_charge(mpc->mpoad_vcc, skb->truesize);
skb_queue_tail(&mpc->mpoad_vcc->sk->sk_receive_queue, skb);
wake_up(&mpc->mpoad_vcc->sleep);
mpc->mpoad_vcc->sk->sk_data_ready(mpc->mpoad_vcc->sk, skb->len);
return 0;
}
......@@ -1226,7 +1226,7 @@ static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry)
atm_force_charge(vcc, skb->truesize);
skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
wake_up(&vcc->sleep);
vcc->sk->sk_data_ready(vcc->sk, skb->len);
dprintk("mpoa: purge_egress_shortcut: exiting:\n");
return;
......
......@@ -44,6 +44,8 @@
#include <linux/ppp_channel.h>
#include <linux/atmppp.h>
#include "common.h"
#if 0
#define DPRINTK(format, args...) \
printk(KERN_DEBUG "pppoatm: " format, ##args)
......@@ -344,17 +346,15 @@ static int pppoatm_ioctl(struct atm_vcc *atmvcc, unsigned int cmd,
/* 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;
pppoatm_ioctl_set(pppoatm_ioctl);
return 0;
}
static void __exit UNUSED pppoatm_exit(void)
{
pppoatm_ioctl_hook = NULL;
pppoatm_ioctl_set(NULL);
}
module_init(pppoatm_init);
......
......@@ -224,7 +224,7 @@ static void vc_info(struct atm_vcc *vcc,char *buf)
here += sprintf(here, "%3d", vcc->sk->sk_family);
}
here += sprintf(here," %04lx %5d %7d/%7d %7d/%7d\n",vcc->flags,
vcc->reply,
vcc->sk->sk_err,
atomic_read(&vcc->sk->sk_wmem_alloc), vcc->sk->sk_sndbuf,
atomic_read(&vcc->sk->sk_rmem_alloc), vcc->sk->sk_rcvbuf);
}
......
......@@ -111,7 +111,7 @@ static struct proto_ops pvc_proto_ops = {
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.getname = pvc_getname,
.poll = atm_poll,
.poll = vcc_poll,
.ioctl = vcc_ioctl,
.listen = sock_no_listen,
.shutdown = pvc_shutdown,
......
......@@ -29,7 +29,7 @@ void atm_push_raw(struct atm_vcc *vcc,struct sk_buff *skb)
{
if (skb) {
skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
wake_up(&vcc->sleep);
vcc->sk->sk_data_ready(vcc->sk, skb->len);
}
}
......@@ -40,7 +40,7 @@ static void atm_pop_raw(struct atm_vcc *vcc,struct sk_buff *skb)
skb->truesize);
atomic_sub(skb->truesize, &vcc->sk->sk_wmem_alloc);
dev_kfree_skb_any(skb);
wake_up(&vcc->sleep);
vcc->sk->sk_write_space(vcc->sk);
}
......
......@@ -61,7 +61,7 @@ static void sigd_put_skb(struct sk_buff *skb)
#endif
atm_force_charge(sigd,skb->truesize);
skb_queue_tail(&sigd->sk->sk_receive_queue,skb);
wake_up(&sigd->sleep);
sigd->sk->sk_data_ready(sigd->sk, skb->len);
}
......@@ -103,7 +103,8 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb)
vcc = *(struct atm_vcc **) &msg->vcc;
switch (msg->type) {
case as_okay:
vcc->reply = msg->reply;
vcc->sk->sk_err = -msg->reply;
clear_bit(ATM_VF_WAITING, &vcc->flags);
if (!*vcc->local.sas_addr.prv &&
!*vcc->local.sas_addr.pub) {
vcc->local.sas_family = AF_ATMSVC;
......@@ -123,8 +124,8 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb)
case as_error:
clear_bit(ATM_VF_REGIS,&vcc->flags);
clear_bit(ATM_VF_READY,&vcc->flags);
vcc->reply = msg->reply;
vcc->sk->sk_err = -msg->reply;
clear_bit(ATM_VF_WAITING, &vcc->flags);
break;
case as_indicate:
vcc = *(struct atm_vcc **) &msg->listen_vcc;
......@@ -137,19 +138,16 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb)
}
vcc->sk->sk_ack_backlog++;
skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
if (vcc->callback) {
DPRINTK("waking vcc->sleep 0x%p\n",
&vcc->sleep);
vcc->callback(vcc);
}
DPRINTK("waking vcc->sk->sk_sleep 0x%p\n", vcc->sk->sk_sleep);
vcc->sk->sk_state_change(vcc->sk);
as_indicate_complete:
release_sock(vcc->sk);
return 0;
case as_close:
set_bit(ATM_VF_RELEASED,&vcc->flags);
clear_bit(ATM_VF_READY,&vcc->flags);
vcc->reply = msg->reply;
vcc->sk->sk_err = -msg->reply;
clear_bit(ATM_VF_WAITING, &vcc->flags);
break;
case as_modify:
modify_qos(vcc,msg);
......@@ -159,7 +157,7 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb)
(int) msg->type);
return -EINVAL;
}
if (vcc->callback) vcc->callback(vcc);
vcc->sk->sk_state_change(vcc->sk);
dev_kfree_skb(skb);
return 0;
}
......@@ -205,9 +203,9 @@ static void purge_vcc(struct atm_vcc *vcc)
if (vcc->sk->sk_family == PF_ATMSVC &&
!test_bit(ATM_VF_META,&vcc->flags)) {
set_bit(ATM_VF_RELEASED,&vcc->flags);
vcc->reply = -EUNATCH;
vcc->sk->sk_err = EUNATCH;
wake_up(&vcc->sleep);
clear_bit(ATM_VF_WAITING, &vcc->flags);
vcc->sk->sk_state_change(vcc->sk);
}
}
......
......@@ -11,9 +11,6 @@
#include <linux/atmsvc.h>
#define WAITING 1 /* for reply: 0: no error, < 0: error, ... */
extern struct atm_vcc *sigd; /* needed in svc_release */
......
......@@ -43,14 +43,6 @@ static int svc_create(struct socket *sock,int protocol);
*/
void svc_callback(struct atm_vcc *vcc)
{
wake_up(&vcc->sleep);
}
static int svc_shutdown(struct socket *sock,int how)
{
return 0;
......@@ -64,13 +56,13 @@ static void svc_disconnect(struct atm_vcc *vcc)
DPRINTK("svc_disconnect %p\n",vcc);
if (test_bit(ATM_VF_REGIS,&vcc->flags)) {
prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(vcc,as_close,NULL,NULL,NULL);
while (!test_bit(ATM_VF_RELEASED,&vcc->flags) && sigd) {
schedule();
prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
}
finish_wait(&vcc->sleep, &wait);
finish_wait(vcc->sk->sk_sleep, &wait);
}
/* beware - socket is still in use by atmsigd until the last
as_indicate has been answered */
......@@ -145,22 +137,22 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr,
goto out;
}
vcc->local = *addr;
vcc->reply = WAITING;
prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
while (vcc->reply == WAITING && sigd) {
while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
schedule();
prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
}
finish_wait(&vcc->sleep, &wait);
finish_wait(sk->sk_sleep, &wait);
clear_bit(ATM_VF_REGIS,&vcc->flags); /* doesn't count */
if (!sigd) {
error = -EUNATCH;
goto out;
}
if (!vcc->reply)
if (!sk->sk_err)
set_bit(ATM_VF_BOUND,&vcc->flags);
error = vcc->reply;
error = -sk->sk_err;
out:
release_sock(sk);
return error;
......@@ -191,13 +183,13 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
error = -EISCONN;
goto out;
case SS_CONNECTING:
if (vcc->reply == WAITING) {
if (test_bit(ATM_VF_WAITING, &vcc->flags)) {
error = -EALREADY;
goto out;
}
sock->state = SS_UNCONNECTED;
if (vcc->reply) {
error = vcc->reply;
if (sk->sk_err) {
error = -sk->sk_err;
goto out;
}
break;
......@@ -226,20 +218,20 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
goto out;
}
vcc->remote = *addr;
vcc->reply = WAITING;
prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote);
if (flags & O_NONBLOCK) {
finish_wait(&vcc->sleep, &wait);
finish_wait(sk->sk_sleep, &wait);
sock->state = SS_CONNECTING;
error = -EINPROGRESS;
goto out;
}
error = 0;
while (vcc->reply == WAITING && sigd) {
while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
schedule();
if (!signal_pending(current)) {
prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
continue;
}
DPRINTK("*ABORT*\n");
......@@ -256,14 +248,14 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
* Kernel <--close--- Demon
*/
sigd_enq(vcc,as_close,NULL,NULL,NULL);
while (vcc->reply == WAITING && sigd) {
prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
schedule();
}
if (!vcc->reply)
if (!sk->sk_err)
while (!test_bit(ATM_VF_RELEASED,&vcc->flags)
&& sigd) {
prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
schedule();
}
clear_bit(ATM_VF_REGIS,&vcc->flags);
......@@ -273,15 +265,15 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
error = -EINTR;
break;
}
finish_wait(&vcc->sleep, &wait);
finish_wait(sk->sk_sleep, &wait);
if (error)
goto out;
if (!sigd) {
error = -EUNATCH;
goto out;
}
if (vcc->reply) {
error = vcc->reply;
if (sk->sk_err) {
error = -sk->sk_err;
goto out;
}
}
......@@ -319,14 +311,14 @@ static int svc_listen(struct socket *sock,int backlog)
error = -EINVAL;
goto out;
}
vcc->reply = WAITING;
prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
while (vcc->reply == WAITING && sigd) {
while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
schedule();
prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
}
finish_wait(&vcc->sleep, &wait);
finish_wait(sk->sk_sleep, &wait);
if (!sigd) {
error = -EUNATCH;
goto out;
......@@ -334,7 +326,7 @@ static int svc_listen(struct socket *sock,int backlog)
set_bit(ATM_VF_LISTEN,&vcc->flags);
vcc->sk->sk_max_ack_backlog = backlog > 0 ? backlog :
ATM_BACKLOG_DEFAULT;
error = vcc->reply;
error = -sk->sk_err;
out:
release_sock(sk);
return error;
......@@ -362,12 +354,12 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
while (1) {
DEFINE_WAIT(wait);
prepare_to_wait(&old_vcc->sleep, &wait, TASK_INTERRUPTIBLE);
prepare_to_wait(old_vcc->sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
while (!(skb = skb_dequeue(&old_vcc->sk->sk_receive_queue)) &&
sigd) {
if (test_bit(ATM_VF_RELEASED,&old_vcc->flags)) break;
if (test_bit(ATM_VF_CLOSE,&old_vcc->flags)) {
error = old_vcc->reply;
error = -sk->sk_err;
break;
}
if (flags & O_NONBLOCK) {
......@@ -381,9 +373,9 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
error = -ERESTARTSYS;
break;
}
prepare_to_wait(&old_vcc->sleep, &wait, TASK_INTERRUPTIBLE);
prepare_to_wait(old_vcc->sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
}
finish_wait(&old_vcc->sleep, &wait);
finish_wait(old_vcc->sk->sk_sleep, &wait);
if (error)
goto out;
if (!skb) {
......@@ -407,23 +399,24 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
goto out;
}
/* wait should be short, so we ignore the non-blocking flag */
new_vcc->reply = WAITING;
prepare_to_wait(&new_vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
set_bit(ATM_VF_WAITING, &new_vcc->flags);
prepare_to_wait(new_vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
while (new_vcc->reply == WAITING && sigd) {
while (test_bit(ATM_VF_WAITING, &new_vcc->flags) && sigd) {
release_sock(sk);
schedule();
lock_sock(sk);
prepare_to_wait(&new_vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
prepare_to_wait(new_vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
}
finish_wait(&new_vcc->sleep, &wait);
finish_wait(new_vcc->sk->sk_sleep, &wait);
if (!sigd) {
error = -EUNATCH;
goto out;
}
if (!new_vcc->reply) break;
if (new_vcc->reply != -ERESTARTSYS) {
error = new_vcc->reply;
if (!new_vcc->sk->sk_err)
break;
if (new_vcc->sk->sk_err != ERESTARTSYS) {
error = -new_vcc->sk->sk_err;
goto out;
}
}
......@@ -451,17 +444,17 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
{
DEFINE_WAIT(wait);
vcc->reply = WAITING;
prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags)
&& sigd) {
while (test_bit(ATM_VF_WAITING, &vcc->flags) &&
!test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) {
schedule();
prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
}
finish_wait(&vcc->sleep, &wait);
finish_wait(vcc->sk->sk_sleep, &wait);
if (!sigd) return -EUNATCH;
return vcc->reply;
return -vcc->sk->sk_err;
}
......@@ -527,7 +520,7 @@ static struct proto_ops svc_proto_ops = {
.socketpair = sock_no_socketpair,
.accept = svc_accept,
.getname = svc_getname,
.poll = atm_poll,
.poll = vcc_poll,
.ioctl = vcc_ioctl,
.listen = svc_listen,
.shutdown = svc_shutdown,
......@@ -547,7 +540,6 @@ static int svc_create(struct socket *sock,int protocol)
sock->ops = &svc_proto_ops;
error = vcc_create(sock, protocol, AF_ATMSVC);
if (error) return error;
ATM_SD(sock)->callback = svc_callback;
ATM_SD(sock)->local.sas_family = AF_ATMSVC;
ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
return 0;
......
......@@ -178,7 +178,7 @@ static struct notifier_block *netdev_chain;
* Device drivers call our routines to queue packets here. We empty the
* queue in the local softnet handler.
*/
struct softnet_data softnet_data[NR_CPUS] __cacheline_aligned;
DEFINE_PER_CPU(struct softnet_data, softnet_data) = { 0, };
#ifdef CONFIG_NET_FASTROUTE
int netdev_fastroute;
......@@ -1280,34 +1280,35 @@ static void get_sample_stats(int cpu)
unsigned long rd;
int rq;
#endif
int blog = softnet_data[cpu].input_pkt_queue.qlen;
int avg_blog = softnet_data[cpu].avg_blog;
struct softnet_data *sd = &per_cpu(softnet_data, cpu);
int blog = sd->input_pkt_queue.qlen;
int avg_blog = sd->avg_blog;
avg_blog = (avg_blog >> 1) + (blog >> 1);
if (avg_blog > mod_cong) {
/* Above moderate congestion levels. */
softnet_data[cpu].cng_level = NET_RX_CN_HIGH;
sd->cng_level = NET_RX_CN_HIGH;
#ifdef RAND_LIE
rd = net_random();
rq = rd % netdev_max_backlog;
if (rq < avg_blog) /* unlucky bastard */
softnet_data[cpu].cng_level = NET_RX_DROP;
sd->cng_level = NET_RX_DROP;
#endif
} else if (avg_blog > lo_cong) {
softnet_data[cpu].cng_level = NET_RX_CN_MOD;
sd->cng_level = NET_RX_CN_MOD;
#ifdef RAND_LIE
rd = net_random();
rq = rd % netdev_max_backlog;
if (rq < avg_blog) /* unlucky bastard */
softnet_data[cpu].cng_level = NET_RX_CN_HIGH;
sd->cng_level = NET_RX_CN_HIGH;
#endif
} else if (avg_blog > no_cong)
softnet_data[cpu].cng_level = NET_RX_CN_LOW;
sd->cng_level = NET_RX_CN_LOW;
else /* no congestion */
softnet_data[cpu].cng_level = NET_RX_SUCCESS;
sd->cng_level = NET_RX_SUCCESS;
softnet_data[cpu].avg_blog = avg_blog;
sd->avg_blog = avg_blog;
}
#ifdef OFFLINE_SAMPLE
......@@ -1357,7 +1358,7 @@ int netif_rx(struct sk_buff *skb)
*/
local_irq_save(flags);
this_cpu = smp_processor_id();
queue = &softnet_data[this_cpu];
queue = &__get_cpu_var(softnet_data);
netdev_rx_stat[this_cpu].total++;
if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
......@@ -1445,14 +1446,14 @@ static __inline__ void skb_bond(struct sk_buff *skb)
static void net_tx_action(struct softirq_action *h)
{
int cpu = smp_processor_id();
struct softnet_data *sd = &__get_cpu_var(softnet_data);
if (softnet_data[cpu].completion_queue) {
if (sd->completion_queue) {
struct sk_buff *clist;
local_irq_disable();
clist = softnet_data[cpu].completion_queue;
softnet_data[cpu].completion_queue = NULL;
clist = sd->completion_queue;
sd->completion_queue = NULL;
local_irq_enable();
while (clist) {
......@@ -1464,12 +1465,12 @@ static void net_tx_action(struct softirq_action *h)
}
}
if (softnet_data[cpu].output_queue) {
if (sd->output_queue) {
struct net_device *head;
local_irq_disable();
head = softnet_data[cpu].output_queue;
softnet_data[cpu].output_queue = NULL;
head = sd->output_queue;
sd->output_queue = NULL;
local_irq_enable();
while (head) {
......@@ -1611,8 +1612,7 @@ static int process_backlog(struct net_device *backlog_dev, int *budget)
{
int work = 0;
int quota = min(backlog_dev->quota, *budget);
int this_cpu = smp_processor_id();
struct softnet_data *queue = &softnet_data[this_cpu];
struct softnet_data *queue = &__get_cpu_var(softnet_data);
unsigned long start_time = jiffies;
for (;;) {
......@@ -1673,7 +1673,7 @@ static int process_backlog(struct net_device *backlog_dev, int *budget)
static void net_rx_action(struct softirq_action *h)
{
int this_cpu = smp_processor_id();
struct softnet_data *queue = &softnet_data[this_cpu];
struct softnet_data *queue = &__get_cpu_var(softnet_data);
unsigned long start_time = jiffies;
int budget = netdev_max_backlog;
......@@ -2979,7 +2979,7 @@ static int __init net_dev_init(void)
for (i = 0; i < NR_CPUS; i++) {
struct softnet_data *queue;
queue = &softnet_data[i];
queue = &per_cpu(softnet_data, i);
skb_queue_head_init(&queue->input_pkt_queue);
queue->throttle = 0;
queue->cng_level = 0;
......
......@@ -816,6 +816,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
skb_set_owner_w(new_skb, skb->sk);
dev_kfree_skb(skb);
skb = new_skb;
old_iph = skb->nh.iph;
}
skb->nh.raw = skb_push(skb, gre_hlen);
......
......@@ -616,6 +616,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
skb_set_owner_w(new_skb, skb->sk);
dev_kfree_skb(skb);
skb = new_skb;
old_iph = skb->nh.iph;
}
skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
......
......@@ -147,7 +147,7 @@ config IP_VS_WLC
unsure, say N.
config IP_VS_LBLC
tristate "locality-based least-connection with replication scheduling"
tristate "locality-based least-connection scheduling"
depends on IP_VS
---help---
The locality-based least-connection scheduling algorithm is for
......@@ -163,7 +163,7 @@ config IP_VS_LBLC
unsure, say N.
config IP_VS_LBLCR
tristate "locality-based least-connection with replication schedulin"
tristate "locality-based least-connection with replication scheduling"
depends on IP_VS
---help---
The locality-based least-connection with replication scheduling
......
......@@ -507,9 +507,6 @@ static void ip_vs_conn_expire(unsigned long data)
* refcnt==1 implies I'm the only one referrer
*/
if (likely(atomic_read(&cp->refcnt) == 1)) {
/* make sure that there is no timer on it now */
del_timer_sync(&cp->timer);
/* does anybody control me? */
if (cp->control)
ip_vs_control_del(cp);
......@@ -517,7 +514,6 @@ static void ip_vs_conn_expire(unsigned long data)
if (unlikely(cp->app != NULL))
ip_vs_unbind_app(cp);
ip_vs_unbind_dest(cp);
//ip_vs_timeout_detach(cp);
if (cp->flags & IP_VS_CONN_F_NO_CPORT)
atomic_dec(&ip_vs_conn_no_cport_cnt);
atomic_dec(&ip_vs_conn_count);
......
......@@ -93,7 +93,7 @@ int ip_vs_get_debug_level(void)
/*
* update_defense_level is called from timer bh and from sysctl.
*/
void update_defense_level(void)
static void update_defense_level(void)
{
struct sysinfo i;
static int old_secure_tcp = 0;
......@@ -210,6 +210,22 @@ void update_defense_level(void)
}
/*
* Timer for checking the defense
*/
static struct timer_list defense_timer;
#define DEFENSE_TIMER_PERIOD 1*HZ
static void defense_timer_handler(unsigned long data)
{
update_defense_level();
if (atomic_read(&ip_vs_dropentry))
ip_vs_random_dropentry();
mod_timer(&defense_timer, jiffies + DEFENSE_TIMER_PERIOD);
}
int
ip_vs_use_count_inc(void)
{
......@@ -2187,6 +2203,12 @@ int ip_vs_control_init(void)
ip_vs_stats.lock = SPIN_LOCK_UNLOCKED;
ip_vs_new_estimator(&ip_vs_stats);
/* Hook the defense timer */
init_timer(&defense_timer);
defense_timer.function = defense_timer_handler;
defense_timer.expires = jiffies + DEFENSE_TIMER_PERIOD;
add_timer(&defense_timer);
LeaveFunction(2);
return 0;
}
......@@ -2196,6 +2218,7 @@ void ip_vs_control_cleanup(void)
{
EnterFunction(2);
ip_vs_trash_cleanup();
del_timer_sync(&defense_timer);
ip_vs_kill_estimator(&ip_vs_stats);
unregister_sysctl_table(ipv4_vs_table.sysctl_header);
proc_net_remove("ip_vs_stats");
......
......@@ -78,7 +78,6 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
.daddr = dest->addr,
.saddr = 0,
.tos = rtos, } },
.proto = cp->protocol,
};
if (ip_route_output_key(&rt, &fl)) {
......@@ -102,7 +101,6 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
.daddr = dest->addr,
.saddr = 0,
.tos = rtos, } },
.proto = cp->protocol,
};
if (ip_route_output_key(&rt, &fl)) {
......
......@@ -19,7 +19,7 @@
*
* Mitsuru KANDA @USAGI : IPv6 Support
* Kazunori MIYAZAWA @USAGI :
* Kunihiro Ishiguro :
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
*
* This file is derived from net/ipv4/ah.c.
*/
......
......@@ -19,7 +19,7 @@
*
* Mitsuru KANDA @USAGI : IPv6 Support
* Kazunori MIYAZAWA @USAGI :
* Kunihiro Ishiguro :
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
*
* This file is derived from net/ipv4/esp.c
*/
......
......@@ -567,6 +567,11 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
if (unlikely(rt == NULL))
goto out;
if (dev)
dev_hold(dev);
if (neigh)
neigh_hold(neigh);
rt->rt6i_dev = dev;
rt->rt6i_nexthop = neigh;
rt->rt6i_expires = 0;
......
......@@ -550,6 +550,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
skb_set_owner_w(new_skb, skb->sk);
dev_kfree_skb(skb);
skb = new_skb;
iph6 = skb->nh.ipv6h;
}
skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
......
......@@ -579,7 +579,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
addr_type = ipv6_addr_type(&usin->sin6_addr);
if(addr_type & IPV6_ADDR_MULTICAST)
if (addr_type & (IPV6_ADDR_ANYCAST | IPV6_ADDR_MULTICAST))
return -ENETUNREACH;
if (addr_type&IPV6_ADDR_LINKLOCAL) {
......@@ -967,12 +967,14 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
struct tcphdr *th = skb->h.th, *t1;
struct sk_buff *buff;
struct flowi fl;
int daddr_type;
if (th->rst)
return;
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
return;
daddr_type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
if (daddr_type & (IPV6_ADDR_ANYCAST | IPV6_ADDR_MULTICAST))
return;
/*
* We need to grab some memory, and put together an RST,
......@@ -1171,13 +1173,14 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
struct tcp_opt tmptp, *tp = tcp_sk(sk);
struct open_request *req = NULL;
__u32 isn = TCP_SKB_CB(skb)->when;
int daddr_type;
if (skb->protocol == htons(ETH_P_IP))
return tcp_v4_conn_request(sk, skb);
/* FIXME: do the same check for anycast */
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
goto drop;
daddr_type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
if (daddr_type & (IPV6_ADDR_ANYCAST | IPV6_ADDR_MULTICAST))
goto drop;
/*
* There are no SYN attacks on IPv6, yet...
......
......@@ -4,7 +4,7 @@
* Authors:
* Mitsuru KANDA @USAGI
* Kazunori MIYAZAWA @USAGI
* Kunihiro Ishiguro
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* YOSHIFUJI Hideaki @USAGI
* IPv6 support
*/
......
......@@ -4,7 +4,7 @@
* Authors:
* Mitsuru KANDA @USAGI
* Kazunori MIYAZAWA @USAGI
* Kunihiro Ishiguro
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* IPv6 support
* YOSHIFUJI Hideaki
* Split up af-specific portion
......
......@@ -4,7 +4,7 @@
* Authors:
* Mitsuru KANDA @USAGI
* Kazunori MIYAZAWA @USAGI
* Kunihiro Ishiguro
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* IPv6 support
* YOSHIFUJI Hideaki @USAGI
* Split up af-specific portion
......
......@@ -685,7 +685,7 @@ EXPORT_SYMBOL(ip_route_me_harder);
EXPORT_SYMBOL(register_gifconf);
EXPORT_SYMBOL(softnet_data);
EXPORT_PER_CPU_SYMBOL(softnet_data);
#ifdef CONFIG_NET_RADIO
#include <net/iw_handler.h> /* Wireless Extensions driver API */
......
......@@ -4,7 +4,7 @@
* Changes:
* Mitsuru KANDA @USAGI
* Kazunori MIYAZAWA @USAGI
* Kunihiro Ishiguro
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* IPv6 support
* Kazunori MIYAZAWA @USAGI
* YOSHIFUJI Hideaki
......
......@@ -4,7 +4,7 @@
* Changes:
* Mitsuru KANDA @USAGI
* Kazunori MIYAZAWA @USAGI
* Kunihiro Ishiguro
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* IPv6 support
* YOSHIFUJI Hideaki @USAGI
* Split up af-specific functions
......
......@@ -5,7 +5,7 @@
* Changes:
* Mitsuru KANDA @USAGI
* Kazunori MIYAZAWA @USAGI
* Kunihiro Ishiguro
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* IPv6 support
*
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment