-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mctpd: Send Discovery Notify on Endpoint role set #15
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2895,6 +2895,48 @@ static int bus_link_get_prop(sd_bus *bus, | |
return rc; | ||
} | ||
|
||
static int notify_discovery(ctx *ctx, int ifindex) | ||
{ | ||
int rc = 0; | ||
dest_phys desti = { 0 }, *dest = &desti; | ||
struct mctp_ctrl_cmd_discovery_notify req = { 0 }; | ||
struct mctp_ctrl_resp_discovery_notify *resp; | ||
uint8_t *buf; | ||
size_t buf_size; | ||
struct sockaddr_mctp_ext resp_addr; | ||
|
||
dest->ifindex = ifindex; | ||
mctp_nl_ifaddr_byindex(ctx->nl, dest->ifindex, &dest->hwaddr_len); | ||
memset(dest->hwaddr, 0, sizeof dest->hwaddr); | ||
|
||
req.ctrl_hdr.command_code = MCTP_CTRL_CMD_DISCOVERY_NOTIFY; | ||
req.ctrl_hdr.rq_dgram_inst = RQDI_REQ; | ||
|
||
rc = endpoint_query_phys(ctx, dest, MCTP_CTRL_HDR_MSG_TYPE, &req, | ||
sizeof(req), &buf, &buf_size, &resp_addr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if (rc < 0) | ||
goto free_buf; | ||
|
||
if (buf_size != sizeof(*resp)) { | ||
warnx("%s: wrong reply length %zu bytes. dest %s", __func__, | ||
buf_size, dest_phys_tostr(dest)); | ||
rc = -ENOMSG; | ||
goto free_buf; | ||
} | ||
resp = (void *)buf; | ||
|
||
if (resp->completion_code != 0) { | ||
// TODO: make this a debug message? | ||
warnx("Failure completion code 0x%02x from %s", | ||
resp->completion_code, dest_phys_tostr(dest)); | ||
rc = -ECONNREFUSED; | ||
goto free_buf; | ||
} | ||
free_buf: | ||
free(buf); | ||
return rc; | ||
} | ||
|
||
static int bus_link_set_prop(sd_bus *bus, | ||
const char *path, const char *interface, const char *property, | ||
sd_bus_message *value, void *userdata, sd_bus_error *berr) | ||
|
@@ -2906,6 +2948,7 @@ static int bus_link_set_prop(sd_bus *bus, | |
link_userdata *lmUserData; | ||
int rc; | ||
struct role role; | ||
int ifindex; | ||
|
||
if (!is_interfaces_path(path)) { | ||
sd_bus_error_setf(berr, SD_BUS_ERROR_INVALID_ARGS, | ||
|
@@ -2921,11 +2964,13 @@ static int bus_link_set_prop(sd_bus *bus, | |
goto out; | ||
} | ||
|
||
lmUserData = mctp_nl_get_link_userdata_byname(ctx->nl, link_name); | ||
if (!lmUserData) { | ||
ifindex = mctp_nl_ifindex_byname(ctx->nl, link_name); | ||
if (!ifindex) { | ||
rc = -ENOENT; | ||
goto out; | ||
} | ||
lmUserData = mctp_nl_get_link_userdata(ctx->nl, ifindex); | ||
assert(lmUserData); | ||
|
||
if (strcmp(property, "Role") != 0) { | ||
printf("Unknown property '%s' for %s iface %s\n", property, path, interface); | ||
|
@@ -2956,6 +3001,16 @@ static int bus_link_set_prop(sd_bus *bus, | |
} | ||
lmUserData->role = role.role; | ||
|
||
// Announce on the bus we are endpoint, print warning and ignore error if failed | ||
if (lmUserData->role == ENDPOINT_ROLE_ENDPOINT) { | ||
rc = notify_discovery(ctx, ifindex); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is done unconditionally, but Discovery Notify messages should only be sent on transport types that require them. We may need a way to query the transport type? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jk-ozlabs It would be great if we have that now (we need them to get control message timing information for the recovery mechanism on each interface anyway). I would propose adding such information to when a binding driver register itself to the MCTP networking subsystem inside the kernel ( static const struct mctp_netdev_ops mctp_i2c_mctp_ops = {
.transport = MCTP_TRANSPORT_SMBUS,
.release_flow = mctp_i2c_release_flow,
}; And then exposing them to userspace through netlink. I don't know how long it would take to merge the patch to linux, but in the meanwhile, we may temporarily provide such information in I could probably open a PR for this if you think this is ok. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, we'd need the kernel to provide the physical medium identifier. It doesn't belong in the ops struct, but there are certainly ways we can provide that to the Given that:
- then I would suggest that we add the infrastructure for Since the Discovery Notify is only required for the non-upstream transport, you'll need kernel patches anyway.
Interface names are not a stable API that we can rely on; they can be renamed arbitrarily. I'm happy to do the IFLA_MCTP_PHYS_MEDIUM support; drivers will just need a minor change to populate the type value. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That would be great 😀 Thank you! |
||
if (rc) { | ||
warnx("Warning: discovery notify on interface '%s' failed: %s", link_name, | ||
strerror(-rc)); | ||
rc = 0; | ||
} | ||
} | ||
|
||
out: | ||
set_berr(ctx, rc, berr); | ||
return rc; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A zero hwaddr is specific to PCIe, right? Do we also need to know the physical broadcast address for this link type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jk-ozlabs The MCTP base spec does not specify that, so I think this depends on the link. (And it is the "default" route to the bus owner, not specifically "broadcast").
As for PCIe, you actually need to specify a routing type before sending it to the bus (Route-to-Root-Complex, Broadcast-from-Root-Complex, Route-by-ID), which I don't find a way to put that in the sockaddr, so I pick the following addressing convention:
0x00:00
for "default route", which corresponds to Route-to-Root-Complex,0xFF:FF
for "broadcast route", which corresponds to Broadcast-from-Root-Complex,(Only Route-by-ID routing type will actually use the address, the formers will simply ignore the value per the PCIe or DSP0238 spec)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
phys addresses don't belong in the
struct sockaddr_mctp
, they would go into thesmctp_haddr
of thestruct sockaddr_mctp_ext
, which is just bytes. If you need the routing type represented in there as well, that's entirely possible too.But this sounds like review details on the driver itself, so probably not the best forum here :)
We do need to ensure we're using values that would work for any transport in future though, and an all-zero dest phys may not be suitable for those...