Skip to content

Commit 65b1357

Browse files
committed
mctpd: add AssignEndpointPreferred for preferred EID
Add AssignEndpointPreferred to allow MCTP reactor to request a preferred EID for an endpoint. mctpd checks whether the requested EID is available before assigning it to the device. The policy for choosing preferred EID assignment or dynamic EID assignment is handled by MCTP reactor. This is used with the MCTP reactor flow that reads the MCTPEndpointID property from Entity Manager and decides whether to request the configured EID or fall back to dynamic EID assignment. Update the README, mctpd documentation, endpoint recovery documentation, and unit tests for the preferred EID assignment flow. Related: https://gerrit.openbmc.org/c/openbmc/entity-manager/+/91151 https://gerrit.openbmc.org/c/openbmc/dbus-sensors/+/91188 Signed-off-by: Henry Wu <Henry_Wu@quantatw.com>
1 parent 4e04aa7 commit 65b1357

5 files changed

Lines changed: 149 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ configuring remote endpoints on that bus:
8585
au.com.codeconstruct.MCTP.Interface1 interface - - -
8686
.AssignEndpoint method ay yisb -
8787
.AssignEndpointStatic method ayy yisb -
88+
.AssignEndpointPreferred method ayy yisb -
8889
.LearnEndpoint method ay yisb -
8990
.SetupEndpoint method ay yisb -
9091

docs/endpoint-recovery.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ root@cc-nvme-mi:~# busctl introspect au.com.codeconstruct.MCTP1 /au/com/codecons
180180
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
181181
au.com.codeconstruct.Interface1 interface - - -
182182
.AssignEndpoint method ay yisb -
183+
.AssignEndpointStatic method ayy yisb -
184+
.AssignEndpointPreferred method ayy yisb -
183185
.LearnEndpoint method ay yisb -
184186
.SetupEndpoint method ay yisb -
185187
org.freedesktop.DBus.Introspectable interface - - -

