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. Digest Authentication 摘要认证

    “摘要”式认证( Digest authentication)是一个简单的认证机制,最初是为HTTP协议开发的,因而也常叫做HTTP摘要,在RFC2671中描述.其身份验证机制很简单,它采用杂凑式(h ...

  2. DLL文件的使用

    一. 动态链接库 什么是动态链接库?DLL三个字母对于你来说一定很熟悉吧,它是Dynamic Link Library 的缩写形式,动态链接库 (DLL) 是作为共享函数库的可执行文件.动态链接提供了 ...

  3. css之导航菜单的制作

    通过设置<a>的背景改变样式,通过a:hover改变交互效果,改变文字颜色color 纵向 <!DOCTYPE html> <html> <head lang ...

  4. go在线图书

    https://books.studygolang.com/The-Golang-Standard-Library-by-Example/

  5. mysql触发器使用方法具体解释

    MySQL触发器语法具体解释: 触发器 trigger是一种特殊的存储过程.他在插入(inset).删除(delete)或改动(update)特定表中的数据时触发运行,它比数据本身标准的功能更精细和更 ...

  6. JBOSS-EAP-6.2集群部署

    1 概述 应用的合理部署即能提高系统的可靠性和稳定性,又能提高系统的可维护性和扩展性.本文档详细阐述基于Apache负载均衡和JBOSS7集群的应用系统部署方案和配置步骤.内容涉及部署方案.环境配置. ...

  7. 2011年冬斯坦福大学公开课 iOS应用开发教程学习笔记(第三课)

    第二课名称是:Objective-C 回顾上节课的内容: 创建了单个MVC模式的项目 显示项目的各个文件,显示或隐藏导航,Assistant Editor, Console, Object Libra ...

  8. 原来javascript 自带 encodeURI 和 decodeURI文 方法了

    今天百度一下才知道js 自带 encodeURI 和 decodeURI 方法了,之前还找了其他代码来处理(笑哭了.jpg <script type="text/javascript& ...

  9. U3D关于message的使用

    Message相关有3条指令: SendMessage ("函数名",参数,SendMessageOptions) //GameObject自身的Script BroadcastM ...

  10. 为什么在js当中没有var就是全局变量

    因为,在js中,如果某个变量没有var声明,会自动移到上一层作用域中去找这个变量的声明语句,如果找到,就是用,如果没找到, 就继续向上寻找,一直查找到全局作用域为止,如果全局中仍然没有这个变量的声明语 ...