Skip to content

Commit 3c2f244

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. Update gateway route for downstream EIDs Signed-off-by: Faizan Ali <[email protected]>
1 parent bc91184 commit 3c2f244

File tree

1 file changed

+149
-1
lines changed

1 file changed

+149
-1
lines changed

src/mctpd.c

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ static int del_local_eid(struct ctx *ctx, uint32_t net, int eid);
252252
static int add_net(struct ctx *ctx, uint32_t net);
253253
static void del_net(struct net *net);
254254
static int add_interface(struct ctx *ctx, int ifindex);
255+
static int endpoint_allocate_eid(struct peer *peer);
255256

256257
static const sd_bus_vtable bus_endpoint_obmc_vtable[];
257258
static const sd_bus_vtable bus_endpoint_cc_vtable[];
@@ -2255,7 +2256,18 @@ static int method_assign_endpoint(sd_bus_message *call, void *data,
22552256
goto err;
22562257

22572258
if (peer->pool_size > 0) {
2258-
//TODO: Implement Allocate EndpointID
2259+
rc = endpoint_allocate_eid(peer);
2260+
if (rc < 0) {
2261+
warnx("Failed to allocate downstream EIDs");
2262+
} else {
2263+
if (peer->ctx->verbose) {
2264+
fprintf(stderr,
2265+
"Downstream EIDs assigned from %d to %d : pool size %d\n",
2266+
peer->pool_start,
2267+
peer->pool_start + peer->pool_size - 1,
2268+
peer->pool_size);
2269+
}
2270+
}
22592271
}
22602272

22612273
return sd_bus_reply_method_return(call, "yisb", peer->eid, peer->net,
@@ -2479,6 +2491,20 @@ static int peer_route_update(struct peer *peer, uint16_t type)
24792491
return mctp_nl_route_add(peer->ctx->nl, peer->eid, 0,
24802492
peer->phys.ifindex, NULL, peer->mtu);
24812493
} else if (type == RTM_DELROUTE) {
2494+
if (peer->pool_size > 0) {
2495+
int rc = 0;
2496+
struct mctp_fq_addr gw_addr = { 0 };
2497+
gw_addr.net = peer->net;
2498+
gw_addr.eid = peer->eid;
2499+
rc = mctp_nl_route_del(peer->ctx->nl, peer->pool_start,
2500+
peer->pool_size - 1,
2501+
peer->phys.ifindex, &gw_addr);
2502+
if (rc < 0)
2503+
warnx("failed to delete route for peer pool eids %d-%d %s",
2504+
peer->pool_start,
2505+
peer->pool_start + peer->pool_size - 1,
2506+
strerror(-rc));
2507+
}
24822508
return mctp_nl_route_del(peer->ctx->nl, peer->eid, 0,
24832509
peer->phys.ifindex, NULL);
24842510
}
@@ -4205,6 +4231,128 @@ static void free_config(struct ctx *ctx)
42054231
free(ctx->config_filename);
42064232
}
42074233

