Skip to content

Commit 0c3c0dd

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 891db02 commit 0c3c0dd

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[];
@@ -2250,6 +2251,18 @@ static int method_assign_endpoint(sd_bus_message *call, void *data,
22502251

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

22552268
return sd_bus_reply_method_return(call, "yisb", peer->eid, peer->net,
@@ -4137,6 +4150,128 @@ static void free_config(struct ctx *ctx)
41374150
free(ctx->config_filename);
41384151
}
41394152

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

0 commit comments

Comments
 (0)