Skip to content

Commit ce42b09

Browse files
committed
Merge branch 'dev/vdm-msg-type-support'
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
2 parents d47e9ee + aaba669 commit ce42b09

4 files changed

Lines changed: 105 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1717

1818
1. Fixed `mctp-bench` compile on musl libc
1919

20+
### Changed
21+
22+
1. `mctpd`'s `RegisterTypeSupport` dbus method will no longer allow the
23+
VDM messaging types (0x7e and 0x7f) to be registered, as these do not
24+
make sense without a corresponding VDM type registration.
25+
26+
Registering a VDM type will automatically include the corresponding VDM type
27+
in the Get Message Type Support response.
28+
2029
### Added
2130

2231
1. `mctpd` now implements the Get Vendor Define Message Support control protocol

docs/mctpd.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ If the message type is already registered, then dbus call will fail.
5050
- `<versions>` Versions supported for this message type formatted as uint32
5151
integers as specified in DSP0236
5252

53+
The `msg_type` value must be a valid message type, and cannot be one of the
54+
VDM types (0x7e or 0x7f). Those VDM types are handled by the
55+
`RegisterVDMTypeSupport` method instead.
56+
5357
De-registration is automatic - the specified types (and versions) are registered
5458
for as long as the dbus sender remains attached to the message bus, and are
5559
unregistered on disconnect.
@@ -72,6 +76,9 @@ If the VDM type is already registered, then dbus call will fail.
7276
- For IANA format: 32-bit unsigned integer (`u`)
7377
- `<command set type>` Command set type (16-bit unsigned integer) as defined by the vendor
7478

79+
Registering a VDM type will cause the corresponding VDM type value (0x7e or
80+
0x7f) to be returned in mctpd's Get Message Type Support response.
81+
7582
De-registration is automatic - the specified VDM types are registered for as
7683
long as the dbus sender remains attached to the message bus, and are
7784
removed when the sender disconnects.

src/mctpd.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ static const char *conf_file_default = MCTPD_CONF_FILE_DEFAULT;
6161

6262
static const mctp_eid_t eid_alloc_min = 0x08;
6363
static const mctp_eid_t eid_alloc_max = 0xfe;
64+
static const uint8_t MCTP_TYPE_VENDOR_PCIE = 0x7e;
65+
static const uint8_t MCTP_TYPE_VENDOR_IANA = 0x7f;
6466

