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源码分析-用户内核通信原理的更多相关文章

  1. 内核通信之Netlink源码分析-用户内核通信原理2

    2017-07-05 上文以一个简单的案例描述了通过Netlink进行用户.内核通信的流程,本节针对流程中的各个要点进行深入分析 sock的创建 sock管理结构 sendmsg源码分析  sock的 ...

  2. 内核通信之Netlink源码分析-用户内核通信原理3

    2017-07-06 上节主讲了用户层通过netlink和内核交互的详细过程,本节分析下用户层接收数据的过程…… 有了之前基础知识的介绍,用户层接收数据只涉及到一个核心调用readmsg(), 其他的 ...

  3. 内核通信之Netlink源码分析-基础架构

    2017-07-04 netlink是一种基于网络的通信机制,一般用于内核内部或者内核与用户层之间的通信.其有一个明显的特点就是异步性,通信的双方不要求同时在线,也就不用阻塞等待.NetLink按照数 ...

  4. v79.01 鸿蒙内核源码分析(用户态锁篇) | 如何使用快锁Futex(上) | 百篇博客分析OpenHarmony源码

    百篇博客分析|本篇为:(用户态锁篇) | 如何使用快锁Futex(上) 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) ...

  5. jQuery 2.0.3 源码分析Sizzle引擎解析原理

    jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...

  6. wifidog源码分析 - 用户连接过程

    引言 之前的文章已经描述wifidog大概的一个工作流程,这里我们具体说说wifidog是怎么把一个新用户重定向到认证服务器中的,它又是怎么对一个已认证的用户实行放行操作的.我们已经知道wifidog ...

  7. Linux内核2.6.14源码分析-双向循环链表代码分析(巨详细)

    Linux内核源码分析-链表代码分析 分析人:余旭 分析时间:2005年11月17日星期四 11:40:10 AM 雨 温度:10-11度 编号:1-4 类别:准备工作 Email:yuxu97101 ...

  8. SOFA 源码分析 — 自定义线程池原理

    前言 在 SOFA-RPC 的官方介绍里,介绍了自定义线程池,可以为指定服务设置一个独立的业务线程池,和 SOFARPC 自身的业务线程池是隔离的.多个服务可以共用一个独立的线程池. API使用方式如 ...

  9. 【MyBatis源码分析】插件实现原理

    MyBatis插件原理----从<plugins>解析开始 本文分析一下MyBatis的插件实现原理,在此之前,如果对MyBatis插件不是很熟悉的朋友,可参看此文MyBatis7:MyB ...

随机推荐

  1. brew 中的时间格式转换

    char * pACNowStr = NULL; JulianType jtNow; ISHELL_GetJulianDate(pIShell, , &jtNow); pACNowStr = ...

  2. SQLServer------如何快速插入几万条测试数据

    方法一: 1.建表 if OBJECT_ID('test') is not null drop table test go create table test (id ,),vid ), constr ...

  3. UVA 1341 - Different Digits(数论)

    UVA 1341 - Different Digits 题目链接 题意:给定一个正整数n.求一个kn使得kn上用的数字最少.假设同样,则输出值最小的 思路: 首先利用鸽笼原理证明最多须要2个数字去组成 ...

  4. 高级类特性----接口(intertface)

    接 口 有时必须从几个类中派生出一个子类,继承它们所有的属性和方法.但是,Java不支持多重继承.有了接口,就可以得到多重继承的效果. 接口(interface)是抽象方法和常量值的定义的集合. 从本 ...

  5. GIS-"地理空间大数据与AI的碰撞"学习笔记

    1.关系 人工智能>机器学习>神经网络>深度学习 2.机器学习-两个过程 训练/学习过程:样本数据.学习器.模型参数 测试/预测过程:预测.预测值 3.神经网络 机器学习模拟人脑神经 ...

  6. 关于直播学习笔记-004-nginx-rtmp、srs、vlc、obs

    1.采集端:OBS RTMP推流地址:rtmp://192.168.198.21:1935/live 流密钥:livestream(任意-但播放地址与此一致) 2.播放端:nginx-rtmp-win ...

  7. NodeJS-003-自动刷新

    修改index.js之后,发现刷新浏览器,没有任何更改,需要关闭应用重新启动. 为了避免每次修改代码后要自动重启.通过安装supervisor来监控代码修改. 安装:npm install -g su ...

  8. STM32学习之路之入门篇

    2006年ARM公司推出了基于ARMV7架构的cortex系列的标准体系结构,以满足各种技术得不同性能要求,包含了A,R,M三个分工明确的系列 其中A系列面向复杂的尖端应用程序,用于运行开放式的复杂操 ...

  9. Xdebug安装与使用

    为什么需要Debugger? 很多PHP程序员调试使用echo.print_r().var_dump().printf()等,其实对 于有较丰富开发经验的程序员来说这些也已经足够了,他们往往可以在程序 ...

  10. Android 使用DatePicker以及TimePicker显示当前日期和时间

    课程内容1.介绍DatePicker和TimePicker两种实现动态输入日期和事件的功能2.介绍DatePickerDialog和TimePickerDialog来年耕种实现动态输入日期和事件的对话 ...