内核通信之Netlink源码分析-用户内核通信原理
2017-07-05
本节从一个小案例入手,结合源码分析下通过netlink进行内核和用户通信的流程。
内核端
按照传统CS模式,其实内核端可以作为是服务器端,用以接收用户的请求并作出处理,但是从netlink本身的特性,其更像是一个对等实体。双方都可以进行主动数据的传递。
内核中首先调用netlink_kernel_create函数创建一个sock结构,其实这里仅仅是返回一个sock结构,而其中创建了相关的socket,netlink_sock,inode等。
老版本的函数参数都是写在netlink_kernel_create函数里的,现在把部分参数抽离到一个netlink_kernel_cfg结构中,其中我们只关心接收数据的处理函数.input。首个参数表示网络命名空间,一般取init_net,NETLINK_TEST是我们自定义的协议类型,netlink支持32个协议0-31,其实就是协商好的一个数字,用来用户层和内核层的通信。第三个就是我们的配置结构。函数内部首先创建了socket,然后创建了sock,并在socket和sock间建立关联,默认创建sock是在全局的命名空间init_net下,所以还需要修改到参数中的net,不过一般我们也正是选择全局的。然后需要设置接收函数到netlink_sock中的netlink_rcv字段。最后需要把sock加入到全局管理结构nl_table中。函数大致功能如此,后面我们再详细讨论。
目前sock已经注册上,如何处理接收到的数据呢?看下我们实现的简单的接收函数rece_msg,
Netlink基于socket,所以其数据是通过套接字缓冲区sk_buff管理的。从skb中获取信息长度,该长度是包含了nlmsghdr的长度加上数据,后面为了方便直接读取的100字节,实际上应该让获取到的长度将去nlmsghdr的长度。操作完毕需要调用skb_pull减去已经读取到的长度。后面没获取一次请求我们就调用了发送函数向用户空间发送一个消息,pid是nlmsghdr头部中的nlmsg_pid,表示发送者的端口。看下发送函数sendmsg
由于是在内核,有些事情需要亲力亲为,比如skb的分配。这里我们首先分配了一个skb,然后获取nlmsghdr,设置skb的源属性,即来自于哪里,这里设置源端口为0,组掩码为0表示不支持组播。接着就赋值数据到skb的数据区,这里依然是通过nlmsghdr。最后才调用netlink_unicast发送出去。
用户端
一下贴图均位于一个main函数中。
用户端首先要创建一个套接字,不过这里就不会返回套接字结构,而是返回一个文件描述符fd;参数都是标准套接字的参数,这里就不多说,针对netlink首个协议族选择AF_NETLINK,第二个参数是socket类型,我们选择的是原生socketSOCK_RAW,最后是指定的协议,这个和前面内核定义的是一致的,否则无法通信。
设置源地址信息,我们设置的源端口为100,也可以是线程ID,保证唯一性即可。组播掩码同样设置0。最后调用bind函数把源地址和socket进行绑定。
分配一个nlmsghdr头部,把源信息记录进去,并设置目标地址信息,这里nl.pid=0表示目标在内核,这点同样是和内核中对应的。nlh->nlmsg_len是对应的包含头部在内的总长度,回想下内核中接收部分就明白了。
设置好之后就要准备发送了,不过用户层发送到内核是通过另一个结构msghdr,这点在首篇文章框架介绍中有详细说明,为此我们还要对msghdr进行填充,中间是通过iov向量管理。填充完毕就调用sendmsg库函数发送到内核。接收就相当简单了,我们利用了前面设置的msg,直接调用recvmsg函数即可
基本的通信流程如上文所述,下文针对每一部分做详细分析,最后效果如图所示……
以马内利
参考资料:
1、《深入linux内核架构》
2、linux3.10.1源码
内核通信之Netlink源码分析-用户内核通信原理的更多相关文章
- 内核通信之Netlink源码分析-用户内核通信原理2
2017-07-05 上文以一个简单的案例描述了通过Netlink进行用户.内核通信的流程,本节针对流程中的各个要点进行深入分析 sock的创建 sock管理结构 sendmsg源码分析 sock的 ...
- 内核通信之Netlink源码分析-用户内核通信原理3
2017-07-06 上节主讲了用户层通过netlink和内核交互的详细过程,本节分析下用户层接收数据的过程…… 有了之前基础知识的介绍,用户层接收数据只涉及到一个核心调用readmsg(), 其他的 ...
- 内核通信之Netlink源码分析-基础架构
2017-07-04 netlink是一种基于网络的通信机制,一般用于内核内部或者内核与用户层之间的通信.其有一个明显的特点就是异步性,通信的双方不要求同时在线,也就不用阻塞等待.NetLink按照数 ...
- v79.01 鸿蒙内核源码分析(用户态锁篇) | 如何使用快锁Futex(上) | 百篇博客分析OpenHarmony源码
百篇博客分析|本篇为:(用户态锁篇) | 如何使用快锁Futex(上) 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) ...
- jQuery 2.0.3 源码分析Sizzle引擎解析原理
jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...
- wifidog源码分析 - 用户连接过程
引言 之前的文章已经描述wifidog大概的一个工作流程,这里我们具体说说wifidog是怎么把一个新用户重定向到认证服务器中的,它又是怎么对一个已认证的用户实行放行操作的.我们已经知道wifidog ...
- Linux内核2.6.14源码分析-双向循环链表代码分析(巨详细)
Linux内核源码分析-链表代码分析 分析人:余旭 分析时间:2005年11月17日星期四 11:40:10 AM 雨 温度:10-11度 编号:1-4 类别:准备工作 Email:yuxu97101 ...
- SOFA 源码分析 — 自定义线程池原理
前言 在 SOFA-RPC 的官方介绍里,介绍了自定义线程池,可以为指定服务设置一个独立的业务线程池,和 SOFARPC 自身的业务线程池是隔离的.多个服务可以共用一个独立的线程池. API使用方式如 ...
- 【MyBatis源码分析】插件实现原理
MyBatis插件原理----从<plugins>解析开始 本文分析一下MyBatis的插件实现原理,在此之前,如果对MyBatis插件不是很熟悉的朋友,可参看此文MyBatis7:MyB ...
随机推荐
- asp.net 后端验证
using EntryRegistration.Filters; using EntryRegistration.Models.Entity; using System; using System.C ...
- vs2008 调试时不会命中断点,源代码与原始版本不同,解决办法
当前不会命中断点,源代码与原始版本不同,解决办法 1.应该是自己一行里写的代码太长了 格式化一下 或者 换下行 2. VC直接把整个文件格式化了一次,断点就可以用了 菜单:编辑-〉高级-〉设置选定内容 ...
- python 包管理和virturlenv
python 包管理工具 Python当前的包管理工具链是 easy_install/pip + distribute/setuptools + distutils,显得较为混乱. 而将来的工具链组合 ...
- 一、NHibernate配置所支持的属性
属性名 用途 dialect 设置NHibernate的Dialect类名 - 允许NHibernate针对特定的关系数据库生成优化的SQL 可用值: full.classname.of.Dialec ...
- MySQL<数据库的高级操作>
数据库的高级操作 MySQL提供了一个mysqldump命令,它可以实现数据的备份 数据的备份 1.备份单个数据库 mysqldump -uusername -ppassword dbname [tb ...
- 异常处理----使用 try…catch…finally 处理异常
使用 try…catch…finally 处理异常 异常处理是通过try-catch-finally语句实现的. try { ...... //可能产生异常的代码 } catch( Exception ...
- CCNet持续集成编译中SVN问题解决
SVN问题 BUILD EXCEPTION Error Message: ThoughtWorks.CruiseControl.Core.CruiseControlException: Source ...
- thinkjs——moment.js之前后台引入问题
前言: 工作中时常会遇见处理时间格式化问题:简言之就是将存在数据库中的时间戳的数字以“YYYY-MM-DD HH:mm:ss”格式展现出来. 过程: 1.在html文件中,通常是引入moment.js ...
- 剑指offer练习
1.题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. public c ...
- mongodb3.2系统性学习——3、update()操作
mongodb 包含众多的原子性操作: 实例: //连接数据库 dbService = connect("localhost:27017"); //选择插入集合 db = dbS ...