ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

双网口模块两种模式详解:独立端口与交换机切换实现

双网口模块两种模式详解:独立端口与交换机切换实现 最近连续做了几个多网口设备的预研项目手头这款双网口模块的规格书第一页就写着Dual Ethernet Module Operates as Independent Ports or Switch。这句话翻译过来很好理解——两个物理网口既能各自当作独立网卡使用也能通过芯片内部的交换逻辑变成一个二口交换机。做网关、边缘计算盒子、工业路由器的朋友看到这类模块大概率都会眼前一亮同一个硬件能覆盖三种产品形态独立端口模式下做双线上网、WAN/LAN 隔离交换机模式下做串联接入或者直接塞在设备中间当一个无感的分线器。这篇文章就把这两种模式从硬件到软件、从原理到调试完整拆一遍重点说清楚为什么“一个模块两种性格”这件事可行以及落地时最容易在哪几个环节翻车。1. 双网口模块到底在解决什么场景问题1.1 从“一根网线只能接一个设备”说起单网口设备有一个天然痛点数据通路只有一条无论它是上行还是下行设备在链路里都只能扮演一个端点。工业现场最常见的接法是“PLC 之间手拉手串联”控制器的以太网口只有两个的非常少绝大多数 PLC 只有一个 RJ45想做菊花链就必须外接一个工业交换机多一个设备就多一个故障点、多一路电源、多一堆现场接线端子。我在现场见过很多配电柜里面的工业交换机比控制器本身还占空间。双网口模块解决的就是这类“设备串接”问题。两个口一个接上行、一个接下行的设备如果模块内部能以交换机模式工作数据就在芯片内部直接完成二层转发不占主控 CPU 的资源。这个场景下模块对两端设备来说就是一根“会发热的网线”不需要任何配置插上就能通。还有一种更常见的需求是网关类产品。设备需要一个 WAN 口接宽带、一个 LAN 口接内网设备两个口必须各自独立IP 段不同、路由策略不同、防火墙策略也不同。这种就是典型的独立端口模式两个口在操作系统里呈现为 eth0 和 eth1 两张网卡各自拥有 MAC 地址和 IP 地址。1.2 两类用户对同一个模块的不同期待我在评估模块时接触过两类完全不同的项目方需求差异很能说明问题。第一类是做数据采集网关的他们对模块的期待是“两个口必须物理独立”。因为现场组网环境不可控两个口可能分别连接两个完全隔离的业务网络A 网的广播风暴不能影响到 B 网A 网的设备也不能通过模块偷偷访问到 B 网。这要求模块的独立端口模式不是“软件桥接之后逻辑隔离”而是从硬件数据通路层面就把两个口切开。第二类是做人机界面或者工业屏的他们的期待恰恰相反。现场设备通常没有交换机却需要一台 HMI 同时连接 PLC 和上位机或者两台 PLC 串联到一个触摸屏。他们希望模块插上就用两个口之间自动互通不需要配 IP、不需要敲命令最好未知设备插上就能通。这两类需求看起来矛盾但聚焦到模块设计上其实只是一个配置差异交换芯片内部怎么处理端口间的转发关系。前者做端口隔离后者做端口互通。芯片本身并不区分谁是谁完全是寄存器里几个 bit 的事情。2. 独立端口模式与交换机模式一枚芯片的两种性格2.1 独立端口模式每个口都有独立 MAC 和独立 IP在独立端口模式下两个网口从主控 CPU 的视角看就是两张普通网卡。数据到达 PHY 之后经过 MAC 进到内存由网卡驱动交给内核协议栈内核根据 IP 地址、路由表、防火墙规则决定这个包是转发出去还是交给本地进程。这个模式最大的特点是“CPU 站在每一跳的中间”。两个口之间的通信哪怕是同一网段的两台设备数据也得先从 A 口进内存内核查一遍路由再从 B 口发出去。好处是灵活你可以对流量做任意处理NAT、防火墙、流量整形、报文过滤都没问题。代价是两个端口之间的吞吐上限就是 CPU 的处理能力如果主控是个低主频的 MCU跑满百兆口都费劲更别说千兆。很多双网口模块的“独立端口模式”在硬件上并不见得有两个独立 MAC而是交换芯片内部做了端口隔离。这部分我在后面硬件拓扑里细说先记住结论逻辑上的独立网卡物理上可能共用一颗交换芯片。2.2 交换机模式硬件转发才是灵魂交换机模式就完全不同了。两个外部端口和连接主控的 CPU 端口之间由交换芯片内置的 MAC 地址表驱动转发。A 口收到一个数据帧芯片查表发现目的 MAC 在 B 口二话不说直接从 B 口发出去整个过程 CPU 连包都见不着。这里有三个关键机制需要理解地址学习芯片自动记录每个源 MAC 地址是从哪个端口学到的形成 MAC 地址表。地址老化MAC 表条目有生存时间典型值 300 秒设备移动端口之后旧条目自动失效不会一直错转。洪泛与广播目的 MAC 查不到或者目的地址是广播地址时芯片会把帧发向除接收端口外的所有端口。交换机模式的价值不只是“能通”而是“通得快”。百兆交换芯片的转发能力通常在线速每个端口都能跑满 100Mbps两端口之间同时双向收发也不会丢包。对主控 CPU 来说这种模式几乎零负担哪怕主控在休眠两个外设之间照样通信。2.3 三种硬件拓扑的横向对比做技术选型之前得先看清“双网口模块”这个说法下面藏着好几种实现路径我整理了一个对比表实现方案典型芯片/平台独立端口能力交换机模式主控占用适用场景SoC 双 MAC 双 PHYRK3568 双 GMAC、i.MX8M Plus物理真独立天然不支持需软件桥接高转发全靠 CPU路由器、防火墙、网闸集成双 PHY 的交换芯片LAN9303、LAN9352支持靠 VLAN / 端口隔离原生支持低硬件转发双网口模块、工业串接设备CPU 口 外置交换芯片KSZ9896、RTL8367支持原生支持低多口交换机、管理型交换机USB/PCIe 桥接芯片AX88179、RTL8153 组双口物理独立不支持软件桥接高树莓派扩展双网口标题里写 “Operates as Independent Ports or Switch” 的模块绝大多数是第二种方案也就是以一颗集成两个 PHY 的交换芯片为核心通过寄存器配置切换性格。第三种方案多见于对端口数要求更多的产品原理一脉相承。选型最怕的是拿方案的工程师对着第四种方案和客户大谈独立模式结果客户追问“那能当交换机用吗”当场卡壳。3. 硬件设计要点双 PHY 布局、管理通道与复位时序3.1 芯片选型10/100 与千兆的分水岭模块产品选交换芯片第一个分水岭是速率。10/100M 的典型选择是 Microchip LAN9303、LAN9352 这类三端口芯片内部集成两个 PHYCPU 通过 MII 或 RMII 接口连接内部第三个端口。千兆级别就得换到 KSZ9896、KSZ9897、RTL8367 这一档外部端口数量更多通常 PHY 也外置PCB 面积和成本都会上去。选型时要盯几个硬指标内部端口数CPU 口 外部口基本决定了产品形态。主机接口类型百兆芯片常见 MII/RMII千兆芯片常见 RGMII。RMII 信号少、布线容易但需要 50MHz 参考时钟RGMII 信号多布线麻烦但是吞吐高。管理接口I2C、SPI、MDIO 都可以对芯片做配置有些芯片只在启动时读取一次配置有些支持运行时动态改寄存器。如果你的产品有可能从独立端口模式切换到交换机模式必须选支持动态改端口转发表项的芯片别选那种只能用外部引脚 strapping 固定模式的。前者是软件能切换后者一焊上去就定死了完全违背标题里的 “or” 字。3.2 一颗芯片怎么管理两个口PHY 地址与 MDIO 总线LAN9303 这种双 PHY 芯片最让人容易忽略的是 PHY 地址分配。芯片内部两个 PHY 通常通过 strap 引脚固定到不同的地址比如 PHY1 在 0x01、PHY2 在 0x02主机通过 MDIO 总线访问时一个地址对应一个 PHY互不干扰。设计 PCB 时一定要注意 MDIO 的时序和上拉。MDC 时钟一般跑 2.5MHzMDIO 是双向数据线必须接对方向的上拉电阻阻值常见 1.5kΩ 到 10kΩ。我遇到过一块板子两个网口都能 link up但读 PHY 寄存器全是 0xFFFF查了半天发现 MDIO 上拉电阻没贴总线电平不稳芯片 ID 都读不出来自然没法进入正常驱动流程。如果 SoC 只有一个 MAC却要通过独立 PHY 芯片扩展两个网口那就得保证两颗 PHY 的外部地址不冲突常见做法是把其中一颗的 RXD 引脚做地址 strap硬件上拉或下拉成不同值。两颗 PHY 用同一个地址的后果是驱动 probe 时只能认出一颗另一颗直接消失而且日志里没有任何报错特别隐蔽。3.3 复位时序两个 PHY 的“起床时间”必须同步PHY 芯片上电之后需要一段内部初始化时间典型值是 10ms 到 50ms 不等具体看数据手册。模块设计上通常把两颗 PHY 的复位引脚接在一起由主控 GPIO 统一控制。上电时先拉低复位至少 10ms再释放然后等待至少 100ms 再让驱动去访问 MDIO 总线。这个 100ms 的等待非常关键。PHY 内部 PLL 没锁定时MDIO 读写寄存器会不稳定Probe 时的 PHY ID 读错驱动就会认为芯片型号不对拒绝注册。我之前调一块板子时问题表现是“十个模块里有两三个网口不通”定位到根因就是复位释放后立刻读寄存器PHY 还没准备好。后来把复位后的延时从 10ms 加大到 150ms故障率直接清零。此外还要注意复位释放时的电平毛刺。如果复位引脚没有加 RC 滤波或者由电源监控芯片控制电源上电瞬间会产生抖动PHY 可能复位到不确定状态。工业级产品建议直接用带延时功能的电源监控芯片控制复位而不是 GPIO 硬拉。4. 软件侧落地从驱动注册到业务配置4.1 内核驱动框架交换芯片驱动的接入方式Linux 内核处理这类嵌入式交换机有一套成熟框架叫 DSADistributed Switch Architecture。DSA 的精髓是把交换芯片的每个外部端口映射成一个标准 net_device比如 eth0、eth1同时保留一个面向主控的 CPU 端口。对用户态和协议栈来说这些端口看起来就像普通网卡但实际数据通路是经过交换芯片转发的。LAN9303 这类芯片在内核已经有现成驱动设备树里声明好之后系统起来一般能看到 eth0 和 eth1 两个接口。下面是设备树片段的简化写法实际项目里要根据总线地址和中断号调整mdio0 { eth_switch: lan93035 { compatible microchip,lan9303; reg 5; reset-gpios gpio4 15 GPIO_ACTIVE_LOW; interrupt-parent gpio4; interrupts 16 IRQ_TYPE_LEVEL_LOW; }; };驱动会通过 MDIO 总线读取芯片 ID确认是 LAN9303 之后注册 DSA 端口。一个常见问题是设备树里忘了写 reset-gpios或者 GPIO 号和实际接线不对表现就是系统起来了但一个网口都看不到内核日志里只有一行 “mdio_bus: probe of mdio-bus failed”排查时特别容易误判为芯片没焊好。如果芯片驱动没有被内核编译进去常见报错就是找不到驱动模组这类问题通常是内核 config 没开 CONFIG_NET_DSA_MICROCHIP_KSZ 或对应选项编译内核时记得确认。4.2 独立端口模式的系统配置双网卡与策略路由独立端口模式下系统起来后 eth0 和 eth1 是两个独立接口直接按普通网卡配置 IP 即可。如果两个口分别接两个运营商线路需要同时上外网单靠默认路由不够需要策略路由。假设 eth0 对应 192.168.1.0/24网关是 192.168.1.1eth1 对应 192.168.2.0/24网关是 192.168.2.1两个口都要能访问外网可以建两个路由表echo 100 wan1 /etc/iproute2/rt_tables echo 200 wan2 /etc/iproute2/rt_tables ip route add default via 192.168.1.1 dev eth0 table wan1 ip rule add from 192.168.1.0/24 table wan1 ip route add default via 192.168.2.1 dev eth1 table wan2 ip rule add from 192.168.2.0/24 table wan2这套配置对双网口模块的意义在于模块的独立端口模式不只是“两个口能同时 up”还要保证流量按照源 IP 从对应口出去否则会出现从 eth0 进来的请求回包从 eth1 走了对端永远收不到响应表现为“ping 得通但网页打不开”。4.3 交换机模式的系统配置bridge 与端口隔离交换机模式有两种落地路径。如果模块在出厂时就固定为交换机模式最简单的方式是把两个 DSA 端口都加进 Linux bridgeip link add name br0 type bridge ip link set eth0 master br0 ip link set eth1 master br0 ip link set br0 up用 bridge 之后主机本身也成了一个三层管理口可以给 br0 配一个 IP 做远程管理。数据流量在两个口之间走的是交换芯片硬件转发bridge 只是提供了管理控制面。如果希望两个口“物理通、逻辑断”即插在 A 口的设备不能访问 B 口的设备就需要做端口隔离。先用 port-based VLAN 把两个口切成两个独立广播域再把主机口配成 trunk 口进行管理端口VLAN 成员是否打标签用途eth0VLAN 10PVIDuntagged业务 Aeth1VLAN 20PVIDuntagged业务 BCPU 口VLAN 10/20tagged网管这种配置在标题里对应的正是 “Independent Ports” 的深层含义两个物理口都在工作数据也走硬件转发但从二层广播域看它们互不可见。很多网口隔离设备、多 WAN 安全网关用的就是这套逻辑。4.4 应用层状态别让 systemd 把网口顺序搞乱独立端口模式还有一个软件坑Linux 的网口命名顺序由内核探测顺序决定如果两个 PHY 驱动 probe 的次序不稳定可能出现上次启动 eth0 是 A 口、这次启动 eth0 变成 B 口。解决办法是用 udev 规则基于 MAC 地址固定网口名SUBSYSTEMnet, ACTIONadd, ATTR{address}xx:xx:xx:xx:xx:01, NAMEwan0 SUBSYSTEMnet, ACTIONadd, ATTR{address}xx:xx:xx:xx:xx:02, NAMElan0模块出厂时每个网口的 MAC 地址要提前规划。两颗 PHY 可以共用同一个 MAC 池里的连续地址也可以分别烧录独立 MAC。注意如果两颗 PHY 的 MAC 地址相同交换机模式下会出幺蛾子后面排查部分详细说。5. 实战调试四个典型故障的完整排查链路5.1 第二个网口不出现先看 PHY 地址再看复位时序曾在调试中遇到过一块双网口模块内核起来之后只认出一个口另外一个口连 link 状态都不对。我的排查链路是这样的第一步看内核日志。登录系统执行 dmesg | grep mdio确认两个 PHY 的 ID 是否都被识别到。如果只识别到一个 ID优先怀疑两个 PHY 地址冲突。用 busybox devmem 之类工具直接读取 MDIO 地址 0-31 的寄存器理论上两个 PHY 应该落在两个不同的地址上。第二步查硬件 strap。双 PHY 芯片的地址一般由引脚电平决定拿万用表量一下 strap 引脚的电压确认确实是一高一低。第三步查复位。很多模块设计上把两颗 PHY 用同一个 GPIO 复位但要确认 PCB 上复位引脚有没有连到 GPIO而不是被电阻直接拉高导致芯片永远处于复位状态。最后一步查内核 config。确认 DSA 驱动和 PHY 驱动都编进去了而且没有因为内核版本差异导致驱动匹配失败。这个排查过程最容易被忽视的是第一步很多人上来就怀疑 PCB 焊接其实 PHY 地址冲突和复位时序出问题的概率远高于虚焊。5.2 link up 但 ping 不通MAC 地址与 VLAN 的锅另一个高频故障是两个口都能正常 link up但两端设备就是 ping 不通。如果确认 IP 地址没配错重点排查两个方向。第一是 MAC 地址冲突。如果两颗 PHY 出厂烧录了相同的 MAC交换芯片的地址学习表会来回抖动A 口学到 MAC X 在端口 1B 口又学到 MAC X 在端口 2数据帧就会在两个端口之间乒乓转发最终丢包。排查办法是用 tcpdump 在主机侧抓包发现请求帧能进来但响应帧源 MAC 地址不对八成就是地址冲突。解决方法是给两个端口分别设置唯一的 MAC用 ip link set eth0 address 命令可以临时验证。第二是 VLAN 配置不一致。如果模块在独立端口模式下做过端口隔离测试寄存器里还残留着 VLAN 配置重新上电后默认配置没有恢复就可能出现“A 口的设备只能和主机通信不能和 B 口设备通信”。解决方法是恢复出厂默认配置或者把交换机芯片的配置动作封装成独立脚本系统初始化时强制执行一遍。5.3 交换机模式的广播风暴环路把芯片打懵测试时还有一次印象很深两块双网口模块用网线把 A 模块的 lan 口和 B 模块的 lan 口对接然后把两个模块的 wan 口都接在同一台交换机上瞬间整个局域网开始疯狂广播CPU 占用直接飙到 100%。这是典型的二层环路。两个模块之间形成了一条物理环路广播帧在环里无限循环MAC 地址表被反复刷新最终打满所有带宽。排查时先断掉其中一条链路广播立刻消失就能确认环路。解决方式是让交换机模式支持 STP/RSTP。工业级模块建议在驱动层就启用 STP 而不是指望用户手动断开网线。如果是模块在半成品阶段做测试先把环路物理拆除等软件方案成熟后再验证。5.4 独立端口模式吞吐上不去中断与缓冲区的博弈有次客户反馈双网口模块在独立模式下千兆带宽只能跑到 400Mbps排除硬件链路问题之后我做了两件事一是看中断分布。两个网口共用同一个中断号时高吞吐流量会让单核 CPU 陷入中断风暴处理不过来的包只能丢弃。做法是把两个网口的中断分开绑定到不同 CPU 核充分发挥多核能力。二是调大 ring buffer。默认的 RX ring 深度可能只有 256突发流量一来就溢出丢包。用 ethtool -G eth0 rx 1024 调大缓冲再用 ethtool -L eth0 combined 2 开多队列吞吐提升非常明显。针对转发类业务还可以检查驱动是否开启 NAPI 和 busy poll这些对低延迟场景都有帮助。6. 选型建议与产品形态扩展6.1 怎么选先问清楚“独立”是哪一种独立如果带着需求去选型我的建议是先分清你要的“独立端口模式”是哪种。如果你需要两个口在物理上完全独立、各自有独立 MAC 和独立中断、操作系统层面就是两张独立网卡那就选 SoC 双 MAC 方案别选交换芯片方案。反过来如果所谓独立只是逻辑上的隔离同时希望保留交换机模式的在线转发能力那选 LAN9303 这类双 PHY 交换芯片最合适。从标题里的 Dual Ethernet Module Operates as Independent Ports or Switch 来看这种模块的定位是“一套硬件覆盖两个模式”本质上是让产品团队少做一个 SKU。选型时注意芯片是否支持运行态切换如果只支持上电时 strap 选择模式那意味着产品机型还得分两个版本模块的灵活性就打了折扣。6.2 模块形态的扩展思考这类模块做成熟之后产品形态可以顺着两条线延伸。一条线是做四口、八口版本核心还是端口隔离加硬件转发只是交换芯片从三端口换到多端口主机接口从 MII 升级到 RGMII 或 PCIe软件框架从 DSA 扩展成更大规模的交换架构管理功能也可以加上 port mirror、QoS、链路聚合。另一条线是做混合模式两个口默认独立但在系统里软件调度断电或者系统崩溃时自动切换成硬件直通。这个特性对工业现场特别有用设备死机了链路还能保持畅通不至于把整个网络段都带崩。我实际测试下来最稳妥的做法是在出厂固件里同时保留两套配置文件一套是独立端口的 sysctl 和 udev 规则一套是交换机模式的 bridge 初始化脚本用一个标志位控制启动时执行哪套。这样模块交付给客户之后改一个配置文件就能切换模式不需要重新烧固件现场维护的同事会感谢你的。6.3 调试经验最后补一句双网口模块的调试硬件问题大多出在复位时序和 PHY 地址软件问题大多出在 MAC 地址唯一性和 VLAN 配置残留。这两类问题有一个共同特点日志都不明显系统不会报错只会表现为“偶尔不通”或者“时通时断”。遇到这种情况不要急于改软件先把硬件基础项一项项确认完再动代码能省下大量排查时间。另外模块的 MAC 地址池在量产时就要做好规划宁可浪费几个地址也不要让两个网口重复否则出货之后用户报修你在办公室排查链路都会被折腾得够呛。
返回列表