
简介rtl83xx_switch-api-v1.3.9.zip 面向从事嵌入式网络设备开发的工程师尤其是熟悉 C 语言与 Linux 内核驱动、需要对接 Realtek RTL83xx 系列交换芯片的技术人员。资源聚焦 RTL8367C 等芯片的驱动与 API 实现可用于初始化交换机、配置端口属性、管理 VLAN、实施 QoS 与 IGMP 侦听、处理数据包转发及端口镜像等场景帮助开发者打通应用层与硬件之间的通信路径。压缩包共 124 个文件以 63 个 .h 头文件和 59 个 .c 源文件为主体另含 1 个 makefile 与 1 张 png 图示整体约 579KB结构紧凑便于按模块查阅接口定义与驱动实现。目前已有 1397 人学习下载。通过研读其中的 API 与驱动代码读者可掌握芯片初始化、数据传输、错误处理与配置管理等核心流程为优化网络性能、构建稳定的交换设备提供可复用的参考实现。1. 从 rtl83xx_switch-api-v1.3.9.zip 说起Realtek 交换芯片驱动到底在驱动什么手上拿到一个rtl83xx_switch-api-v1.3.9.zip很多人第一反应是解压找 README然后卡在“这堆 .c/.h 到底怎么编进内核”。Realtek 的 rtl83xx 系列交换芯片常见于家用路由、工业交换机、部分 NVR 主板和普通网卡芯片不一样它是一颗带多个 PHY、支持 VLAN、端口镜像、QoS 的交换 ASIC驱动要做的不是收发单个包而是把芯片内部的寄存器表、端口状态、转发表映射成 Linux 能识别的 netdev 和 bridge 操作。标题里的switch-api就是这层映射的接口层v1.3.9是这套 API 的版本号rtl80 则是早期 rtl8306/8308 这类 8 口交换芯片的统称。搞不清这层关系后面编译报错、端口不通、VLAN 打不上都会变成玄学。2. rtl83xx switch-api 的目录结构与编译前必须确认的三件事2.1 解压后先看这几个文件别急着 make拿到 zip 先别make先tree或find看结构。典型 rtl83xx switch-api 包会包含unzip rtl83xx_switch-api-v1.3.9.zip -d rtl83xx_switch-api cd rtl83xx_switch-api find . -maxdepth 2 -type f | sort常见输出里你会看到src/、include/、Makefile、Kconfig、rtl83xx_switch_api.c、rtl83xx_reg.h、rtl83xx_port.c等。include/下通常有rtl83xx_switch_api.h这是对外暴露的 ioctl 和 netdev 操作接口rtl83xx_reg.h是寄存器偏移定义改错一个 bit 就可能把 PHY 关掉。逻辑说明find只列两层避免被深层测试用例干扰sort让输出稳定方便对比不同版本。参数上-maxdepth 2是经验值再深就是芯片型号分支目录初看没必要展开。2.2 确认内核版本和 CONFIG_SWITCH 相关选项Realtek 这套 API 对内核版本敏感v1.3.9 常见适配 4.4/4.9/5.4 的 BSP 内核。先查uname -r zcat /proc/config.gz | grep -E CONFIG_SWITCH|CONFIG_BRIDGE|CONFIG_VLAN如果/proc/config.gz不存在去/boot/config-$(uname -r)找。必须确认CONFIG_BRIDGEy或m因为 rtl83xx 的端口默认要挂到 bridge 上才能转发CONFIG_VLAN_8021Q也要开否则后面vconfig或bridge vlan会失败。提示如果内核是厂商 BSP 内核CONFIG_SWITCH可能已经被改成CONFIG_RTL83XX_SWITCH用grep -i rtl83xx /boot/config-*再确认一次。2.3 交叉编译工具链和 ARCH 必须和板子一致在 x86 上直接make出来的 .ko 是没法 insmod 到 MIPS/ARM 板子上的。常见做法是export CROSS_COMPILEmips-linux-gnu- export ARCHmips export KERNEL_DIR/path/to/board/kernel make -C $KERNEL_DIR M$PWD/src modules逻辑说明M$PWD/src告诉内核构建系统只编译当前目录的模块CROSS_COMPILE和ARCH决定指令集。参数上KERNEL_DIR必须是板子实际运行的内核源码树不能拿 Ubuntu 的/lib/modules/$(uname -r)/build糊弄否则 vermagic 不匹配insmod 会报invalid module format。3. 用 switch-api 把 rtl83xx 端口拉起来的最小操作序列3.1 加载模块并确认 netdev 是否生成编译出rtl83xx_switch.ko后insmod rtl83xx_switch.ko dmesg | tail -30 ip link show正常会看到eth0、eth1… 或者swp0、swp1这类命名。如果 dmesg 里出现rtl83xx: probe failed先查 MDIO 总线号是否和硬件一致。很多板子交换芯片挂在mdio-bus0但驱动默认写死0实际是1这时要改rtl83xx_switch_api.c里的mdio_bus_id或通过模块参数传insmod rtl83xx_switch.ko mdio_bus_id1参数说明mdio_bus_id是 MDIO 控制器编号对应设备树里mdio节点的reg或别名传错会导致 PHY 读不到 ID端口全部 down。3.2 用 switch-api 的 ioctl 查端口状态switch-api 一般会暴露一个字符设备或 proc 节点常见是/proc/rtl83xx/port或/dev/switch。查端口 link 状态cat /proc/rtl83xx/port # 或 switch_api_cli port show如果包里带了switch_api_cli工具直接用它更稳。输出里重点看link、speed、duplex、vlan四列。linkdown但插了网线先换网线再查 PHY 供电和复位 GPIO。rtl83xx 的 PHY 复位脚经常接在 GPIO 扩展芯片上设备树里reset-gpios写错PHY 永远起不来。3.3 把端口加入 bridge 并验证转发最小转发验证ip link set swp0 up ip link set swp1 up ip link add br0 type bridge ip link set swp0 master br0 ip link set swp1 master br0 ip addr add 192.168.10.1/24 dev br0 ip link set br0 up ping -I br0 192.168.10.2逻辑说明master br0把交换端口变成 bridge 从口内核 bridge 会调用 switch-api 的ndo_add_slave回调把端口加入芯片的 VLAN 转发表。参数上192.168.10.1/24只是示例实际按现场网段改。如果 ping 不通先bridge fdb show看 MAC 是否学到再cat /proc/rtl83xx/vlan看 VLAN 成员是否包含两个端口。检查项命令正常表现端口 linkcat /proc/rtl83xx/portlinkup, speed1000bridge 成员bridge link showswp0/swp1 state forwardingVLAN 表cat /proc/rtl83xx/vlan两个端口在同一 VIDFDBbridge fdb show有对端 MAC 动态条目4. rtl83xx switch-api 的 VLAN、镜像和 QoS 参数怎么设4.1 VLAN 划分别直接 vconfig先看 switch-api 的 VID 范围rtl83xx 芯片的 VLAN 表通常只有 16 或 32 个条目不是 4096。用bridge vlan之前先确认cat /proc/rtl83xx/vlan_cap # 输出示例max_vlan16, vid_range1-4094如果max_vlan16你建 20 个 VLAN 就会静默失败。常见做法是只给需要隔离的端口分 VLAN其余走默认 VID 1。设置命令bridge vlan add dev swp0 vid 10 pvid untagged bridge vlan add dev swp1 vid 10 bridge vlan add dev swp2 vid 20 pvid untagged逻辑说明pvid表示端口收到 untagged 帧打上该 VIDuntagged表示出方向剥掉 tag。参数上vid 10必须在vid_range内且总条目不超过max_vlan。如果bridge vlan add返回RTNETLINK answers: No space left on device就是 VLAN 表满了删掉不用的再试。4.2 端口镜像用 switch-api 的 mirror 接口而不是 tcpdump在交换芯片上做镜像tcpdump 只能看到本机收发的包看不到其他端口转发的流量。switch-api 一般提供 mirror 配置switch_api_cli mirror set src swp0 dst swp3 direction both # 或通过 proc echo 0 3 3 /proc/rtl83xx/mirror参数说明src swp0是被镜像口dst swp3是监控口direction both表示进出都镜像。echo 0 3 3这种写法里三个数字通常是src_port dst_port mode具体顺序看include/rtl83xx_switch_api.h里的枚举定义别照抄。镜像口不要再加入 bridge否则会形成环路。4.3 QoSDSCP 到队列的映射表在哪改rtl83xx 支持 4 或 8 个优先级队列。改映射switch_api_cli qos map dscp 46 to queue 7 switch_api_cli qos map dscp 0 to queue 0 switch_api_cli qos show逻辑说明dscp 46是 EF 语音流量映射到最高队列 7dscp 0是默认流量映射到队列 0。参数上队列号不能超过芯片支持的max_queue用switch_api_cli qos cap查。如果映射后测速没变化检查端口是否开了流控ethtool -a swp0看RX/TX flow control是否为 on。注意改 QoS 映射前先备份/proc/rtl83xx/qos的原始输出不同 v1.3.9 小版本的默认表可能不一样改错会导致管理流量被丢。5. 排错与验证rtl83xx 驱动加载失败、端口不通、VLAN 不生效的排查顺序5.1 驱动加载失败先看 vermagic 和符号依赖insmod报invalid module format九成是内核版本不匹配modinfo rtl83xx_switch.ko | grep vermagic uname -r两个字符串必须完全一致包括-dirty后缀。如果板子内核是4.9.120-rt你编译用的是4.9.120就会失败。解决方法是拿板子厂商的 SDK 内核重新编或者用--force强载不推荐容易 oops。符号依赖用modprobe --dump-modversions rtl83xx_switch.ko | head看crc是否和当前内核的Module.symvers一致。不一致就重新编内核模块别混用。5.2 端口不通从 PHY ID 读到 link up 的完整链路排查顺序固定dmesg | grep -i phy看有没有读到 PHY ID正常是Realtek RTL8211F之类。cat /proc/rtl83xx/port看 link 状态。ethtool swp0看Link detected: yes/no。如果 PHY ID 读不到量 MDC/MDIO 波形查上拉电阻。如果 PHY ID 正常但 link down换网线、换对端口排除变压器问题。常见坑rtl83xx 的某些端口和 CPU 口共用 SerDes设备树里phy-mode写成rgmii但实际是sgmiilink 永远起不来。改phy-mode后重新编 dtb。5.3 VLAN 不生效查 PVID、成员表和 CPU 口 tagVLAN 不通的典型原因是 CPU 口没打 tag。CPU 口连主控的那个口必须配置成 tagged 成员否则内核收不到带 VID 的帧bridge vlan add dev eth0 vid 10 tagged bridge vlan show逻辑说明eth0是 CPU 口tagged表示进出保留 802.1Q 头。参数上vid 10要和用户口一致。如果bridge vlan show里 CPU 口没有对应 VID内核协议栈就无法把帧交给br0.10这类子接口。验证ip link add link br0 name br0.10 type vlan id 10 ip addr add 192.168.10.1/24 dev br0.10 ip link set br0.10 up ping -I br0.10 192.168.10.2能 ping 通说明 VLAN 转发链路完整。5.4 性能验证用 iperf3 打流看是否走硬件转发交换芯片的价值在于硬件转发如果流量走了 CPU吞吐会掉到几百兆。验证方法# 两台 PC 分别接 swp0 和 swp1同网段 iperf3 -s -B 192.168.10.2 iperf3 -c 192.168.10.2 -t 30 -P 4同时看板子 CPU 占用top -d 1如果 iperf3 跑满 1G 但 CPU 占用低于 5%说明走硬件转发如果 CPU 飙到 80% 以上检查是不是误把两个端口都挂到br0但没启用 switch-api 的 offload或者芯片转发表没下发。常见原因是bridge的multicast_snooping或stp在软件路径处理关掉再测echo 0 /sys/class/net/br0/bridge/multicast_snooping echo 0 /sys/class/net/br0/bridge/stp_state6. 把 rtl83xx switch-api 接进自研管理面一个可复用的封装技巧很多做工业交换机或 NVR 的团队不会直接用switch_api_cli而是把 switch-api 的 ioctl 封装成自己的配置服务。一个可复用的做法是在用户态起一个 daemon通过 netlink 或 Unix socket 接收配置再翻译成 switch-api 调用。关键是把端口、VLAN、镜像、QoS 四类操作抽象成 JSON避免每次改需求都动 C 代码。/* 示例封装 switch-api 的 VLAN 设置带错误码返回 */ #include rtl83xx_switch_api.h int set_vlan_member(int vid, int port, int tagged) { struct rtl83xx_vlan_cfg cfg {0}; cfg.vid vid; cfg.port port; cfg.tagged tagged; int ret rtl83xx_vlan_add(cfg); if (ret ! RTL83XX_OK) { /* 常见错误RTL83XX_ERR_VLAN_FULL 表示表满 */ return -ret; } return 0; }逻辑说明rtl83xx_vlan_add是 switch-api 暴露的函数RTL83XX_ERR_VLAN_FULL对应前面说的 VLAN 表满。参数上tagged对用户口一般传 0对 CPU 口传 1。封装层要把错误码转成 HTTP 或 JSON 错误方便前端提示“VLAN 资源不足”。验证封装是否生效不用重启设备# 调用你的 daemon 接口 curl -X POST http://127.0.0.1:8080/vlan -d {vid:10,port:0,tagged:0} # 再查芯片实际状态 cat /proc/rtl83xx/vlan | grep 10如果 daemon 返回成功但/proc/rtl83xx/vlan没变化检查 daemon 是否以 root 运行以及 switch-api 的字符设备权限。常见坑是 daemon 在容器里跑/dev/switch没映射进去ioctl 直接返回ENODEV。把设备节点和/proc/rtl83xx挂进容器或者用--privileged跑就能解决。最后v1.3.9 的 API 在端口统计上有个细节rtl83xx_port_stats读的是芯片计数器不是内核 netdev 统计两者在丢包场景下会对不上做监控时以芯片计数器为准别拿ifconfig的 dropped 去告警。本文还有配套的精品资源点击获取