linux内核通信-netlink使用例子

合集下载

Netlink编程-用户主动发起会话

Netlink编程-用户主动发起会话

Netlink编程-用户主动发起会话Netlink是一种在内核态和用户态可以进行双向通信的机制,也就是说,用户进程既可以作为服务器端又可以作为客户端,内核也是如此。

用户进程和内核谁是服务器端谁是客户端,这个问题与谁先主动发起数据交互会话有关。

用户进程主动向内核发起会话在Linux内核中很常见,比如系统调用、对/proc的操作等。

本文通过详解一个简单的实例程序来说明用户进程通过netlink机制如何主动向内核发起会话。

在该程序中,用户进程向内核发送一段字符串,内核接收到后再将该字符串后再重新发给用户进程。

用户态程序netlink是一种特殊的套接字,在用户态除了一些参数的传递对其使用的方法与一般套接字无较大差异,。

1.宏与数据结构的定义在使用netlink进行用户进程和内核的数据交互时,最重要的是定义好通信协议。

协议一词直白的说就是用户进程和内核应该以什么样的形式发送数据,以什么样的形式接收数据。

而这个“形式”通常对应程序中的一个特定数据结构。

本文所演示的程序并没有使用netlink已有的通信协议,因此我们自定义一种协议类型NETLINK_TEST。

1 #define NETLINK_TEST 182 #define MAX_PAYLOAD 102434 struct req {5 struct nlmsghdr nlh;6 char buf[MAX_PAYLOAD];7 };除此之外,我们应该再自定义一个数据报类型req,该结构包含了netlink数据包头结构的变量nlh和一个MAX_PAYLOAD大小的缓冲区。

这里我们为了演示简单,并没有像上文中描述的那样将一个特定数据结构与nlmsghdr 封装起来。

2.创建netlink 套接字要使用netlink ,必须先创建一个netlink 套接字。

创建方法同样采用socket(),只是这里需要注意传递的参数:1int sock_fd; 2 sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST); 3if (sock_fd < 0) { 4 eprint(errno, "socket", __LINE__);5return errno; 6 } 第一个参数必须指定为PF_NETLINK 或AF_NETLINK 。

Netlink内核实现分析3

Netlink内核实现分析3

Netlink内核实现分析3Netlink IPC 数据结构#define NETLINK_ROUTE 0 /* Routing/device hook */#define NETLINK_UNUSED 1 /* Unused number */#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */#define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */#define NETLINK_SOCK_DIAG 4 /* socket monitoring */#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */#define NETLINK_XFRM 6 /* ipsec */#define NETLINK_SELINUX 7 /* SELinux event notifications */#define NETLINK_ISCSI 8 /* Open-iSCSI */#define NETLINK_AUDIT 9 /* auditing */#define NETLINK_FIB_LOOKUP 10#define NETLINK_CONNECTOR 11#define NETLINK_NETFILTER 12 /* netfilter subsystem */#define NETLINK_IP6_FW 13#define NETLINK_DNRTMSG 14 /* DECnet routing messages */#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */#define NETLINK_GENERIC 16/* leave room for NETLINK_DM (DM Events) */#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */#define NETLINK_ECRYPTFS 19#define NETLINK_RDMA 20#define NETLINK_CRYPTO 21 /* Crypto layer */#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG#define MAX_LINKS 32View Code/*其中(1)nl_family始终为AF_NETLINK;(2)nl_pad始终为0;(3)nl_pid为netlink套接字的单播地址,在发送消息时⽤于表⽰⽬的套接字的地址,在⽤户空间绑定时可以指定为当前进程的PID号(对于内核来说这个值为0)或者⼲脆不设置(在绑定bind时由内核调⽤netlink_autobind()设置为当前进程的PID),但需要注意的是当⽤户同⼀个进程中需要创建多个netlink套接字时则必须保证这个值是唯⼀的(⼀般在多线程中可以使⽤”pthread_self() << 16 | getpid()“这样的⽅法进⾏设置);(4)nl_groups表⽰组播组。

NetLink使用实例(YGM)

NetLink使用实例(YGM)

如何使用Netlink Connector Author: Yang gongming简介:本文详细介绍了 Linux 2.6.34.14 内核引入的内核空间与用户空间通信的新机制连接器,并通过典型示例讲解了它的使用。

一、概述连接器是一种新的用户态与内核态的通信方式,它使用起来非常方便。

本质上,连接器是一种netlink,它的 netlink 协议号为 NETLINK_CONNECTOR,与一般的 netlink 相比,它提供了更容易的使用接口,使用起来更方便。

netlink本质上是socket,不过它可用于用户程序和内核程序的通信。

1.内核模块使用方法注册一个标识 ID 和回调函数,即可使用连接器。

cn_msg结构://标识netlink的IDstruct cb_id{__u32 idx;__u32 val;};//netlink控制信息头struct cn_msg{struct cb_id id;__u32 seq;__u32 ack;__u32 len;/* Length of the following data */__u8 data[0];};三个内核模块常用的API。

int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));void cn_del_callback(struct cb_id *id);void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask);结构 cb_id 是连接器实例的标识 ID,它用于确定 netlink 消息与回调函数的对应关系。

当连接器接收到标识 ID 为 {idx,val} 的 netlink 消息时,注册的回调函数 void (*callback) (void *) 将被调用。

该回调函数的参数为结构struct cn_msg 的指针。

用户空间和内核空间通讯之【Netlink下】

用户空间和内核空间通讯之【Netlink下】

用户空间和内核空间通讯之【Netlink下】在上一篇博文中我们所遇到的情况都是用户空间作为消息进程的发起者,Netlink还支持内核作为消息的发送方的情况。

这一般用于内核主动向用户空间报告一些内核状态,例如我们在用户空间看到的USB的热插拔事件的通告就是这样的应用。

先说一下我们的目标,内核线程每个一秒钟往一个多播组里发送一条消息,然后用户空间所以加入了该组的进程都会收到这样的消息,并将消息内容打印出来。

