Skip to content

Commit f5b41b9

Browse files
Implement ALLOCATE_ENDPOINT_ID support for bridges
Add implementation for the MCTP ALLOCATE_ENDPOINT_ID control command to enable bridges to allocate EID pools for downstream endpoints. - Add endpoint_send_allocate_endpoint_id() for sending allocation requests - Add get_pool_start() to find contiguous available EIDs of required pool size - Integrate allocation of dynamic eid for downstream endpoints of bridge with AssignEndpoint and AssignEndpointStatic and SetEndpointID d-bus methods Signed-off-by: Faizan Ali <faizana@nvidia.com>
1 parent 2db04f0 commit f5b41b9

1 file changed

Lines changed: 161 additions & 1 deletion

File tree

src/mctpd.c

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ static int del_local_eid(struct ctx *ctx, uint32_t net, int eid);
250250
static int add_net(struct ctx *ctx, uint32_t net);
251251
static void del_net(struct net *net);
252252
static int add_interface(struct ctx *ctx, int ifindex);
253+
static int endpoint_allocate_eid(struct peer *peer);
253254

254255
static const sd_bus_vtable bus_endpoint_obmc_vtable[];
255256
static const sd_bus_vtable bus_endpoint_cc_vtable[];
@@ -2033,6 +2034,20 @@ static int method_setup_endpoint(sd_bus_message *call, void *data, sd_bus_error
20332034
if (ctx->verbose)
20342035
fprintf(stderr, "%s returning from endpoint_assign_eid %s\n",
20352036
__func__, peer_tostr(peer));
2037+
if (peer->pool_size > 0) {
2038+
// Dynamic pool EID starts after bridge's EID
2039+
peer->pool_start = peer->eid + 1;
2040+
// Call for Allocate EndpointID
2041+
rc = endpoint_allocate_eid(peer);
2042+
if (rc < 0) {
2043+
warnx("Failed to allocate downstream EIDs");
2044+
} else {
2045+
if (peer->ctx->verbose) {
2046+
fprintf(stderr, "Downstream EIDs assigned from %d to %d : pool size %d\n",
2047+
peer->pool_start, peer->pool_start + peer->pool_size - 1, peer->pool_size);
2048+
}
2049+
}
2050+
}
20362051
return sd_bus_reply_method_return(call, "yisb",
20372052
peer->eid, peer->net, peer_path, 1);
20382053

@@ -2087,6 +2102,15 @@ static int method_assign_endpoint(sd_bus_message *call, void *data, sd_bus_error
20872102
// Dynamic pool EID starts after bridge's EID
20882103
peer->pool_start = peer->eid + 1;
20892104
// Call for Allocate EndpointID
2105+
rc = endpoint_allocate_eid(peer);
2106+
if (rc < 0) {
2107+
warnx("Failed to allocate downstream EIDs");
2108+
} else {
2109+
if (peer->ctx->verbose) {
2110+
fprintf(stderr, "Downstream EIDs assigned from %d to %d : pool size %d\n",
2111+
peer->pool_start, peer->pool_start + peer->pool_size - 1, peer->pool_size);
2112+
}
2113+
}
20902114
}
20912115

20922116
return sd_bus_reply_method_return(call, "yisb",
@@ -2164,6 +2188,15 @@ static int method_assign_endpoint_static(sd_bus_message *call, void *data,
21642188
// Dynamic pool EID starts after bridge's EID
21652189
peer->pool_start = peer->eid + 1;
21662190
// Call for Allocate EndpointID
2191+
rc = endpoint_allocate_eid(peer);
2192+
if (rc < 0) {
2193+
warnx("Failed to allocate downstream EIDs");
2194+
} else {
2195+
if (peer->ctx->verbose) {
2196+
fprintf(stderr, "Downstream EIDs assigned from %d to %d : pool size %d\n",
2197+
peer->pool_start, peer->pool_start + peer->pool_size - 1, peer->pool_size);
2198+
}
2199+
}
21672200
}
21682201

21692202
return sd_bus_reply_method_return(call, "yisb",
@@ -2196,7 +2229,6 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
21962229
if (rc < 0)
21972230
return sd_bus_error_setf(berr, SD_BUS_ERROR_INVALID_ARGS,
21982231
"Bad physaddr");
2199-
22002232
rc = get_endpoint_peer(ctx, berr, dest, &peer, &eid);
22012233
if (rc == -EEXIST) {
22022234
/* We have a conflict with an existing endpoint, so can't
@@ -2308,6 +2340,15 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
23082340
peer->pool_size = min(peer->pool_size, pool_size);
23092341

23102342
//call for Allocate EndpointID
2343+
rc = endpoint_allocate_eid(peer);
2344+
if (rc < 0) {
2345+
msg_len += snprintf(msg + msg_len, sizeof(msg) - msg_len,
2346+
". Failed to allocate downstream EIDs");
2347+
} else {
2348+
msg_len += snprintf(msg + msg_len, sizeof(msg) - msg_len,
2349+
". Downstream EIDs assigned from %d to %d : pool size %d",
2350+
peer->pool_start, peer->pool_start + peer->pool_size - 1, peer->pool_size);
2351+
}
23112352
}
23122353

23132354
return sd_bus_reply_method_return(call, "yisbs",
@@ -2876,6 +2917,7 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
28762917
SD_BUS_PARAM(found),
28772918
method_learn_endpoint,
28782919
0),
2920+
28792921
SD_BUS_METHOD_WITH_NAMES("AssignBridgeStatic",
28802922
"ayyyy",
28812923
SD_BUS_PARAM(physaddr)
@@ -3964,6 +4006,124 @@ static void free_config(struct ctx *ctx)
39644006
free(ctx->config_filename);
39654007
}
39664008

4009+
static int endpoint_send_allocate_endpoint_id(struct peer *peer,
4010+
mctp_eid_t eid_start, uint8_t eid_pool_size, mctp_ctrl_cmd_alloc_eid_op oper,
4011+
uint8_t *allocated_pool_size, mctp_eid_t *allocated_pool_start)
4012+
{
4013+
struct sockaddr_mctp_ext addr;
4014+
struct mctp_ctrl_cmd_alloc_eid req = {0};
4015+
struct mctp_ctrl_resp_alloc_eid *resp = NULL;
4016+
uint8_t *buf = NULL;
4017+
size_t buf_size;
4018+
uint8_t iid, stat;
4019+
int rc;
4020+
4021+
iid = mctp_next_iid(peer->ctx);
4022+
req.ctrl_hdr.rq_dgram_inst = RQDI_REQ | iid;
4023+
req.ctrl_hdr.command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS;
4024+
req.alloc_eid_op = (uint8_t)(oper & 0x03);
4025+
req.pool_size = eid_pool_size;
4026+
req.start_eid = eid_start;
4027+
rc = endpoint_query_peer(peer, MCTP_CTRL_HDR_MSG_TYPE, &req, sizeof(req),
4028+
&buf, &buf_size, &addr);
4029+
if (rc < 0)
4030+
goto out;
4031+
4032+
rc = mctp_ctrl_validate_response(buf, buf_size, sizeof(*resp),
4033+
peer_tostr_short(peer), iid,
4034+
MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS);
4035+
4036+
if (rc)
4037+
goto out;
4038+
4039+
resp = (void *)buf;
4040+
if (!resp) {
4041+
warnx("%s Invalid response Buffer\n", __func__);
4042+
return -ENOMEM;
4043+
}
4044+
4045+
stat = resp->status & 0x03;
4046+
if (stat == 0x00) {
4047+
if(peer->ctx->verbose) {
4048+
fprintf(stderr, "%s Allocation Accepted \n", __func__);
4049+
}
4050+
}
4051+
else if (stat == 0x1) {
4052+
warnx("%s Allocation was rejected as it was Allocated by other bus \n", __func__);
4053+
}
4054+
4055+
*allocated_pool_size = resp->eid_pool_size;
4056+
*allocated_pool_start = resp->eid_set;
4057+
if(peer->ctx->verbose) {
4058+
fprintf(stderr, "%s Allocated size of %d, starting from EID %d\n", __func__,
4059+
resp->eid_pool_size, resp->eid_set);
4060+
}
4061+
4062+
return 0;
4063+
out:
4064+
free(buf);
4065+
return rc;
4066+
}
4067+
4068+
static mctp_eid_t get_pool_start(struct peer *peer, mctp_eid_t eid_start, uint8_t pool_size)
4069+
{
4070+
uint8_t count = 0;
4071+
mctp_eid_t pool_start = eid_alloc_max;
4072+
struct net *n = lookup_net(peer->ctx, peer->net);
4073+
4074+
if (!n) {
4075+
warnx("BUG: Unknown net %d : failed to get pool start\n", peer->net);
4076+
return eid_alloc_max;
4077+
}
4078+
4079+
for (mctp_eid_t e = eid_start; e <= eid_alloc_max; e++) {
4080+
if (n->peers[e] == NULL) {
4081+
if(pool_start == eid_alloc_max) {
4082+
pool_start = e;
4083+
}
4084+
count++;
4085+
if (count == pool_size) return pool_start;
4086+
} else {
4087+
pool_start = eid_alloc_max;
4088+
count = 0;
4089+
}
4090+
}
4091+
4092+
return eid_alloc_max;
4093+
}
4094+
4095+
static int endpoint_allocate_eid(struct peer* peer)
4096+
{
4097+
uint8_t allocated_pool_size = 0;
4098+
mctp_eid_t allocated_pool_start = 0;
4099+
int rc = 0;
4100+
4101+
/* Find pool sized contiguous unused eids to allocate on the bridge. */
4102+
peer->pool_start = get_pool_start(peer, peer->pool_start, peer->pool_size);
4103+
if (peer->pool_start == eid_alloc_max) {
4104+
warnx("%s failed to find contiguous EIDs of required size", __func__);
4105+
return -1;
4106+
} else {
4107+
if (peer->ctx->verbose)
4108+
fprintf(stderr, "%s Asking for contiguous EIDs for pool with start eid : %d\n", __func__, peer->pool_start);
4109+
}
4110+
4111+
rc = endpoint_send_allocate_endpoint_id(peer, peer->pool_start, peer->pool_size,
4112+
mctp_ctrl_cmd_alloc_eid_alloc_eid, &allocated_pool_size, &allocated_pool_start);
4113+
if (rc) {
4114+
warnx("%s failed to allocate endpoints, returned %s %d\n",
4115+
__func__, strerror(-rc), rc);
4116+
} else {
4117+
peer->pool_size = allocated_pool_size;
4118+
peer->pool_start = allocated_pool_start;
4119+
4120+
// add Gateway route for all Bridge's downstream eids
4121+
// Polling logic for downstream EID
4122+
}
4123+
4124+
return rc;
4125+
}
4126+
39674127
int main(int argc, char **argv)
39684128
{
39694129
struct ctx ctxi = {0}, *ctx = &ctxi;

0 commit comments

Comments
 (0)