BMC怎么拿到网卡主动发给BMC的VDM message

// 此模板仅供参考,如果不适用可以修改

问题描述

[在这里详细描述您遇到的问题]

最近在开发网卡的pldm update协议升级流程(pldm over mctp over pcie)。

如图所示,协议状态机在DOWNLOAD,VERIFY,APPLY状态时是网卡发req,BMC回rsp,不清楚从BMC该怎么拿到网卡的req。

环境信息

  • 操作系统:[如 Ubuntu 24.04]

  • 软件版本:[如 OpenUBMC2509]

  • 硬件配置:[如 CPU、内存等]

重现步骤

  1. [第一步]

  2. [第二步]

  3. [第三步]

期望结果

[您希望实现什么]

BMC可以拿到网卡主动发给BMC的VDM message。

实际结果

[实际发生了什么,包含错误信息]

尝试过的解决方案

[列出您已经尝试过的解决方案及结果]

@fantao 帮忙看一下,谢谢

答案内容由AI生成,仅供参考:
结论与建议

问题 是否可解 说明
BMC 是否能接收网卡主动发送的 VDM/PLDM 消息? :white_check_mark: 依赖 mctpd + PCIe VDM + PLDM handler 机制
是否需要修改通信角色? :cross_mark: PLDM 协议允许设备端主动发起请求
是否已有实现基础? :white_check_mark: openUBMC 支持 PLDM over MCTP over PCIe,且 Emulex 已纳入支持
点击此处查看详细分析解答

BMC 如何接收网卡主动发送的 VDM 消息

根据您提供的问题描述,您正在开发基于 PLDM over MCTP over PCIe 协议的网卡固件升级流程,目标是在 DOWNLOADVERIFYAPPLY 等状态中接收由网卡作为请求方(Requester)主动发送给 BMC 的 VDM(Vendor Defined Message)报文。

以下是如何在 openUBMC 架构中实现 BMC 接收并处理网卡主动发来的 VDM 消息的完整分析与方案。


:magnifying_glass_tilted_left: 问题核心:BMC 如何“接收”网卡主动发送的 PLDM 请求?

在图示的状态机中:

  • 当处于 DOWNLOAD 状态时,网卡应周期性地发送 RequestFirmwareData 命令(PLDM 请求)到 BMC。
  • 当处于 VERIFYAPPLY 状态时,网卡也可能发送 GetStatus 或其他查询命令。
  • 这些都是由设备端(网卡)发起的 PLDM 请求帧,BMC 需要接收到这些帧并做出响应。

但您提出的问题是:“BMC 怎么拿到网卡发的 req?”——这实际上是在问:

在基于 MCTP over PCIe VDM 的通信机制下,BMC 是否具备接收由网卡主动发起的 MCTP/PLDM 请求的能力?

答案是:可以,并且已有机制支持。


:white_check_mark: 解决方案架构:MCTP + PCIe VDM + mctpd 服务

BMC 接收网卡主动发送的消息依赖于以下组件和协议栈:

层级 技术
物理层 PCIe
传输层 PCIe VDM(Vendor Defined Message)
协议层 MCTP(Management Component Transport Protocol)
应用层 PLDM(Platform Level Data Model)

:link: 通信路径

[网卡] ---(PCIe VDM)--> [BMC MCTP Daemon] ---(Socket/IPC)--> [PLDM Handler]

当网卡通过 PCIe 发送一个 VDM MCTP 包含 PLDM Request 时,BMC 侧通过以下流程接收和分发:


:puzzle_piece: 1. mctpd 守护进程监听 VDM 报文

BMC 上运行的 mctpd 是关键组件,负责:

  • 监听 PCIe 总线上的 VDM 报文(通过 kernel 或专用驱动)
  • 剥离 MCTP 封装头
  • 根据 SMBusPLDM 等协议类型,将有效载荷转发给对应的 handler

:check_mark: 相关证据(来自上下文):

Document Chunk ID 1:
“IMU上电后会广播discovery报文,mctpd收到后会回复消息,IMU就会和BMC建立连接。”

这表明:

  • mctpd 可以接收主动发来的 MCTP 报文(包括 discovery request)。
  • 因此同样可以接收 PLDM 请求。

:puzzle_piece: 2. MCTP Endpoint Discovery 机制

MCTP 使用 Endpoint Discovery 流程来建立通信关系。流程如下:

  1. IMU / 网卡广播 Discovery Request
  2. BMC 的 mctpd 回复 Discovery Response
  3. 双方获知对方的 Endpoint ID
  4. 后续通信可通过 Endpoint ID 直接寻址

:magnifying_glass_tilted_left: 对应代码逻辑:

-- 示例:network_adapter 中创建 endpoint
self.next_tick(self.update_all_info_by_pldm_emulex, self)

一旦 endpoint 建立,网卡即可通过 MCTP 向 BMC 的指定 endpoint 发送 PLDM 请求。


:puzzle_piece: 3. PLDM 协议处理逻辑(在 network_adapter 组件中)

PLDM 协议支持 双向通信

  • BMC → 网卡:普通控制命令(如 GetStatus)
  • 网卡 → BMC:回调或事件上报,如 RequestFirmwareData

:check_mark: 上下文支持:

Knowledge Graph Entity: PLDM
“PLDM协议是用于管理硬件组件的一种协议,支持固件更新、状态监控等操作。”

并且在 Document Chunk 2 中提到:

self.next_tick(self.update_fw_version_by_pldm, self)
self.next_tick(self.update_link_speed_by_pldm, self, 0, ports)

