Skip to content

GOOSE 跨平台收发与自发自收 ​

本文说明 EMS Simulate 在 Linux 和 Windows 上如何发送、捕获和订阅 GOOSE,以及本机发出的报文在旧版 Linux 接收路径中被丢弃的原因。

GOOSE 使用以太网二层组播,协议 EtherType 为 0x88B8。发布器、订阅器和抓包器各自选择网卡。这里的自发自收指发布器和订阅器在同一台主机、同一块以太网网卡上运行,订阅器读取系统抓包接口提供的本机出站帧副本。选用发布时的实际网卡即可。模型加载后,GOOSE 可以独立于 MMS 连接运行,详见 IEC 61850 操作指南。

Linux 与 Windows 的实现差异 ​

项目LinuxWindows
发布由 pyiec61850-ng 调用 libiec61850,按发布配置构造并发送以太网帧由 Scapy 构造以太网帧和 GOOSE 负载,通过 Npcap 发送
VLAN ID 为 0发布器仍生成 802.1Q 标签。VID 为 0,PCP 携带配置的优先级发布器生成无标签帧。报文中没有 VLAN PCP 字段
VLAN ID 大于 0发布器生成带 VID 和 PCP 的 802.1Q 帧Scapy 添加带 VID 和 PCP 的 Dot1Q 头。现场可在对端抓包确认网卡实际发出的标签
订阅和独立抓包AF_PACKET 原始套接字绑定指定网卡,使用 ETH_P_ALL 接收,并在应用内解析 EtherTypeScapy 在指定的 Npcap 适配器上抓取二层帧,再使用同一套 GOOSE 解析器
运行条件后端进程在对应网络命名空间中具有 CAP_NET_RAW,并能看到目标网卡安装并启用 Npcap。若安装时限制为仅管理员访问,后端需要相应权限
订阅历史中的 timestamp毫秒级 GOOSE 事件时标,取自帧内字段 t毫秒级本机捕获时刻

两端都用本机捕获时刻更新订阅的最后接收时间。抓包详情会区分帧内事件时标与捕获时刻。同一状态的周期重发通常保留事件时标,接收计数和 sqNum 更适合判断订阅是否持续收到报文。

原先的 libiec61850 Windows 接收路径曾出现接口启动后未收到回调的情况。当前二层收发使用 Scapy/Npcap。安装要求和迁移背景可参阅以下资料。 Npcap 用户指南 · GOOSE 接收、DataSet 历史与抓包链路重构

Linux 旧接收路径为何漏掉本机帧 ​

两种帧的差别出现在源 MAC 之后。下表中的偏移从以太网帧首字节开始计算。

帧格式偏移 12–13偏移 14–15偏移 16–17APPID 起始偏移
无标签 GOOSE0x88B8APPIDGOOSE 长度14
单层 802.1Q GOOSE0x8100VLAN TCI,含 PCP、DEI 和 VID0x88B818

例如 VID 为 0、PCP 为 4、DEI 为 0 时,带标签的帧从偏移 12 开始可见 81 00 80 00 88 B8。旧过滤器读到的是前两个字节 81 00。

  1. Linux 发布端调用 GoosePublisher_create()。libiec61850 v1.6.1 通过该入口启用 VLAN 标签,因此默认 VID 为 0 时,帧仍以 0x8100 作为外层 EtherType。 libiec61850 v1.6.1 发布端源码
  2. Linux 可将本机发送的帧以 PACKET_OUTGOING 类型交给同一接口上的其他抓包套接字。本机可以通过这份副本观察发布流量,无需等待交换机把帧送回。 Linux packet(7)
  3. 旧订阅路径使用 libiec61850 的 Linux GOOSE 接收器。其内核过滤器只比较偏移 12–13 的值与 0x88B8。当出站副本保留 802.1Q 头时,该位置是 0x8100,帧在到达 GOOSE 解析和订阅匹配之前就被丢弃。这解释了同一网卡上独立抓包有数据、订阅计数却为零的现象。 libiec61850 v1.6.1 Linux 接收过滤器源码

Windows 默认 VID 为 0 时构造的是无标签帧,接收也走 Npcap 路径。相同的发布参数在两个系统上可能生成不同的以太网头。

修复后的 Linux 接收流程 ​

text
GOOSE Publisher → 指定以太网网卡 → 本机出站帧副本
                                          ↓
外部 GOOSE 组播 → 同一网卡 ───────→ AF_PACKET / ETH_P_ALL
                                          ↓
                              识别无标签或单层 802.1Q
                                          ↓
                                 解析 GOOSE 头和 PDU
                                          ↓
                           匹配启用的订阅 → 更新数据和历史
  • 接收套接字按网卡绑定,并使用套接字级的 PACKET_MR_ALLMULTI 接收该网卡上的外部二层组播。套接字关闭时,内核清理这项成员资格。 Linux packet(7)
  • 应用识别帧头是否含单层 0x8100 标签,再从正确位置读取 0x88B8 和 APPID。Linux 发布端继续使用 libiec61850,现有的 VID 和优先级配置仍可使用。
  • 订阅器仅处理已启用、goCbRef 完全一致的订阅。配置了 APPID 或目的 MAC 时,对应字段也必须相同。独立抓包有数据只说明捕获到了帧,订阅还需通过这些条件。
  • confRev 用于提示配置版本是否一致。若报文已匹配但数据成员含义不符,核对 DataSet 引用、成员顺序和配置版本。

