SSDP 功能使用指导

概述

本文档介绍 openUBMC SSDP (Simple Service Discovery Protocol) 功能的使用方法。SSDP 是应用层协议,是构成 UPnP(通用即插即用)技术的核心协议之一,为网络客户端提供了一种发现网络服务的机制。

认识 SSDP

SSDP 简介

SSDP(简单服务发现协议)采用基于通知和发现路由的多播方式实现。它是在 HTTPU 和 HTTPMU 的基础上实现的协议。

SSDP 工作原理

发现机制

当控制点(客户端)接入网络时,可以向特定的多播地址的 SSDP 端口使用 M-SEARCH 方法发送 "ssdp:discover" 消息。当设备监听到这个保留的多播地址上由控制点发送的消息时,设备会分析控制点请求的服务,如果自身提供了控制点请求的服务,设备将通过单播的方式直接响应控制点的请求。

通知机制

当设备接入网络时,它应当向特定的多播地址的 SSDP 端口使用 NOTIFY 方法发送 "ssdp:alive" 消息。控制点根据自己的策略处理监听到的消息。

"ssdp:alive" 消息必须在 HTTP 协议头 CACHE-CONTROL 里面指定超时值,设备必须在约定的超时值到达以前重发 "ssdp:alive" 消息。如果控制点在指定的超时值内没有再次收到设备发送的 "ssdp:alive" 消息,控制点将认为设备已经失效。

当设备计划从网络上卸载时,它应当向特定的多播地址的 SSDP 端口使用 NOTIFY 方法发送 "ssdp:byebye" 消息。

多播地址

IPv4 环境

SSDP 使用多播地址 239.255.255.250 和 UDP 端口号 1900

IPv6 环境

SSDP 使用多播地址 FF0X::C,这里的 X 根据 scope 的不同可以有不同的取值:

Scope地址描述
LinkFF02::C链路本地地址
SiteFF05::C站点本地地址
OrganizationFF08::C组织本地地址

SSDP 消息类型

消息类型方向描述
M-SEARCH客户端 → 组播地址发现请求,查询某种类型的服务
NOTIFY设备 → 组播地址存在通知,宣布设备存在

发现信息内容

发现结果和存在通知消息提供的信息包括:

信息项描述
服务类型 URI服务的类型标识
USN唯一服务名称,标识一种服务实例
位置信息包含一个或多个位置 URI,客户端用于找到服务
期限信息客户端在 cache 中保存此服务的时间

SSDP 资源树

资源树属性

属性名类型读/写描述
Typestring只读软件类型,openUBMC 为 __initialized.___bmc
EthernetInterfacestring只读使用的网口,期望只使用对外的网口
NotifyEnabledboolean读/写SSDP 服务消息多播使能状态
NotifyMulticastIntervalSecondsuint32读/写Alive 消息发送的时间间隔,最大 1800s;为 0 表示关闭 notify 功能
NotifyTTLuint32读/写SSDP hop count
IPv4Addrstring只读SSDP 组播 IPv4 地址(239.255.255.250)
IPv6Addrstring只读SSDP 组播 IPv6 地址(FF0X::C)
NotifyIPv6Scopestring读/写IPv6 scope,可选值为 Link、Site、Organization

查看资源树

使用 busctl 查看 SSDP 资源树

bash
busctl --user tree bmc.kepler.ssdp

查看 SSDP 对象

bash
busctl --user introspect bmc.kepler.ssdp /bmc/kepler/Managers/1/Ssdp/0

获取 SSDP 所有属性

bash
busctl --user call bmc.kepler.ssdp /bmc/kepler/Managers/1/Ssdp/0 org.freedesktop.DBus.Properties GetAll s bmc.kepler.Managers.SsdpConfig

SSDP 配置

接口说明

Redfish 接口

bash
# 查询 SSDP 配置
GET https://{bmc_ip}/redfish/v1/Managers/{ManagerId}/NetworkProtocol

# 更新 SSDP 配置
PATCH https://{bmc_ip}/redfish/v1/Managers/{ManagerId}/NetworkProtocol

CLI 接口

查询使能开关和端口号

bash
ipmcget -t service -d list

设置使能开关

bash
ipmcset -t service -d state -v SSDP enabled

设置端口号

bash
ipmcset -t service -d port -v SSDP 1900

启用 SSDP

通过 busctl 启用

bash
busctl --user set-property bmc.kepler.ssdp /bmc/kepler/Managers/1/Ssdp/0 bmc.kepler.Managers.SsdpConfig NotifyEnabled b true

通过 Redfish 启用

bash
PATCH https://{bmc_ip}/redfish/v1/Managers/{ManagerId}/NetworkProtocol

请求体:

json
{
    "SSDP": {
        "ProtocolEnabled": true
    }
}

配置 IPv6 Scope

通过 busctl 设置 IPv6 scope:

bash
# 设置为 Link(FF02::C)
busctl --user call bmc.kepler.ssdp /bmc/kepler/Managers/1/Ssdp/0 bmc.kepler.Managers.SsdpConfig SetNotifyIPv6Scope a{ss}s 0 "Link"

