Как мне создать "netlink" между ядром и пользовательским пространством? - PullRequest
4 голосов
/ 30 апреля 2009

Я хочу использовать netlink для связи между приложением и пространством ядра. Моя версия ядра Linux - 2.6.28, и мой код неверен:

nf_sock=netlink_kernel_create(NL_PROTO,0,nl_user_skb,THIS_MODULE);

Сокращенное сообщение об ошибке:

error: too few arguments to function 'netlink_kernel_create'

В файле <linux/netlink.h> функция netlink_kernel_create() определяется как

extern struct sock *netlink_kernel_create(struct net *net,int unit,unsigned int groups,void (*input)(struct sk_buff *skb),struct mutex *cb_mutex,struct module *module)

Я не понимаю, что использовать для первого аргумента, net. Может кто-нибудь объяснить, что я должен использовать здесь?

Ответы [ 4 ]

4 голосов
/ 01 мая 2009

A struct net содержит информацию о сетевом пространстве имен, наборе сетевых ресурсов, доступных процессам. Обратите внимание, что может быть несколько сетевых пространств имен (то есть несколько экземпляров сетевого стека), но большинство драйверов используют пространство имен init_net.

Ваш звонок должен выглядеть примерно так:

nf_sock = netlink_kernel_create(&init_net,
                                NETLINK_USERSOCK,
                                0,
                                nl_rcv_func,
                                NULL,
                                THIS_MODULE);

где nl_rcv_func - функция, принимающая struct sk_buff *skb в качестве единственного аргумента и обрабатывающая полученное сообщение netlink.

2 голосов
/ 30 апреля 2009

Вы, похоже, следовали руководству, такому как , этому , которое (начиная с 2005 года) вполне могло опередить развитие ядра. Похоже, что внутренний API для создания netlink со стороны ядра изменился.

Либо проверьте папку Documentation / в локальном дереве ядра на наличие некоторой (возможно, более свежей) документации, либо прочитайте сам код. Вы также можете trawl архивы списков рассылки ядра Linux для любого упоминания об изменениях, которые, по-видимому, произошли.

Здесь - это фактическая реализация по состоянию на 2.6.29, если вы предпочитаете загадывать ее задом наперед (и, конечно, еще не проверяли это в своем дереве).

1 голос
/ 13 ноября 2012

Да, struct net действительно предназначена для пространства имен net, но не всегда нужно использовать init_net, вы должны зарегистрировать свои собственные pernet_operations, например:

static struct pernet_operations fib_net_ops = {
        .init = fib_net_init,
        .exit = fib_net_exit,
};

static int __net_init fib_net_init(struct net *net)
{
        int error;

#ifdef CONFIG_IP_ROUTE_CLASSID
        net->ipv4.fib_num_tclassid_users = 0;
#endif
        error = ip_fib_net_init(net);
        if (error < 0)
                goto out;
        error = nl_fib_lookup_init(net);
        if (error < 0)
                goto out_nlfl;
        error = fib_proc_init(net);
        if (error < 0)
                goto out_proc;
out:
        return error;

out_proc:
        nl_fib_lookup_exit(net);
out_nlfl:
        ip_fib_net_exit(net);
        goto out;
}

static int __net_init nl_fib_lookup_init(struct net *net)
{
        struct sock *sk;
        struct netlink_kernel_cfg cfg = {
                .input  = nl_fib_input,
        };

        sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, &cfg);
        if (sk == NULL)
                return -EAFNOSUPPORT;
        net->ipv4.fibnl = sk;
        return 0;
}

и наконец:

register_pernet_subsys(&fib_net_ops);
0 голосов
/ 30 апреля 2009

Я бы предложил ioctl для взаимодействия ядра / пользователя. Интерфейс ioctl является стандартным, и вероятность обновления между ядрами мала.

...