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

网卡状态变更,virtio-net检测

实现方案:
现在在amp模式下linux端有个真实的物理网卡eth0,有一个虚拟网卡virtio-net0后端,此时需要一种机制,将真实物理网卡的状态发送rtos的virtio-net0前端。这里使用register_netdevice_notifier机制,每个virtio-net设备都有自己的notifier,支持多个virtio-net设备实例。

这个实现的特点:

  1. 每个virtio-net设备独立管理自己的notifier,支持多实例
  2. 正确处理网卡引用计数(dev_get_by_name/dev_put)
  3. 可以通过carrier_notify_enabled动态控制状态同步
  4. 在probe时同步初始状态
  5. 在remove时正确清理资源

注意:

  1. 使用字符串保存物理网卡名称,而不是直接保存指针,否则可能会出现物理网卡还未初始化的情况。
  2. 不管物理网卡是否就绪都会注册notifier
  3. 在notifier回调中,当检测到目标网卡时才获取其设备指针
  4. 避免了在probe时因找不到网卡而无法注册notifier的问题

这里详细讲讲register_netdevice_notifier通知链。register_netdevice_notifier 是 Linux 网络子系统中的一个通知链(Notification Chain)机制,它允许内核模块注册一个回调函数来监听网络设备状态的变化。主要用途如下:

  1. 通知链的基本概念:
struct notifier_block {int (*notifier_call)(struct notifier_block *, unsigned long, void *);struct notifier_block *next;int priority;
};
  1. 主要事件类型:
// 一些重要的网络设备事件
#define NETDEV_UP        0x0001  // 网卡启用
#define NETDEV_DOWN      0x0002  // 网卡禁用  
#define NETDEV_REBOOT    0x0003  // 网卡重启
#define NETDEV_CHANGE    0x0004  // 网卡状态改变
#define NETDEV_REGISTER  0x0005  // 网卡注册
#define NETDEV_UNREGISTER 0x0006 // 网卡注销
#define NETDEV_CHANGEMTU 0x0007  // MTU改变
#define NETDEV_CHANGEADDR 0x0008 // MAC地址改变
  1. 注册流程:
