C 我如何创建一个;“网络链接”;在内核和用户空间之间?

C 我如何创建一个;“网络链接”;在内核和用户空间之间?,c,linux,linux-kernel,device-driver,netlink,C,Linux,Linux Kernel,Device Driver,Netlink,我想使用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' 在文件中,函数netlink\u kernel\u create()定义为 extern struct s

我想使用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'
在文件
中,函数
netlink\u kernel\u 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
。有人能解释一下我应该在这里使用什么吗?

您似乎一直在遵循这样一个指南,该指南(从2005年开始)很可能已经被内核的开发所超越。从内核端创建netlink的内部API似乎已经改变

检查本地内核树中的文档/文件夹以获取一些(希望更新鲜的)文档,或者阅读代码本身。您还可以查看Linux内核邮件列表存档,以了解似乎已经发生的任何更改


是从2.6.29开始的实际实现,如果您想向后解开它(当然,还没有在您自己的树中检查它)。

我建议进行内核/用户通信。ioctl接口是标准的,在内核之间进行更新的机会很小

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消息。

是的,struct net确实用于网络名称空间,但始终使用init_net并不合适,您应该注册自己的pernet_操作,如下所示:

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;
}

ioctl可能适用于简单的更改,但界面是一个陈旧而脆弱的界面。Netlink是内核开发人员对于任何中等复杂的东西的首选API。你从哪里得到函数定义的?请记住,libc-API的用户空间可能不是libc-to-kernel系统调用API。@展开:您的上一个链接已断开,所以我更改了它。我对我的猜测很有信心,但请检查它以确保我链接到了正确的页面。
register_pernet_subsys(&fib_net_ops);