新闻资讯
Group news
青岛广盛源肥业有限公司    您的位置: 首页  >  新闻资讯  >  正文

linux 内核与用户空间通信之netlink使用方法

2019年10月12日 文章来源:网络整理 热度:72℃ 作者:刘英

Linux中的进程间通信机制源自于Unix平台上的进程通信机制。Unix的两大分支AT&T Unix和BSD Unix在进程通信实现机制上的各有所不同,前者形成了运行在单个计算机上的System V IPC,后者则实现了基于socket的进程间通信机制。同时Linux也遵循IEEE制定的Posix IPC标准,在三者的基础之上实现了以下几种主要的IPC机制:管道(Pipe)及命名管道(Named Pipe),信号(Signal),消息队列(Message queue),共享内存(Shared Memory),信号量(Semaphore),套接字(Socket)。通过这些IPC机制,用户空间进程之间可以完成互相通信。为了完成内核空间与用户空间通信,Linux提供了基于socket的Netlink通信机制,可以实现内核与用户空间数据的及时交换。

本文第2节概述相关研究工作,第3节与其他IPC机制对比,详细介绍Netlink机制及其关键技术,第4节使用KGDB+GDB组合调试,通过一个示例程序演示Netlink通信过程。第5节做总结并指出Netlink通信机制的不足之处。

2 相关研究

到目前Linux提供了9种机制完成内核与用户空间的数据交换,分别是内核启动参数、模块参数与 sysfs、sysctl、系统调用、netlink、procfs、seq_file、debugfs和relayfs,其中模块参数与sysfs、procfs、debugfs、relayfs是基于文件系统的通信机制,用于内核空间向用户控件输出信息;sysctl、系统调用是由用户空间发起的通信机制。由此可见,以上均为单工通信机制,在内核空间与用户空间的双向互动数据交换上略显不足。Netlink是基于socket的通信机制,由于socket本身的双共性、突发性、不阻塞特点,因此能够很好的满足内核与用户空间小量数据的及时交互,因此在Linux 2.6内核中广泛使用,例如SELinux,Linux系统的防火墙分为内核态的netfilter和用户态的iptables,netfilter与iptables的数据交换就是通过Netlink机制完成。 

3 Netlink机制及其关键技术

3.1 Netlink机制

Linux操作系统中当CPU处于内核状态时,可以分为有用户上下文的状态和执行硬件、软件中断两种。其中当处于有用户上下文时,由于内核态和用户态的内存映射机制不同,不可直接将本地变量传给用户态的内存区;处于硬件、软件中断时,无法直接向用户内存区传递数据,代码执行不可中断。针对传统的进程间通信机制,他们均无法直接在内核态和用户态之间使用,原因如下表:

通信方法

无法介于内核态与用户态的原因

管道(不包括命名管道)

局限于父子进程间的通信。

消息队列

在硬、软中断中无法无阻塞地接收数据。

信号量

无法介于内核态和用户态使用。

内存共享

需要信号量辅助,而信号量又无法使用。

套接字

在硬、软中断中无法无阻塞地接收数据。

1*(引自 参考文献5)

    解决内核态和用户态通信机制可分为两类:

处于有用户上下文时,可以使用Linux提供的copy_from_user()和copy_to_user()函数完成,但由于这两个函数可能阻塞,因此不能在硬件、软件的中断过程中使用。

处于硬、软件中断时。

2.1   可以通过Linux内核提供的spinlock自旋锁实现内核线程与中断过程的同步,由于内核线程运行在有上下文的进程中,因此可以在内核线程中使用套接字或消息队列来取得用户空间的数据,然后再将数据通过临界区传递给中断过程.

2.2   通过Netlink机制实现。Netlink 套接字的通信依据是一个对应于进程的标识,一般定为该进程的 ID。Netlink通信最大的特点是对对中断过程的支持,它在内核空间接收用户空间数据时不再需要用户自行启动一个内核线程,而是通过另一个软中断调用用户事先指定的接收函数。通过软中断而不是自行启动内核线程保证了数据传输的及时性。

3.2 Netlink优点

Netlink相对于其他的通信机制具有以下优点:

使用Netlink通过自定义一种新的协议并加入协议族即可通过socket API使用Netlink协议完成数据交换,而ioctl和proc文件系统均需要通过程序加入相应的设备或文件。

Netlink使用socket缓存队列,是一种异步通信机制,而ioctl是同步通信机制,如果传输的数据量较大,会影响系统性能。

Netlink支持多播,属于一个Netlink组的模块和进程都能获得该多播消息。

Netlink允许内核发起会话,而ioctl和系统调用只能由用户空间进程发起。

在内核源码有关Netlink协议的头文件中包含了内核预定义的协议类型,如下所示:

#define NETLINK_ROUTE 0 #define NETLINK_W1 1 #define NETLINK_USERSOCK 2 #define NETLINK_FIREWALL 3 #define NETLINK_INET_DIAG 4 #define NETLINK_NFLOG 5 #define NETLINK_XFRM 6 #define NETLINK_SELINUX 7 #define NETLINK_ISCSI 8 #define NETLINK_AUDIT 9 #define NETLINK_FIB_LOOKUP 10#define NETLINK_CONNECTOR 11#define NETLINK_NETFILTER 12 #define NETLINK_IP6_FW 13#define NETLINK_DNRTMSG 14 #define NETLINK_KOBJECT_UEVENT 15 #define NETLINK_GENERIC 16

上一篇:需要了解的Linux MTD层次等问题


下一篇:了解并学习Linux加密框架设计与实现

友情链接
Links