// 1. 定义通知块
struct notifier_block netdev_notifier = {.notifier_call = virtnet_netdev_event,  // 回调函数
};// 2. 注册通知
register_netdevice_notifier(&netdev_notifier);// 3. 实现回调函数
static int virtnet_netdev_event(struct notifier_block *this,unsigned long event, void *ptr)
{struct net_device *dev = netdev_notifier_info_to_dev(ptr);switch(event) {case NETDEV_UP:// 处理网卡启用事件break;case NETDEV_DOWN:// 处理网卡禁用事件break;// ...}return NOTIFY_DONE;
}
  1. 工作原理:
  • 当网络设备状态发生变化时,内核会遍历所有注册的通知块
  • 按照优先级顺序调用每个通知块的 notifier_call 回调函数
  • 回调函数可以返回:
    • NOTIFY_OK: 事件处理成功
    • NOTIFY_DONE: 事件与该模块无关
    • NOTIFY_BAD: 事件处理失败
  1. 在你的代码中的应用:
// 注册通知监听物理网卡状态
vi->netdev_notifier.notifier_call = virtnet_netdev_event;
vi->carrier_notify_enabled = true;err = register_netdevice_notifier(&vi->netdev_notifier);
if (err) {dev_err(&vdev->dev, "Failed to register netdev notifier\n");return err;
}

当物理网卡状态发生变化时:

  • UP事件: 更新虚拟网卡状态为启用,并通知前端
  • DOWN事件: 更新虚拟网卡状态为禁用,并通知前端
  • CHANGE事件: 根据物理网卡carrier状态更新虚拟网卡
  1. 注销流程:
// 在驱动卸载时需要注销通知
unregister_netdevice_notifier(&vi->netdev_notifier);

这种通知机制的优点:

  1. 解耦合 - 模块间通过事件通知而不是直接调用
  2. 灵活性 - 可以动态注册/注销监听器
  3. 实时性 - 能及时获得网络设备状态变化
  4. 可扩展 - 支持多个模块同时监听同一事件

在你的虚拟网卡驱动中,这个机制用于同步物理网卡和虚拟网卡的状态,确保虚拟网卡能正确反映物理网卡的工作状态。

结构体:

struct virtnet_info {...char eth_name[IFNAMSIZ];        // 保存物理网卡名称struct net_device *eth_dev;      // 物理网卡指针(动态获取)struct notifier_block netdev_notifier;bool carrier_notify_enabled;}

初始化:

static int virtnet_probe(struct virtio_device *vdev)
{/* 在netdev注册后初始化carrier notify */printk("------------>carrier notify init\r\n");// 设置要监控的物理网卡名称,最好是设备树中定义的网卡名称,先写定strncpy(vi->eth_name, "eth0", IFNAMSIZ-1);vi->eth_name[IFNAMSIZ-1] = '\0';vi->eth_dev = NULL;  // 初始时设为NULL// 初始化并注册notifiervi->netdev_notifier.notifier_call = virtnet_netdev_event;// 设置notifier为启用状态,最好是设备树中定义的状态是否启用vi->carrier_notify_enabled = true;err = register_netdevice_notifier(&vi->netdev_notifier);if (err) {dev_err(&vdev->dev, "Failed to register netdev notifier\n");goto free_unregister_netdev;}

通知链中的触发处理函数:

static int virtnet_netdev_event(struct notifier_block *this,unsigned long event, void *ptr)
{struct net_device *dev = netdev_notifier_info_to_dev(ptr);struct virtnet_info *vi = container_of(this, struct virtnet_info, netdev_notifier);struct virtio_net_config *config;int cpu = 2;u16 status;// 检查参数有效性if (!dev || !vi || !vi->dev)return NOTIFY_DONE;// 只关心指定物理网卡的事件if (strcmp(dev->name, vi->eth_name) != 0)return NOTIFY_DONE;// 如果找到匹配的网卡,保存其指针if (!vi->eth_dev) {vi->eth_dev = dev;dev_hold(dev);  // 增加引用计数printk("------------>Found target network device: %s\n", dev->name);}if (!vi->carrier_notify_enabled)return NOTIFY_DONE;// 获取共享内存中的配置区域指针config = (struct virtio_net_config *)vi->vdev->config_ptr;switch (event) {case NETDEV_UP:// 物理网卡up时,更新carrier状态和共享内存状态netif_carrier_on(vi->dev);status = VIRTIO_NET_S_LINK_UP | VIRTIO_NET_S_ANNOUNCE;config->status = cpu_to_virtio16(vi->vdev, status);virtio_irq_trigger(virtio_irq_controller_get_default(), vi->vdev->irq, cpu);break;case NETDEV_DOWN:// 物理网卡down时,更新carrier状态和共享内存状态netif_carrier_off(vi->dev);status = VIRTIO_NET_S_ANNOUNCE;  // 只设置ANNOUNCE标志config->status = cpu_to_virtio16(vi->vdev, status);virtio_irq_trigger(virtio_irq_controller_get_default(), vi->vdev->irq, cpu);break;case NETDEV_CHANGE:......break;default:return NOTIFY_DONE;}return NOTIFY_OK;
}

相关文章:

网卡状态变更,virtio-net检测

实现方案: 现在在amp模式下linux端有个真实的物理网卡eth0,有一个虚拟网卡virtio-net0后端,此时需要一种机制,将真实物理网卡的状态发送rtos的virtio-net0前端。这里使用register_netdevice_notifier机制,每个virtio-n…...

中华人民共和国保守国家秘密法

中华人民共和国保守国家秘密法 (1988年9月5日第七届全国人民代表大会常务委员会第三次会议通过 2010年4月29日第十一届全国人民代表大会常务委员会第十四次会议第一次修订 2024年2月27日第十四届全国人民代表大会常务委员会第八次会议第二次修订) 目…...

ELK日志收集系统部署

1、 ElasticSearch部署 Elastic — 搜索 AI 公司 | Elastic 系统类型:Centos7.4 节点IP:172.16.246.234 软件版本:jdk-8u191-linux-x64.tar.gz、elasticsearch-6.5.4.tar.gz 示例节点:172.16.246.234 1、安装配置jdk8 ES运行依…...

3D线上艺术展:艺术与技术的完美融合

随着数字技术的飞速发展,未来的艺术展览正逐步迈向线上线下融合的新阶段。其中,3D线上展览以其独特的魅力,成为线下展览的延伸与拓展,为艺术爱好者们开辟了全新的观赏途径。 对于艺术家和策展人而言,3D线上展览不仅打…...

TiDB 的MPP架构概述

MPP架构介绍: 如图,TiDB Server 作为协调者,首先 TiDB Server 会把每个TiFlash 拥有的region 会在TiFlash上做交换,让表连接在一个TiFlash上。另外 TiFlash会作为计算节点,每个TiFlash都负责数据交换,表连接…...

Leetcode 10-正则表达式匹配/ 剑指 Offer 19. 正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 ‘*’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。 题解 字符串匹配多…...

FFmpeg 编码和解码

文章目录 音频格式AACADIF音频数据交换格式ADTS音频数据传输流 音频解码音频编码 视频格式H264GOP图像组I帧,P帧,B帧H264压缩技术H264压缩级别H264视频级别H264码流结构SPSPPS 解码视频编码视频 音频格式 AAC AAC全称 Advanced Audio Coding&#xff0…...

kali当中web扫描工具的用法

1. cadaver 用途&#xff1a;用于与WebDAV服务器交互&#xff0c;可进行文件上传、下载、目录浏览等操作。使用方法 连接到WebDAV服务器&#xff1a;cadaver <WebDAV服务器地址>&#xff0c;例如cadaver https://example.com/dav&#xff0c;然后按提示输入用户名和密码…...

深度剖析 Android Animation 框架

深度剖析 Android Animation 框架 目录 引言Android Animation 框架概述架构设计 3.1 核心类与接口3.2 动画类型3.3 动画执行流程使用指南 4.1 属性动画4.2 视图动画4.3 过渡动画设计模式 5.1 策略模式5.2 观察者模式5.3 工厂模式核心逻辑 6.1 动画插值器6.2 动画估值器6.3 动…...

泰山派GPIO子系统驱动---亮灯

本人linux驱动小白&#xff0c;文章基于B站up主 李Sir______ 视频内容记录&#xff0c;做笔记用。如有错误欢迎指正。本文将以开发板第40引脚GPIO3_B4作为LED灯珠的控制引脚&#xff0c;高电平灯亮&#xff0c;低电平灯灭。 杂话 在linux内核中&#xff0c;芯片厂商已经把所有…...

【C#特性整理】C#特性及语法基础

1. C#特性 1.1 统一的类型系统 C#中, 所有类型都共享一个公共的基类型. 例如&#xff0c;任何类型的实例都可以通过调用ToString方法将自身转换为一个字符串 1.2 类和接口 接口: 用于将标准与实现隔离, 仅仅定义行为,不做实现. 1.3 属性、方法、事件 属性: 封装了一部分对…...

Presence:Colyseus用于管理实时分布式数据的工具

Colyseus Presence 详细介绍 Presence 是 Colyseus 中用于管理实时分布式数据的一种工具。它主要用于在多房间、多服务器或分布式部署中实现玩家的实时在线状态、数据共享和通信。Presence 提供了一套简单的 API 来处理诸如在线玩家跟踪、分布式数据存储和发布/订阅模式等功能…...

Ubuntu 搭建SVN服务

目录 ​ 1、安装SVN服务端 2、创建SVN版本库 3、修改SVN配置svnserve.conf 3.1 配置文件介绍 3.2 svnserve.conf配置 3.3 authz配置设置用户读写权限 3.4 passwd配置 用户名密码 4、启动SVN服务 4.1 配置开机启动 1、安装SVN服务端 sudo apt-get install subversion…...

HTML速查

HTML 基本文档 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>文档标题</title></head><body>可见文本...</body> </html>基本标签&#xff08;Basic Tags&#xff09; <h1>最大的…...

day-102 二进制矩阵中的最短路径

思路 BFS 解题过程 从起点依次向八个方向尝试&#xff08;之后也一样&#xff09;&#xff0c;如果某个位置在矩阵内且值为0且没有访问过&#xff0c;将其添加到一个队列中&#xff0c;依次类推&#xff0c;直到到达出口 Code class Solution {public int shortestPathBinar…...

SQL Server大批量数据插入

数据库连接及相关操作 public class DataBase {/*** 驱动*/private static final String DRIVER PropertiesUtil.getString("spring.datasource.driver-class-name");/*** 数据库地址*/private static final String URL PropertiesUtil.getString("spring.da…...

在 Ubuntu 下通过 Docker 部署 Caddy 服务器

嘿&#xff0c;伙伴们&#xff01;今天我们来聊聊如何在 Ubuntu 系统下通过 Docker 部署 Caddy 服务器。Caddy 是一个现代的 Web 服务器&#xff0c;支持自动 HTTPS&#xff0c;简单易用&#xff0c;特别适合快速搭建网站。而 Docker 则是一个让你可以隔离和管理应用的神器。结…...

ZooKeeper注册中心实现

具体步骤 安装ZooKeeper&#xff08;启动端口占用&#xff0c;2181&#xff1a;客户端&#xff0c;8080&#xff1a;管理端&#xff09;引入客户端依赖实现注册中心接口SPI补充ZooKeeper注册中心 引入依赖 <!-- zookeeper --> <dependency><groupId>org.a…...

数仓建模:如何进行实体建模?

目录 1 如何进行实体建模? 业务建模 领域建模 逻辑建模 2 实体建模具体步骤 需求分析...

Python编程技术

设计目的 该项目框架Scrapy可以让我们平时所学的技术整合旨在帮助学习者提高Python编程技能并熟悉基本概念&#xff1a; 1. 学习基本概念&#xff1a;介绍Python的基本概念&#xff0c;如变量、数据类型、条件语句、循环等。 2. 掌握基本编程技巧&#xff1a;教授学生如何使…...

「Mac玩转仓颉内测版55」应用篇2 - 使用函数实现更复杂的计算

本篇教程基于仓颉编程语言扩展了计算器功能&#xff0c;支持加减乘除的基础运算&#xff0c;以及幂运算和开平方等高级功能。代码经过简化后&#xff0c;移除了对输入的复杂校验&#xff0c;提升了程序的可维护性和交互效率。 关键词 仓颉编程语言函数封装高级运算 一、功能说…...

map参数详解

const items new Array(15).fill(null).map((_, index) > ({key: index 1,label: nav ${index 1}, })); $.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性)&#xff0c;并将处理结果封装为新的数组返回。 注意&#xff1a;1. 在jQuery 1.6 之前&#…...

OSI 七层模型 | TCP/IP 四层模型

注&#xff1a;本文为 “OSI 七层模型 | TCP/IP 四层模型” 相关文章合辑。 未整理去重。 OSI 参考模型&#xff08;七层模型&#xff09; BeretSEC 于 2020-04-02 15:54:37 发布 OSI 的概念 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xf…...

高转速风扇|无刷暴力风扇方案设计

在当今科技高速发展的时代&#xff0c;电子设备的性能不断提升&#xff0c;散热问题也日益成为关注的焦点。而 13w 高转速暴力风扇方案的出现&#xff0c;为解决各种设备的散热难题提供了强大的技术支持。 一、高转速暴力风扇的重要性 随着电子设备的不断升级&#xff0c;其功率…...

GPU 进阶笔记(三):华为 NPU/GPU 演进

大家读完觉得有意义记得关注和点赞&#xff01;&#xff01;&#xff01; 1 术语 1.1 CPU1.2 GPU1.3 NPU / TPU1.4 小结2 华为 DaVinci 架构&#xff1a;一种方案覆盖所有算力场景 2.1 场景、算力需求和解决方案2.2 Ascend NPU 设计3 路线一&#xff1a;NPU 用在手机芯片&…...

计算机网络 (13)信道复用技术

前言 计算机网络中的信道复用技术是一种提高网络资源利用率的关键技术。它允许在一条物理信道上同时传输多个用户的信号&#xff0c;从而提高了信道的传输效率和带宽利用率。 一、信道复用技术的定义 信道复用&#xff08;Multiplexing&#xff09;就是在一条传输媒体上同时传输…...

数据库约束和查询

一 约束意义 这个后面的字段是什么意思呢? 先前说数据类型是一种约束&#xff0c;约束我们只能放该类型的数据&#xff0c;还有其它的约束来保证数据的合法性&#xff0c;下面的字段就和约束有关。 编译器的编译就是一个约束&#xff0c;保证我们的代码一定是语法合格的。我们…...

网工日记:FTP两种工作模式的区别

FTP 的主动模式和被动模式在连接建立的发起方、数据传输端口以及对网络环境的适应性等方面存在明显区别&#xff1a; 1. 连接发起方 主动模式&#xff1a;数据连接由服务器主动发起。在控制连接建立后&#xff0c;客户端通过 PORT 命令告知服务器自己用于接收数据的临时端口号…...

NLP模型工程化部署

文章目录 一、理论-微服务、测试与GPU1&#xff09;微服务架构2&#xff09;代码测试3&#xff09;GPU使用 二、实践-封装微服务&#xff0c;编写测试用例和脚本&#xff0c;并观察GPU1&#xff09;微服务封装(RestFul和RPC)2&#xff09;测试编写(unit_test\api_test\load_tes…...

分布式版本管理工具——git 中忽略文件的版本跟踪(初级方法及高级方法)

git工具忽略指定文件的版本跟踪 一、简单方式实现二、复杂方式实现&#xff08;模式匹配&#xff09;1. 相关规则2. 应用案例a) 忽略所有内容b) 忽略所有目录&#xff08;不忽略当前目录的具体文件&#xff09;c)忽略指定目录下的所有文件&#xff0c;但排除某文件d&#xff09…...