4234+
static int endpoint_send_allocate_endpoint_id(struct peer *peer,
4235+
mctp_eid_t eid_start,
4236+
uint8_t eid_pool_size,
4237+
mctp_ctrl_cmd_alloc_eid_op oper,
4238+
uint8_t *allocated_pool_size,
4239+
mctp_eid_t *allocated_pool_start)
4240+
{
4241+
struct sockaddr_mctp_ext addr;
4242+
struct mctp_ctrl_cmd_alloc_eid req = { 0 };
4243+
struct mctp_ctrl_resp_alloc_eid *resp = NULL;
4244+
uint8_t *buf = NULL;
4245+
size_t buf_size;
4246+
uint8_t iid, stat;
4247+
int rc;
4248+
4249+
iid = mctp_next_iid(peer->ctx);
4250+
mctp_ctrl_msg_hdr_init_req(&req.ctrl_hdr, iid,
4251+
MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS);
4252+
req.alloc_eid_op = (uint8_t)(oper & 0x03);
4253+
req.pool_size = eid_pool_size;
4254+
req.start_eid = eid_start;
4255+
rc = endpoint_query_peer(peer, MCTP_CTRL_HDR_MSG_TYPE, &req,
4256+
sizeof(req), &buf, &buf_size, &addr);
4257+
if (rc < 0)
4258+
goto out;
4259+
4260+
rc = mctp_ctrl_validate_response(buf, buf_size, sizeof(*resp),
4261+
peer_tostr_short(peer), iid,
4262+
MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS);
4263+
4264+
if (rc)
4265+
goto out;
4266+
4267+
resp = (void *)buf;
4268+
if (!resp) {
4269+
warnx("Invalid response buffer");
4270+
return -ENOMEM;
4271+
}
4272+
4273+
stat = resp->status & 0x03;
4274+
if (stat == 0x00) {
4275+
if (peer->ctx->verbose) {
4276+
fprintf(stderr, "Allocation accepted\n");
4277+
}
4278+
if (resp->eid_pool_size != eid_pool_size ||
4279+
resp->eid_set != eid_start) {
4280+
warnx("Unexpected pool start %d pool size %d",
4281+
resp->eid_set, resp->eid_pool_size);
4282+
rc = -1;
4283+
goto out;
4284+
}
4285+
*allocated_pool_size = resp->eid_pool_size;
4286+
*allocated_pool_start = resp->eid_set;
4287+
} else {
4288+
if (stat == 0x1)
4289+
warnx("Allocation was rejected: already allocated by other bus"
4290+
" pool size %d, pool start %d",
4291+
resp->eid_pool_size, resp->eid_set);
4292+
rc = -1;
4293+
goto out;
4294+
}
4295+
4296+
if (peer->ctx->verbose) {
4297+
fprintf(stderr, "Allocated size of %d, starting from EID %d\n",
4298+
resp->eid_pool_size, resp->eid_set);
4299+
}
4300+
4301+
out:
4302+
free(buf);
4303+
return rc;
4304+
}
4305+
4306+
static int endpoint_allocate_eid(struct peer *peer)
4307+
{
4308+
uint8_t allocated_pool_size = 0;
4309+
mctp_eid_t allocated_pool_start = 0;
4310+
int rc = 0;
4311+
4312+
if (peer->pool_start >= peer->ctx->dyn_eid_max ||
4313+
peer->pool_start <= 0) {
4314+
warnx("Invalid pool start %d", peer->pool_start);
4315+
return -1;
4316+
}
4317+
rc = endpoint_send_allocate_endpoint_id(
4318+
peer, peer->pool_start, peer->pool_size,
4319+
mctp_ctrl_cmd_alloc_eid_alloc_eid, &allocated_pool_size,
4320+
&allocated_pool_start);
4321+
if (rc) {
4322+
//reset peer pool
4323+
peer->pool_size = 0;
4324+
peer->pool_start = 0;
4325+
return rc;
4326+
} else {
4327+
peer->pool_size = allocated_pool_size;
4328+
peer->pool_start = allocated_pool_start;
4329+
4330+
// add gateway route for all bridge's downstream eids
4331+
if (peer->pool_size > 0) {
4332+
struct mctp_fq_addr gw_addr = { 0 };
4333+
gw_addr.net = peer->net;
4334+
gw_addr.eid = peer->eid;
4335+
rc = mctp_nl_route_add(peer->ctx->nl, peer->pool_start,
4336+
peer->pool_size - 1,
4337+
peer->phys.ifindex, &gw_addr,
4338+
peer->mtu);
4339+
if (rc < 0) {
4340+
warnx("Failed to add gateway route for EID %d: %s",
4341+
gw_addr.eid, strerror(-rc));
4342+
// If the route already exists, continue polling
4343+
if (rc == -EEXIST) {
4344+
rc = 0;
4345+
} else {
4346+
return rc;
4347+
}
4348+
}
4349+
// TODO: Polling logic for downstream EID
4350+
}
4351+
}
4352+
4353+
return rc;
4354+
}
4355+
42084356
int main(int argc, char **argv)
42094357
{
42104358
struct ctx ctxi = { 0 }, *ctx = &ctxi;

0 commit comments

Comments
 (0)