Netlink地址结构体中的nl_groups是32位,也就是说每种Netlink协议最多支持32个多播组。

如何理解这里所说的每种Netlink 协议?在</usr/include/linux/netlink.h>里预定义的如下协议都是Netlink协议簇的具体协议,还有我们添加的NETLINK_TEST也是一种Netlink协议。

1.#define NETLINK_ROUTE 0 /*Routing/device hook */2.#define NETLINK_UNUSED 1 /*Unused number */3.#define NETLINK_USERSOCK 2 /*Reserved for user mode socket protocols */4.#define NETLINK_FIREWALL 3 /*Firewalling hook */5.#define NETLINK_INET_DIAG 4 /*INET socket monitoring */6.#define NETLINK_NFLOG 5 /*netfilter/iptables ULOG */7.#define NETLINK_XFRM 6 /* ipsec */8.#define NETLINK_SELINUX 7 /*SELinux event notifications */9.#define NETLINK_ISCSI 8 /* Open-iSCSI */10.#define NETLINK_AUDIT 9 /* auditing */11.#define NETLINK_FIB_LOOKUP 1012.#define NETLINK_CONNECTOR 1113.#define NETLINK_NETFILTER 12 /*netfilter subsystem */14.#define NETLINK_IP6_FW 1315.#define NETLINK_DNRTMSG 14 /*DECnet routing messages */16.#define NETLINK_KOBJECT_UEVENT 15 /*Kernel messages to userspace */17.#define NETLINK_GENERIC 1618./* leave room for NETLINK_DM (DM Events)*/19.#define NETLINK_SCSITRANSPORT 18 /*SCSI Transports */20.#define NETLINK_ECRYPTFS 1921.#define NETLINK_TEST 20 /* 用户添加的自定义协议 */在我们自己添加的NETLINK_TEST协议里,同样地,最多允许我们设置32个多播组,每个多播组用1个比特表示,所以不同的多播组不可能出现重复。

Netlink套接字在Linux系统通信中的应用研究

Netlink套接字在Linux系统通信中的应用研究
d ti| e al
Ke r s N t n o k t y t m o y wo d : e l k s e ;s se c mmu iai n P i c nc t ;I C o
0 引 言
’不能用在硬 、 软中断中, 只能由用户方主动发起通信 , 内核 不能主 动向用 户 进 程 写数 据 。这 种 通 信 方式 比 Ln x 作 系 统 作 为 目前 最 流 行 的 开 源 操 作 系 较适 用于读 写硬件 系统驱 动程序 的参 数 。 iu 操 ( ) rc 2 pof 口。虚 拟 文 件 系统 , 常 挂 接 在/ s接 通 统, 为许 多硬 软件 产品 的开发 提供 了 良好 的平 台。开 rc目录下 , 内核通过 文件 形式将 内部 信息展 现 给用 发 者可对 内核进行 裁减 和修 改 , 制最适合 的操作 系 po 定 户空 间进程 , 创建这 些文件 的 内核模 块规定用 户 空 间 统平台, 并在 此基 础 之 上进 行 用 户 应用 程 序 的开 发 。 po Lnx为用 户 进 程 和 内核 进 程 的通 信 提 供 了 多种 方 的文件访 问权 限。/ rc目录对 于用户 空 间是 不可 写 iu
中 图分 类 号 :P l T 3
文献 标 识 码 : A
Re e r h o p ia in o t n o k ti i u y t m mm u i t n s a c n Ap l t fNel k S c e L n x S se Co c o i n nc i a o
维普资讯
20 07年第 3期
计 算 机 与 现 代 化 J U N IY I N AHU I A J U XA D I A S
总 第 19期 3
文 章 编 号 :0 62 7 ( 07 0 -190 10 -4 5 2 0 )300 - 3

netlink

netlink

netlink socket编程why & how作者: Kevin Kaichuan He@2005-1-5翻译整理:duanjigang @2008-9-15<duanjigang1983@>原文:/article/7356开发和维护内核是一件很繁杂的工作,因此,只有那些最重要或者与系统性能息息相关的代码才将其安排在内核中。

其它程序,比如GUI,管理以及控制部分的代码,一般都会作为用户态程序。

在linux系统中,把系统的某个特性分割成在内核中和在用户空间中分别实现一部分的做法是很常见的(比如linux系统的防火墙就分成了内核态的Netfilter和用户态的iptables)。

然而,内核程序与用户态的程序又是怎样行通讯的呢?答案就是通过各种各样的用户态和内核态的IPC(interprocess communication )机制来实现。

比如系统调用,ioctl接口,proc文件系统以及netlink socket,本文就是要讨论netlink socekt并向读者展示这种用网络通讯接口方式实现的IPC机制的优点。

介绍:netlink socekt是一种用于在内核态和用户态进程之间进行数据传输的特殊的IPC。

它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket 接口的方式,实现了一种全双工的通讯连接。

类似于TCP/IP中使用AF_INET地址族一样,netlink socket使用地址族AF_NETLINK。

每一个netlink socket在内核头文件include/linux/netlink.h中定义自己的协议类型。

下面是netlink socket 目前的特性集合以及它支持的协议类型:¾NETLINK_ROUTE: 用户空间的路由守护程序之间的通讯通道,比如BGP,OSPF,RIP以及内核数据转发模块。

用户态的路由守护程序通过此类型的协议来更新内核中的路由表。

Linux用户态与内核态的交互

Linux用户态与内核态的交互

Linux 用户态与内核态的交互Linux用户态与内核态的交互2010-06-13 22:30Linux用户态与内核态的交互在Linux 2.4版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用netlink套接字实现的,例如iprote2网络管理工具,它与内核的交互就全部使用了netlink,著名的内核包过滤框架Netfilter在与用户空间的通读,也在最新版本中改变为netlink,无疑,它将是Linux用户态与内核态交流的主要方法之一。

它的通信依据是一个对应于进程的标识,一般定为该进程的ID。

当通信的一端处于中断过程时,该标识为0。

当使用netlink套接字进行通信,通信的双方都是用户态进程,则使用方法类似于消息队列。

