Linux中与内核通信的Netlink机制

上传人:ni****g 文档编号:486225228 上传时间:2024-03-03 格式:DOCX 页数:12 大小:32.07KB
返回 下载 相关 举报
Linux中与内核通信的Netlink机制_第1页
第1页 / 共12页
Linux中与内核通信的Netlink机制_第2页
第2页 / 共12页
Linux中与内核通信的Netlink机制_第3页
第3页 / 共12页
Linux中与内核通信的Netlink机制_第4页
第4页 / 共12页
Linux中与内核通信的Netlink机制_第5页
第5页 / 共12页
点击查看更多>>
资源描述

《Linux中与内核通信的Netlink机制》由会员分享,可在线阅读,更多相关《Linux中与内核通信的Netlink机制(12页珍藏版)》请在金锄头文库上搜索。

1、Linux中与内核通信的Netlink机制Netlink在2.6版本的内核中变化也是很大的,在最新的2.6.37内核中,其定义已经改成下面这种形式,传递的参数已经达到6个。其中第一个参数和mutex参数都是最新添加的。Mutex也可以为空。这里主要是关于内核空间中的netlink函数的使用。externstructsock*netlink_kernel_create(structnet*net,intunit,unsignedintgroups,void(*input)(structsk_buff*skb),structmutex*cb_mutex,structmodule*module);s

2、tructnet是一个网络名字空间namespace,在不同的名字空间里面可以有自己的转发信息库,有自己的一套net_device等等。默认情况下都是使用init_net这个全局变量,下面是内核中调用netlink_kernel_create()函数的一个示例。在内核中,audit_sock=netlink_kernel_create(&init_net,NETLINK_AUDIT,0,audit_receive,NULL,THIS_MODULE);模块调用函数netlink_unicast来发送单播消息:intnetlink_unicast(structsock*ssk,structsk_b

3、uff*skb,u32pid,intnonblock)参数ssk为函数netlink_kernel_create()返回的socket,参数skb存放消息,它的data字段指向要发送的netlink消息结构,而skb的控制块保存了消息的地址信息,前面的宏NETLINK_CB(skb)就用于方便设置该控制块,参数pid为接收消息进程的pid,参数nonblock表示该函数是否为非阻塞,如果为1,该函数将在没有接收缓存可利用时立即返回,而如果为0,该函数在没有接收缓存可利用定时睡眠。netlink的内核实现在.c文件net/core/af_netlink.c中,内核模块要想使用netlink,也必

4、须包含头文件linux/netlink.h。内核使用netlink需要专门的API,这完全不同于用户态应用对netlink的使用。如果用户需要增加新的netlink协议类型,必须通过修改linux/netlink.h来实现,当然,目前的netlink实现已经包含了一个通用的协议类型NETLINK_GENERIC以方便用户使用,用户可以直接使用它而不必增加新的协议类型。前面讲到,为了增加新的netlink协议类型,用户仅需增加如下定义到linux/netlink.h就可以:只要增加这个定义之后,用户就可以在内核的任何地方引用该协议。在内核中,为了创建一个netlinksocket用户需要调用如下

5、函数:externstructsock*netlink_kernel_create(structnet*net,intunit,unsignedintgroups,void(*input)(structsk_buff*skb),structmutex*cb_mutex,structmodule*module);structnet是一个网络名字空间namespace,在不同的名字空间里面可以有自己的转发信息库,有自己的一套net_device等等。默认情况下都是使用init_net这个全局变量参数unit表示netlink协议类型,如NETLINK_MYTEST,参数input则为内核模块定义的

6、netlink消息处理函数,当有消息到达这个netlinksocket时,该input函数指针就会被引用。函数指针input的参数skb实际上就是函数netlink_kernel_create返回的structsock指针,sock实际是socket的一个内核表示数据结构,用户态应用创建的socket在内核中也会有一个structsock结构来表示。函数input()会在发送进程执行sendmsg()时被调用,这样处理消息比较及时,但是,如果消息特别长时,这样处理将增加系统调用sendmsg()的执行时间,也就是说当用户的程序调用sendmsg()函数时,如果input()函数处理时间过长,也

