Skip to content

Commit 6744e5d

Browse files
committed
Merge branch 'discovery-messages' of github.com:khangng-ampere/mctp
Signed-off-by: Jeremy Kerr <[email protected]>
2 parents 2c009be + 67f8f16 commit 6744e5d

File tree

8 files changed

+273
-9
lines changed

8 files changed

+273
-9
lines changed

meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ conf.set10('HAVE_STRUCT_MCTP_FQ_ADDR',
2525
cc.has_type('struct mctp_fq_addr', prefix: '#include <linux/mctp.h>'),
2626
description: 'Is struct mctp_fq_addr available?'
2727
)
28+
conf.set10('HAVE_IFLA_MCTP_PHYS_BINDING',
29+
cc.has_header_symbol('linux/if_link.h', 'IFLA_MCTP_PHYS_BINDING'),
30+
description: 'Is IFLA_MCTP_PHYS_BINDING enum member available?'
31+
)
2832
conf.set10('MCTPD_RECOVER_NIL_UUID',
2933
get_option('unsafe-recover-nil-uuid'),
3034
description: 'Consider a nil UUID to be valid for endpoint recovery purposes',

src/mctp-control-spec.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,21 @@ static inline void mctp_ctrl_msg_hdr_init_resp(struct mctp_ctrl_msg_hdr *resp,
395395
resp->command_code = req.command_code;
396396
resp->rq_dgram_inst = (req.rq_dgram_inst & RQDI_IID_MASK) | RQDI_RESP;
397397
}
398+
399+
/* MCTP IDs and Codes from DMTF specification
400+
* "DSP0239 Management Component Transport Protocol (MCTP) IDs and Codes"
401+
* https://www.dmtf.org/sites/default/files/standards/documents/DSP0239_1.11.1.pdf
402+
*/
403+
enum mctp_phys_binding {
404+
MCTP_PHYS_BINDING_UNSPEC = 0x00,
405+
MCTP_PHYS_BINDING_SMBUS = 0x01,
406+
MCTP_PHYS_BINDING_PCIE_VDM = 0x02,
407+
MCTP_PHYS_BINDING_USB = 0x03,
408+
MCTP_PHYS_BINDING_KCS = 0x04,
409+
MCTP_PHYS_BINDING_SERIAL = 0x05,
410+
MCTP_PHYS_BINDING_I3C = 0x06,
411+
MCTP_PHYS_BINDING_MMBI = 0x07,
412+
MCTP_PHYS_BINDING_PCC = 0x08,
413+
MCTP_PHYS_BINDING_UCIE = 0x09,
414+
MCTP_PHYS_BINDING_VENDOR = 0xFF,
415+
};

src/mctp-netlink.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/rtnetlink.h>
1616
#include <linux/netdevice.h>
1717

18+
#include "mctp-control-spec.h"
1819
#include "mctp-netlink.h"
1920
#include "mctp.h"
2021
#include "mctp-util.h"
@@ -29,6 +30,7 @@ struct linkmap_entry {
2930
uint32_t min_mtu;
3031
uint32_t max_mtu;
3132
uint32_t hwaddr_len;
33+
uint8_t phys_binding;
3234

3335
mctp_eid_t *local_eids;
3436
size_t num_local;
@@ -59,7 +61,8 @@ static void sort_linkmap(mctp_nl *nl);
5961
static int linkmap_add_entry(mctp_nl *nl, struct ifinfomsg *info,
6062
const char *ifname, size_t ifname_len,
6163
uint32_t net, bool up, uint32_t min_mtu,
62-
uint32_t max_mtu, size_t hwaddr_len);
64+
uint32_t max_mtu, size_t hwaddr_len,
65+
uint8_t phys_binding);
6366
static struct linkmap_entry *entry_byindex(const mctp_nl *nl, int index);
6467

6568
static int open_nl_socket(void)
@@ -727,6 +730,7 @@ static int parse_getlink_dump(mctp_nl *nl, struct nlmsghdr *nlh, uint32_t len)
727730
char *ifname = NULL;
728731
size_t ifname_len, rlen, nlen, mlen, hwaddr_len;
729732
uint32_t net, min_mtu = 0, max_mtu = 0;
733+
uint8_t phys_binding;
730734
bool up;
731735

732736
if (nlh->nlmsg_type == NLMSG_DONE)
@@ -785,11 +789,14 @@ static int parse_getlink_dump(mctp_nl *nl, struct nlmsghdr *nlh, uint32_t len)
785789
hwaddr_len = 0;
786790
mctp_get_rtnlmsg_attr(IFLA_ADDRESS, rta, rlen, &hwaddr_len);
787791

788-
/* TODO: media type */
792+
/* Treat missing physical binding type attribute as UNSPEC */
793+
phys_binding = MCTP_PHYS_BINDING_UNSPEC;
794+
mctp_get_rtnlmsg_attr_u8(IFLA_MCTP_PHYS_BINDING, rt_mctp, mlen,
795+
&phys_binding);
789796

790797
up = info->ifi_flags & IFF_UP;
791798
linkmap_add_entry(nl, info, ifname, ifname_len, net, up,
792-
min_mtu, max_mtu, hwaddr_len);
799+
min_mtu, max_mtu, hwaddr_len, phys_binding);
793800
}
794801
// Not done.
795802
return 1;
@@ -1068,6 +1075,15 @@ int mctp_nl_hwaddr_len_byindex(const mctp_nl *nl, int index,
10681075
return 0;
10691076
}
10701077