docs/mctpd.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ au.com.codeconstruct.MCTP.Interface1 interface - - -
138138
au.com.codeconstruct.MCTP.BusOwner1 interface - - -
139139
.AssignEndpoint method ay yisb -
140140
.AssignEndpointStatic method ayy yisb -
141+
.AssignEndpointPreferred method ayy yisb -
141142
.LearnEndpoint method ay yisb -
142143
.SetupEndpoint method ay yisb -
143144
```
@@ -203,6 +204,20 @@ This call will fail if the endpoint already has an EID, and that EID is
203204
different from `static-EID`, or if `static-EID` is already assigned to another
204205
endpoint.
205206

207+
#### `.AssignEndpointPreferred`: `ayy``yisb`
208+
209+
Similar to AssignEndpointStatic, but takes the additional EID argument as a
210+
preferred EID rather than a strict static assignment:
211+
212+
```
213+
AssignEndpointPreferred <hwaddr> <preferred-EID>
214+
```
215+
216+
If `<preferred-EID>` is available, it will be assigned to the endpoint. If that
217+
EID is already assigned to another endpoint, `mctpd` falls back to dynamic EID
218+
allocation. If the endpoint is already known to `mctpd`, the existing endpoint
219+
record is returned.
220+
206221
#### `.LearnEndpoint`: `ay``yisb`
207222

208223
Like SetupEndpoint but will not assign EIDs, will only query endpoints for a

src/mctpd.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3126,6 +3126,84 @@ static int method_assign_endpoint_static(sd_bus_message *call, void *data,
31263126
return rc;
31273127
}
31283128

3129+
static int method_assign_endpoint_preferred(sd_bus_message *call, void *data,
3130+
sd_bus_error *berr)
3131+
{
3132+
dest_phys desti, *dest = &desti;
3133+
const char *peer_path = NULL;
3134+
struct peer *peer = NULL;
3135+
struct link *link = data;
3136+
struct ctx *ctx = link->ctx;
3137+
uint8_t eid;
3138+
int rc;
3139+
3140+
dest->ifindex = link->ifindex;
3141+
if (dest->ifindex <= 0)
3142+
return sd_bus_error_setf(berr, SD_BUS_ERROR_INVALID_ARGS,
3143+
"Unknown MCTP interface");
3144+
3145+
rc = message_read_hwaddr(call, dest);
3146+
if (rc < 0)
3147+
goto err;
3148+
3149+
rc = sd_bus_message_read(call, "y", &eid);
3150+
if (rc < 0)
3151+
goto err;
3152+
3153+
rc = validate_dest_phys(ctx, dest);
3154+
if (rc < 0)
3155+
return sd_bus_error_setf(berr, SD_BUS_ERROR_INVALID_ARGS,
3156+
"Bad physaddr");
3157+
3158+
peer = find_peer_by_phys(ctx, dest);
3159+
if (peer) {
3160+
// Return existing record, even if it differs from the preferred EID.
3161+
peer_path = path_from_peer(peer);
3162+
if (!peer_path)
3163+
goto err;
3164+
3165+
return sd_bus_reply_method_return(call, "yisb", peer->eid,
3166+
peer->net, peer_path, 0);
3167+
} else {
3168+
uint32_t netid;
3169+
struct net *net;
3170+
3171+
netid = mctp_nl_net_byindex(ctx->nl, dest->ifindex);
3172+
net = lookup_net(ctx, netid);
3173+
peer = find_peer_by_addr(ctx, eid, netid);
3174+
if (peer || (net && is_eid_in_bridge_pool(net, ctx, eid))) {
3175+
if (peer) {
3176+
warnx("Preferred EID %d already in use by %s, using dynamic EID for %s",
3177+
eid, peer_tostr(peer),
3178+
dest_phys_tostr(dest));
3179+
} else {
3180+
warnx("Preferred EID %d is in a bridge pool, using dynamic EID for %s",
3181+
eid, dest_phys_tostr(dest));
3182+
}
3183+
rc = endpoint_assign_eid(ctx, berr, dest, &peer, 0,
3184+
true);
3185+
} else {
3186+
rc = endpoint_assign_eid(ctx, berr, dest, &peer, eid,
3187+
false);
3188+
}
3189+
if (rc < 0)
3190+
goto err;
3191+
}
3192+
3193+
if (peer->pool_size > 0)
3194+
endpoint_allocate_eids(peer);
3195+
3196+
peer_path = path_from_peer(peer);
3197+
if (!peer_path)
3198+
goto err;
3199+
3200+
return sd_bus_reply_method_return(call, "yisb", peer->eid, peer->net,
3201+
peer_path, 1);
3202+
err:
3203+
set_berr(ctx, rc, berr);
3204+
return rc;
3205+
}
3206+
31293207
static int method_learn_endpoint(sd_bus_message *call, void *data,
31303208
sd_bus_error *berr)
31313209
{
@@ -4055,6 +4133,18 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
40554133
method_assign_endpoint_static,
40564134
0),
40574135

4136+
SD_BUS_METHOD_WITH_NAMES("AssignEndpointPreferred",
4137+
"ayy",
4138+
SD_BUS_PARAM(physaddr)
4139+
SD_BUS_PARAM(eid),
4140+
"yisb",
4141+
SD_BUS_PARAM(eid)
4142+
SD_BUS_PARAM(net)
4143+
SD_BUS_PARAM(path)
4144+
SD_BUS_PARAM(new),
4145+
method_assign_endpoint_preferred,
4146+
0),
4147+
40584148
SD_BUS_METHOD_WITH_NAMES("LearnEndpoint",
40594149
"ay",
40604150
SD_BUS_PARAM(physaddr),

tests/test_mctpd.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,47 @@ async def test_assign_endpoint_static_conflict(dbus, mctpd):
409409
assert str(ex.value) == "Address in use"
410410

411411

412+
async def test_assign_endpoint_preferred_static(dbus, mctpd):
413+
"""Test that preferred assignment uses the requested EID when available"""
414+
iface = mctpd.system.interfaces[0]
415+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
416+
dev = mctpd.network.endpoints[0]
417+
preferred_eid = 12
418+
419+
(eid, _, _, new) = await mctp.call_assign_endpoint_preferred(
420+
dev.lladdr, preferred_eid
421+
)
422+
423+
assert eid == preferred_eid
424+
assert dev.eid == preferred_eid
425+
assert new
426+
427+
428+
async def test_assign_endpoint_preferred_conflict_falls_back(dbus, mctpd):
429+
"""Test that preferred assignment falls back to dynamic EID on conflict"""
430+
iface = mctpd.system.interfaces[0]
431+
mctp = await mctpd_mctp_iface_obj(dbus, iface)
432+
dev1 = mctpd.network.endpoints[0]
433+
dev2 = Endpoint(iface, bytes([0x1E]))
434+
preferred_eid = 12
435+
436+
mctpd.network.add_endpoint(dev2)
437+
438+
(eid1, _, _, new1) = await mctp.call_assign_endpoint_static(
439+
dev1.lladdr, preferred_eid
440+
)
441+
assert eid1 == preferred_eid
442+
assert new1
443+
444+
(eid2, _, _, new2) = await mctp.call_assign_endpoint_preferred(
445+
dev2.lladdr, preferred_eid
446+
)
447+
448+
assert eid2 != preferred_eid
449+
assert dev2.eid == eid2
450+
assert new2
451+
452+
412453
async def test_assign_endpoint_static_varies(dbus, mctpd):
413454
"""Test that we cannot re-assign a static EID to an endpoint that already
414455
has a different EID allocated

0 commit comments

Comments
 (0)