netlink

news/2025/2/5 13:49:28/

      Netlink套接字是用以实现内核进程和用户进程通信的一种特殊的进程间通信(IPC),从linux 2.2开始引入内核,当时名为AF_NETLINK,旨在提供一种更灵活的内核和用户空间的通信方法,用以替换笨拙的IOCTL.

      IOCTL 方式通信,需要定义IOCTL号,而且只能从用户空间到内核空间空间单向通信,相比之下netlink具有一下有点。

  1.  netlink使用简单,只需要在include/linux/netlink.h中增加一个新类型的 netlink 协议定义即可,(如 #define NETLINK_TEST 20 然后,内核和用户态应用就可以立即通过 socket API 使用该 netlink 协议类型进行数据交换);
  2. netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息;
  3.  使用 netlink 的内核部分可以采用模块的方式实现,使用 netlink 的应用部分和内核部分没有编译时依赖;
  4.  netlink 支持多播,内核模块或应用可以把消息多播给一个netlink组,属于该neilink 组的任何内核模块或应用都能接收到该消息,内核事件向用户态的通知机制就使用了这一特性;
  5.  内核可以使用 netlink 首先发起会 

     netlink可以用于用户进程通信,不过一般推荐使用,如果进程之间使用socket通信,一般是 Unix域socket

1 netlink 内核

Netlink协议是一种在RFC3549 (Linux Netlinkasan IP Services Protocol)中定义的进程间通信(Inter Process Communication,IPC)机制,为用户空间和内核以及内核的有些部分之间提供了双向通信信道,是对标准套接字实现的扩展。

netlink 主要实现位于内核 net/netlink/下,主要包含和几个头文件

├── af_netlink.c
├── af_netlink.h
├── diag.c
├── genetlink.c
├── Kconfig
├── policy.c

af_netlink 是比较常用模块,提供创建使用等常用接口

diag 监视模块,用于读写netlink有关信息

genetlink 新的通用api,由于netlink协议最多支持32个协议簇,目前Linux5.10的内核中已经使用其中23个,对于用户需要定制特殊的协议类型略显不够,而且用户还需自行在include/linux/netlink.h中添加簇定义,但有时不方便,为此Linux设计了这种通用Netlink协议簇,用户可在此之上定义更多类型的子协议。Generic Netlink使用NETLINK_GENERIC类型协议簇,同样基于netlink子系统,如下为内核中已经定义的协议

#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_SMC		22	/* SMC monitoring */#define NETLINK_INET_DIAG	NETLINK_SOCK_DIAG#define MAX_LINKS 32	

policy 用于向用户空间发布策略

1.1 创建流程

netlink模块的初始化是在系统启动阶段进行的,它位于af_netlink.c 的netlink_proto_init函数,

static int __init netlink_proto_init(void)
{int i;//向内核注册netlink协议int err = proto_register(&netlink_proto, 0);if (err != 0)goto out;#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)err = bpf_iter_register();if (err)goto out;
#endifBUILD_BUG_ON(sizeof(struct netlink_skb_parms) > sizeof_field(struct sk_buff, cb));//申请netlink table MAX_LINKS如上所示为32nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);if (!nl_table)goto panic;//初始化netlink tablefor (i = 0; i < MAX_LINKS; i++) {if (rhashtable_init(&nl_table[i].hash,&netlink_rhashtable_params) < 0) {while (--i > 0)rhashtable_destroy(&nl_table[i].hash);kfree(nl_table);goto panic;}}//初始化NETLINK_USERSOCK类型的套接字netlink_add_usersock_entry();//向系统注册AF_NETLINK协议族sock_register(&netlink_family_ops);//协议命名空间相关初始化,其中会创建/proc/net/netlink文件register_pernet_subsys(&netlink_net_ops);register_pernet_subsys(&netlink_tap_net_ops);/* The netlink device handler may be needed early. */rtnetlink_init();
out:return err;
panic:panic("netlink_init: Cannot allocate nl_table\n");
}

比较关键是nl_table表数组,这个表是整个netlink实现的最关键的一步,每种协议类型占数组中的一项,后续内核中创建的不同种协议类型的netlink都将保存在这个表中,由该表统一维护,如下为其定义和结构

struct netlink_table {struct rhashtable	hash;// 哈希表,以pid为key,保存了该协议所有的已绑定传输控制块对象struct hlist_head	mc_list;// 组织所有监听该协议的多播数据的传输控制块对象struct listeners __rcu	*listeners;// 标记该协议哪些多播组被监听,被监听多播组对应bit为1unsigned int		flags;unsigned int		groups;//协议支持的最大多播组数量struct mutex		*cb_mutex;struct module		*module;int			(*bind)(struct net *net, int group);void			(*unbind)(struct net *net, int group);bool			(*compare)(struct net *net, struct sock *sock);int			registered;// 标识该协议对象是否已经完成注册
};extern struct netlink_table *nl_table;
extern rwlock_t nl_table_lock; //访问保护锁

rtnetlink_init()创建NETLINK_ROUTE协议类型的netlink,该种类型的netlink才是当初内核设计netlink的初衷,它用来传递网络路由子系统、邻居子系统、接口设置、防火墙等消息。

创建netlink套接字


http://www.ppmy.cn/news/47402.html

相关文章

dockerFile记录

后端打包dockerFile内容 FROM openjdk:8-alpine RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo Asia/Shanghai > /etc/timezone ENV projectName operation RUN mkdir -p /home/${projectName} WORKDIR /home/${projectName} COPY ./ /home/${pro…

「OceanBase 4.1 体验」|国产分布式数据库不好用?别再打脸了

文章目录 分布式数据库分布式数据库有哪些&#xff1f;OceanBase4.1安装部署Index Skip Scan总结 随着互联网的高速发展和数据量的爆炸式增长&#xff0c;如何能够高效、可靠、安全地存储海量数据成为了每个企业的重要课题。 分布式数据库 分布式数据库通常是由多个独立的数据…

从底层理解类

函数调用约定_thiscall thiscall是对象调用类成员函数时的约定 class Role { public:int hp;int mp;int add(int a, int b){return hp mp a b;} }; int main() {Role r;r.add(100, 200); } 查看汇编代码 15: Role r;16: r.add(100, 200); 00F91B08 push 0C…

[网络安全]第三次作业

目录 1. 什么是IDS&#xff1f; 2. IDS和防火墙有什么不同&#xff1f; 3. IDS工作原理&#xff1f; 4. IDS的主要检测方法有哪些详细说明&#xff1f; 5. IDS的部署方式有哪些&#xff1f; 6. IDS的签名是什么意思&#xff1f;签名过滤器有什么作用&#xff1f;例外签名…

记录解决Maven依赖冲突导致的NoSuchMethodError问题的过程

摘要 本文记录了解决 Maven 依赖冲突导致的 NoSuchMethodError 问题的过程。问题出现的原因是多个库包含了 Jackson 库&#xff0c;导致 Jackson 序列化与反序列化时出现 NoSuchMethodError 异常。通过查看依赖树&#xff0c;排除冲突库的方法&#xff0c;最终成功解决了该问题…

查询练习:YEAR 与 NOW 函数

查询 student 表中每个学生的姓名和年龄。 -- 使用函数 YEAR(NOW()) 计算出当前年份&#xff0c;减去出生年份后得出年龄。 SELECT name, YEAR(NOW()) - YEAR(birthday) as age FROM student; ----------------- | name | age | ----------------- | 曾华 | 42 |…

垃圾收集器面试总结(一)

垃圾收集器 Serial 收集器&#xff08;GC日志标识&#xff1a;DefNew&#xff09; Serial&#xff08;串行&#xff09;收集器是最基本、历史最悠久的垃圾收集器了。大家看名字就知道这个收集器是一个单线程收集器了。 它的 “单线程” 的意义不仅仅意味着它只会使用一条垃圾…

Python OpenCV3 计算机视觉秘籍:6~9

原文&#xff1a;OpenCV 3 Computer Vision with Python Cookbook 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 计算机视觉 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 当别人说你没有底线的时候&…