2009-04-30 83 views
4

我想使用netlink在应用程序和内核空间之间进行通信。我的Linux内核版本2.6.28是,和下面是我的错误代码:如何在内核和用户空间之间创建一个“netlink”?

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使用什么。有人可以解释我应该在这里使用什么吗?

+0

你从哪里得到函数定义?记住libc API的用户空间可能不完全是内核syscall API的libc。 – stsquad 2009-04-30 10:32:58

回答

4

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作为唯一的参数和处理接收到的网络链路的消息。

2

你好像一直在关注如this one这样的指南,它(从2005年开始)可能已经超过了内核的发展。看起来从内核创建netlink的内部API已经改变。

请检查本地内核树中的文档/文件夹中的某些(希望更新鲜)文档,或者阅读代码本身。你也可以通过trawl的Linux Kernel邮件列表来归档任何可能发生的变化。

Here是2.6.29中的实际实现,如果你想让它向后困惑(当然还没有在你自己的树中检查过它)。

+1

@unwind:你最后一个链接被打破了,所以我改变了它。我对我的猜测非常有信心,但请检查它以确保我链接到了正确的页面。 – 2009-06-06 14:04:27

-3

对于内核/用户通信,我会建议ioctl。 ioctl界面是标准的,内核之间更新的机会很小。

+2

ioctl的可能适用于简单的更改,但界面是一个古老而脆弱的界面。对于任何中等复杂的内核开发者来说,Netlink是首选的API。 – stsquad 2009-04-30 10:31:21

1

是,结构网确实是净命名空间,但它是不恰当的总是使用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); 
相关问题