15

私はnet/core / dev.cやその他のファイルを調べて、現在構成されているネットワークデバイスのリストを取得する方法を見つけようとしていますが、見つけるのが少し難しいことがわかっています。

最終的な目標は、dev.cのdev_get_statsを使用してネットワークデバイスの統計を取得できるようにすることですが、net_device構造体を取得して渡すことができるように、現在のインターフェイスを知る必要があります。これは、カーネル内で行う必要があります。現在のネットワークデバイスからの統計に関連する新しい/proc/エントリを追加するモジュールを作成しているので、収集できるものから、これはカーネル内で実行する必要があります。

誰かが私にインターフェースを取得する方法を教えてくれたら、それは大いにありがたいです。

4

2 に答える 2

17

これでうまくいくはずです:

#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);
于 2010-12-20T23:04:25.663 に答える
17

関心のあるネット名前空間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使用する名前空間を取得するには、procファイルをregister_pernet_subsys()次のように登録する必要があります。

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;
}
于 2010-12-21T00:43:46.497 に答える