本机自发自收验证 ​

配置发布与订阅 ​

  1. 在测试网段中打开已加载模型的 IEC 61850 设备,选择一条已配置 DataSet 的 GOOSE 发布项。
  2. 发布和订阅选同一块已启用的以太网网卡。Linux 可用 ip -br link 查网卡名称。Windows 可用 Get-NetAdapter 查适配器名称和状态。容器或虚拟机内的后端需要使用其自身可见的网卡。
  3. 从发布配置复制实际的 GoCBRef、APPID 和目的组播 MAC。例如 GoCBRef 可以是 IED1LD0/LLN0$GO$gcb1。填写订阅后先启用本地接收,再启动发布。
  4. 查看订阅的最新数据和接收历史。周期重发时,接收计数应递增,stNum 通常保持稳定,sqNum 递增。变更一个发布成员值后,检查订阅值和 stNum 是否更新。
  5. 在 Linux 上先用 VID 0 验证默认的优先级标签,再在允许该 VLAN 的测试网段验证非零 VID。Windows 可分别验证 VID 0 的无标签帧和非零 VID 的带标签帧。

Linux 抓包 ​

将 eth0 替换为后端所用的网卡名。使用 -Q out 查看本机出站帧,省略该选项可同时观察入站和出站流量。 tcpdump 手册源码

bash
sudo tcpdump -ni eth0 -Q out -e -vv +  'ether proto 0x88b8 or (vlan and ether proto 0x88b8)'

预期能看到与发布配置一致的目的 MAC。带标签的帧通常会显示 802.1Q、VLAN ID 和优先级,内层协议为 0x88b8。该命令以提升后的权限运行,应用后端进程的套接字权限需要单独核对。若只看到本机出站帧,可在另一台测试主机或交换机镜像口确认线上是否收到。

Windows 抓包 ​

在 Wireshark 中选择与 EMS Simulate 相同的以太网适配器,开始抓包后使用显示过滤器 goose。要缩小范围,可用 goose.appid == 0x0001 并替换为实际 APPID。展开以太网、802.1Q 和 GOOSE 层,核对目的 MAC、标签和 GoCBRef。 Wireshark GOOSE 显示过滤器参考

如果后端无法打开适配器,先检查 Npcap 驱动和安装时的访问设置,再重新启动后端。 Npcap 用户指南

驱动或网卡可能移除 VLAN 标签,导致本机抓包看不到标签。需要确认线上的标签时,可使用能保留 VLAN 标签的对端抓包接口,或使用保留标签的交换机镜像口。 Wireshark VLAN 抓包说明

按现象定位 ​

现场现象核对顺序
启动接收时提示原始套接字权限不足Linux 核对实际后端进程的 CAP_NET_RAW 及其网络命名空间。Windows 核对 Npcap 驱动、访问权限和所选适配器
指定网卡抓不到本机发布帧确认发布已启用、选中的网卡处于可用状态、抓包绑定同一网卡,再检查发布日志。发布状态和抓到实际帧是两项独立证据
旧版 Linux 能抓到带标签的出站帧,订阅计数为零确认是否仍在使用 libiec61850 接收路径。更新含本修复的后端后,启动日志应显示 GOOSE Receiver 已启动 (AF_PACKET)
更新后能抓到帧,订阅计数仍为零核对本地订阅已启用,订阅网卡一致,goCbRef 完全相同,APPID 和目的 MAC 与帧一致
订阅有接收记录,成员值或版本不符比对帧中的 datSet、confRev、成员个数及顺序,检查订阅使用的 SCL 模型
本机自收正常,对端仍收不到在对端或交换机镜像口抓包,核对端口 VLAN、标签处理和二层组播转发。自收只验证本机发布与订阅链路

自动化验证范围 ​

回归测试模拟 Linux 原始套接字,分别注入无标签帧、VID 0 优先级标签帧和 VID 100 帧。测试检查绑定的网卡、订阅匹配、数据集历史和事件时标,并验证短帧以及 APPID 或目的 MAC 不匹配的帧不会更新订阅。

bash
python -m pytest tests/protocols/iec61850/goose/test_capture_subscriber.py -q

该测试覆盖应用的收包和解析流程。网卡驱动是否提供出站帧副本,以及跨主机的 VLAN 标签和转发行为,需要按上面的实机步骤验证。

评论与讨论

Released under the Apache 2.0 License.