但通信双方有一端是中断过程,使用方法则不同。

netlink套接字的最大特点是对中断过程的支持,它在内核空间接收用户空间数据时不再需要用户自行启动一个内核线程,而是通过另一个软中断调用用户事先指定的接收函数。

《UNIX Network Programming Volume 1-3rd Edition》第18章讲到BSD UNIX系统中routing socket的应用,这种套接字是按下面方式生成的:rt_socket=socket(AF_ROUTE,SOCK_RAW,0);然后就可以用它跟内核交互,进行网络环境管理的操作,如读取/设置/删除路由表信息,更改网关等等,但书中所列代码只在4.3BSD及以后版本的原始UNIX系统下可用,Linux虽然实现了AF_ROUTE族套接字,但用法却完全不同。

由于网上这方面知识的资料想对匮乏,现对Linux下routing socket的使用做一介绍。

由于我现在在MagicLinux1.0下工作,所以以下的讲解全部基于2.4.10内核。

Linux从v2.2开始引入这一机制,因此可以肯定从v2.2到v2.4的内核都是适用的,更新的v2.6我没有试过。

linux中link用法

linux中link用法

linux中link用法摘要:1.Linux 中的link 是什么2.link 的基本用法3.link 的参数及用法详解4.link 的实际应用举例5.总结正文:【1.Linux 中的link 是什么】在Linux 系统中,link 是一种用于创建文件或目录的快捷方式的命令。

它可以为文件或目录创建一个链接,使得用户可以通过该链接快速地访问原始文件或目录,而不需要记住其具体的路径。

【2.link 的基本用法】link 命令的基本用法如下:```link [选项] 源文件或目录目标文件或目录```其中,源文件或目录是要创建链接的文件或目录,目标文件或目录是链接所指向的文件或目录。

【3.link 的参数及用法详解】link 命令支持以下参数:- -s:创建软链接,即创建一个指向源文件或目录的快捷方式。

软链接的特点是,当源文件或目录被删除时,软链接也会失效。

- -h:创建硬链接,即创建一个与源文件或目录相同的文件或目录。

硬链接的特点是,当源文件或目录被删除时,硬链接仍然可以访问原始内容。

- -v:显示详细信息,用于显示创建的链接的详细信息。

【4.link 的实际应用举例】例1:创建一个指向文件的软链接```link -s source.txt link_to_source.txt```执行以上命令后,会在当前目录下创建一个名为“link_to_source.txt”的文件,它指向“source.txt”。

例2:创建一个指向文件的硬链接```link -h source.txt link_to_source.txt```执行以上命令后,会在当前目录下创建一个名为“link_to_source.txt”的文件,它与“source.txt”指向同一个内容。

例3:创建一个指向目录的软链接```link -s dir1 link_to_dir1```执行以上命令后,会在当前目录下创建一个名为“link_to_dir1”的目录,它指向“dir1”。

netlink用法

netlink用法

netlink用法1. 什么是netlinknetlink是Linux内核中一个用于内核和用户空间进程通信的机制。

它允许内核向用户空间应用程序发送消息,并提供了一种用于配置,管理和监视内核子系统的接口。

2. netlink的特性netlink的特性使其成为了Linux环境下进行内核和用户空间通信的重要工具,具有以下特点:2.1 强大而灵活netlink提供了一种灵活的通信机制,允许内核和用户空间之间进行双向通信。

应用程序可以通过发送消息给内核来请求信息,而内核也可以通过发送消息给应用程序来通知其发生的事件。

2.2 支持多种消息类型netlink支持多种消息类型,如路由信息、网络配置、接口状态等。

这使得开发者可以利用netlink来实现各种不同的功能。

2.3 可靠和高效netlink使用基于内存的套接字,相比于其他IPC机制(如管道和信号量),netlink是一种更加可靠和高效的通信机制。

它避免了不必要的内核空间与用户空间的拷贝,从而提高了系统的性能。

3. netlink的使用3.1 netlink的工作原理netlink通信的基本单位是消息(message),消息由一个头部(header)和一个有效载荷(payload)组成。

头部包含了消息的类型、源地址、目的地址等信息,有效载荷是实际的数据。

3.2 使用netlink库函数为了方便使用netlink,Linux提供了一组用户空间的库函数。

通过这些库函数,我们可以方便地发送和接收netlink消息。

3.2.1 创建netlink套接字首先,我们需要使用socket系统调用创建一个netlink套接字。

通过指定NETLINK_XXX作为协议参数,可以选择不同的netlink协议。

3.2.2 绑定套接字在创建套接字之后,我们需要使用bind函数将套接字与一个本地地址进行绑定。

这个本地地址可以是任意的netlink协议中定义的地址。

3.2.3 构造消息使用netlink库函数,我们可以方便地构造一个netlink消息。

linux内核态与用户态通讯方式-guolele

linux内核态与用户态通讯方式-guolele

内核态与用户态通讯方式主要有几种:1、procfs2、系统调用(syscall)3、netlink4、mmap5、驱动文件,统一APIproc 文件系统特点:虚拟文件系统,提供一种便捷的用户和内核间的交互方式,一般用于调试日志以及配置参数缺点:不够实时,无法传输大数据量使用:创建proc文件驱动,然后像操作文件一样操作,驱动负责解析应用层的read write 请求mmap特点:直接用户空间与内核空间映射,直接操作,无需拷贝,可传输数据量大,实时性好。

缺点:没有专门同步机制,需要配合别的操作使用,简单数据量不使用此方法,过于复杂使用:字符或者块设备驱动将内核空间地址提供mmap映射,此内核空间可在uboot中预留大空间,也可使用kmalloc(转小,连续物理内存) vmalloc(较大,连续虚拟内存,物理不连续)创建在Linux内核中, kmalloc能够分配的最大连续内存为2的(MAX_ORDER-1)次方个page(参见alloc_pages函数, "if (unlikely(order >= MAX_ORDER)) return NULL;"), page的大小一般是4K bytes, MAX_ORDER缺省定义为11, 所以如果不修改内核, kmalloc能够分配的最大连续内存一般是4M bytes.vmalloc 一般用于将非连续物理内存映射成连续虚拟内存空间以便普通使用,也有预留于超大内存>8GB,使用内核参数vmalloc=xxxM来将超大的空间用起来,64bit不存在这个问题了。

