Skip to content

Commit 823a7f5

Browse files
Add Allocate Endpoint ID support for MCTP Bridge
* New mctpd method to send Allocate Endpoint ID mctp control message * Check for presence of contiguous available EIDs of pool size. * Send Allocate Endpoint ID for dynamic pool eid from AssignEndoint and AssignEndpointStatic d-bus methods Signed-off-by: Faizan Ali <[email protected]>
1 parent 6439eab commit 823a7f5

File tree

1 file changed

+146
-1
lines changed

1 file changed

+146
-1
lines changed

src/mctpd.c

Lines changed: 146 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[];
@@ -2087,6 +2088,15 @@ static int method_assign_endpoint(sd_bus_message *call, void *data, sd_bus_error
20872088
// Dynamic pool EID starts after bridge's EID
20882089
peer->pool_start = peer->eid + 1;
20892090
// Call for Allocate EndpointID
2091+
rc = endpoint_allocate_eid(peer);
2092+
if (rc < 0) {
2093+
warnx("Failed to allocate downstream EIDs");
2094+
} else {
2095+
if (peer->ctx->verbose) {
2096+
printf("Downstream EIDs assigned from %d to %d : pool size %d\n",
2097+
peer->pool_start, peer->pool_start + peer->pool_size - 1, peer->pool_size);
2098+
}
2099+
}
20902100
}
20912101

20922102
return sd_bus_reply_method_return(call, "yisb",
@@ -2164,6 +2174,15 @@ static int method_assign_endpoint_static(sd_bus_message *call, void *data,
21642174
// Dynamic pool EID starts after bridge's EID
21652175
peer->pool_start = peer->eid + 1;
21662176
// Call for Allocate EndpointID
2177+
rc = endpoint_allocate_eid(peer);
2178+
if (rc < 0) {
2179+
warnx("Failed to allocate downstream EIDs");
2180+
} else {
2181+
if (peer->ctx->verbose) {
2182+
printf("Downstream EIDs assigned from %d to %d : pool size %d\n",
2183+
peer->pool_start, peer->pool_start + peer->pool_size - 1, peer->pool_size);
2184+
}
2185+
}
21672186
}
21682187

21692188
return sd_bus_reply_method_return(call, "yisb",
@@ -2196,7 +2215,6 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
21962215
if (rc < 0)
21972216
return sd_bus_error_setf(berr, SD_BUS_ERROR_INVALID_ARGS,
21982217
"Bad physaddr");
2199-
22002218
rc = get_endpoint_peer(ctx, berr, dest, &peer, &eid);
22012219
if (rc == -EEXIST) {
22022220
/* We have a conflict with an existing endpoint, so can't
@@ -2308,6 +2326,15 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
23082326
peer->pool_size = min(peer->pool_size, pool_size);
23092327

23102328
//call for Allocate EndpointID
2329+
rc = endpoint_allocate_eid(peer);
2330+
if (rc < 0) {
2331+
msg_len += snprintf(msg + msg_len, sizeof(msg) - msg_len,
2332+
". Failed to allocate downstream EIDs");
2333+
} else {
2334+
msg_len += snprintf(msg + msg_len, sizeof(msg) - msg_len,
2335+
". Downstream EIDs assigned from %d to %d : pool size %d",
2336+
peer->pool_start, peer->pool_start + peer->pool_size - 1, peer->pool_size);
2337+
}
23112338
}
23122339

23132340
return sd_bus_reply_method_return(call, "yisbs",
@@ -2876,6 +2903,7 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
28762903
SD_BUS_PARAM(found),
28772904
method_learn_endpoint,
28782905
0),
2906+
28792907
SD_BUS_METHOD_WITH_NAMES("AssignBridgeStatic",
28802908
"ayyyy",
28812909
SD_BUS_PARAM(physaddr)
@@ -3964,6 +3992,123 @@ static void free_config(struct ctx *ctx)
39643992
free(ctx->config_filename);
39653993
}
39663994

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

0 commit comments

Comments
 (0)