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
If you don't know what to use this for, you don't need it.
config ETHERTAP
tristate "Ethertap network tap (OBSOLETE)"
depends on NETDEVICES && EXPERIMENTAL
tristate "Ethertap network tap"
depends on NETDEVICES && EXPERIMENTAL && NETLINK_DEV
---help---
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
......
......@@ -89,7 +89,6 @@ extern int apne_probe(struct net_device *);
extern int bionet_probe(struct net_device *);
extern int pamsnet_probe(struct net_device *);
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 bagetlance_probe(struct net_device *);
extern int mvme147lance_probe(struct net_device *dev);
......@@ -387,17 +386,6 @@ static int __init ethif_probe(struct net_device *dev)
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
extern int sdla_init(struct net_device *);
static struct net_device sdla0_dev = {
......
......@@ -33,7 +33,6 @@
* Index to functions.
*/
int ethertap_probe(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_close(struct net_device *dev);
......@@ -45,7 +44,11 @@ static void set_multicast_list(struct net_device *dev);
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.
......@@ -64,24 +67,28 @@ struct net_local
* To call this a probe is a bit misleading, however for real
* hardware it would have to check what was present.
*/
int __init ethertap_probe(struct net_device *dev)
static int __init ethertap_probe(int unit)
{
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);
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);
if (dev->mem_start & 0xf)
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.
*/
......@@ -94,17 +101,19 @@ int __init ethertap_probe(struct net_device *dev)
dev->set_multicast_list = set_multicast_list;
#endif
/*
* Setup the generic properties
*/
ether_setup(dev);
dev->tx_queue_len = 0;
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;
out_free:
free_netdev(dev);
out:
return err;
}
/*
......@@ -116,11 +125,12 @@ static int ethertap_open(struct net_device *dev)
struct net_local *lp = (struct net_local*)dev->priv;
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);
if (lp->nl == NULL)
return -ENOBUFS;
netif_start_queue(dev);
return 0;
}
......@@ -302,7 +312,7 @@ static void ethertap_rx(struct sock *sk, int len)
}
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)
ethertap_rx_skb(skb, dev);
......@@ -314,7 +324,7 @@ static int ethertap_close(struct net_device *dev)
struct sock *sk = lp->nl;
if (ethertap_debug > 2)
printk("%s: Shutting down.\n", dev->name);
printk(KERN_DEBUG "%s: Shutting down.\n", dev->name);
netif_stop_queue(dev);
......@@ -332,45 +342,49 @@ static struct net_device_stats *ethertap_get_stats(struct net_device *dev)
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 = " ",
.init = ethertap_probe
};
int i, err = 0;
int init_module(void)
{
dev_ethertap.base_addr=unit+NETLINK_TAPBASE;
sprintf(dev_ethertap.name,"tap%d",unit);
if (dev_get(dev_ethertap.name))
{
printk(KERN_INFO "%s already loaded.\n", dev_ethertap.name);
return -EBUSY;
/* netlink can only hande 16 entries unless modified */
if (max_taps > MAX_LINKS - NETLINK_TAPBASE)
return -E2BIG;
tap_map = kmalloc(sizeof(struct net_device *)*max_taps, GFP_KERNEL);
if (!tap_map)
return -ENOMEM;
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]);
}
break;
}
}
if (register_netdev(&dev_ethertap) != 0)
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;
unregister_netdev(&dev_ethertap);
/*
* Free up the private structure.
*/
kfree(dev_ethertap.priv);
dev_ethertap.priv = NULL; /* gets re-allocated by ethertap_probe */
int i;
for (i = 0; i < max_taps; i++) {
struct net_device *dev = tap_map[i];
if (dev) {
tap_map[i] = NULL;
unregister_netdev(dev);
free_netdev(dev);
}
}
kfree(tap_map);
}
module_exit(ethertap_cleanup);
#endif /* MODULE */
MODULE_LICENSE("GPL");
......@@ -230,12 +230,18 @@ static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL;
#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();
if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock)))
BUG();
if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) {
/* 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)
......@@ -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))
goto out;
icmp_xmit_lock();
if (icmp_xmit_lock())
return;
icmp_param->data.icmph.checksum = 0;
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)
}
}
icmp_xmit_lock();
if (icmp_xmit_lock())
return;
/*
* Construct source address and options.
......
......@@ -141,7 +141,7 @@ static void send_reset(struct sk_buff *oldskb, int local)
nskb->nf_debug = 0;
#endif
nskb->nfmark = 0;
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
#ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(nskb->nf_bridge);
nskb->nf_bridge = NULL;
#endif
......
......@@ -40,6 +40,7 @@
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/security.h>
......@@ -964,62 +965,108 @@ int netlink_post(int unit, struct sk_buff *skb)
#endif
#ifdef CONFIG_PROC_FS
static int netlink_read_proc(char *buffer, char **start, off_t offset,
int length, int *eof, void *data)
static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
{
off_t pos=0;
off_t begin=0;
int len=0;
int i;
struct sock *s;
struct hlist_node *node;
len+= sprintf(buffer,"sk Eth Pid Groups "
"Rmem Wmem Dump Locks\n");
loff_t off = 0;
for (i=0; i<MAX_LINKS; i++) {
read_lock(&nl_table_lock);
sk_for_each(s, node, &nl_table[i]) {
struct netlink_opt *nlk = nlk_sk(s);
len+=sprintf(buffer+len,"%p %-3d %-6d %08x %-8d %-8d %p %d",
s,
s->sk_protocol,
nlk->pid,
nlk->groups,
atomic_read(&s->sk_rmem_alloc),
atomic_read(&s->sk_wmem_alloc),
nlk->cb,
atomic_read(&s->sk_refcnt)
);
buffer[len++]='\n';
pos=begin+len;
if(pos<offset) {
len=0;
begin=pos;
if (off == pos) {
seq->private = (void *) i;
return s;
}
if(pos>offset+length) {
read_unlock(&nl_table_lock);
goto done;
++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;
}
}
read_unlock(&nl_table_lock);
}
*eof = 1;
done:
*start=buffer+(offset-begin);
len-=(offset-begin);
if(len>length)
len=length;
if(len<0)
len=0;
return len;
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);
seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %d\n",
s,
s->sk_protocol,
nlk->pid,
nlk->groups,
atomic_read(&s->sk_rmem_alloc),
atomic_read(&s->sk_wmem_alloc),
nlk->cb,
atomic_read(&s->sk_refcnt)
);
}
return 0;
}
struct seq_operations netlink_seq_ops = {
.start = netlink_seq_start,
.next = netlink_seq_next,
.stop = netlink_seq_stop,
.show = netlink_seq_show,
};
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
int netlink_register_notifier(struct notifier_block *nb)
......@@ -1069,7 +1116,7 @@ static int __init netlink_proto_init(void)
}
sock_register(&netlink_family_ops);
#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
/* The netlink device handler may be needed early. */
rtnetlink_init();
......@@ -1079,7 +1126,7 @@ static int __init netlink_proto_init(void)
static void __exit netlink_proto_exit(void)
{
sock_unregister(PF_NETLINK);
remove_proc_entry("net/netlink", NULL);
proc_net_remove("netlink");
}
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