Commit 424e8db5 authored by Stephen Hemminger's avatar Stephen Hemminger

[NET]: Convert /proc/net/dev_mcast to seq_file.

parent 53f02ec2
......@@ -41,6 +41,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <net/ip.h>
#include <net/route.h>
......@@ -219,59 +220,78 @@ void dev_mc_discard(struct net_device *dev)
}
#ifdef CONFIG_PROC_FS
static int dev_mc_read_proc(char *buffer, char **start, off_t offset,
int length, int *eof, void *data)
static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos)
{
off_t pos = 0, begin = 0;
struct dev_mc_list *m;
int len = 0;
struct net_device *dev;
loff_t off = 0;
read_lock(&dev_base_lock);
for (dev = dev_base; dev; dev = dev->next) {
spin_lock_bh(&dev->xmit_lock);
for (m = dev->mc_list; m; m = m->next) {
int i;
if (off++ == *pos)
return dev;
}
return NULL;
}
static void *dev_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct net_device *dev = v;
++*pos;
return dev->next;
}
len += sprintf(buffer+len,"%-4d %-15s %-5d %-5d ", dev->ifindex,
dev->name, m->dmi_users, m->dmi_gusers);
static void dev_mc_seq_stop(struct seq_file *seq, void *v)
{
read_unlock(&dev_base_lock);
}
for (i = 0; i < m->dmi_addrlen; i++)
len += sprintf(buffer+len, "%02x", m->dmi_addr[i]);
len += sprintf(buffer+len, "\n");
static int dev_mc_seq_show(struct seq_file *seq, void *v)
{
struct dev_mc_list *m;
struct net_device *dev = v;
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
if (pos > offset + length) {
spin_unlock_bh(&dev->xmit_lock);
goto done;
}
}
spin_unlock_bh(&dev->xmit_lock);
spin_lock_bh(&dev->xmit_lock);
for (m = dev->mc_list; m; m = m->next) {
int i;
seq_printf(seq, "%-4d %-15s %-5d %-5d ", dev->ifindex,
dev->name, m->dmi_users, m->dmi_gusers);
for (i = 0; i < m->dmi_addrlen; i++)
seq_printf(seq, "%02x", m->dmi_addr[i]);
seq_putc(seq, '\n');
}
*eof = 1;
spin_unlock_bh(&dev->xmit_lock);
return 0;
}
done:
read_unlock(&dev_base_lock);
*start = buffer + (offset - begin);
len -= (offset - begin);
if (len > length)
len = length;
if (len < 0)
len = 0;
return len;
static struct seq_operations dev_mc_seq_ops = {
.start = dev_mc_seq_start,
.next = dev_mc_seq_next,
.stop = dev_mc_seq_stop,
.show = dev_mc_seq_show,
};
static int dev_mc_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &dev_mc_seq_ops);
}
static struct file_operations dev_mc_seq_fops = {
.owner = THIS_MODULE,
.open = dev_mc_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
#endif
void __init dev_mcast_init(void)
{
#ifdef CONFIG_PROC_FS
create_proc_read_entry("net/dev_mcast", 0, 0, dev_mc_read_proc, NULL);
#endif
proc_net_fops_create("dev_mcast", 0, &dev_mc_seq_fops);
}
EXPORT_SYMBOL(dev_mc_add);
......
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