Skip to content

Commit 22a4f1c

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 - Update gateway route for downstream EIDs - Integrate allocation of dynamic eid for downstream endpoints of bridge with AssignEndpoint d-bus method Signed-off-by: Faizan Ali <[email protected]>
1 parent 9e1fc7c commit 22a4f1c

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

src/mctpd.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ static int del_local_eid(struct ctx *ctx, uint32_t net, int eid);
253253
static int add_net(struct ctx *ctx, uint32_t net);
254254
static void del_net(struct net *net);
255255
static int add_interface(struct ctx *ctx, int ifindex);
256+
static int endpoint_allocate_eid(struct peer *peer);
256257

257258
static const sd_bus_vtable bus_endpoint_obmc_vtable[];
258259
static const sd_bus_vtable bus_endpoint_cc_vtable[];
@@ -2251,6 +2252,18 @@ static int method_assign_endpoint(sd_bus_message *call, void *data,
22512252

22522253
if (peer->pool_size > 0) {
22532254
// Call for Allocate EndpointID
2255+
rc = endpoint_allocate_eid(peer);
2256+
if (rc < 0) {
2257+
warnx("Failed to allocate downstream EIDs");
2258+
} else {
2259+
if (peer->ctx->verbose) {
2260+
fprintf(stderr,
2261+
"Downstream EIDs assigned from %d to %d : pool size %d\n",
2262+
peer->pool_start,
2263+
peer->pool_start + peer->pool_size - 1,
2264+
peer->pool_size);
2265+
}
2266+
}
22542267
}
22552268

22562269
return sd_bus_reply_method_return(call, "yisb", peer->eid, peer->net,
@@ -4138,6 +4151,128 @@ static void free_config(struct ctx *ctx)
41384151
free(ctx->config_filename);
41394152
}
41404153

4154+
static int endpoint_send_allocate_endpoint_id(struct peer *peer,
4155+
mctp_eid_t eid_start,
4156+
uint8_t eid_pool_size,
4157+
mctp_ctrl_cmd_alloc_eid_op oper,
4158+
uint8_t *allocated_pool_size,
4159+
mctp_eid_t *allocated_pool_start)
4160+
{
4161+
struct sockaddr_mctp_ext addr;
4162+
struct mctp_ctrl_cmd_alloc_eid req = { 0 };
4163+
struct mctp_ctrl_resp_alloc_eid *resp = NULL;
4164+
uint8_t *buf = NULL;
4165+
size_t buf_size;
4166+
uint8_t iid, stat;
4167+
int rc;
4168+
4169+
iid = mctp_next_iid(peer->ctx);
4170+
req.ctrl_hdr.rq_dgram_inst = RQDI_REQ | iid;
4171+
req.ctrl_hdr.command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS;
4172+
req.alloc_eid_op = (uint8_t)(oper & 0x03);
4173+
req.pool_size = eid_pool_size;
4174+
req.start_eid = eid_start;
4175+
rc = endpoint_query_peer(peer, MCTP_CTRL_HDR_MSG_TYPE, &req,
4176+
sizeof(req), &buf, &buf_size, &addr);
4177+
if (rc < 0)
4178+
goto out;
4179+
4180+
rc = mctp_ctrl_validate_response(buf, buf_size, sizeof(*resp),
4181+
peer_tostr_short(peer), iid,
4182+
MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS);
4183+
4184+
if (rc)
4185+
goto out;
4186+
4187+
resp = (void *)buf;
4188+
if (!resp) {
4189+
warnx("%s Invalid response Buffer\n", __func__);
4190+
return -ENOMEM;
4191+
}
4192+
4193+
stat = resp->status & 0x03;
4194+
if (stat == 0x00) {
4195+
if (peer->ctx->verbose) {
4196+
fprintf(stderr, "%s Allocation Accepted \n", __func__);
4197+
}
4198+
if (resp->eid_pool_size != eid_pool_size ||
4199+
resp->eid_set != eid_start) {
4200+
warnx("Unexpected pool start %d pool size %d",
4201+
resp->eid_set, resp->eid_pool_size);
4202+
rc = -1;
4203+
goto out;
4204+
}
4205+
} else {
4206+
if (stat == 0x1)
4207+
warnx("%s Allocation was rejected: already allocated by other bus"
4208+
" pool start %d, pool size %d",
4209+
__func__, resp->eid_pool_size, resp->eid_set);
4210+
rc = -1;
4211+
goto out;
4212+
}
4213+
4214+
*allocated_pool_size = resp->eid_pool_size;
4215+
*allocated_pool_start = resp->eid_set;
4216+
if (peer->ctx->verbose) {
4217+
fprintf(stderr,
4218+
"%s Allocated size of %d, starting from EID %d\n",
4219+
__func__, resp->eid_pool_size, resp->eid_set);
4220+
}
4221+
4222+
out:
4223+
free(buf);
4224+
return rc;
4225+
}
4226+
4227+
static int endpoint_allocate_eid(struct peer *peer)
4228+
{
4229+
uint8_t allocated_pool_size = 0;
4230+
mctp_eid_t allocated_pool_start = 0;
4231+
int rc = 0;
4232+
4233+
/* Find pool sized contiguous unused eids to allocate on the bridge. */
4234+
if (peer->pool_start >= eid_alloc_max || peer->pool_start <= 0) {
4235+
warnx("%s Invalid Pool start %d", __func__, peer->pool_start);
4236+
return -1;
4237+
}
4238+
rc = endpoint_send_allocate_endpoint_id(
4239+
peer, peer->pool_start, peer->pool_size,
4240+
mctp_ctrl_cmd_alloc_eid_alloc_eid, &allocated_pool_size,
4241+
&allocated_pool_start);
4242+
if (rc) {
4243+
//reset peer pool
4244+
peer->pool_size = 0;
4245+
peer->pool_start = 0;
4246+
} else {
4247+
peer->pool_size = allocated_pool_size;
4248+
peer->pool_start = allocated_pool_start;
4249+
4250+
// add Gateway route for all Bridge's downstream eids
4251+
if (peer->pool_size > 0) {
4252+
struct mctp_fq_addr gw_addr;
4253+
gw_addr.net = peer->net;
4254+
gw_addr.eid = peer->eid;
4255+
rc = mctp_nl_route_add(peer->ctx->nl, peer->pool_start,
4256+
peer->pool_size - 1,
4257+
peer->phys.ifindex, &gw_addr,
4258+
peer->mtu);
4259+
if (rc < 0) {
4260+
warnx("Failed to add Gateway route for EID %d: %s",
4261+
gw_addr.eid, strerror(-rc));
4262+
// If the route already exists, continue polling
4263+
if (rc != -EEXIST) {
4264+
return rc;
4265+
} else {
4266+
rc = 0;
4267+
}
4268+
}
4269+
// TODO: Polling logic for downstream EID
4270+
}
4271+
}
4272+
4273+
return rc;
4274+
}
4275+
41414276
int main(int argc, char **argv)
41424277
{
41434278
struct ctx ctxi = { 0 }, *ctx = &ctxi;

0 commit comments

Comments
 (0)