2017-07-04


netlink是一种基于网络的通信机制,一般用于内核内部或者内核与用户层之间的通信。其有一个明显的特点就是异步性,通信的双方不要求同时在线,也就不用阻塞等待。NetLink按照数据包的格式发送/接收消息,提供双向通信,和其他内核与用户层通信机制相比,NetLink有其特有的优势:

  • 任何一方不需要轮训,如果通过文件传递状态信息,则需要不断的检查是否有新消息到达。
  • 系统调用和ioctl均可以从用户层向内核传递消息,但比简单的Netlink链接难于实现,另外,NetLink是系统提供的机制,不会和任何模块其冲突,兼容性好。
  • 使用NetLink可以让内核主动的向用户层发消息,此时内核扮演的就是一个逻辑用户;而ioctl和系统调用、/proc均只能由用户层发起请求,让内核去被动响应。
  • Netlink不仅支持单播,也支持多播即向多个进程发送消息。

从逻辑上来讲,NetLink应该处于传输层,因此其同样需要特定的协议。对于NetLink就是Netlink协议,内核中有netlink_family_ops,在用户层创建netlink类型的socket的时候最终会调用到netlink_family_ops注册的create函数

static const struct net_proto_family netlink_family_ops = {
.family = PF_NETLINK,
.create = netlink_create,
.owner = THIS_MODULE, /* for consistency 8) */
};

每种协议都需要一组协议处理函数,针对Netlink有netlink_ops

static const struct proto_ops netlink_ops = {
.family = PF_NETLINK,
.owner = THIS_MODULE,
.release = netlink_release,
.bind = netlink_bind,
.connect = netlink_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.getname = netlink_getname,
.poll = netlink_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 = netlink_mmap,
.sendpage = sock_no_sendpage,
};

我们重点关注netlink_sendmsg和netlink_recvmsg,这是netlink发送和接收数据的处理函数。

地址表示

NetLink的地址表示由sockaddr_nl负责

struct sockaddr_nl {
__kernel_sa_family_t nl_family; /* AF_NETLINK */
unsigned short nl_pad; /* zero */
__u32 nl_pid; /* port ID */
__u32 nl_groups; /* multicast groups mask */
};

nl_family制定了协议族,这里肯定是AF_NETLINK,nl_pid用以该套接字,对于内核套接字来讲,nl_pid为0,而对于用户层程序而言,该值可以为任何值,协商好并保证唯一性即可。一般取为进程id或线程ID。nl_groups用以多播,当不需要多播时,该字段为0。

NetLink消息

NetLink消息是作为套接字缓冲区sk_buff的数据部分传递的,其消息本身又分为头部和数据。头部为

struct nlmsghdr {
__u32 nlmsg_len; /* Length of message including header */
__u16 nlmsg_type; /* Message content */
__u16 nlmsg_flags; /* Additional flags */
__u32 nlmsg_seq; /* Sequence number */
__u32 nlmsg_pid; /* Sending process port ID */
};

nlmsg_len为消息的长度,包含该头部在内。nlmsg_pid为发送进程的端口ID,这个用户可以自定义。其余的字段暂时用不到。在用户层还用到了一个结构

struct msghdr {
void * msg_name; /* Socket name */
int msg_namelen; /* Length of name */
struct iovec * msg_iov; /* Data blocks */
__kernel_size_t msg_iovlen; /* Number of blocks */
void * msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
__kernel_size_t msg_controllen; /* Length of cmsg list */
unsigned int msg_flags;
};

msg_name是目标socket的地址结构sockaddr_nl的地址,msg_namelen是长度。msg_iov指向一个iov向量,msg_iovlen是向量的个数。剩下的暂不考察。当用户层向内核发送消息时,该结构作为参数传递。nlmsghdr 只能描述单个消息,而msghdr描述一组消息。通过iov向量聚合所有的消息,每个消息都有其对应的nlmsghdr.逻辑结构如下:

之前提到,socket也是一种特殊的文件,通过VFS的借口同样可以对其实现管理。sokket本身就需要实现文件系统的相应接口,有自己的文件系统操作。

内核中的表示

netlink socket在内核中涉及到的结构有下:socket,sock,netlink_sock,前者是套接字通用结构,sock是套接字在网络层的体现,而sock其实是内嵌在netlink_sock结构中,后者保存有链接两端的端口ID,并包含一个函数,用于在接收数据时使用!

以马内利

参考资料:

《linux3.10.1源码》

内核通信之Netlink源码分析-基础架构的更多相关文章

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

    2017-07-05 本节从一个小案例入手,结合源码分析下通过netlink进行内核和用户通信的流程. 内核端 按照传统CS模式,其实内核端可以作为是服务器端,用以接收用户的请求并作出处理,但是从ne ...

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

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

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

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

  4. 精尽 MyBatis 源码分析 - 基础支持层

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

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

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

  6. spring transaction源码分析--事务架构

    1. 引言  事务特性 事务是并发控制的单元,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.通过事务将逻辑相关的一组操作绑定在一起,以便服务器 保持数据的完整性.事 ...

  7. 精尽 MyBatis 源码分析 - 整体架构

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  8. Backbone源码分析-Backbone架构+流程图

    作者:nuysoft/高云/nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. Backbone0.9.1源码分析分析系列 jQuery1.6.1源码分析系 ...

  9. Hessian源码分析--总体架构

    Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...

随机推荐

  1. 转:Linux下which、whereis、locate、find 命令的区别

    我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索.这些是从网上找到的资料,因为有时很长时间不会用到,当要用的时候经常弄混了,所以放到这里方便使用. which    ...

  2. [vundle]利用vundle工具来管理vim插件

    转自:http://os.51cto.com/art/201507/484174.htm Vim是Linux上一款用途广泛的轻量级文本编辑工具.虽然对普通的Linux用户来说开始学用起来难度相当大,但 ...

  3. Java多线程之Lock的使用<转>

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util ...

  4. CSS实现文字半透明显示在图片上方法

    CSS实现文字半透明显示在图片上方法 在css中文字半透明我们会需要使用滤镜效果也就是css中的filter:alpha来实现了,下面来看两个文字显示在图片上并且半透明的例子. CSS让一行文字显示在 ...

  5. ubuntu 安装dlib 出现dlib.so: undefined symbol: png_set_longjmp_fn

    参考网上的教程安装dlib 安装教程1 sudo apt-get install libboost-python-dev cmake sudo pip install dlib 安装教程2ubuntu ...

  6. [web开发] php优势 - PHP与ASP.NET的比较

    php 优势 - PHP与ASP.NET的比较 如今当提到 Web 开发时,您有许多选择.这些方法中许多都涉及到预处理 — 即,利用特定的标记将代码嵌入到 HTML 页面中,这些标记告诉预处理器,它们 ...

  7. 敏捷软件开发实践-Release Process/Release Plan(转)

    介绍: 因为我们的开发周期是迭代进行的,以Sprint为单位,我们每个 Sprint如何去和客户说我们的成果呢,那么我就需要Demo和release一些新功能,或者一些bug fixing.Demo我 ...

  8. 让div也出现滑动框。

    <div id="box" style="height: 300px; width: 200px; border:1px solid #CCC; overflow: ...

  9. python+selenium之自定义封装一个简单的Log类

    python+selenium之自定义封装一个简单的Log类 一. 问题分析: 我们需要封装一个简单的日志类,主要有以下内容: 1. 生成的日志文件格式是 年月日时分秒.log 2. 生成的xxx.l ...

  10. sql server函数(isnull,charindex,cast,自定义函数)

    SELECT charindex( CAST ( dbo.ufn_IsNullOrEmpty ('109722A3-622D-4FD4-A060-0287C933A89E', a.OUID) AS V ...