内核启动参数传递"mem="参数, 如"mem=80M", 预留部分内存; 然后通过request_mem_region和ioremap_nocache将预留的内存映射到模块中. 需要修改内核启动参数, 无需重新编译内核. 但这种方法不支持x86架构, 只支持ARM, PowerPC等非x86架构. request_mem_region只为了显示在/proc/iomem,只为了显示,不用也能正常用。

在Linux终端中配置网络连接的方法

在Linux终端中配置网络连接的方法

在Linux终端中配置网络连接的方法Linux终端是一种功能强大的工具,它不仅可以执行各种命令和操作系统任务,还可以通过配置网络连接来实现对互联网的访问。

本文将介绍几种在Linux终端中配置网络连接的方法。

方法一:使用ifconfig命令在Linux终端中,可以使用ifconfig命令配置网络连接。

该命令可以查看和设置网络接口的配置信息。

以下是使用ifconfig命令配置网络连接的步骤:1. 打开终端并输入以下命令查看当前的网络接口:$ ifconfig2. 根据需要选择要配置的网络接口,例如eth0或wlan0。

3. 输入以下命令来配置选定的网络接口:$ ifconfig [接口名称] [IP地址] [掩码]其中,[接口名称]是网络接口的名称,[IP地址]是你希望设置的IP 地址,[掩码]是网段的掩码。

例如,要将eth0接口的IP地址设置为192.168.1.100,掩码为255.255.255.0,可以输入以下命令: $ ifconfig eth0 192.168.1.100 netmask 255.255.255.04. 输入以下命令来启用网络接口:$ ifconfig [接口名称] up例如,要启用eth0接口,可以输入以下命令:$ ifconfig eth0 up方法二:使用ip命令除了ifconfig命令外,还可以使用ip命令配置网络连接。

ip命令是一个更高级的网络配置工具,具有更多的功能和选项。

以下是使用ip命令配置网络连接的步骤:1. 打开终端并输入以下命令查看当前的网络接口:$ ip addr2. 根据需要选择要配置的网络接口,例如eth0或wlan0。

3. 输入以下命令来配置选定的网络接口:$ ip addr add [IP地址/掩码] dev [接口名称]其中,[IP地址/掩码]是你希望设置的IP地址和掩码,[接口名称]是网络接口的名称。

例如,要将eth0接口的IP地址设置为192.168.1.100/24,可以输入以下命令:$ ip addr add 192.168.1.100/24 dev eth04. 输入以下命令来启用网络接口:$ ip link set [接口名称] up例如,要启用eth0接口,可以输入以下命令:$ ip link set eth0 up方法三:编辑网络配置文件另一种配置网络连接的方法是通过编辑网络配置文件。

Linux中与内核通信的Netlink机制

Linux中与内核通信的Netlink机制

Linux中与内核通信的Netlink机制Netlink在2.6版本的内核中变化也是很大的,在最新的2.6.37内核中,其定义已经改成下面这种形式,传递的参数已经达到6个。

其中第一个参数和mutex参数都是最新添加的。

Mutex 也可以为空。

这里主要是关于内核空间中的netlink函数的使用。

extern struct sock *netlink_kernel_create(struct net *net,int unit,unsigned int groups,void (*input)(struct sk_buff *skb),struct mutex *cb_mutex,struct module *module);struct net是一个网络名字空间namespace,在不同的名字空间里面可以有自己的转发信息库,有自己的一套net_device等等。

默认情况下都是使用init_net这个全局变量,下面是内核中调用netlink_kernel_create()函数的一个示例。

在内核中,audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0,audit_receive, NULL, THIS_MODULE);模块调用函数netlink_unicast 来发送单播消息:int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock)参数ssk为函数netlink_kernel_create()返回的socket,参数skb存放消息,它的data字段指向要发送的netlink消息结构,而skb的控制块保存了消息的地址信息,前面的宏NETLINK_CB(skb)就用于方便设置该控制块,参数pid为接收消息进程的pid,参数nonblock 表示该函数是否为非阻塞,如果为1,该函数将在没有接收缓存可利用时立即返回,而如果为0,该函数在没有接收缓存可利用定时睡眠。

netlink用法

netlink用法

Netlink是Linux内核提供的一种进程间通信机制,用于完成内核与用户空间之间的通信。

常用于协议实现、网络管理、虚拟网络等场景。

下面是netlink的常用用法:
创建Socket:使用socket()系统调用来创建一个Netlink 的Socket。

绑定Socket:使用bind()系统调用将Socket与Netlink协议族绑定。

创建Netlink消息:通过Netlink的数据结构来创建Netlink 消息,并填充消息头部和传输数据部分。

发送Netlink消息:使用sendmsg()系统调用来发送Netlink 消息。

接收Netlink消息:使用recvmsg()系统调用来接收Netlink 消息。

解析Netlink消息:使用Netlink的数据结构来解析接收到的Netlink消息,包括消息头部和传输数据部分。

处理Netlink消息:根据不同的消息类型和操作,使用Netlink 的数据结构来处理接收到的Netlink消息。

关闭Socket:使用close()系统调用来关闭Netlink Socket。

总的来说,Netlink是Linux内核中非常重要的IPC机制之一,常被用于内核与用户空间之间的通信,可用于协议实现与管理等多个场景。

【IT专家】如何在内核和用户空间之间创建“netlink”?

【IT专家】如何在内核和用户空间之间创建“netlink”?

本文由我司收集整编,推荐下载,如有疑问,请与我司联系如何在内核和用户空间之间创建“netlink”?如何在内核和用户空间之间创建“netlink”?[英]How do I create a “netlink”between kernel and userspace? I want to use netlink to communicate between anapplication and kernel space. My Linux kernel version is 2.6.28, and the following is my wrong code:我想使用netlink 在应用程序和内核空间之间进行通信。