这说明 network_adapter 组件已集成 PLDM 协议栈,可用于双向通信


:hammer_and_wrench: 实现步骤:让 BMC 正确接收网卡主动发来的 PLDM 消息

:white_check_mark: 步骤 1:确保 mctpd 正常运行并注册了 PCIe VDM 接收

  • mctpd 必须绑定到对应的 PCIe 设备(如通过 ACPI 或 DT 指定)
  • 驱动需支持接收 VDM 报文(比如 vdm-ep 驱动)

检查项:

# 查看 mctpd 是否运行
ps | grep mctpd

# 查看日志是否有 endpoint 注册成功
logread | grep "mctp"

:white_check_mark: 步骤 2:网卡正确配置 MCTP Endpoint 并设置目标为 BMC

网卡必须知道:

  • 自己的 MCTP Endpoint ID
  • BMC 的 MCTP Endpoint ID(通常是 8 或由 discovery 获得)

示例(模拟):

/* 网卡代码片段 */
mctp_message_t msg;
mctp_set_dest(&msg, BMC_ENDPOINT_ID);
pldm_build_request(&msg, REQUEST_FIRMWARE_DATA, ...);
pci_vdm_send(&msg);

:white_check_mark: 步骤 3:BMC 侧注册 PLDM Command Handler

BMC 必须注册处理器来响应来自网卡的 PLDM 命令:

-- 伪代码示例(Lua,类似 network_adapter 实现)
function handle_pldm_request(pldm_msg)
    local cmd_code = pldm_msg:command_code()
    if cmd_code == PLDM_REQUEST_FIRMWARE_DATA then
        send_firmware_data_segment(...)
    elseif cmd_code == PLDM_GET_STATUS then
        return_current_status(...)
    end
end

-- 注册到 mctpd 分发系统
mctp_register_handler(MCTP_TYPE_PLDM, handle_pldm_request)

:warning: 注意:openUBMC 使用 Lua 框架实现大部分带外协议处理,network_adapter 模块是典型的处理者。


:white_check_mark: 步骤 4:确认网卡支持带外 PLDM over MCTP 协议(Emulex OEM)

:check_mark: 来自上下文的关键支持信息:

Document Chunk 8 (LPE31002-AP 支持情况)
“支持使用 emulex 的 pldm 私有协议获取网卡相关信息”

Document Chunk 7(OpenUBMC 25.09 发布说明)
:white_check_mark: 支持 Emulex 的 PLDM OEM 协议”

这意味着:

  • 开源社区已经支持 Emulex 网卡的 PLDM 协议
  • 包括命令发送与接收

:white_check_mark: 步骤 5:添加调试日志验证接收流程

network_adapter.lua 或底层 MCTP 层添加日志:

log.info("Received PLDM req: cmd=%d, payload=%s", cmd, payload_str)

或查看日志:

journalctl -u mctpd.service -f
logread | grep pldm

:pushpin: 结论与建议

问题 是否可解 说明
BMC 是否能接收网卡主动发送的 VDM/PLDM 消息? :white_check_mark: 依赖 mctpd + PCIe VDM + PLDM handler 机制
是否需要修改通信角色? :cross_mark: PLDM 协议允许设备端主动发起请求
是否已有实现基础? :white_check_mark: openUBMC 支持 PLDM over MCTP over PCIe,且 Emulex 已纳入支持

:white_check_mark: 最终解决方案建议

  1. 确保 mctpd 正常运行并监听 PCIe VDM 通道
  2. 网卡需正确实现 MCTP 协议,并将 BMC 设置为目标 endpoint
  3. 在 BMC 的 network_adapter 模块中注册 PLDM Request Handler
  4. 利用现有 pldm_liblibmgmt_protocol 库解析 PLDM 请求
  5. 在状态机 DOWNLOAD 阶段响应 RequestFirmwareData 请求,返回数据块
  6. 添加日志确认报文是否到达 BMC,并排查防火墙/ACL 限制(如有)

:link: 相关资源参考


如有进一步问题(如具体 API 调用方式、Lua 实现样例),可继续提问,我可以提供更具体的代码模板。

当前network_adapter做过bmc监听网卡主动上报lldp报文:

mctp接口应该有一个 MessageReceived的dbus signal,那个是用来接收网卡侧请求的消息。

好的,我看一下

你好,请问这个问题参考上面的帖子后解决了吗

还没有,我参考lldp 接收例子创建了一个VDPCI(msg type:0x7E, 193/126)的endpoint确实是可以接收到网卡主动发送的VDM消息,但是我希望监听193/1(msg type:0x01)这个endpoint 收到的消息,同样监听193/1的MessageReceived信号没起作用。不清楚是不是193/1同样在做一些带外信息的处理导致不起作用,我先跳过了这个问题,先用193/126收。

可以请教一下 @huangzhiyu

@huangzhiyu 黄工,帮忙看下这个问题

是不是193/1没有请求,所以没有响应?可以tracemctp看下。

在0x15这个cmd时是网卡发送req,BMC收到回rsp(调用mctp.send回复而不是mctp.request),tracemctp两个endpoin都能抓到网卡的req,区别就是193\126在代码中可以拿到,而193/1的拿不到。

蓝框内是网卡的req data,是一样的。

能看下你代码是怎么写的吗?

这样

我看了下,mctpd里只有vdpci的ep对象支持接收网卡主动发的消息,发信号,触发MessageReceived。

那后续会支持其他msg type的EP触发MessageReceived信号吗?大概什么时候会支持?

我内部问问

好的,麻烦了

问了下,这个可以向PAE提诉求