Commit b18a7cb9 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 0bc1a622 c79bd96d
...@@ -132,8 +132,8 @@ config TUN ...@@ -132,8 +132,8 @@ config TUN
If you don't know what to use this for, you don't need it. If you don't know what to use this for, you don't need it.
config ETHERTAP config ETHERTAP
tristate "Ethertap network tap (OBSOLETE)" tristate "Ethertap network tap"
depends on NETDEVICES && EXPERIMENTAL depends on NETDEVICES && EXPERIMENTAL && NETLINK_DEV
---help--- ---help---
If you say Y here (and have said Y to "Kernel/User network link If you say Y here (and have said Y to "Kernel/User network link
driver", above) and create a character special file /dev/tap0 with driver", above) and create a character special file /dev/tap0 with
......
...@@ -89,7 +89,6 @@ extern int apne_probe(struct net_device *); ...@@ -89,7 +89,6 @@ extern int apne_probe(struct net_device *);
extern int bionet_probe(struct net_device *); extern int bionet_probe(struct net_device *);
extern int pamsnet_probe(struct net_device *); extern int pamsnet_probe(struct net_device *);
extern int cs89x0_probe(struct net_device *dev); extern int cs89x0_probe(struct net_device *dev);
extern int ethertap_probe(struct net_device *dev);
extern int hplance_probe(struct net_device *dev); extern int hplance_probe(struct net_device *dev);
extern int bagetlance_probe(struct net_device *); extern int bagetlance_probe(struct net_device *);
extern int mvme147lance_probe(struct net_device *dev); extern int mvme147lance_probe(struct net_device *dev);
...@@ -387,17 +386,6 @@ static int __init ethif_probe(struct net_device *dev) ...@@ -387,17 +386,6 @@ static int __init ethif_probe(struct net_device *dev)
return -ENODEV; return -ENODEV;
} }
#ifdef CONFIG_ETHERTAP
static struct net_device tap0_dev = {
.name = "tap0",
.base_addr = NETLINK_TAPBASE,
.next = NEXT_DEV,
.init = ethertap_probe,
};
#undef NEXT_DEV
#define NEXT_DEV (&tap0_dev)
#endif
#ifdef CONFIG_SDLA #ifdef CONFIG_SDLA
extern int sdla_init(struct net_device *); extern int sdla_init(struct net_device *);
static struct net_device sdla0_dev = { static struct net_device sdla0_dev = {
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
* Index to functions. * Index to functions.
*/ */
int ethertap_probe(struct net_device *dev);
static int ethertap_open(struct net_device *dev); static int ethertap_open(struct net_device *dev);
static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev); static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int ethertap_close(struct net_device *dev); static int ethertap_close(struct net_device *dev);
...@@ -45,7 +44,11 @@ static void set_multicast_list(struct net_device *dev); ...@@ -45,7 +44,11 @@ static void set_multicast_list(struct net_device *dev);
static int ethertap_debug; static int ethertap_debug;
static struct net_device *tap_map[32]; /* Returns the tap device for a given netlink */ static int max_taps = 1;
MODULE_PARM(max_taps, "i");
MODULE_PARM_DESC(max_taps,"Max number of ethernet tap devices");
static struct net_device **tap_map; /* Returns the tap device for a given netlink */
/* /*
* Board-specific info in dev->priv. * Board-specific info in dev->priv.
...@@ -64,24 +67,28 @@ struct net_local ...@@ -64,24 +67,28 @@ struct net_local
* To call this a probe is a bit misleading, however for real * To call this a probe is a bit misleading, however for real
* hardware it would have to check what was present. * hardware it would have to check what was present.
*/ */
static int __init ethertap_probe(int unit)
int __init ethertap_probe(struct net_device *dev)
{ {
struct net_device *dev;
int err = -ENOMEM;
dev = alloc_netdev(sizeof(struct net_local), "tap%d",
ether_setup);
if (!dev)
goto out;
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
sprintf(dev->name, "tap%d", unit);
dev->base_addr = unit + NETLINK_TAPBASE;
netdev_boot_setup_check(dev);
memcpy(dev->dev_addr, "\xFE\xFD\x00\x00\x00\x00", 6); memcpy(dev->dev_addr, "\xFE\xFD\x00\x00\x00\x00", 6);
if (dev->mem_start & 0xf) if (dev->mem_start & 0xf)
ethertap_debug = dev->mem_start & 0x7; ethertap_debug = dev->mem_start & 0x7;
/*
* Initialize the device structure.
*/
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
if (dev->priv == NULL)
return -ENOMEM;
memset(dev->priv, 0, sizeof(struct net_local));
/* /*
* The tap specific entries in the device structure. * The tap specific entries in the device structure.
*/ */
...@@ -94,17 +101,19 @@ int __init ethertap_probe(struct net_device *dev) ...@@ -94,17 +101,19 @@ int __init ethertap_probe(struct net_device *dev)
dev->set_multicast_list = set_multicast_list; dev->set_multicast_list = set_multicast_list;
#endif #endif
/*
* Setup the generic properties
*/
ether_setup(dev);
dev->tx_queue_len = 0; dev->tx_queue_len = 0;
dev->flags|=IFF_NOARP; dev->flags|=IFF_NOARP;
tap_map[dev->base_addr]=dev;
err = register_netdev(dev);
if (err)
goto out_free;
tap_map[unit]=dev;
return 0; return 0;
out_free:
free_netdev(dev);
out:
return err;
} }
/* /*
...@@ -116,11 +125,12 @@ static int ethertap_open(struct net_device *dev) ...@@ -116,11 +125,12 @@ static int ethertap_open(struct net_device *dev)
struct net_local *lp = (struct net_local*)dev->priv; struct net_local *lp = (struct net_local*)dev->priv;
if (ethertap_debug > 2) if (ethertap_debug > 2)
printk("%s: Doing ethertap_open()...", dev->name); printk(KERN_DEBUG "%s: Doing ethertap_open()...", dev->name);
lp->nl = netlink_kernel_create(dev->base_addr, ethertap_rx); lp->nl = netlink_kernel_create(dev->base_addr, ethertap_rx);
if (lp->nl == NULL) if (lp->nl == NULL)
return -ENOBUFS; return -ENOBUFS;
netif_start_queue(dev); netif_start_queue(dev);
return 0; return 0;
} }
...@@ -302,7 +312,7 @@ static void ethertap_rx(struct sock *sk, int len) ...@@ -302,7 +312,7 @@ static void ethertap_rx(struct sock *sk, int len)
} }
if (ethertap_debug > 3) if (ethertap_debug > 3)
printk("%s: ethertap_rx()\n", dev->name); printk(KERN_DEBUG "%s: ethertap_rx()\n", dev->name);
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL)
ethertap_rx_skb(skb, dev); ethertap_rx_skb(skb, dev);
...@@ -314,7 +324,7 @@ static int ethertap_close(struct net_device *dev) ...@@ -314,7 +324,7 @@ static int ethertap_close(struct net_device *dev)
struct sock *sk = lp->nl; struct sock *sk = lp->nl;
if (ethertap_debug > 2) if (ethertap_debug > 2)
printk("%s: Shutting down.\n", dev->name); printk(KERN_DEBUG "%s: Shutting down.\n", dev->name);
netif_stop_queue(dev); netif_stop_queue(dev);
...@@ -332,45 +342,49 @@ static struct net_device_stats *ethertap_get_stats(struct net_device *dev) ...@@ -332,45 +342,49 @@ static struct net_device_stats *ethertap_get_stats(struct net_device *dev)
return &lp->stats; return &lp->stats;
} }
#ifdef MODULE
static int unit;
MODULE_PARM(unit,"i");
MODULE_PARM_DESC(unit,"Ethertap device number");
static struct net_device dev_ethertap = int __init ethertap_init(void)
{ {
.name = " ", int i, err = 0;
.init = ethertap_probe
};
int init_module(void) /* netlink can only hande 16 entries unless modified */
{ if (max_taps > MAX_LINKS - NETLINK_TAPBASE)
dev_ethertap.base_addr=unit+NETLINK_TAPBASE; return -E2BIG;
sprintf(dev_ethertap.name,"tap%d",unit);
if (dev_get(dev_ethertap.name)) tap_map = kmalloc(sizeof(struct net_device *)*max_taps, GFP_KERNEL);
{ if (!tap_map)
printk(KERN_INFO "%s already loaded.\n", dev_ethertap.name); return -ENOMEM;
return -EBUSY;
for (i = 0; i < max_taps; i++) {
err = ethertap_probe(i);
if (err) {
while (--i > 0) {
unregister_netdev(tap_map[i]);
free_netdev(tap_map[i]);
} }
if (register_netdev(&dev_ethertap) != 0) break;
return -EIO; }
return 0; }
if (err)
kfree(tap_map);
return err;
} }
module_init(ethertap_init);
void cleanup_module(void) void __exit ethertap_cleanup(void)
{ {
tap_map[dev_ethertap.base_addr]=NULL; int i;
unregister_netdev(&dev_ethertap);
for (i = 0; i < max_taps; i++) {
/* struct net_device *dev = tap_map[i];
* Free up the private structure. if (dev) {
*/ tap_map[i] = NULL;
unregister_netdev(dev);
kfree(dev_ethertap.priv); free_netdev(dev);
dev_ethertap.priv = NULL; /* gets re-allocated by ethertap_probe */ }
}
kfree(tap_map);
} }
module_exit(ethertap_cleanup);
#endif /* MODULE */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -230,12 +230,18 @@ static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; ...@@ -230,12 +230,18 @@ static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL; static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL;
#define icmp_socket __get_cpu_var(__icmp_socket) #define icmp_socket __get_cpu_var(__icmp_socket)
static __inline__ void icmp_xmit_lock(void) static __inline__ int icmp_xmit_lock(void)
{ {
local_bh_disable(); local_bh_disable();
if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) {
BUG(); /* This can happen if the output path signals a
* dst_link_failure() for an outgoing ICMP packet.
*/
local_bh_enable();
return 1;
}
return 0;
} }
static void icmp_xmit_unlock(void) static void icmp_xmit_unlock(void)
...@@ -376,7 +382,8 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) ...@@ -376,7 +382,8 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
if (ip_options_echo(&icmp_param->replyopts, skb)) if (ip_options_echo(&icmp_param->replyopts, skb))
goto out; goto out;
icmp_xmit_lock(); if (icmp_xmit_lock())
return;
icmp_param->data.icmph.checksum = 0; icmp_param->data.icmph.checksum = 0;
icmp_out_count(icmp_param->data.icmph.type); icmp_out_count(icmp_param->data.icmph.type);
...@@ -488,7 +495,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info) ...@@ -488,7 +495,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
} }
} }
icmp_xmit_lock(); if (icmp_xmit_lock())
return;
/* /*
* Construct source address and options. * Construct source address and options.
......
...@@ -141,7 +141,7 @@ static void send_reset(struct sk_buff *oldskb, int local) ...@@ -141,7 +141,7 @@ static void send_reset(struct sk_buff *oldskb, int local)
nskb->nf_debug = 0; nskb->nf_debug = 0;
#endif #endif
nskb->nfmark = 0; nskb->nfmark = 0;
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) #ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(nskb->nf_bridge); nf_bridge_put(nskb->nf_bridge);
nskb->nf_bridge = NULL; nskb->nf_bridge = NULL;
#endif #endif
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/security.h> #include <linux/security.h>
...@@ -964,27 +965,73 @@ int netlink_post(int unit, struct sk_buff *skb) ...@@ -964,27 +965,73 @@ int netlink_post(int unit, struct sk_buff *skb)
#endif #endif
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static int netlink_read_proc(char *buffer, char **start, off_t offset, static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
int length, int *eof, void *data)
{ {
off_t pos=0;
off_t begin=0;
int len=0;
int i; int i;
struct sock *s; struct sock *s;
struct hlist_node *node; struct hlist_node *node;
loff_t off = 0;
len+= sprintf(buffer,"sk Eth Pid Groups "
"Rmem Wmem Dump Locks\n");
for (i=0; i<MAX_LINKS; i++) { for (i=0; i<MAX_LINKS; i++) {
read_lock(&nl_table_lock);
sk_for_each(s, node, &nl_table[i]) { sk_for_each(s, node, &nl_table[i]) {
if (off == pos) {
seq->private = (void *) i;
return s;
}
++off;
}
}
return NULL;
}
static void *netlink_seq_start(struct seq_file *seq, loff_t *pos)
{
read_lock(&nl_table_lock);
return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : (void *) 1;
}
static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct sock *s;
++*pos;
if (v == (void *) 1)
return netlink_seq_socket_idx(seq, 0);
s = sk_next(v);
if (!s) {
int i = (int) seq->private;
while (++i < MAX_LINKS) {
s = sk_head(&nl_table[i]);
if (s) {
seq->private = (void *) i;
break;
}
}
}
return s;
}
static void netlink_seq_stop(struct seq_file *seq, void *v)
{
read_unlock(&nl_table_lock);
}
static int netlink_seq_show(struct seq_file *seq, void *v)
{
if (v == (void *)1)
seq_puts(seq,
"sk Eth Pid Groups "
"Rmem Wmem Dump Locks\n");
else {
struct sock *s = v;
struct netlink_opt *nlk = nlk_sk(s); struct netlink_opt *nlk = nlk_sk(s);
len+=sprintf(buffer+len,"%p %-3d %-6d %08x %-8d %-8d %p %d", seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %d\n",
s, s,
s->sk_protocol, s->sk_protocol,
nlk->pid, nlk->pid,
...@@ -995,31 +1042,31 @@ static int netlink_read_proc(char *buffer, char **start, off_t offset, ...@@ -995,31 +1042,31 @@ static int netlink_read_proc(char *buffer, char **start, off_t offset,
atomic_read(&s->sk_refcnt) atomic_read(&s->sk_refcnt)
); );
buffer[len++]='\n';
pos=begin+len;
if(pos<offset) {
len=0;
begin=pos;
}
if(pos>offset+length) {
read_unlock(&nl_table_lock);
goto done;
}
}
read_unlock(&nl_table_lock);
} }
*eof = 1; return 0;
}
done:
*start=buffer+(offset-begin); struct seq_operations netlink_seq_ops = {
len-=(offset-begin); .start = netlink_seq_start,
if(len>length) .next = netlink_seq_next,
len=length; .stop = netlink_seq_stop,
if(len<0) .show = netlink_seq_show,
len=0; };
return len;
static int netlink_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &netlink_seq_ops);
} }
static struct file_operations netlink_seq_fops = {
.owner = THIS_MODULE,
.open = netlink_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
#endif #endif
int netlink_register_notifier(struct notifier_block *nb) int netlink_register_notifier(struct notifier_block *nb)
...@@ -1069,7 +1116,7 @@ static int __init netlink_proto_init(void) ...@@ -1069,7 +1116,7 @@ static int __init netlink_proto_init(void)
} }
sock_register(&netlink_family_ops); sock_register(&netlink_family_ops);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
create_proc_read_entry("net/netlink", 0, 0, netlink_read_proc, NULL); proc_net_fops_create("netlink", 0, &netlink_seq_fops);
#endif #endif
/* The netlink device handler may be needed early. */ /* The netlink device handler may be needed early. */
rtnetlink_init(); rtnetlink_init();
...@@ -1079,7 +1126,7 @@ static int __init netlink_proto_init(void) ...@@ -1079,7 +1126,7 @@ static int __init netlink_proto_init(void)
static void __exit netlink_proto_exit(void) static void __exit netlink_proto_exit(void)
{ {
sock_unregister(PF_NETLINK); sock_unregister(PF_NETLINK);
remove_proc_entry("net/netlink", NULL); proc_net_remove("netlink");
} }
core_initcall(netlink_proto_init); core_initcall(netlink_proto_init);
......
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