netlink实现分析

上传人:ya****h 文档编号:117409715 上传时间:2022-07-08 格式:DOCX 页数:8 大小:235.35KB
收藏 版权申诉 举报 下载
netlink实现分析_第1页
第1页 / 共8页
netlink实现分析_第2页
第2页 / 共8页
netlink实现分析_第3页
第3页 / 共8页
资源描述:

《netlink实现分析》由会员分享,可在线阅读,更多相关《netlink实现分析(8页珍藏版)》请在装配图网上搜索。

1、内核与用户空间通信第二部分-netlink本文档的Copyleft归wwwlkk所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。E-mail:wwwlkk126com来源:netlink实现分析1)网络file对象。12)netlink网络file对象。33)netlink消息接收端。5(3.1)内核路径注册netlink接收端。6(3.2)用户进程注册netlink接收端。6(3.3)内核netlink接收端接收消息。6(3.4)用户进程netlink接收端接收消息。64)通信效率分析。75)实现零拷贝的两个理论方案。7(1)网络file对象当网络双

2、方的通信线路建立好之后,双发就可以开始互相传递数据,可以使用writeoffread()传递数据。可见网络通信也同样使用了文件系统的架构,这里的file对象是比较特殊的,结构如图1所示:structfileprivatedatainode;&sockettlkopsnetlink实现分析2010-10-096/7.owner=图1网络file对象结构其中staticconststructfile_operationssocket_file_ops=THIS_MODULE,.llseek=no_llseek,.aio_read=sock_aio_read对应read().aio_write=so

3、ck_aio_write对应write().poll=sock_poll,.unlocked_ioctl=sock_ioctl,.mmap=sock_mmap,.open=sock_no_open,/*specialopencodetodisallowopenvia/proc*/.release=sock_close,.fasync=sock_fasync,.sendpage=sock_sendpage,.splice_write=generic_splice_sendpage,.splice_read=sock_splice_read,;说明:如果file-f_op-write为空,则会调用

4、file-f_op-aio_writefile-f_op-read为空,则会调用file-f_op-aio_read从sock_aio_write()开始的函数调用流程如下:sock_aio_write()Tdo_sock_write()T_sock_sendmsg()Tsock-ops-sendmsg(iocb,sock,msg,size);从sock_aio_read()开始的函数调用流程如下:sock_aio_read()Tdo_sock_read()T_sock_recvmsg()T_sock_recvmsg_nosec()Tsock-ops-recvmsg(iocb,sock,msg

5、,size,flags);可见发送和接受过程最终都是调用操作函数集sock-ops,其结构如下:structproto_ops*owner;(*release)(structsocket*sock);(*bind)(structsocket*sock,structsockaddr*myaddr,intsockaddr_len);(*connect)(structsocket*sock,structsockaddr*vaddr,intsockaddr_len,intflags);(*socketpair)(structsocket*sock1,structsocket*sock2);(*acce

6、pt)(*getname)intfamily;(structsocket*sock,structsocket*newsock,intflags);(structsocket*sock,structsockaddr*addr,int*sockaddr_len,intpeer);(structfile*file,structsocket*sock,structpoll_table_struct*wait);(structsocket*sock,unsignedintcmd,unsignedlongarg);unsignedint(*poll)intintintintstructmoduleinti

7、ntintintintint(*ioctl)(*compat_ioctl)(structsocket*sock,unsignedintcmd,unsignedlongarg);(*listen)(structsocket*sock,intlen);(*shutdown)(structsocket*sock,intflags);int(*setsockopt)(structsocket*sock,intlevel,intoptname,char_user*optval,unsignedintoptlen);int(*getsockopt)(structsocket*sock,intlevel,i

8、ntoptname,char_user*optval,int_user*optlen);int(*compat_setsockopt)(structsocket*sock,intlevel,intoptname,char*optval,unsignedintoptlen);int(*compat_getsockopt)(structsocket*sock,intlevel,intoptname,char*optval,int*optlen);int(*sendmsg)(structkiocb*iocb,structsocket*sock,structmsghdr*m,size_ttotal_l

9、en);int(*recvmsg)(structkiocb*iocb,structsocket*sock,structmsghdr*m,size_ttotal_len,intflags);int(*mmap)(structfile*file,structsocket*sock,structvm_area_struct*vma);ssize_t(*sendpage)(structsocket*sock,structpage*page,intoffset,size_tsize,intflags);ssize_t(*splice_read)(structsocket*sock,loff_t*ppos

10、,structpipe_inode_info*pipe,size_tlen,unsignedintflags);应用程序的bind()jlisten(),accept(),connect(),read(),write(),close()都最终调用structproto_ops内的函数。(2)netlink网络file对象当网络应用程序调用socket。时,将会建立如图1所示的file结构。例如:socket(AF_NETLINKSOCK_RAW,NETLINK_GENERIC);函数调用流程如下:SYSCALL_DEFINE2(socketcall,int,call,unsignedlong_

11、user*,args)Tsys_socket()SYSCALL_DEFINE3(socket,int,family,int,type,int,protocol)-sock_create()T_sock_create()Tpf=rcu_dereference(net_familiesfamily)Terr=pf-create(net,sock,protocol,kern);Tsock_map_fd()在staticint_initnetlink_proto_init(void)中可以看到netlink协议的注册函数:sock_register(&netlink_family_ops);其中sta

