【问题标题】:Getting list of network devices inside the Linux kernel获取 Linux 内核中的网络设备列表
【发布时间】:2011-05-28 12:22:54
【问题描述】:

我一直在查看 net/core/dev.c 和其他文件,试图找出如何获取当前配置的网络设备列表,但事实证明这有点难以找到。

最终目标是能够使用 dev.c 中的 dev_get_stats 获取网络设备统计信息,但我需要知道当前接口,以便获取 net_device 结构以传入。我必须在内核,因为我正在编写一个模块,该模块添加了一个新的 /proc/ 条目,该条目与当前网络设备的一些统计信息相关,因此据我所知,这必须在内核中完成。

如果有人能指出如何获得接口,将不胜感激。

【问题讨论】:

标签: linux network-programming linux-kernel kernel-module


【解决方案1】:

这应该可以解决问题:

#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)。
  • 太棒了!就像一个魅力,就像我在看错文件干杯!
  • 如果可能的话,您能否也解决我的问题,stackoverflow.com/questions/36917950/…
【解决方案2】:

给定一个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;
}

【讨论】:

    猜你喜欢
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2015-01-27
    • 2014-03-13
    • 2014-10-27
    相关资源
    最近更新 更多