7、就是说input()函数不执行不完,用户程序调用的sendmsg()函数就不会返回。只有当内核空间中的input()函数返回时,用户调用的sendmsg()函数才会返回。对于这种情况,可以定义一个内核线程专门负责消息接收,而函数input的工作只是唤醒该内核线程,这样sendmsg将很快返回。(这里网上的的说明)不过在查看Linux2.6.37版本的内核时并没有发现这种处理过程,一般都是按下面的方法进行处理。这里注册的netlink协议为NETLINK_XFRMnlsk=netlink_kernel_create(net,NETLINK_XFRM,XFRMNLGRP_MAX,xfrm_netl

8、ink_rcv,NULL,THIS_MODULE);staticvoidxfrm_netlink_rcv(structsk_buff*skb)mutex_lock(&xfrm_cfg_mutex);netlink_rcv_skb(skb,&xfrm_user_rcv_msg);mutex_unlock(&xfrm_cfg_mutex);在netlink_rcv_skb()函数中进行接收处理。intnetlink_broadcast(structsock*ssk,structsk_buff*skb,u32pid,u32group,gfp_tallocation)前面的三个参数与netlink_u

9、nicast相同,参数group为接收消息的多播组,该参数的每ID一个位代表一个多播组,因此如果发送给多个多播组,就把该参数设置为多个多播组组的位或。参数allocation为内核内存分配类型,一般地为GFP_ATOMIC或GFP_KERNEL,GFP_ATOMIC用于原子的上下文(即不可以睡眠),而GFP_KERNEL用于非原子上下文。NETLINK_CB(skb).pid=0;NETLINK_CB(skb).dst_pid=0;NETLINK_CB(skb).dst_group=1;字段pid表示消息发送者进程ID,也即源地址,对于内核,它为0,dst_pid表示消息接收者进程ID,也即目

10、标地址,如果目标为组或内核,它设置为0,否则dst_group表示目标组地址,如果它目标为某一进程或内核,dst_group应当设置为0。下面是参考网上使用netlink写的和内核通信的两个程序,一个是用户空间,一个是内核空间。内核空间:#include#include#include#include#include#include#include#defineNETLINK_TEST25#defineMAX_MSGSIZE1024intstringlength(char*s);voidsendnlmsg(char*message);intpid;interr;structsock*nl_sk

11、=NULL;intflag=0;voidsendnlmsg(char*message)structsk_buff*skb_1;structnlmsghdr*nlh;intlen=NLMSG_SPACE(MAX_MSGSIZE);intslen=0;if(!message|!nl_sk)return;skb_1=alloc_skb(len,GFP_KERNEL);if(!skb_1)printk(KERN_ERRmy_net_link:alloc_skb_1errorn);slen=stringlength(message);nlh=nlmsg_put(skb_1,0,0,0,MAX_MSGSI

12、ZE,0);NETLINK_CB(skb_1).pid=0;NETLINK_CB(skb_1).dst_group=0;messageslen=0;memcpy(NLMSG_DATA(nlh),message,slen+1);printk(my_net_link:sendmessage%s.n,(char*)NLMSG_DATA(nlh);netlink_unicast(nl_sk,skb_1,pid,MSG_DONTWAIT);intstringlength(char*s)intslen=0;for(;*s;s+)slen+;returnslen;voidnl_data_ready(stru

13、ctsk_buff*_skb)structsk_buff*skb;structnlmsghdr*nlh;charstr100;structcompletioncmpl;inti=10;skb=skb_get(_skb);if(skb-len=NLMSG_SPACE(0)nlh=nlmsg_hdr(skb);memcpy(str,NLMSG_DATA(nlh),sizeof(str);printk(Messagereceived:%sn,str);pid=nlh-nlmsg_pid;while(i-)init_completion(&cmpl);wait_for_completion_timeo

14、ut(&cmpl,3*HZ);sendnlmsg(Iamfromkernel!);flag=1;kfree_skb(skb);/Initializenetlinkintnetlink_init(void)nl_sk=netlink_kernel_create(&init_net,NETLINK_TEST,1,nl_data_ready,NULL,THIS_MODULE);if(!nl_sk)printk(KERN_ERRmy_net_link:createnetlinksocketerror.n);return1;printk(my_net_link_3:createnetlinksocket

15、ok.n);return0;staticvoidnetlink_exit(void)if(nl_sk!=NULL)sock_release(nl_sk-sk_socket);printk(my_net_link:selfmoduleexitedn);module_init(netlink_init);module_exit(netlink_exit);MODULE_AUTHOR(frankzfz);MODULE_LICENSE(GPL);下面是用户空间的程序:#include#include#include#include#include#include#include#include#include#include#include#defineNETLINK_TEST25#defineMAX_PAYLOAD1024/maximumpayloadsizeintmain(intargc,char*

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 活动策划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号