我的Linux 内核版本是2.6.28,以下是我的错误代码:nf_sock=netlink_kernel_create(NL_PROTO,0,nl_user_skb,THIS_MODULE); The abbreviated error message is:缩写错误消息是:error: too few arguments to function ‘netlink_kernel_create’ In the file linux/netlink.h , the function netlink_kernel_create() is defined as在文件中,函数netlink_kernel_create()定义为extern struct sock *netlink_kernel_create(struct net *net,int unit,unsigned int groups,void (*input)(struct sk_buff *skb),struct mutex *cb_mutex,struct module *module) I don’t understand what to use for the first argument, net. Can someone explain what Ishould use here?我不明白第一个参数net 用什么。

Netlink内核实现分析1

Netlink内核实现分析1

Netlink内核实现分析1Netlink 是⼀种IPC(Inter Process Commumicate)机制,它是⼀种⽤于内核与⽤户空间通信的机制,在⼀般情况下,⽤户态和内核态通信会使⽤传统的Ioctl、sysfs属性⽂件或者procfs属性⽂件,这3种通信⽅式都是同步通信⽅式,由⽤户态主动发起向内核态的通信,内核⽆法主动发起通信。

Netlink是⼀种异步全双⼯的通信⽅式,它⽀持由内核态主动发起通信,内核为Netlink通信提供了⼀组特殊的API接⼝,⽤户态则基于socket API,内核发送的数据会保存在接收进程socket 的接收缓存中,由接收进程处理。

netlink 优点:可以由内核发起,⽤户进程可以使⽤IO复⽤模型⽀持组播,即内核态可以将消息发送给多个接收进程Netlink ⼦系统初始化流程netlink 内核⼦接⼝初始化实在 net/netlink/af_netlink.c中初始化完成static const struct rhashtable_params netlink_rhashtable_params = {.head_offset = offsetof(struct netlink_sock, node),.key_len = netlink_compare_arg_len,.obj_hashfn = netlink_hash,.obj_cmpfn = netlink_compare,.automatic_shrinking = true,};/*这⾥的hash(哈希表)⽤来索引同种协议类型的不同netlink套接字实例,mc_list为多播使⽤的sock散列表,listeners为监听者掩码,groups为协议⽀持的最⼤多播组数量,同时还定义了⼀些函数指针,它们会在内核⾸次创建netlink时被赋值,后续应⽤层创建和绑定socket时调⽤到。

回到初始化函数中,接下来初始化应⽤层使⽤的NETLINK_USERSOCK协议类型的netlink(⽤于应⽤层进程间通信);然后调⽤sock_register向内核注册协议处理函数,即将netlink的socket创建处理函数注册到内核中,如此以后应⽤层创建netlink类型的socket时将会调⽤该协议处理函数,其中*/static int __init netlink_proto_init(void){int i;int err = proto_register(&netlink_proto, 0);if (err != 0)goto out;BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));//之开辟了MAX_LINKS个na_talbe指针空间nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);if (!nl_table)goto panic;//分配MAX_LINKS个netlink表结构, nl_table, 每个成员代表⼀种协议类型for (i = 0; i < MAX_LINKS; i++) {if (rhashtable_init(&nl_table[i].hash,&netlink_rhashtable_params) < 0) {rhashtable_destroy(&nl_table[i].hash);kfree(nl_table);goto panic;}}INIT_LIST_HEAD(&netlink_tap_all);netlink_add_usersock_entry();sock_register(&netlink_family_ops);//将netlink socket 创建函数注册到内核中,即创建netlink socket 时回调函数为 netlink_family_ops->create 回调register_pernet_subsys(&netlink_net_ops);/* The netlink device handler may be needed early. */rtnetlink_init();out:return err;panic:panic("netlink_init: Cannot allocate nl_table\n");}core_initcall(netlink_proto_init本初始化函数⾸先向内核注册netlink协议;然后创建并初始化了nl_table表数组,这个表是整个netlink实现的最关键的⼀步,每种协议类型占数组中的⼀项,后续内核中创建的不同种协议类型的netlink都将保存在这个表中.struct netlink_table {struct rhashtable hash;// hash表控制块,内部的hash表记录了已经创建的同种协议类型的所有netlink套接字struct hlist_head mc_list; // 这个hash表头节点⽤于记录同种协议类型下所有阅订了组播功能的套接字struct listeners __rcu *listeners; // 记录了同种协议类型下所有被阅订了的组播消息集合为监听者掩码unsigned int flags;unsigned int groups;// 记录了该协议类型⽀持的最⼤组播数量(通常就是32个)struct mutex *cb_mutex;struct module *module;//函数指针会在内核⾸次创建netlink时被赋值,后续应⽤层创建和绑定socket时调⽤到int (*bind)(struct net *net, int group);void (*unbind)(struct net *net, int group);bool (*compare)(struct net *net, struct sock *sock);int registered;};/*应⽤层创建PF_NETLINK(AF_NETLINK)类型的socket()系统调⽤时将由netlink_create()函数负责处理*/static const struct net_proto_family netlink_family_ops = {.family = PF_NETLINK,.create = netlink_create,.owner = THIS_MODULE, /* for consistency 8) */};Netlink 套接字对于每个类型都会创建⼀个内核的netlink 套接字⽤于和应⽤层通信;以NETLINK_ROUTE为例static int __net_init rtnetlink_net_init(struct net *net){struct sock *sk;struct netlink_kernel_cfg cfg = {.groups = RTNLGRP_MAX,.input = rtnetlink_rcv,.cb_mutex = &rtnl_mutex,.flags = NL_CFG_F_NONROOT_RECV,};sk = netlink_kernel_create(net, NETLINK_ROUTE, &cfg);if (!sk)return -ENOMEM;net->rtnl = sk;return 0;}/*定义了⼀个netlink_kernel_cfg结构体实例,设置groups为RTNLGRP_MAX后指定消息接收处理函数为rtnetlink_rcv,并设置flag为NL_CFG_F_NONROOT_RECV,这表明⾮超级⽤户可以绑定到多播组,但是没有设置NL_CFG_F_NONROOT_SEND,这表明⾮超级⽤户将不能发送组播消息。

