Commit f10972be authored by David S. Miller's avatar David S. Miller

Merge master.kernel.org:/home/acme/BK/llc-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 414abb51 2bbb6a8e
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* PPPoE --- PPP over Ethernet (RFC 2516) * PPPoE --- PPP over Ethernet (RFC 2516)
* *
* *
* Version: 0.6.10 * Version: 0.6.11
* *
* 220102 : Fix module use count on failure in pppoe_create, pppox_sk -acme * 220102 : Fix module use count on failure in pppoe_create, pppox_sk -acme
* 030700 : Fixed connect logic to allow for disconnect. * 030700 : Fixed connect logic to allow for disconnect.
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
* 121301 : New ppp channels interface; cannot unregister a channel * 121301 : New ppp channels interface; cannot unregister a channel
* from interrupts. Thus, we mark the socket as a ZOMBIE * from interrupts. Thus, we mark the socket as a ZOMBIE
* and do the unregistration later. * and do the unregistration later.
* 081002 : seq_file support for proc stuff -acme
* *
* Author: Michal Ostrowski <mostrows@speakeasy.net> * Author: Michal Ostrowski <mostrows@speakeasy.net>
* Contributors: * Contributors:
...@@ -75,6 +76,7 @@ ...@@ -75,6 +76,7 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
...@@ -974,63 +976,102 @@ int pppoe_rcvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, int ...@@ -974,63 +976,102 @@ int pppoe_rcvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, int
return error; return error;
} }
int pppoe_proc_info(char *buffer, char **start, off_t offset, int length) #ifdef CONFIG_PROC_FS
static int pppoe_seq_show(struct seq_file *seq, void *v)
{ {
struct pppox_opt *po; struct pppox_opt *po;
int len = 0; char *dev_name;
off_t pos = 0;
off_t begin = 0;
int size;
int i;
len += sprintf(buffer, if (v == (void *)1) {
"Id Address Device\n"); seq_puts(seq, "Id Address Device\n");
pos = len; goto out;
}
write_lock_bh(&pppoe_hash_lock); po = v;
dev_name = po->pppoe_pa.dev;
for (i = 0; i < PPPOE_HASH_SIZE; i++) { seq_printf(seq, "%08X %02X:%02X:%02X:%02X:%02X:%02X %8s\n",
po->pppoe_pa.sid,
po->pppoe_pa.remote[0], po->pppoe_pa.remote[1],
po->pppoe_pa.remote[2], po->pppoe_pa.remote[3],
po->pppoe_pa.remote[4], po->pppoe_pa.remote[5], dev_name);
out:
return 0;
}
static __inline__ struct pppox_opt *pppoe_get_idx(loff_t pos)
{
struct pppox_opt *po = NULL;
int i = 0;
for (; i < PPPOE_HASH_SIZE; i++) {
po = item_hash_table[i]; po = item_hash_table[i];
while (po) { while (po) {
char *dev = po->pppoe_pa.dev; if (!pos--)
goto out;
size = sprintf(buffer + len, po = po->next;
"%08X %02X:%02X:%02X:%02X:%02X:%02X %8s\n", }
po->pppoe_pa.sid,
po->pppoe_pa.remote[0],
po->pppoe_pa.remote[1],
po->pppoe_pa.remote[2],
po->pppoe_pa.remote[3],
po->pppoe_pa.remote[4],
po->pppoe_pa.remote[5],
dev);
len += size;
pos += size;
if (pos < offset) {
len = 0;
begin = pos;
} }
out:
return po;
}
if (pos > offset + length) static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos)
break; {
loff_t l = *pos;
po = po->next; read_lock_bh(&pppoe_hash_lock);
return l ? pppoe_get_idx(--l) : (void *)1;
}
static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct pppox_opt *po;
++*pos;
if (v == (void *)1) {
po = pppoe_get_idx(0);
goto out;
} }
po = v;
po = po->next;
if (!po) {
int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
while (++hash < PPPOE_HASH_SIZE) {
po = item_hash_table[hash];
if (po) if (po)
break; break;
} }
write_unlock_bh(&pppoe_hash_lock); }
out:
return po;
}
*start = buffer + (offset - begin); static void pppoe_seq_stop(struct seq_file *seq, void *v)
len -= (offset - begin); {
if (len > length) read_unlock_bh(&pppoe_hash_lock);
len = length;
if (len < 0)
len = 0;
return len;
} }
struct seq_operations pppoe_seq_ops = {
.start = pppoe_seq_start,
.next = pppoe_seq_next,
.stop = pppoe_seq_stop,
.show = pppoe_seq_show,
};
static int pppoe_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &pppoe_seq_ops);
}
static struct file_operations pppoe_seq_fops = {
.open = pppoe_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
#endif /* CONFIG_PROC_FS */
struct proto_ops pppoe_ops = { struct proto_ops pppoe_ops = {
.family = AF_PPPOX, .family = AF_PPPOX,
...@@ -1061,13 +1102,28 @@ int __init pppoe_init(void) ...@@ -1061,13 +1102,28 @@ int __init pppoe_init(void)
{ {
int err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto); int err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
if (err == 0) { if (err)
goto out;
#ifdef CONFIG_PROC_FS
{
struct proc_dir_entry *p = create_proc_entry("pppoe", S_IRUGO,
proc_net);
err = -ENOMEM;
if (!p)
goto out_unregister;
p->proc_fops = &pppoe_seq_fops;
err = 0;
}
#endif /* CONFIG_PROC_FS */
dev_add_pack(&pppoes_ptype); dev_add_pack(&pppoes_ptype);
dev_add_pack(&pppoed_ptype); dev_add_pack(&pppoed_ptype);
register_netdevice_notifier(&pppoe_notifier); register_netdevice_notifier(&pppoe_notifier);
proc_net_create("pppoe", 0, pppoe_proc_info); out:
}
return err; return err;
out_unregister:
unregister_pppox_proto(PX_PROTO_OE);
goto out;
} }
void __exit pppoe_exit(void) void __exit pppoe_exit(void)
...@@ -1076,7 +1132,7 @@ void __exit pppoe_exit(void) ...@@ -1076,7 +1132,7 @@ void __exit pppoe_exit(void)
dev_remove_pack(&pppoes_ptype); dev_remove_pack(&pppoes_ptype);
dev_remove_pack(&pppoed_ptype); dev_remove_pack(&pppoed_ptype);
unregister_netdevice_notifier(&pppoe_notifier); unregister_netdevice_notifier(&pppoe_notifier);
proc_net_remove("pppoe"); remove_proc_entry("pppoe", proc_net);
} }
module_init(pppoe_init); module_init(pppoe_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