12、ticconststructnet_proto_familynetlink_family_ops=.family=PF_NETLINK,.create=netlink_create,.owner=THIS_MODULE,/*forconsistency8)*/;现在可以知道上边的pf-create(net,sock,protocol,kern)是调用netlink_create()生成的file对象结构如图2所示:Anctiinkopssinternetlinksock一一structsock$k;斗十u32pid;u32dst_pid;u32dstgroup;u32flags;u32subs

13、eriptKjns;u32ngroups;unsignedlongroups;unsignedlongstute:wailqiienc_hcad_wait;structrietlinkcailback*cb;structniutex+cb_Tiuitex;structmutexeb_defmutex;void(*netlinkrcv)(stmctsk_buff*skb);struefmodule*modulc;Mructsocketsocketstatestate;shorttype;unsignedLongflags;structfasynextinct4fasynclist;wait_qu

14、eue_head_twait;structflcEak;tons!structprotoopsops;&socket_tlk_opsstructtilepijva(e_daUstruC1Sncket-alJoc5“struct$1)42ketsocket盃伽tdUiwk伽舁祖M少加血;/图2netlink的file对象结构其中staticconststructproto_opsnetlink_ops=.family=PF_NETLINK,.owner=THIS_MODULE,.release=netlink_release,.bind=netlink_bind,.connect=netlink

15、_connect,.socketpair=sock_no_socketpair,.accept=sock_no_accept,.getname=netlink_getname,.poll=datagram_poll,.ioctl=sock_no_ioctl,.listen=sock_no_listen,.shutdown=sock_no_shutdown,.setsockopt=netlink_setsockopt,.getsockopt=netlink_getsockopt,.sendmsg=netlink_sendmsg,.recvmsg=netlink_recvmsg,.mmap=soc

16、k_no_mmap,.sendpage=sock_no_sendpage,;structsock对象是包含在netlink_sock中。(3)netlink消息接收端一个netlink消息接收端口必须先在内核中注册后,其它内核路径才可能将消息发送给这个接收端。内核中netlink所有的接收端都必须在nl_tables中注册,如图3所示:strucEnetlinksoclstructncdink_ockstructntbtlink_tabicstructnl_pi(i_hash阴希;structhhst_hcadmclist;unsigned(?ng*listeners;unsignedmtn_

17、nwnroct;unsignedintgroups;stnictnnirexcb-inutexistructmodule*modulc:mtregistered;structulpidhashstructhJhthemlunsignedlongrel!n_tiie;unsignedhnnik;unsignedunsignedyftentries;unsigneynitTnax_sliiii;u32rn/structsockstructhlistnodesktnode;-nQQQQQQQQaastructsk_bufT_heads!netlink_rcv(skb);其中nlk-netlink_r

18、cv指向netlink_kernel_create()中的inputo在发送函数内就会直接调用注册的接收函数处理消息。(3.4)用户进程netlink接收端接收消息用户进程创建的netlink接收端(pid0),接收过程分为2个部分。第一部分:其它内核路径将netlink消息数据包加入sk_receive_queue队列。netlink_unicast()netlink_sendskb()今skb_queue_tail(&sk-sk_receive_queue,skb);第二部分:用户空间调用read接收数据(也可以调用其它函数比如recvmsg()。read(Q陷入内核态netlink_re

19、cvmsg()9内核与用户空间通信第二部分netlinkskb_recv_datagram(Q_skb_recv_datagramskb=skb_peek(&sk-sk_receive_queue);用户空间通过调用接收函数来获取netlink消息。(4)通信效率分析现在可以看到:1. 在内核中给内核注册的netlink接收端发送消息效率是比较高,因为不需要进行数据的一次拷贝,直接把发送端生成的skb作为参数,接收端直接处理这个skb。2. 但是用户空间和内核的通信效率就比较低了,因为需要进行数据的一次拷贝。用户空间使用structmsghdr结构存储消息,内核空间使用skb存储消息,所以必须

20、进行消息类型的转换,而且还需要进行消息数据的拷贝。用户空间和内核的通信必须进行数据的拷贝原因有2点:(在misc设备实现机制中也有讲解)1. 用户空间使用的线性地址是在前3个G的空间,而内核使用的线性地址是在第4个G,所以用户空间没法使用内核中的线性地址。2. 当前运行进程是不断替换的,内核是使用当前运行进程的页表,虽然不同进程的页表的内核空间部分是相同的,但是用户空间部分是不同的,如果内核要长期使用某个用户空间的数据,将会出现问题(同样的线性地址,在不同的进程上下文中将会引用不同的物理地址)。(5)实现零拷贝的两个理论方案理论上是可以实现netlink数据的零拷贝,有两个方案:1. 使某个进

21、程的状态总是处于内核态。正常进行系统调用时,首先将CPU变为内核级,系统调用返回时又变为用户级。可以将用户代码和数据段的DPL改为0,这样进程就总是处于内核级。这个技术在论文IPv6下基于病毒过滤防火墙的设计与实现有提到,但是这种方案的用户空间可以随意修改内核的数据,系统会很不稳定。实现原理:CPU的cs寄存器有2位的字段,用于指明CPU的当前特权级(CPL),值为0表示内核级,3表示用户级。当把_KERNEL_CS宏产生的值装进CS寄存器,CPU就是内核级,当把_USER_CS宏产生的值装进CS寄存器,CPU就是用户级,具体做法就是修改_USER_CS宏产生的值使CPU变为0。2. 将skb指向的数据的物理地址,映射到进程的用户空间。这个技术在misc设备实现机制中已经应用到。netlink实现分析2010-10-098/7

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!