linux中link的用法和搭配

linux中link的用法和搭配

linux中link的用法和搭配
在Linux中,`link`命令用于创建一个新的文件链接或目录链接。

它的用法和搭配有以下几种:
1. 创建硬链接:
`link <源文件> <目标文件>`
`ln <源文件> <目标文件>`
例如,要在当前目录下创建一个名为`newfile`的硬链接指向`oldfile`,可以使用以下命令:`link oldfile newfile`或`ln oldfile newfile`。

2. 创建符号链接(软链接):
`ln -s <源文件> <目标文件>`
例如,要在当前目录下创建一个名为`newfile`的符号链接指向`oldfile`,可以使用以下命令:`ln -s oldfile newfile`。

3. 使用绝对路径创建链接:
`ln -s /path/to/source /path/to/target`
这种方式可以在不同的目录之间创建链接。

4. 创建目录链接:
`ln -s <源目录> <目标目录>`
若要将一个目录创建为另一个目录的链接,可以使用以上类似的命令。

5. 查看链接信息:
`ls -l <链接文件>`
对于硬链接,`ls -l`命令会显示链接文件和源文件的相同
inode号码和权限。

而对于符号链接,`ls -l`命令会显示链接文
件和源文件之间的路径关系。

这些是`link`命令的主要用法和搭配方式。

通过这些命令形式,可以在Linux中有效地创建链接,便于管理和组织文件和目录。

linux的nlmsghdr用法

linux的nlmsghdr用法

linux的nlmsghdr用法在Linux系统中,nlmsghdr结构体用于表示Netlink消息头。

Netlink是一种进程间通信协议,旨在为内核和用户空间提供一种可靠的数据传输机制。

Netlink提供了多种协议族,其中之一是NETLINK_GENERIC协议族,它可以用来实现自定义通信协议。

nlmsghdr结构体的定义如下:```cstruct nlmsghdr {__u32 nlmsg_len;__u16 nlmsg_type;__u16 nlmsg_flags;__u32 nlmsg_seq;__u32 nlmsg_pid;};```其中,各成员变量的含义如下:- nlmsg_len 表示Netlink消息的总长度,包括消息头和消息体。

- nlmsg_type 表示Netlink消息的类型。

- nlmsg_flags 表示Netlink消息的标记,可以包括NLM_F_REQUEST、NLM_F_ACK、NLM_F_DUMP等,具体含义请参考官方文档。

- nlmsg_seq 表示Netlink消息的序列号,用于标识消息的顺序。

- nlmsg_pid 表示发送或接收Netlink消息的进程ID。

下面是一个简单的使用例子,展示如何创建一个Netlink消息并向内核发送:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <linux/netlink.h>#define NETLINK_TEST 25#define MAX_PAYLOAD 1024//创建Netlink socketsockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);if (sockfd < 0) {perror("socket");return -1;}//绑定源地址memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid();src_addr.nl_groups = 0;ret = bind(sockfd, (struct sockaddr *)&src_addr, sizeof(src_addr)); if (ret < 0) {perror("bind");return -1;}//构造Netlink消息头nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);nlh->nlmsg_type = 1; //自定义消息类型nlh->nlmsg_flags = NLM_F_REQUEST;nlh->nlmsg_seq = 0;nlh->nlmsg_pid = getpid();//设置消息体strcpy(NLMSG_DATA(nlh), "Hello, kernel!");//设置iovec结构体iov.iov_base = (void *)nlh;iov.iov_len = nlh->nlmsg_len;//解析Netlink消息头nlh = (struct nlmsghdr *)msg.msg_iov->iov_base;printf("Received message: %s\n", (char *)NLMSG_DATA(nlh));//释放资源free(nlh);close(sockfd);return 0;}```在这个例子中,我们创建了一个Netlink socket,并设置了源地址和目的地址。

nl80211 程序 例子

nl80211 程序 例子

nl80211是一个用于与Linux 内核的nl80211 驱动交互的库。

它允许用户空间程序与无线网卡进行交互,例如扫描无线网络、连接到网络等。

以下是一个简单的nl80211程序示例,该程序扫描可用的无线网络并打印其详细信息:c复制代码#include<stdio.h>#include<stdlib.h>#include<nl80211.h>#include<netlink/netlink.h>#include<netlink/socket.h>#include<netlink/attr.h>int main(void) {struct nl_sock *sk;struct nl_msg *msg;int err;int seq = 1;int flags = NLM_F_DUMP | NLM_F_REQUEST;struct nlattr *nest;struct nlattr *tb[NL80211_ATTR_MAX + 1];struct nl_msg *req;char buf[1024];struct nl_parser *parser;struct nl_cache *cache;int ifindex = 0; // 使用默认的无线网络接口sk = nl_socket_alloc();if (!sk) {fprintf(stderr, "Failed to allocate netlink socket.\n");exit(EXIT_FAILURE);}if (genl_connect(sk) < 0) {fprintf(stderr, "Failed to connect to generic netlink.\n");exit(EXIT_FAILURE);}req = nlmsg_alloc();if (!req) {fprintf(stderr, "Failed to allocate netlink message.\n");exit(EXIT_FAILURE);}nl_msg_put_header(req, sk, &seq, flags, NL80211_CMD_GET_WIPHY);nest = nla_nest_start(req, NL80211_ATTR_WIPHY);nla_put_u32(req, NL80211_WIPHY_INDEX, ifindex);nla_nest_end(req, nest);if ((err = nl_send_auto_complete(sk, req)) < 0) {fprintf(stderr, "Failed to send netlink message: %s.\n", strerror(-err));exit(EXIT_FAILURE);}parser = nl_parser_alloc();if (!parser) {fprintf(stderr, "Failed to allocate netlink parser.\n");exit(EXIT_FAILURE);}if ((err = nl_parser_start(parser, sk)) < 0) {fprintf(stderr, "Failed to start netlink parser: %s.\n", strerror(-err));exit(EXIT_FAILURE);}while (nl_recvmsgs(sk, buf, sizeof buf) > 0) {if ((err = nl_parser_next(parser)) < 0) {fprintf(stderr, "Failed to parse netlink message: %s.\n", strerror(-err));exit(EXIT_FAILURE);} else if (nl_msg_parse(parser, tb) < 0) {fprintf(stderr, "Failed to parse netlink attributes.\n");exit(EXIT_FAILURE);} else if (tb[NL80211_ATTR_WIPHY]) {struct wiphy *wiphy = nla_data(tb[NL80211_ATTR_WIPHY]);struct wiphy_info info;wiphy_info(*wiphy, &info); // 获取 wiphy 的信息并存储在 info 中,这里仅打印 wiphy 的名称和 wiphy 的频率范围。

