当前位置: 首页 > news >正文

驱动-热插拔-Netlink广播监听内核状态

Netlink广播监听内核状态

文章目录

  • 前言
  • 参考资料
  • 一、Netlink 知识点
    • 核心特点
    • 与其他机制的对比
    • 在 Linux 中的主要应用
      • 网络配置 (Routing, Addressing, Links)
      • 网络防火墙与过滤 (Netfilter/IPTables)
      • 策略路由和高级路由
      • 设备与内核事件通知
      • 进程管理与审计
      • 内核与用户空间自定义通信
      • 其他系统任务
    • Nitlink 知识点小结
  • 二、Nitlink 实现内核事件
    • 源码程序
    • 配置交叉编译器
    • 测试实验
    • 相关知识点小结
      • 函数 bzero
  • 总结


前言

前面了解过uevent 事件,内核发送事件到用户空间。 监听方式 使用 udevadm 命令 后台监听事件,查看打印内核信息。

那么 我们看看其它方式来监听 内核信息

参考资料

驱动-热插拔-内核发送事件到用户空间-uevent

驱动-热插拔-kset_uevent_ops知识点

netlink监听广播信息

热插拔

一、Netlink 知识点

     Netlink Linux 内核提供的一种用于内核与用户空间进程之间进行双向通信的 IPC(进程间通信)机制。它构建在标准的 Unix 套接字(socket)接口之上,专门设计用来传输各种类型的网络和系统信息。
    你可以把它想象成一条专门用于“系统管理”的高速数据总线,用户空间的程序(如网络配置工具、监控工具)可以通过这条总线向内核发送指令或请求,内核也可以通过它向用户空间主动发送事件通知(如设备热插拔、网络链路状态变化)。

它本质上面我理解就是一个: socket

核心特点

  • 全双工通信:通信是双向的,用户空间可以发消息给内核,内核也可以发消息给用户空间。
  • 异步机制:通信通常是异步的,发送方不需要等待接收方的即时响应。
  • 面向数据报:基于消息(message)而非字节流,每个消息都是一个自包含的数据包,简化了协议解析。
  • 协议族:Netlink 不是一个单一的协议,而是一个协议族。每个子系统(如路由、防火墙、设备通知)都有自己独特的 Netlink 协议号(NETLINK_ROUTE, NETLINK_NFLOG 等),这使得通信井井有条,互不干扰。
  • 支持多播:内核可以将一条消息多播给多个用户空间的监听者,这对于事件通知(如“有一个新USB设备插入”)非常高效。

与其他机制的对比

机制描述缺点(与 Netlink 相比)
IOCTL通过设备文件进行控制,是传统的控制方式。单向(只能用户空间发起),需要定义复杂的数据结构,扩展性差。
/proc 或 /sys通过读写虚拟文件来获取信息或设置参数。单向(通常为用户空间轮询),适用于输出信息,但不擅长复杂的控制和事件通知。
系统调用用户空间调用内核函数。需要预先定义,功能固定,不适合传输大量或动态变化的数据。

Netlink 克服了这些缺点,提供了更现代、灵活和强大的通信方式。

在 Linux 中的主要应用

网络配置 (Routing, Addressing, Links)

这是 Netlink 最经典的应用场景。用于配置网络接口、IP地址、路由表、邻居表(ARP/NDP)等。

工具:iproute2 工具集(如 ip addr, ip link, ip route, ip neigh)完全替代了古老的 ifconfig, route, arpnet-tools工具集,其背后就是通过 Netlink 套接字(NETLINK_ROUTE 协议)与内核通信。

示例:

当你执行ip addr add 192.168.1.10/24 dev eth0时,ip 命令会通过 Netlink 发送一个 RTM_NEWADDR 消息给内核,内核收到后为 eth0 接口添加这个 IP 地址。

当你执行 ip link set eth0 up 时,会发送 RTM_NEWLINK 消息来启动接口。

网络防火墙与过滤 (Netfilter/IPTables)

Netlink 用于与内核的 Netfilter 子系统交互,管理防火墙规则。

工具: iptables, nftables(下一代防火墙工具)。

**机制:**虽然传统的 iptables 使用模块和内核系统调用,但 nftables 及其用户空间工具 nft 严重依赖 Netlink(NETLINK_NETFILTER)来传递规则集和计数器信息,效率更高。

策略路由和高级路由

对于复杂的网络环境,如多路由表、基于策略的路由,配置完全依赖于 Netlink

设备与内核事件通知

内核可以通过 Netlink 多播组向用户空间主动发送事件消息。

协议: NETLINK_KOBJECT_UEVENT(最重要的应用之一)

工具: udev(设备管理器)

**机制:**当内核中发生设备事件(如U盘插入、硬盘热拔插)时,内核会向 NETLINK_KOBJECT_UEVENT 多播组发送一条消息(uevent)。udevd 守护进程一直在监听这个组,收到消息后,会根据 /lib/udev/rules.d/ 下的规则来创建设备节点、加载驱动、设置权限等。这是现代 Linux 桌面和服务器自动识别设备的基础。

进程管理与审计

协议: NETLINK_AUDIT, NETLINK_CONNECTOR(NETLINK_USERSOCK)

工具: auditd(审计守护进程)

机制: 内核的审计子系统可以通过 Netlink 将安全审计信息(如谁调用了某个系统调用、文件访问记录等)发送给用户空间的 auditd 进程进行记录和分析。

内核与用户空间自定义通信

开发者可以创建自己的 Netlink 协议号(NETLINK_USER 或更高)来编写内核模块和对应的用户空间程序,实现自定义的、高性能的内核-用户通信。这在某些特殊需求的驱动或内核模块开发中非常有用。

其他系统任务

