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. vc 获取 硬盘序列号 和 cpu

    vc 获取 硬盘序列号 和 cpu 唯一iD的方法?如题---------网上找来很多资料 也没找到, 要支持xp win7 32/64 系统下都能获取 硬盘序列号 和cpu ID 哪位朋友帮帮忙: ...

  2. js使用正则表达式从url中获取参数值

    //从url中获取参数值 function getvl(name) { var reg = new RegExp("(^|\\?|&)"+ name +"=([^ ...

  3. andriod sdk 安卓模拟器修改imei码,位置信息

      imei码就是手机卡的信息一段15位数字,就好像pc的mac地址.很多app注册会检测你是否是手机登录的,就会读取你的imei码,如果读取不到,就说明你可能是用平板等移动设备上网的. app也可以 ...

  4. 【mysql】恢复备份

    windows环境: 打开cmd cd 到备份数据目录 mysql -u*** -p use database; source *****.sql;

  5. php-fpm配置文件,指定session保存目录

    cd  /etc/php-fpm.d 目录下 cat www.conf文件 修改user ,group 指定session 保存路径 www.conf日志配置路径 php-fpm.conf

  6. 配置Java的jdk环境变量

    1.classpath E:\Java\jdk1..0_20\jre\lib\rt.jar;.;E:\Tomcat\lib; 2.JAVA_HOME E:\Java\jdk1..0_20; 3.Pat ...

  7. Python3 抓取豆瓣电影Top250

    利用 requests 抓取豆瓣电影 Top 250: import re import requests def main(url): global num headers = {"Use ...

  8. PHP webservice 接口实例

    原文地址,就不摘抄了 http://www.sky00.com/archives/91.html

  9. PyQt4菜单栏

    菜单栏是GUI程序最明显的组成部分.它由一组位于不同菜单中的命令组成.在控制台程序中,我们必须记住那些晦涩难懂的命令.但在GUI程序中,通过菜单栏我们将命令合理的放置在不同的菜单中来降低学习新应用程序 ...

  10. ecplise部署gradle web项目

    gradle项目结构图: build.gradle apply plugin: 'java' apply plugin: 'war' //用来生成war apply plugin: 'eclipse- ...