引言
Alan Cox在内核1.3版本的开发阶段最先引入了Netlink,刚开始时Netlink是以字符驱动接口的方式提供内核与用户空间的双向数据通信;随后,在2.1内核开发过程中,Alexey Kuznetsov将Netlink改写成一个更加灵活、且易于扩展的基于消息通信接口,并将其应用到高级路由子系统的基础框架里。自那时起,Netlink就成了Linux内核子系统和用户态的应用程序通信的主要手段之一。
2001年,ForCES IETF委员会正式对Netlink进行了标准化的工作。Jamal Hadi Salim提议将Netlink定义成一种用于网络设备的路由引擎组件和其控制管理组件之间通信的协议。不过他的建议最终没有被采纳,取而代之的是我们今天所看到的格局:Netlink被设计成一个新的协议域,domain。
Linux之父托瓦斯曾说过“Linux is evolution, not intelligent design”。什么意思?就是说,Netlink也同样遵循了Linux的某些设计理念,即没有完整的规范文档,亦没有设计文档。只有什么?你懂得---“Read the f**king source code”。
当然,本文不是分析Netlink在Linux上的实现机制,而是就“什么是Netlink”以及“如何用好Netlink”的话题和大家做个分享,只有在遇到问题时才需要去阅读内核源码弄清个所以然。
什么是Netlink
关于Netlink的理解,需要把握几个关键点:
1、面向数据报的无连接消息子系统
2、基于通用的BSD Socket架构而实现
关于第一点使我们很容易联想到UDP协议,能想到这一点就非常棒了。按着UDP协议来理解Netlink不是不无道理,只要你能触类旁通,做到“活学”,善于总结归纳、联想,最后实现知识迁移这就是学习的本质。Netlink可以实现内核->用户以及用户->内核的双向、异步的数据通信,同时它还支持两个用户进程之间、甚至两个内核子系统之间的数据通信。本文中,对后两者我们不予考虑,焦点集中在如何实现用户<->内核之间的数据通信。
看到第二点脑海中是不是瞬间闪现了下面这张图片呢?如果是,则说明你确实有慧根;当然,不是也没关系,慧根可以慢慢长嘛,呵呵。
Netlink通信类型
Netlink支持两种类型的通信方式:单播和多播。
单播:经常用于一个用户进程和一个内核子系统之间1:1的数据通信。用户空间发送命令到内核,然后从内核接受命令的返回结果。