IPC 命名空间 ipcrm, ipcs 等工具使用 Netlink 来管理 System V IPC 对象。

SELinuxSELinux 安全策略的某些通信也通过 Netlink 进行。

Nitlink 知识点小结

     Netlink 是现代 Linux 系统中内核与用户空间进行“管理信息”交换的基石级机制。 它使得功能强大的用户空间工具(如 iproute2, udev, nftables, auditd)能够高效、灵活地控制和监控内核的各个方面,特别是在网络栈和设备管理领域。可以说,没有 Netlink,就没有现代 Linux 灵活而强大的网络配置和设备管理功能。

二、Nitlink 实现内核事件

上面介绍了nitlink 知识点,其实就是如何监听 内核事件

源码程序

#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>int main(int argc, char *argv[])
{int ret;struct sockaddr_nl *nl; // 定义一个指向 struct sockaddr_nl 结构体的指针 nlint len = 0;char buf[4096] = {0}; // 数据接收缓冲区int i = 0;bzero(nl, sizeof(struct sockaddr_nl)); // 将 nl 指向的内存区域清零, 确保结构体的字段初始化为 0nl->nl_family = AF_NETLINK;            // 设置 nl 结构体的 nl_family 字段为 AF_NETLINK, 指定地址族为 Netlinknl->nl_pid = 0;                        // 设置 nl 结构体的 nl_pid 字段为 0, 表示目标进程 ID 为 0, 即广播给所有进程nl->nl_groups = 1;                     // 设置 nl 结构体的 nl_groups 字段为 1, 表示只接收基本组的内核事件int socket_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); // 创建一个 Netlink套接字if (socket_fd < 0){printf("socket error\n");return -1;}ret = bind(socket_fd, (struct sockaddr *)nl, sizeof(struct sockaddr_nl)); // 使用 bind 函数将 socket_fd 套接字与 nl 地址结构体绑定在一起if (ret < 0){printf("bind error\n");return -1;}while (1){bzero(buf, 4096);                     // 将缓冲区 buf 清零, 确保数据接收前的初始化len = recv(socket_fd, &buf, 4096, 0); // 从 socket_fd 套接字接收数据, 存储到缓冲区 buf 中,最大接收字节数为 4096for (i = 0; i < len; i++){if (*(buf + i) == '\0'){buf[i] = '\n'; // 如果接收到的数据中有 '\0' 字符, 将其替换为 '\n', 以便在打印时换行显示}}printf("%s\n", buf); // 打印接收到的数据}return 0;
}

配置交叉编译器

之前 HelloWorld驱动编写和加载驱动实验 篇有详细介绍,这里暂不再次说明:
在这里插入图片描述

测试实验

首先 交叉编译器 生成 可执行文件:

aarch64-linux-gnu-gcc   -o netlink netlink.c 

在这里插入图片描述
在这里插入图片描述

卸载驱动时候,也会有相关的 netlink 监听到的内核相关信息打印:
在这里插入图片描述

相关知识点小结

函数 bzero

功能: bzero(代表 “byte zero”)是一个传统的 C 库函数,用于将一段指定长度的内存块的所有字节设置为零(\0)。

参数:

  • 第一个参数 void *s: 指向要清零的内存块的起始地址的指针。
  • 第二个参数 size_t n: 要清零的字节数。

现状:

  • 这个函数起源于 BSD 系统,目前已经被标记为废弃。在现代编程中,更推荐使用标准 C 库中的 memset 函数来实现相同的功能。
  • 等价于: memset(nl, 0, sizeof(struct sockaddr_nl));

总结

Netlink 作用蛮多,这里举例用Netlink 来实现 内核监听的一个实例,实际开发当中使用很多,能够快速获取内核相关信息,调试、开发等。

http://www.dtcms.com/a/350593.html

相关文章:

  • HarmonyOS实战(DevEco AI篇)—CodeGenie + DeepSeek构建鸿蒙开发的超级外挂工作流
  • rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十九)子窗口
  • 您的连接不是私密连接问题解决
  • 借Copilot之力,实现办公效率的跃升
  • 数据库原理及应用_数据库基础_第2章关系数据库标准语言SQL_索引和视图
  • 软件使用教程(二):VS Code的Copilot、Git设置与使用
  • 复制和下载飞书文档的方法教程
  • Unity开发如何实现换装技术
  • Ubuntu 14.10 i386桌面版安装教程(U盘启动详细步骤-附安装包下载)​
  • LeetCode 100题(3)(10题)
  • 实用电脑小工具分享,守护电脑隐私与提升效率21/64
  • CANopen - DCF(Device Configuration File) 介绍
  • 平安产险青海分公司助力国家电投黄河公司安全生产
  • 2024鸿蒙样题需要掌握的知识点
  • Shopify 集合页实现自定义广告位插入(支持分页)
  • C++ 指针与引用面试深度解析
  • k8s数据存储
  • PMP项目管理知识点-④ 项⽬整合管理
  • 3-2.Python 函数 - None(None 概述、None 应用场景)
  • Flink的CheckPoint与SavePoint
  • 使用 Prometheus 监控服务器节点:Node Exporter 详解与配置
  • 【2025】政策变动
  • 从认识Docker到安装
  • 深分页实战
  • 服务注册信息丢失ERROR 2003 (HY000):Can‘t connect to MySQL server on ‘localhost’(10061)
  • 数据结构青铜到王者第三话---ArrayList与顺序表(1)
  • 【MTCNN网络结构记忆卡片】--003nets.py
  • STM32之DMA详解
  • 专题:2025人工智能2.0智能体驱动ERP、生成式AI经济现状落地报告|附400+份报告PDF、原数据表汇总下载
  • 基于知识图谱的装备健康智能维护系统KGPHMAgent