Linux的配置接口-netlink原理和设计

Linux内核是可配置的,配置的方式有好多种呢!对于Linux平台上上的开发者和管理员来讲,这几种配置方式可困扰了不少人儿。这里的配置不是指运行中的内核动态的配置,而是指当有新的设备或者内核特性添加进内核的时候,用户需要进行的配置。本文主要列举三种配置方式,最终落实于netlink方式的配置。

1.传统方式

传统方式一般认为是使用ioctl或者系统调用的方式,如果使用ioctl,当我们为设备驱动或者内核本身增加一个新的配置时,需要增加一个新的ioctl命令,这就可能就要修改ioctl的分发代码,类似于为芯片增加一个功能需要增加一个引脚且新布一根线一样,如果使用系统调用的方式,当既有的系统调用无法满足我们的需求时,我们就不得不增加一个新的系统调用,这就意味着需要重新编译内核代码。

2.procfs和sysfs的方式

这两种方式基于文件系统,所有的配置都可以通过文件读写接口完成,主谓宾(定状补最为参数和约束)的配置方式需要操作者记住诸多的选项参数,而sysfs通过文件名(kobject的属性)代替了诸多的选项参数,诸多选项参数需要另一个额外的参数“-h/--help”来展示,而sysfs的方式只要要记住ls命令即可,通过ls列出的文件代表kobject的属性,一般而言,一个好程序员会将-h选项参数所展示的帮助信息体现在文件名上!

然而你增加一个新配置的时候,意味着在去除这个新配置之前,procfs或者sysfs中会永久性的增加一个新的文件或者目录,这样会导致procfs和sysfs的膨胀,还容易引起程序员/管理员的误解,平添了复杂性,再者,即使增加一个再简单不过的配置,你也不得不实现一个proc的entry或者一个kobject(或者其attribute),而对于很多人,这并不是一件容易的事!

3.netlink的方式

netlink机制是一种最适宜的方式,在接口上,它使用socket,很简单,在实现上,它不依赖任何其它的内核业务组件,类似一个扩展的支持多点对多点的管道,在这种管道的任何一端,你都可以随意的加入自己的处理逻辑,形成一条自适应,自给自足的带有端点的通用链路。除了在通信过程中,其余任何时候,netlink都不会在内核中留下任何足迹,除非你想留下!比如一个简单的例子,一个用户进程想告诉内核“XX hello world”,那么它将通过netlink将XX hello world写入内核,然后内核收到之后会根据XX来处理之,如果XX是print的话,那么内核将输出一条hello world,如果XX为laugh at的话,内核将嘲笑你一番,因为你是个菜鸟,或者将hello world发给其它进程也是可以的!完成XX之后,这件事将不留下任何痕迹。

除了在内核态和用户态之间架设了一条通用的链路之外,如果你不希望,netlink不在任何位置留下任何信息。

netlink一般被理解为“内核态和用户态通信的接口”,然而它也可以用作进程间通信的接口,并且这种进程间通信可以基于组而不是基于进程的pid。典型的例子就是设置路由以及其它网络协议栈参数的iproute2工具链,其完全是基于netlink实现的,也就是说你在其源代码中再也看不到诸如ioctl之类的系统调用了。

netlink在使用方面的优势在于其简单性,在设计上的精华在于它的“软化”,还记得软化是什么意思吗?就是将复杂的控制逻辑集中在通信实体的两端而不是链路上,关于软化,典型的例子一般都来自于硬件链路的设计,比如并行链路发展为串行链路,链路本身不再约束任何通信协议相关的控制逻辑,而将控制逻辑集中在链路两端的芯片中,比如串行链路使用帧来传输协议pdu,协议相关的控制全部又帧的格式决定,以往在并行链路上,协议控制逻辑是由链路而不是帧决定的,比如“第x根线路代表数据准备好,第y根线传输同步信息”等。对于netlink而言,其设计十分类似于这种出自于硬件的“软化”思想,不再需要特定的ioctl来实现控制,而将控制集中在netlink套结字的发送和接收端,发送和接收端之间的“netlink链路”对传输的信息还不知情,它仅仅负责传输!

毫不夸张的说,有了netlink,就可以去除一切系统调用了,这里我们把系统调用比喻成“硬连线”的逻辑,每一根或者几根线完成一个特定的控制逻辑,而netlink作为一个“串行的,软化”的逻辑,只在链路上传输“帧”,只在发送方和接收方处理控制逻辑。使用netlink的方式,操纵系统接口的可扩展性将大大增强。

我们可以把操作系统分为若干个模块,大的方面说可以分为:用户空间/内核空间。其中用户空间又可以根据应用分为若干组,同理内核空间也是如此,可以看出,这就是完全基于消息的接口方式,所有消息通过netlink传输,并且,可以超级简单的实现消息的路由和中转,基于中转机制,甚至用户空间进程的IPC都可以完全使用netlink机制。

如下图:
Linux的配置接口-netlink原理和设计

以上为传统的方式

Linux的配置接口-netlink原理和设计

以上为本文预测的netlink方式