1078+
uint8_t mctp_nl_phys_binding_byindex(const mctp_nl *nl, int index)
1079+
{
1080+
struct linkmap_entry *entry = entry_byindex(nl, index);
1081+
if (!entry) {
1082+
return MCTP_PHYS_BINDING_UNSPEC;
1083+
}
1084+
return entry->phys_binding;
1085+
}
1086+
10711087
mctp_eid_t *mctp_nl_addrs_byindex(const mctp_nl *nl, int index, size_t *ret_num)
10721088
{
10731089
struct linkmap_entry *entry = entry_byindex(nl, index);
@@ -1151,7 +1167,8 @@ bool mctp_nl_if_exists(const mctp_nl *nl, int ifindex)
11511167
static int linkmap_add_entry(mctp_nl *nl, struct ifinfomsg *info,
11521168
const char *ifname, size_t ifname_len,
11531169
uint32_t net, bool up, uint32_t min_mtu,
1154-
uint32_t max_mtu, size_t hwaddr_len)
1170+
uint32_t max_mtu, size_t hwaddr_len,
1171+
uint8_t phys_binding)
11551172
{
11561173
struct linkmap_entry *entry;
11571174
size_t newsz;
@@ -1192,6 +1209,7 @@ static int linkmap_add_entry(mctp_nl *nl, struct ifinfomsg *info,
11921209
entry->max_mtu = max_mtu;
11931210
entry->min_mtu = min_mtu;
11941211
entry->hwaddr_len = hwaddr_len;
1212+
entry->phys_binding = phys_binding;
11951213
return 0;
11961214
}
11971215

src/mctp-netlink.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/if.h>
77
#include <linux/rtnetlink.h>
88

9+
#include "mctp-control-spec.h"
910
#include "mctp.h"
1011

1112
struct mctp_nl;
@@ -83,6 +84,8 @@ uint32_t mctp_nl_max_mtu_byindex(const mctp_nl *nl, int index);
8384
/* Returns negative errno on failure */
8485
int mctp_nl_hwaddr_len_byindex(const mctp_nl *nl, int index,
8586
size_t *ret_hwaddr_len);
87+
/* Returns interface physical binding, or MCTP_PHYS_BINDING_UNSPEC if bad index */
88+
uint8_t mctp_nl_phys_binding_byindex(const mctp_nl *nl, int index);
8689
/* Caller to free */
8790
mctp_eid_t *mctp_nl_addrs_byindex(const mctp_nl *nl, int index,
8891
size_t *ret_num);

src/mctp.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,22 @@ struct sockaddr_mctp_ext {
8282
enum {
8383
IFLA_MCTP_UNSPEC,
8484
IFLA_MCTP_NET,
85+
IFLA_MCTP_PHYS_BINDING,
8586
__IFLA_MCTP_MAX,
8687
};
8788

8889
#define IFLA_MCTP_MAX (__IFLA_MCTP_MAX - 1)
8990

91+
#else /* IFLA_MCTP_MAX */
92+
93+
#if !HAVE_IFLA_MCTP_PHYS_BINDING
94+
enum {
95+
IFLA_MCTP_PHYS_BINDING = IFLA_MCTP_NET + 1,
96+
};
97+
#undef IFLA_MCTP_MAX
98+
#define IFLA_MCTP_MAX IFLA_MCTP_PHYS_BINDING
99+
#endif /* HAVE_IFLA_MCTP_PHYS_BINDING */
100+
90101
#endif /* IFLA_MCTP_MAX */
91102

92103
/* setsockopt(2) options */

src/mctpd.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,14 @@ static const struct role roles[] = {
119119
},
120120
};
121121

122+
enum discovery_state {
123+
DISCOVERY_UNSUPPORTED,
124+
DISCOVERY_DISCOVERED,
125+
DISCOVERY_UNDISCOVERED,
126+
};
127+
122128
struct link {
129+
enum discovery_state discovered;
123130
bool published;
124131
int ifindex;
125132
enum endpoint_role role;
@@ -786,6 +793,9 @@ static int handle_control_set_endpoint_id(struct ctx *ctx, int sd,
786793
warnx("ERR: cannot add bus owner to object lists");
787794
}
788795

796+
if (link_data->discovered != DISCOVERY_UNSUPPORTED) {
797+
link_data->discovered = DISCOVERY_DISCOVERED;
798+
}
789799
resp->status =
790800
SET_MCTP_EID_ASSIGNMENT_STATUS(MCTP_SET_EID_ACCEPTED) |
791801
SET_MCTP_EID_ALLOCATION_STATUS(MCTP_SET_EID_POOL_NONE);
@@ -795,6 +805,20 @@ static int handle_control_set_endpoint_id(struct ctx *ctx, int sd,
795805
return reply_message(ctx, sd, resp, resp_len, addr);
796806

797807
case MCTP_SET_EID_DISCOVERED:
808+
if (link_data->discovered == DISCOVERY_UNSUPPORTED) {
809+
resp->completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA;
810+
resp_len = sizeof(struct mctp_ctrl_resp);
811+
return reply_message(ctx, sd, resp, resp_len, addr);
812+
}
813+
814+
link_data->discovered = DISCOVERY_DISCOVERED;
815+
resp->status =
816+
SET_MCTP_EID_ASSIGNMENT_STATUS(MCTP_SET_EID_REJECTED) |
817+
SET_MCTP_EID_ALLOCATION_STATUS(MCTP_SET_EID_POOL_NONE);
818+
resp->eid_set = req->eid;
819+
resp->eid_pool_size = 0;
820+
return reply_message(ctx, sd, resp, resp_len, addr);
821+
798822
case MCTP_SET_EID_RESET:
799823
// unsupported
800824
resp->completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA;
@@ -957,6 +981,97 @@ handle_control_resolve_endpoint_id(struct ctx *ctx, int sd,
957981
return reply_message(ctx, sd, resp, resp_len, addr);
958982
}
959983

984+
static int handle_control_prepare_endpoint_discovery(
985+
struct ctx *ctx, int sd, const struct sockaddr_mctp_ext *addr,
986+
const uint8_t *buf, const size_t buf_size)
987+
{
988+
struct mctp_ctrl_msg_hdr *req = NULL;
989+
struct mctp_ctrl_resp_prepare_discovery respi = { 0 }, *resp = &respi;
990+
struct link *link_data;
991+
992+
if (buf_size < sizeof(*req)) {
993+
warnx("short Prepare for Endpoint Discovery message");
994+
return -ENOMSG;
995+
}
996+
997+
link_data = mctp_nl_get_link_userdata(ctx->nl, addr->smctp_ifindex);
998+
if (!link_data) {
999+
bug_warn("unconfigured interface %d", addr->smctp_ifindex);
1000+
return -ENOENT;
1001+
}
1002+
1003+
if (link_data->role == ENDPOINT_ROLE_BUS_OWNER) {
1004+
// ignore message if we are bus owner
1005+
return 0;
1006+
}
1007+
1008+
req = (void *)buf;
1009+
resp = (void *)resp;
1010+
mctp_ctrl_msg_hdr_init_resp(&resp->ctrl_hdr, *req);
1011+
1012+
if (link_data->discovered == DISCOVERY_UNSUPPORTED) {
1013+
warnx("received prepare for discovery request to unsupported interface %d",
1014+
addr->smctp_ifindex);
1015+
resp->completion_code = MCTP_CTRL_CC_ERROR_UNSUPPORTED_CMD;
1016+
return reply_message_phys(ctx, sd, resp,
1017+
sizeof(struct mctp_ctrl_resp), addr);
1018+
}
1019+
1020+
if (link_data->discovered == DISCOVERY_DISCOVERED) {
1021+
link_data->discovered = DISCOVERY_UNDISCOVERED;
1022+
warnx("clear discovered flag of interface %d",
1023+
addr->smctp_ifindex);
1024+
}
1025+
1026+
// we need to send using physical addressing, no entry in routing table yet
1027+
resp->completion_code = MCTP_CTRL_CC_SUCCESS;
1028+
return reply_message_phys(ctx, sd, resp, sizeof(*resp), addr);
1029+
}
1030+
1031+
static int
1032+
handle_control_endpoint_discovery(struct ctx *ctx, int sd,
1033+
const struct sockaddr_mctp_ext *addr,
1034+
const uint8_t *buf, const size_t buf_size)
1035+
{
1036+
struct mctp_ctrl_msg_hdr *req = NULL;
1037+
struct mctp_ctrl_resp_endpoint_discovery respi = { 0 }, *resp = &respi;
1038+
struct link *link_data;
1039+
1040+
if (buf_size < sizeof(*req)) {
1041+
warnx("short Endpoint Discovery message");
1042+
return -ENOMSG;
1043+
}
1044+
1045+
link_data = mctp_nl_get_link_userdata(ctx->nl, addr->smctp_ifindex);
1046+
if (!link_data) {
1047+
bug_warn("unconfigured interface %d", addr->smctp_ifindex);
1048+
return -ENOENT;
1049+
}
1050+
1051+
if (link_data->role == ENDPOINT_ROLE_BUS_OWNER) {
1052+
// ignore message if we are bus owner
1053+
return 0;
1054+
}
1055+
1056+
if (link_data->discovered == DISCOVERY_UNSUPPORTED) {
1057+
resp->completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA;
1058+
return reply_message(ctx, sd, resp,
1059+
sizeof(struct mctp_ctrl_resp), addr);
1060+
}
1061+
1062+
if (link_data->discovered == DISCOVERY_DISCOVERED) {
1063+
// if we are already discovered (i.e, assigned an EID), then no reply
1064+
return 0;
1065+
}
1066+
1067+
req = (void *)buf;
1068+
resp = (void *)resp;
1069+
mctp_ctrl_msg_hdr_init_resp(&resp->ctrl_hdr, *req);
1070+
1071+
// we need to send using physical addressing, no entry in routing table yet
1072+
return reply_message_phys(ctx, sd, resp, sizeof(*resp), addr);
1073+
}
1074+
9601075
static int handle_control_unsupported(struct ctx *ctx, int sd,
9611076
const struct sockaddr_mctp_ext *addr,
9621077
const uint8_t *buf, const size_t buf_size)
@@ -1039,6 +1154,14 @@ static int cb_listen_control_msg(sd_event_source *s, int sd, uint32_t revents,
10391154
rc = handle_control_resolve_endpoint_id(ctx, sd, &addr, buf,
10401155
buf_size);
10411156
break;
1157+
case MCTP_CTRL_CMD_PREPARE_ENDPOINT_DISCOVERY:
1158+
rc = handle_control_prepare_endpoint_discovery(ctx, sd, &addr,
1159+
buf, buf_size);
1160+
break;
1161+
case MCTP_CTRL_CMD_ENDPOINT_DISCOVERY:
1162+
rc = handle_control_endpoint_discovery(ctx, sd, &addr, buf,
1163+
buf_size);
1164+
break;
10421165
default:
10431166
if (ctx->verbose) {
10441167
warnx("Ignoring unsupported command code 0x%02x",
@@ -4150,10 +4273,13 @@ static int add_interface(struct ctx *ctx, int ifindex)
41504273
return -ENOENT;
41514274
}
41524275

4276+
uint8_t phys_binding = mctp_nl_phys_binding_byindex(ctx->nl, ifindex);
4277+
41534278
struct link *link = calloc(1, sizeof(*link));
41544279
if (!link)
41554280
return -ENOMEM;
41564281

4282+
link->discovered = DISCOVERY_UNSUPPORTED;
41574283
link->published = false;
41584284
link->ifindex = ifindex;
41594285
link->ctx = ctx;
@@ -4182,6 +4308,10 @@ static int add_interface(struct ctx *ctx, int ifindex)
41824308
bus_link_owner_vtable, link);
41834309
}
41844310

4311+
if (phys_binding == MCTP_PHYS_BINDING_PCIE_VDM) {
4312+
link->discovered = DISCOVERY_UNDISCOVERED;
4313+
}
4314+
41854315
link->published = true;
41864316
rc = emit_interface_added(link);
41874317
if (rc < 0) {

0 commit comments

Comments
 (0)