SylixOS -- 双网卡冗余备份设计方案
1.设计概述
1.1设计目标
目前SylixOS支持多网卡,每块网卡都有独立的物理地址和IP地址,以独立的形式让应用程序使用。但根据客户对网络通信可靠性方面的要求,需要在SylixOS下实现双网卡绑定同一IP地址,应用程序对该IP地址进行数据收发操作,拔掉任意一路网线,能切换到另一网卡,保证只要有一路网线连通,应用程序数据收发都没有问题。
设计目标如下:
- 两个网卡共用一个IP地址和物理地址;
- 网卡出现故障时能切换至另一网卡;
1.2设计前提
双网卡冗余备份方案是将多块物理网卡进行绑定,需要设备包含至少两个网卡并且能进行正常通信。
2.方案简介
2.1设计原理
双网卡冗余备份方案采用"主-备份"网卡策略,即同一时刻只有一块网卡进行工作,另一块作为备份网卡暂时不工作,当一块网卡或线路出现故障时能自动切换到备份网卡,保障网络能持续通信。
双网卡冗余备份对于应用程序仍呈现单网卡的特征,两个网卡只有一个物理地址和IP地址,应用程序不需要关心是哪块网卡在工作,也不需要关心网卡之间如何切换。
2.2正常双网卡通信
网卡驱动程序中通过操作物理寄存器、DMA描述符和DMA缓冲区控制物理网卡进行数据发送和接收。在SylixOS中,这些数据成员被保存在网卡驱动的私有结构体中,通过netdev结构体中的priv指针指向这些数据。
因此,真正控制物理网卡进行工作的是网络接口结构中的私有成员和网卡驱动程序中的接收和发送函数。如图 2.1所示,en1、en2网络接口操作各自的私有结构控制物理网卡收发。
图 2.1正常双网卡通信
正常双网卡通信整体框图如图 2.2所示。
图 2.2正常双网卡通信
2.3双网卡冗余备份通信
双网卡冗余备份方案设计思路为:创建一个虚拟网络接口,通过虚拟网络接口中对私有成员和网络驱动函数的替换,实现控制不同的物理网卡进行数据发送和接收,如图 2.3所示。
图 2.3双网卡冗余备份后
双网卡冗余备份功能实现后,网络通信框图改变为如图 2.4所示。
图 2.4双网卡冗余备份通信
2.4模块加载
双网卡冗余备份方案通过模块方式加载,在加载前后均不影响系统的正常运行。
模块加载后会占用一部分系统资源(全局结构体,信号量等),并添加shell命令用于开启/关闭功能;模块卸载前会检测功能是否已经被关闭,保证不会在运行时释放资源导致系统错误。
执行开启功能shell命令后,调用函数进行双网卡绑定;执行关闭功能shell命令后,解除双网卡绑定,恢复初始状态。
2.5模块划分
双网卡冗余备份功能拆解如表 2.1所示。
表 2.1双网卡冗余备份模块划分
模块 |
功能 |
配置模块 |
配置网卡IP地址 |
配置网卡子网掩码 | |
配置网卡默认网关 | |
配置网卡的MAC地址 | |
配置被绑定的网卡名称 | |
配置被绑定的网卡中断号 | |
配置工作模式 | |
配置线程检测时间间隔 | |
配置PHY中断引脚输出 | |
配置高/低,上升/下降延触发 | |
初始化模块 |
读取和备份配置文件 |
获取系统网络接口 | |
虚拟网络接口创建和绑定 | |
创建检测线程 | |
(中断机制)使能gpio中断 | |
数据通信模块 |
网络数据包发送 |
网络数据包接收 | |
线程检测模块 |
(中断机制)等待中断触发 |
(轮询机制)等待miimon毫秒 | |
物理网卡链路状态检测 | |
物理网卡切换 | |
外部命令模块 |
开启双网卡冗余备份功能 |
关闭双网卡冗余备份功能 |
3.具体设计方案
3.1双网卡冗余备份功能初始化
双网卡冗余备份功能初始化函数仅将两个物理网卡进行绑定,不会对物理网卡重新进行初始化。
初始化函数主要做以下工作:
- 读取配置文件。包含需要绑定的网络接口名、网卡中断号、工作模式等,读取的数据保存在配置文件结构体中。
- 获取系统网络接口。通过SylixOS提供的API接口获得指定网络接口结构,将获得的网络接口结构进行备份。
- 网络接口绑定。创建虚拟网络接口,将网卡接收中断服务函数参数替换为新的虚拟网络接口结构,再将私有结构指针指向不同的私有结构成员,实现控制不同的物理网卡进行数据发送和接收。替换过程中需要关闭中断。
- 创建检测线程。中断机制下等待中断触发、轮询机制下等待miimon秒,检测物理网卡网络连通状态,并判断是否进行物理网卡切换。
- 创建GPIO中断。通过调用ioctl函数设置 PHY 中断控制寄存器,使能链接状态改变中断,并将硬件 PHY上的中断引脚设置为输出。创建GPIO中断,触发条件为PHY连接状态改变。
绑定初始化函数流程图如图 3.1所示。
图 3.1功能初始化
3.1.1网络接口绑定
网络接口绑定主要做以下工作:
- 关闭网卡收发中断,禁用指定网络接口。保证在网卡绑定过程中指定的网络接口没有进行数据收发。
- 创建虚拟网络接口。根据配置文件内容新建虚拟网络接口。
- 网络接口结构替换。将网卡接收中断服务函数参数替换为新的虚拟网络接口结构。
- 私有结构成员赋值。(私有成员包括网络收发缓冲描述符指针和DMA缓冲区地址)将虚拟网络接口结构体私有成员指针指向指定网络接口结构中的私有成员,则会使用该网络接口结构对应的物理网卡进行通信。
绑定流程如图 3.2所示。
图 3.2网络接口绑定
3.2数据包发送
上层协议需要发送数据时,调用虚拟网卡的发送函数。在虚拟网卡的发送函数中,选择当前处于活跃的物理网卡,并调用物理网卡的发送函数,实现数据包的发送。
发送流程如图 3.3所示。
图 3.3数据包发送
3.3数据包接收
当物理网卡接收到数据时,产生接收中断,在接收中断中处理并进入虚拟网卡的接收函数。在虚拟网卡的接收函数中,调用物理网卡的接收函数,将数据上传至上层协议。
接收流程如图 3.4所示。
图 3.4数据包接收
3.4循环检测线程
检测线程主要做以下工作:
- 等待触发条件。中断机制下等待中断触发,轮询机制下等待miimon毫秒。
- 检测各个物理网卡的链路连接状态。通过ioctl函数,调用底层网卡驱动,读取PHY设备状态。
- 根据标志位判断是否需要进行物理网卡切换。将私有成员指针指向另一网卡的私有结构。
线程检测流程如图 3.5所示。
图 3.5循环检测线程
3.5问题分析
可能遇到的问题 |
是否有解决方法 |
读取时配置文件不存在/内容格式错误 |
配置文件打开/读取时判断是否成功,失败直接返回 |
多次执行绑定/解绑命令 |
设置标志位,标志位有效时才能执行绑定/解绑命令 |
如何设置物理网卡的MAC地址 |
没有ioctl暂时不能做通用设置物理地址,可以对应某一块板子,调用驱动中的设置物理地址函数,或者采用网卡混杂模式 |
绑定过程中是否加锁 |
添加自旋锁,防止绑定过程中再次被执行命令 |
传输过程中网卡断开连接 |
一段时间内网络不通,线程检测并进行网卡切换后通信恢复正常。如果是UDP传输可能造成丢包 |
对传输过程中网卡断开连接导致的数据丢失是否有保护机制 |
物理网卡只进行数据的收发,是否传输失败/是否重传由协议栈进行判断。 |
用户主动杀死线程 |
线程被杀死后,无法进行网卡切换。(可以换成延时工作队列方式检测网络状态) |
物理网卡是否需要重新初始化 |
功能仅对物理网卡进行绑定,并不对物理网卡重新进行初始化 |