我一直在查看net/core/dev.c和其他文件,尝试找出如何获取当前配置的网络设备列表,但发现有些困难。
最终目标是能够使用dev.c中的dev_get_stats获取网络设备的统计信息,但我需要知道当前的接口,以便获取net_device结构体进行传递。由于我正在编写一个模块,它会添加一个新的/proc/条目,以显示当前网络设备的某些统计信息,因此必须在内核中完成此操作。
如果有人能够指导我如何获取这些接口,将不胜感激。
我一直在查看net/core/dev.c和其他文件,尝试找出如何获取当前配置的网络设备列表,但发现有些困难。
最终目标是能够使用dev.c中的dev_get_stats获取网络设备的统计信息,但我需要知道当前的接口,以便获取net_device结构体进行传递。由于我正在编写一个模块,它会添加一个新的/proc/条目,以显示当前网络设备的某些统计信息,因此必须在内核中完成此操作。
如果有人能够指导我如何获取这些接口,将不胜感激。
这个应该可以解决问题:
#include <linux/netdevice.h>
struct net_device *dev;
read_lock(&dev_base_lock);
dev = first_net_device(&init_net);
while (dev) {
printk(KERN_INFO "found [%s]\n", dev->name);
dev = next_net_device(dev);
}
read_unlock(&dev_base_lock);
dev_base_lock
)。 - caf给定一个标识你感兴趣的网络命名空间的 struct net *net
,你应该获取 dev_base_lock
并使用 for_each_netdev()
:
read_lock(&dev_base_lock);
for_each_netdev(net, dev) {
/* Inspect dev */
}
read_unlock(&dev_base_lock);
在较新的内核中,您可以使用RCU,但在这种情况下可能会过于复杂。
要获取要使用的net
名称空间,您应该使用register_pernet_subsys()
注册您的proc
文件:
static const struct file_operations foostats_seq_fops = {
.owner = THIS_MODULE,
.open = foostats_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = foostats_seq_release,
};
static int foo_proc_init_net(struct net *net)
{
if (!proc_net_fops_create(net, "foostats", S_IRUGO,
&foostats_seq_fops))
return -ENOMEM;
return 0;
}
static void foo_proc_exit_net(struct net *net)
{
proc_net_remove(net, "foostats");
}
static struct pernet_operations foo_proc_ops = {
.init = foo_proc_init_net,
.exit = foo_proc_exit_net,
};
register_pernet_subsys(&foo_proc_ops)
在你的foostats_seq_open()
函数中,你引用了net
命名空间,并在释放函数中将其删除:
static int foostats_seq_open(struct inode *inode, struct file *file)
{
int err;
struct net *net;
err = -ENXIO;
net = get_proc_net(inode);
if (net == NULL)
goto err_net;
err = single_open(file, foostats_seq_show, net);
if (err < 0)
goto err_open;
return 0;
err_open:
put_net(net);
err_net:
return err;
}
static int foostats_seq_release(struct inode *inode, struct file *file)
{
struct net *net = ((struct seq_file *)file->private_data)->private;
put_net(net);
return single_release(inode, file);
}
foostats_seq_show()
函数可以获取 net
,遍历设备,收集统计信息并生成输出:
static int sockstat6_seq_show(struct seq_file *seq, void *v)
{
struct net *net = seq->private;
struct net_device *dev;
int foostat, barstat;
read_lock(&dev_base_lock);
for_each_netdev(net, dev) {
/* Inspect dev */
}
read_unlock(&dev_base_lock);
seq_printf(seq, "Foo: %d\n", foostat);
seq_printf(seq, "Bar: %d\n", barstat);
return 0;
}