libnl库应用详解(一)

libnl库应用详解(一),第1张

   libnl 库提供了一套应用于Linux系统基于Netlink协议通信的API接口。从本质上看,Netlink其实是一种典型的IPC机制,只不过此IPC主要是介于用户空间与内核空间之间的通信,而非传统意义上用户空间进程之间的通信。Netlink是设计出来替换 ioctl 机制,就目前的使用情况,这一点显然还没有完全达到。

   libnl 在设计上被分割为若干个小型库( small libraries ),应用程序在链接时可以择库链接,无需将所有库链接到应用程序中。

libnl提供的主要头文件为 <netlink/netlink.h>,此外还提供了一些其他头文件,可以视应用程序的需要酌情增删。

可以在gcc中直接链接libnl库

  Netlink 协议是基于套接字的进程间通信(IPC)机制,它可用于用户空间进程和内核之间或者用户空间进程之间的通信。Netlink协议基于BSD套接字并使用AF_NETLINK地址簇。每一个Netlink协议都有自己的协议号(比如:NETLINK_ROUTE、NETLINK_NETFILTER等)。它的寻址方案是基裂改于 32 位的端口号(之前被称为 PID),此端口号用于唯一地标识每一个对等通信节点。

  Netlink 地址(端口)由一个 32 位的整数睁唯组成。端口(port)零保留给内核使用,表示每个Netlink协议簇中内核部分的套接字,其他的端口则通常指的是用户空间的套接字。

   注意: 最初通常使用进程标识符(PID)作为本地端口号,但这种方式随着线程化Netlink应用程序的引入而失效,因为这类进程需要多个套接字。为解决此项冲突,libnl以进程标识符为基数再加上一个偏移量来生成唯一的端口号,此方式可以让一个进程使用多个套接字。出于向后兼容方面的考虑,第一个套接字还是以进程标识符作为端口号。

  Netlink最常见的应用场景就是用户空间应用程序发送请求给内核,比如设置/读取接口的IP地址,然后接受并处理内核返回的信息,这个回复信息要么是请求悉源培出错的信息,要么就是请求成功的通知信息。

  Netlink也可以直接作为用户空间应用程序之间的进程间通信机制,但这种方式并不常见,通常会代之以unix域套接字。这种通信并不限制在两个对等通信节点之间,任意一个节点都可以和其他的对等点进行通信。此外因为Netlink支持多播,一条消息可以由多个节点同时接收到。

  注意:为了让套接字对通信双方可见,这两个套接字必须在同一个Netlink协议簇下创建。

  此类Netlink通信是一种非常常见的应用方式,此方式可以让用户空间那些需要处理特定内核事件的的守护进程侦听内核反馈的消息/事件。这些应用程序进程通常会订阅内核使用的某个多播组,内核则在某些事件发生的时候通过它来通知订阅该组播组的进程。

  相对于直接寻址来说,多播(组播)寻址是一个更好的方式,因为它有更高的灵活性,可以在无需通知内核的情况下随时与用户空间应用组件交换信息。

  Netlink协议通常是基于消息的,消息则通常是由Netlink消息头部(struct nlmsghdr)加上有效载荷组成。虽然有效载荷可以由任何数据组成,但是它通常的格式是一 个固定大小的协议相关头部后面紧跟一系列的属性。

  Netlink 在请求消息(requests)、通知消息(notifications)和应答消息(replies)的 处理上是有区别的。请求消息设有 NLM_F_REQUEST 标志位,它用来向接收方请求某种响应 。一般来说请求消息都是从用户空间发送到内核的。虽然不是强制规定,但每次发送的请求 消息序列号都应该是上一个序列号加一。

  由于请求自身的特性,接收方在收到请求消息之后可能会发送另一条 netlink 消息来响应 这个请求。应答消息的序列号必须和它响应的那条请求消息的序列号一致。

  通知消息则没有那么严谨,它不需要应答,所以序列号通常是被设置成 0 的。

消息的类型主要是由消息头部中 16 位的消息类型字段确定的。Netlink 定义了如下标准消息类型:

  每个 netlink 协议都可以自由的定义自己的消息类型。需要注意的是小于 NLMSG_MIN_TYPE(0x10) 的类型是保留的,所以不能使用。通常我们会定义自己的消息类型来实现 RPC 模式。假设你的 netlink 协议的目的是允许你 配置一个网络设备的某些部分,所以你想要提供各种配置选项的读/写访问。完成这项任务 典型的 “netlik 解决方案” 是定义两种消息类型 MSG_SETCFG,MSG_GETCFG :

  发送一条 MSG_GETCFG 请求消息通常会收到一条包含当前配置信息的类型为 MSG_SETCFG 的应答消息。用面向对象的术语来说这叫做 “内核在用户空间设置了配置信息的本地拷贝”

  理论上一条 netlink 消息的最大长度是 4GiB,但是套接字的缓冲区一般不会设置有如此大的空间来容纳4GiB消息。通常情况下,消息的长度被限制在页的大小(PAGE_SIZE )之内,然后使用分片机制把大消息分割为多个消息。分片消息设有 NLM_F_MULTI 标志位,接收者需要不断的接收和解析消息,直至收到一个消息类型为 NLMSG_DONE 的消息为止。

  和分片之后的ip包不一样,分片之后的Netlink消息无需重组,但是如果协议需要重组,也可以执行重组动作。分片消息经常会被用来发送对象列表或者是对象树,这种情况下消息段只是简单的承载几个对象,一般允许单独处理每个消息分片。

  错误消息可以作为请求消息的响应发送回去,错误消息必须使用标准的消息类型 NLMSG_ERROR ,它的有效载荷是由错误码和原来的请求消息头部组成。

  发送方可以通过设置 NLM_F_ACK 标志位来要求接收方为处理过的每一个请求消息都发送一 个ACK消息。这种方式通常是用来让发送方在请求被接收方处理之后同步下一步的 *** 作。

   NLM_F_ECHO 标志和 NLM_F_ACK 标志类似,它可以和 NLM_F_REQUEST 标志位一起使 用,使得发送者能够收到作为这条请求消息的响应而产生的通知信息,无论发送者是否订阅过相应的多播组。

GET 请求还定义了一些额外的通用标志位:

  这些标志的使用是完全可选的,许多netlink协议都只使用NLM_F_DUMP标志。这个标志通常用来请求接收者发送一个包含所有对象的列表,而这个列表则通常是一系列的消息分片。

  还有一些和 NEW 或者是 SET 请求相关的标志。这些标志和 GET 的那些标志是彼此互斥的 :

这些标志含义在不同的 netlink 协议中可能会有细微的差别。

  Netlink允许通过序列号来关联回复和请求。需要注意的是,这里的序列号和 TCP 这类的协议的序列号是不一样的,Netlink的序列号并不强制使用。序列号唯一的用途就是把一条应答消息和相应的请求消息联系起来,序列号是以单个套接字为基础来管理。

broadcom netlink fast ethernet

博通Netlink快速以太网

套接字Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。 Netlink套接字可以使用标准的套接字APIs来创建。socket(), bind(), sendmsg(), recvmsg() 和 close()很容易地应用到 netlink socket。山坦派 netlink包含于头文件linux/netlink.h中,逗贺网关产品厂商产品厂商:德国Hilscher(赫优讯)的主要网信氏关产品。

.

-----------------------------------

如有疑问欢迎追问!

满意请点击右上方【选为满意回答】按钮


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12132307.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存