6567
// arbitrary sanity
6668
static size_t MAX_PEER_SIZE = 1000000;
@@ -981,6 +983,7 @@ static int handle_control_get_message_type_support(
981983
{
982984
struct mctp_ctrl_resp_get_msg_type_support *resp = NULL;
983985
struct mctp_ctrl_cmd_get_msg_type_support *req = NULL;
986+
bool pcie_support = false, iana_support = false;
984987
size_t i, resp_len, type_count;
985988
uint8_t *resp_buf, *msg_types;
986989
int rc;
@@ -992,6 +995,15 @@ static int handle_control_get_message_type_support(
992995

993996
req = (void *)buf;
994997
type_count = ctx->num_supported_msg_types;
998+
999+
for (i = 0; i < ctx->num_supported_vdm_types; i++) {
1000+
pcie_support |= ctx->supported_vdm_types[i].format ==
1001+
VID_FORMAT_PCIE;
1002+
iana_support |= ctx->supported_vdm_types[i].format ==
1003+
VID_FORMAT_IANA;
1004+
}
1005+
type_count += (pcie_support + iana_support);
1006+
9951007
// Allocate extra space for the message types
9961008
resp_len = sizeof(*resp) + type_count;
9971009
resp_buf = malloc(resp_len);
@@ -1004,13 +1016,19 @@ static int handle_control_get_message_type_support(
10041016
mctp_ctrl_msg_hdr_init_resp(&resp->ctrl_hdr, req->ctrl_hdr);
10051017
resp->completion_code = MCTP_CTRL_CC_SUCCESS;
10061018

1007-
resp->msg_type_count = type_count;
10081019
// Append message types after msg_type_count
10091020
msg_types = (uint8_t *)(resp + 1);
1010-
for (i = 0; i < type_count; i++) {
1021+
for (i = 0; i < ctx->num_supported_msg_types; i++) {
10111022
msg_types[i] = ctx->supported_msg_types[i].msg_type;
10121023
}
1024+
if (pcie_support) {
1025+
msg_types[i++] = MCTP_TYPE_VENDOR_PCIE;
1026+
}
1027+
if (iana_support) {
1028+
msg_types[i++] = MCTP_TYPE_VENDOR_IANA;
1029+
}
10131030

1031+
resp->msg_type_count = type_count;
10141032
rc = reply_message(ctx, sd, resp, resp_len, addr);
10151033
free(resp_buf);
10161034

@@ -3587,6 +3605,10 @@ static int method_register_type_support(sd_bus_message *call, void *data,
35873605
rc = sd_bus_message_read(call, "y", &msg_type);
35883606
if (rc < 0)
35893607
goto err;
3608+
if (msg_type == 0 || msg_type >= MCTP_TYPE_VENDOR_PCIE) {
3609+
return sd_bus_error_setf(berr, SD_BUS_ERROR_INVALID_ARGS,
3610+
"Invalid message type %d", msg_type);
3611+
}
35903612
rc = sd_bus_message_read_array(call, 'u', (const void **)&versions,
35913613
&versions_len);
35923614
if (rc < 0)

tests/test_mctpd.py

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,14 @@ async def test_get_message_types(dbus, mctpd, routed_ep):
12691269
mctp = await mctpd_mctp_base_iface_obj(dbus)
12701270
await mctp.call_register_type_support(5, [0xF1F2F3F4])
12711271

1272+
# Verify invalid msg type causes error
1273+
with pytest.raises(asyncdbus.errors.DBusError) as ex:
1274+
await mctp.call_register_type_support(0x0, [0xF1F2F3F4])
1275+
assert str(ex.value) == "Invalid message type 0"
1276+
with pytest.raises(asyncdbus.errors.DBusError) as ex:
1277+
await mctp.call_register_type_support(0x7e, [0xF1F2F3F4])
1278+
assert str(ex.value) == "Invalid message type 126"
1279+
12721280
# Verify get message type response includes spdm
12731281
cmd = MCTPControlCommand(True, 0, 0x05, bytes([0x00]))
12741282
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
@@ -1297,6 +1305,11 @@ async def test_register_vdm_type_support_pcie_only(dbus, mctpd, routed_ep):
12971305
v_type = asyncdbus.Variant('q', 0xABCD)
12981306
await mctp.call_register_vdm_type_support(0x00, v_type, 0x0001)
12991307

1308+
# Verify Get Message Type Support response includes PCI VDM type
1309+
cmd = MCTPControlCommand(True, 0, 0x05, bytes([0x00]))
1310+
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1311+
assert rsp.hex(' ') == '00 05 00 02 00 7e'
1312+
13001313
# Verify PCIe VDM (selector 0)
13011314
cmd = MCTPControlCommand(True, 0, 0x06, bytes([0x00]))
13021315
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
@@ -1316,11 +1329,46 @@ async def test_register_vdm_type_support_iana_only(dbus, mctpd, routed_ep):
13161329
v_type = asyncdbus.Variant('u', 0x1234ABCD)
13171330
await mctp.call_register_vdm_type_support(0x01, v_type, 0x5678)
13181331

1332+
# Verify Get Message Type Support response includes IANA VDM type
1333+
cmd = MCTPControlCommand(True, 0, 0x05, bytes([0x00]))
1334+
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1335+
assert rsp.hex(' ') == '00 05 00 02 00 7f'
1336+
13191337
# Verify IANA VDM (selector 0)
13201338
cmd = MCTPControlCommand(True, 0, 0x06, bytes([0x00]))
13211339
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
13221340
assert rsp.hex(' ') == '00 06 00 ff 01 12 34 ab cd 56 78'
13231341

1342+
""" Test RegisterVDMTypeSupport when both IANA and PCI types are registered """
1343+
async def test_register_vdm_type_support_both(dbus, mctpd, routed_ep):
1344+
ep = routed_ep
1345+
mctp = await mctpd_mctp_base_iface_obj(dbus)
1346+
1347+
# Register IANA VDM: format=0x01, VID=0x1234ABCD, command_set=0x5678
1348+
v_type = asyncdbus.Variant('u', 0x1234ABCD)
1349+
await mctp.call_register_vdm_type_support(0x01, v_type, 0x5678)
1350+
1351+
# Register PCI VDM: format=0x00, VID=0xABCD, command_set=0x5678
1352+
v_type = asyncdbus.Variant('q', 0xABCD)
1353+
await mctp.call_register_vdm_type_support(0x00, v_type, 0x5678)
1354+
1355+
# Verify Get Message Type Support response includes both VDM types
1356+
cmd = MCTPControlCommand(True, 0, 0x05, bytes([0x00]))
1357+
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1358+
assert rsp.hex(' ') == '00 05 00 03 00 7e 7f'
1359+
1360+
# we assume ordering of IANA vs PCI here, but current mctpd will
1361+
# preserve that.
1362+
# Verify IANA VDM (selector 0)
1363+
cmd = MCTPControlCommand(True, 0, 0x06, bytes([0x00]))
1364+
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1365+
assert rsp.hex(' ') == '00 06 00 01 01 12 34 ab cd 56 78'
1366+
1367+
# Verify PCI VDM (selector 1)
1368+
cmd = MCTPControlCommand(True, 0, 0x06, bytes([0x01]))
1369+
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1370+
assert rsp.hex(' ') == '00 06 00 ff 00 ab cd 56 78'
1371+
13241372
""" Test RegisterVDMTypeSupport with dbus disconnect """
13251373
async def test_register_vdm_type_support_dbus_disconnect(mctpd, routed_ep):
13261374
ep = routed_ep
@@ -1333,14 +1381,24 @@ async def test_register_vdm_type_support_dbus_disconnect(mctpd, routed_ep):
13331381
async with asyncdbus.MessageBus().connect() as temp_bus:
13341382
mctp = await mctpd_mctp_base_iface_obj(temp_bus)
13351383

1336-
# Register PCIe VDM: format=0x00, VID=0xABCD, command_set=0x0001
1384+
# Register PCIe VDM: format=0x00, VID=0xABCD, command_set=1 and 2
13371385
v_type = asyncdbus.Variant('q', 0xABCD)
13381386
await mctp.call_register_vdm_type_support(0x00, v_type, 0x0001)
1387+
await mctp.call_register_vdm_type_support(0x00, v_type, 0x0002)
13391388

13401389
# Verify PCIe VDM (selector 0)
13411390
cmd = MCTPControlCommand(True, 0, 0x06, bytes([0x00]))
13421391
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1343-
assert rsp.hex(' ') == '00 06 00 ff 00 ab cd 00 01'
1392+
assert rsp.hex(' ') == '00 06 00 01 00 ab cd 00 01'
1393+
# Verify PCIe VDM (selector 1)
1394+
cmd = MCTPControlCommand(True, 0, 0x06, bytes([0x01]))
1395+
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1396+
assert rsp.hex(' ') == '00 06 00 ff 00 ab cd 00 02'
1397+
1398+
# Verify GetMsgType includes VDM
1399+
cmd = MCTPControlCommand(True, 0, 0x05)
1400+
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1401+
assert rsp.hex(' ') == '00 05 00 02 00 7e'
13441402

13451403
# Give mctpd a moment to process the disconnection
13461404
await trio.sleep(0.1)
@@ -1350,6 +1408,11 @@ async def test_register_vdm_type_support_dbus_disconnect(mctpd, routed_ep):
13501408
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
13511409
assert rsp.hex(' ') == '00 06 02' # Should be error again
13521410

1411+
# Verify GetMsgType has only control command
1412+
cmd = MCTPControlCommand(True, 0, 0x05)
1413+
rsp = await ep.send_control(mctpd.network.mctp_socket, cmd)
1414+
assert rsp.hex(' ') == '00 05 00 01 00'
1415+
13531416
""" Test RegisterVDMTypeSupport error handling """
13541417
async def test_register_vdm_type_support_errors(dbus, mctpd):
13551418
mctp = await mctpd_mctp_base_iface_obj(dbus)

0 commit comments

Comments
 (0)