# 设置为 Site(FF05::C)
busctl --user call bmc.kepler.ssdp /bmc/kepler/Managers/1/Ssdp/0 bmc.kepler.Managers.SsdpConfig SetNotifyIPv6Scope a{ss}s 0 "Site"

# 设置为 Organization(FF08::C)
busctl --user call bmc.kepler.ssdp /bmc/kepler/Managers/1/Ssdp/0 bmc.kepler.Managers.SsdpConfig SetNotifyIPv6Scope a{ss}s 0 "Organization"

SSDP 报文

Alive 报文(Notification)

Alive 报文用于设备向组播地址通知自己的存在。

抓取 Alive 报文

bash
# 使用 tcpdump 抓取指定 IP 的报文
tcpdump ip host xx.xx.xx.xx and port 1900 -nn -X

Alive 报文示例

http
NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age = 1800
LOCATION: http://192.168.1.100/redfish/v1
NT: urn:dmtf-org:service:redfish:http:1
NTS: ssdp:alive
SERVER: openUBMC/1.0 UPnP/1.0
USN: uuid:12345678-1234-1234-1234-123456789abc::urn:dmtf-org:service:redfish:http:1

报文头说明

头名称描述示例值
HOST多播地址和端口239.255.255.250:1900
CACHE-CONTROL消息缓存时间(秒)max-age = 1800
LOCATION设备描述文档 URLhttp://192.168.1.100/redfish/v1
NT通知类型urn:dmtf-org:service:redfish:http:1
NTS通知子类型ssdp:alive、ssdp:byebye
SERVER服务器信息openUBMC/1.0 UPnP/1.0
USN唯一服务名称uuid:device-uuid::nt-value

M-SEARCH 报文

M-SEARCH 报文用于向组播地址发送,ProtocolEnabled 为 true 的 BMC 在监听到 M-SEARCH 报文后,会对发送 M-SEARCH 报文的客户端进行响应。

M-SEARCH 报文格式

http
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
ST: ssdp:all
MAN: "ssdp:discover"
MX: 3

报文头说明

头名称描述必须值
HOST多播地址和端口239.255.255.250:1900(IPv4)或 FF0x::C(IPv6)
MAN协议查询类型"ssdp:discover"
MX设备响应最长等待时间0 到此值之间随机选择响应延迟
ST服务查询目标见下表

ST(搜索目标)选项

选项含义
ssdp:all搜索所有设备和服务
upnp:rootdevice仅搜索网络中的根设备
uuid:device-UUID查询 UUID 标识的设备
urn:schemas-upnp-org:device:device-Type:version查询 device-Type 指定的设备类型
urn:schemas-upnp-org:service:service-Type:version查询 service-Type 指定的服务类型

M-SEARCH 响应报文

当 BMC 监听到发送至组播地址的 M-SEARCH 报文时,会以单播方式发送 M-SEARCH 响应报文。

响应报文示例

http
HTTP/1.1 200 OK
CACHE-CONTROL: max-age = 1800
LOCATION: http://192.168.1.100/redfish/v1
ST: urn:dmtf-org:service:redfish:http:1
SERVER: openUBMC/1.0 UPnP/1.0
USN: uuid:12345678-1234-1234-1234-123456789abc::urn:dmtf-org:service:redfish:http:1

抓取响应报文

bash
# 使用 tcpdump 抓取报文
tcpdump ip host xx.xx.xx.xx and port 1900 -nn -X

发送 M-SEARCH 报文

bash
# 使用 nc 发送 M-SEARCH 报文至组播地址
cat msearch.pcap | /dev/shm/busybox_x nc -w 1 -vu 239.255.255.250 1900

常见问题

无法发现设备

问题现象:发送 M-SEARCH 后没有收到响应

可能原因

  1. SSDP 功能未启用
  2. NotifyEnabled 为 false
  3. 网络不支持多播
  4. 防火墙阻止 SSDP 流量

解决方法

  1. 检查并启用 SSDP:busctl --user set-property bmc.kepler.ssdp /bmc/kepler/Managers/1/Ssdp/0 bmc.kepler.Managers.SsdpConfig NotifyEnabled b true
  2. 检查网络多播支持
  3. 配置防火墙规则
  4. 确认设备和客户端在同一网段

产品名显示为空

问题现象:SSDP 报文中产品名为空

可能原因: FruData 提供的产品名为空。

解决方法: 查询 fruid 为 0 的 fru 数据:

bash
# 参考命令
busctl --user introspect bmc.kepler.frudata /bmc/kepler/Systems/1/FruDatas/FruData_Fru0_010104

Alive 报文未发送

问题现象:无法收到 BMC 发送的 NOTIFY 消息

可能原因

  1. NotifyEnabled 为 false
  2. NotifyMulticastIntervalSeconds 设置为 0
  3. 网络多播未启用

解决方法

  1. 启用 Notify:busctl --user set-property bmc.kepler.ssdp /bmc/kepler/Managers/1/Ssdp/0 bmc.kepler.Managers.SsdpConfig NotifyEnabled b true
  2. 设置发送间隔:确保 NotifyMulticastIntervalSeconds 不为 0
  3. 启用网络多播

附录

参考资料