Generic Netlink详解

Generic Netlink详解

∙双向传输,异步通信∙用户空间中使用标准socket API∙内核空间中使用专门的API∙支持多播∙可由内核端发起通信∙支持32种协议类型netlink仅支持32种协议类型,这在实际应用中可能并不足够。

因此产生了generic netlink(以下简称为genl)。

generic netlink支持1023个子协议号,弥补了netlink协议类型较少的缺陷。

支持协议号自动分配。

它基于netlink,但是在内核中,generic netlink的接口与netlink并不相同。

1. Generic Netlink框架概述图1表示了Generic Netlink框架。

Kernel socket API向用户空间和内核空间分别提供接口。

Netlink子系统(1)是所有genl通信的基础。

Netlink子系统中收到的所有Generic类型的netlink数据都被送到genl总线(2)上;从内核发出的数据也经由genl总线送至netlink子系统,再打包送至用户空间。

Generic Netlink控制器(4)作为内核的一部分,负责动态地分配genl通道(即genl family id),并管理genl任务。

genl控制器是一个特殊的genl内核用户,它负责监听genl bus上的通信通道。

genl通信建立在一系列的通信通道的基础上,每个genl family对应多个通道,这些通道由genl控制器动态分配。

+---------------------+ +---------------------+| (3) application "A" | | (3) application "B" |+------+--------------+ +--------------+------+| |\ /\ /| |+-------+--------------------------------+-------+| : : |user-space=====+ : (5) Kernel socket API :+================| : : |kernel-space+--------+-------------------------------+-------+| |+-----+-------------------------------+----+| (1) Netlink subsystem |+---------------------+--------------------+|+---------------------+--------------------+| (2) Generic Netlink bus |+--+--------------------------+-------+----+| | |+-------+---------+ | || (4) Controller | / \+-----------------+ / \| |+------------------+--++--+------------------+| (3) kernel user "X" | | (3) kernel user "Y" | +---------------------++---------------------+图1:generic netlink框架2 Generic Netlink相关结构体2.1 genl familyGeneric Netlink是基于客户端-服务端模型的通信机制。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Netlink 是一种特殊的socket,它是Linux 所特有的,类似于BSD 中的AF_ROUTE 但又远比它的功能强大,目前在最新的Linux 内核(2.6.14)中使用netlink 进行应用与内核通信的应用很多,包括:路由daemon (NETLINK_ROUTE),1-wire 子系统(NETLINK_W1),用户态socket 协议(NETLINK_USERSOCK),防火墙(NETLINK_FIREWALL),socket 监视(NETLINK_INET_DIAG),netfilter 日志(NETLINK_NFLOG),ipsec 安全策略(NETLINK_XFRM),SELinux 事件通知(NETLINK_SELINUX),iSCSI 子系统(NETLINK_ISCSI),进程审计(NETLINK_AUDIT),转发信息表查询(NETLINK_FIB_LOOKUP),netlinkconnector(NETLINK_CONNECTOR),netfilter 子系统(NETLINK_NETFILTER),IPv6 防火墙(NETLINK_IP6_FW),DECnet 路由信息(NETLINK_DNRTMSG),内核事件向用户态通知(NETLINK_KOBJECT_UEVENT),通用netlink (NETLINK_GENERIC)。

Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的socket API 就可以使用netlink 提供的强大功能,内核态需要使用专门的内核API 来使用netlink。

Netlink 相对于系统调用,ioctl 以及/proc 文件系统而言具有以下优点:1,为了使用netlink,用户仅需要在include/linux/netlink.h 中增加一个新类型的netlink 协议定义即可,如#define NETLINK_MYTEST 17 然后,内核和用户态应用就可以立即通过socket API 使用该netlink 协议类型进行数据交换。

但系统调用需要增加新的系统调用,ioctl 则需要增加设备或文件,那需要不少代码,proc 文件系统则需要在/proc 下添加新的文件或目录,那将使本来就混乱的/proc 更加混乱。

2. netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息,但系统调用与ioctl 则是同步通信机制,如果传递的数据太长,将影响调度粒度。

3.使用netlink 的内核部分可以采用模块的方式实现,使用netlink 的应用部分和内核部分没有编译时依赖,但系统调用就有依赖,而且新的系统调用的实现必须静态地连接到内核中,它无法在模块中实现,使用新系统调用的应用在编译时需要依赖内核。

4.netlink 支持多播,内核模块或应用可以把消息多播给一个netlink组,属于该neilink 组的任何内核模块或应用都能接收到该消息,内核事件向用户态的通知机制就使用了这一特性,任何对内核事件感兴趣的应用都能收到该子系统发送的内核事件,在后面的文章中将介绍这一机制的使用。

5.内核可以使用netlink 首先发起会话,但系统调用和ioctl 只能由用户应用发起调用。

6.netlink 使用标准的socket API,因此很容易使用,但系统调用和ioctl则需要专门的培训才能使用。

用户态使用netlink用户态应用使用标准的socket APIs,socket(), bind(), sendmsg(), recvmsg() 和close() 就能很容易地使用netlink socket,查询手册页可以了解这些函数的使用细节,本文只是讲解使用netlink 的用户应该如何使用这些函数。

注意,使用netlink 的应用必须包含头文件linux/netlink.h。

当然socket 需要的头文件也必不可少,sys/socket.h。

为了创建一个netlink socket,用户需要使用如下参数调用socket():socket(AF_NETLINK, SOCK_RAW, netlink_type)第一个参数必须是AF_NETLINK 或PF_NETLINK,在Linux 中,它们俩实际为一个东西,它表示要使用netlink,第二个参数必须是SOCK_RAW或SOCK_DGRAM,第三个参数指定netlink协议类型,如前面讲的用户自定义协议类型NETLINK_MYTEST,NETLINK_GENERIC是一个通用的协议类型,它是专门为用户使用的,因此,用户可以直接使用它,而不必再添加新的协议类型。

内核预定义的协议类型有:#define NETLINK_ROUTE 0 /* Routing/device hook */ #define NETLINK_W1 1 /* 1-wire subsystem */ #define NETLINK_USERSOCK 2 /* Reserved for user modesocket protocols */#define NETLINK_FIREWALL 3 /* Firewalling hook */#define NETLINK_INET_DIAG 4 /* INET socket monitoring */ #define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */#define NETLINK_XFRM 6 /* ipsec */#define NETLINK_SELINUX 7 /* SELinux event notifications */ #define NETLINK_ISCSI 8 /* Open-iSCSI */#define NETLINK_AUDIT 9 /* auditing */#define NETLINK_FIB_LOOKUP 10#define NETLINK_CONNECTOR 11#define NETLINK_NETFILTER 12 /* netfilter subsystem */#define NETLINK_IP6_FW 13#define NETLINK_DNRTMSG 14 /* DECnet routing messages */ #define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages touserspace */#define NETLINK_GENERIC 16对于每一个netlink协议类型,可以有多达32多播组,每一个多播组用一个位表示,netlink 的多播特性使得发送消息给同一个组仅需要一次系统调用,因而对于需要多拨消息的应用而言,大大地降低了系统调用的次数。

函数bind() 用于把一个打开的netlink socket 与netlink 源socket 地址绑定在一起。

netlink socket 的地址结构如下:struct sockaddr_nl{sa_family_t nl_family;unsigned short nl_pad;__u32 nl_pid;__u32 nl_groups;};字段nl_family 必须设置为AF_NETLINK 或着PF_NETLINK,字段nl_pad 当前没有使用,因此要总是设置为0,字段nl_pid 为接收或发送消息的进程的ID,如果希望内核处理消息或多播消息,就把该字段设置为0,否则设置为处理消息的进程ID。

字段nl_groups 用于指定多播组,bind 函数用于把调用进程加入到该字段指定的多播组,如果设置为0,表示调用者不加入任何多播组。

传递给bind 函数的地址的nl_pid 字段应当设置为本进程的进程ID,这相当于netlink socket 的本地地址。

但是,对于一个进程的多个线程使用netlink socket 的情况,字段nl_pid 则可以设置为其它的值,如:pthread_self() << 16 | getpid();因此字段nl_pid 实际上未必是进程ID,它只是用于区分不同的接收者或发送者的一个标识,用户可以根据自己需要设置该字段。

函数bind 的调用方式如下:bind(fd, (struct sockaddr*)&nladdr, sizeof(struct sockaddr_nl));fd为前面的socket 调用返回的文件描述符,参数nladdr 为struct sockaddr_nl 类型的地址。

为了发送一个netlink 消息给内核或其他用户态应用,需要填充目标netlink socket 地址,此时,字段nl_pid 和nl_groups 分别表示接收消息者的进程ID 与多播组。

如果字段nl_pid 设置为0,表示消息接收者为内核或多播组,如果nl_groups为0,表示该消息为单播消息,否则表示多播消息。

使用函数sendmsg 发送netlink 消息时还需要引用结构struct msghdr、struct nlmsghdr 和struct iovec,结构struct msghdr 需如下设置:struct msghdr msg;memset(&msg, 0, sizeof(msg));msg.msg_name = (void *)&(nladdr);msg.msg_namelen = sizeof(nladdr);其中nladdr 为消息接收者的netlink 地址。

struct nlmsghdr 为netlink socket 自己的消息头,这用于多路复用和多路分解netlink 定义的所有协议类型以及其它一些控制,netlink 的内核实现将利用这个消息头来多路复用和多路分解已经其它的一些控制,因此它也被称为netlink 控制块。

因此,应用在发送netlink 消息时必须提供该消息头。

struct nlmsghdr{__u32 nlmsg_len; /* Length of message */__u16 nlmsg_type; /* Message type*/__u16 nlmsg_flags; /* Additional flags */__u32 nlmsg_seq; /* Sequence number */__u32 nlmsg_pid; /* Sending process PID */};字段nlmsg_len 指定消息的总长度,包括紧跟该结构的数据部分长度以及该结构的大小,字段nlmsg_type 用于应用内部定义消息的类型,它对netlink 内核实现是透明的,因此大部分情况下设置为0,字段nlmsg_flags 用于设置消息标志,可用的标志包括:/* Flags values */#define NLM_F_REQUEST 1 /* It is request message. */ #define NLM_F_MULTI 2 /* Multipart message, terminatedby NLMSG_DONE */#define NLM_F_ACK 4 /* Reply with ack, with zero orerror code */#define NLM_F_ECHO 8 /* Echo this request *//* Modifiers to GET request */#define NLM_F_ROOT 0x100 /* specify tree root */#define NLM_F_MATCH 0x200 /* return all matching */#define NLM_F_ATOMIC 0x400 /* atomic GET */#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)/* Modifiers to NEW request */#define NLM_F_REPLACE 0x100 /* Override existing */#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */#define NLM_F_CREATE 0x400 /* Create, if it does not exist */#define NLM_F_APPEND 0x800 /* Add to end of list */标志NLM_F_REQUEST用于表示消息是一个请求,所有应用首先发起的消息都应设置该标志。

相关文档
最新文档