Skip to content

Commit 0caac53

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. Signed-off-by: Faizan Ali <[email protected]>
1 parent a118274 commit 0caac53

File tree

1 file changed

+142
-12
lines changed

1 file changed

+142
-12
lines changed

src/mctpd.c

Lines changed: 142 additions & 12 deletions
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[];
@@ -2184,7 +2185,6 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
21842185
if (rc < 0)
21852186
return sd_bus_error_setf(berr, SD_BUS_ERROR_INVALID_ARGS,
21862187
"Bad physaddr");
2187-
21882188
rc = get_endpoint_peer(ctx, berr, dest, &peer, &eid);
21892189
if (rc == -EEXIST) {
21902190
/* We have a conflict with an existing endpoint, so can't
@@ -2211,15 +2211,19 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
22112211
static int method_assign_bridge_static(sd_bus_message *call, void *data,
22122212
sd_bus_error *berr)
22132213
{
2214-
char *peer_path = NULL;
2214+
const char *peer_path = NULL;
22152215
dest_phys desti, *dest = &desti;
22162216
struct link *link = data;
22172217
struct ctx *ctx = link->ctx;
22182218
struct peer *peer = NULL;
22192219
uint8_t eid, pool_start, pool_size;
2220+
char msg[200]; // Increased buffer size for multiple messages
2221+
int msg_len = 0;
22202222
int rc;
22212223

22222224
dest->ifindex = link->ifindex;
2225+
memset(msg, '\0', sizeof(msg));
2226+
22232227
if (dest->ifindex <= 0)
22242228
return sd_bus_error_setf(berr, SD_BUS_ERROR_INVALID_ARGS,
22252229
"Unknown MCTP interface");
@@ -2257,8 +2261,8 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
22572261
if (!peer_path)
22582262
goto err;
22592263

2260-
return sd_bus_reply_method_return(call, "yisb",
2261-
peer->eid, peer->net, peer_path, 0);
2264+
return sd_bus_reply_method_return(call, "yisbs",
2265+
peer->eid, peer->net, peer_path, 0, msg);
22622266
} else {
22632267
uint32_t netid;
22642268

@@ -2277,21 +2281,29 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
22772281
}
22782282

22792283
peer_path = path_from_peer(peer);
2284+
msg_len = snprintf(msg, sizeof(msg), "Statically assigned Bridge %d", peer->eid);
22802285
if (!peer_path) {
22812286
goto err;
22822287
}
22832288

2284-
if(peer->pool_size > 0) {
2289+
if (peer->pool_size > 0) {
22852290
peer->pool_start = pool_start;
2286-
if(peer->pool_size && peer->pool_size > pool_size) {
2287-
peer->pool_size = pool_size;
2291+
peer->pool_size = min(peer->pool_size, pool_size);
22882292

2289-
//call for Allocate EndpointID
2293+
//call for Allocate EndpointID
2294+
rc = endpoint_allocate_eid(peer);
2295+
if (rc < 0) {
2296+
msg_len += snprintf(msg + msg_len, sizeof(msg) - msg_len,
2297+
". Failed to allocate downstream EIDs");
2298+
} else {
2299+
msg_len += snprintf(msg + msg_len, sizeof(msg) - msg_len,
2300+
". Downstream EIDs assigned from %d to %d : pool size %d",
2301+
peer->pool_start, peer->pool_start + peer->pool_size - 1, peer->pool_size);
22902302
}
22912303
}
22922304

2293-
return sd_bus_reply_method_return(call, "yisb",
2294-
peer->eid, peer->net, peer_path, 1);
2305+
return sd_bus_reply_method_return(call, "yisbs",
2306+
peer->eid, peer->net, peer_path, 1, msg);
22952307
err:
22962308
set_berr(ctx, rc, berr);
22972309
return rc;
@@ -2856,17 +2868,19 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
28562868
SD_BUS_PARAM(found),
28572869
method_learn_endpoint,
28582870
0),
2871+
28592872
SD_BUS_METHOD_WITH_NAMES("AssignBridgeStatic",
28602873
"ayyyy",
28612874
SD_BUS_PARAM(physaddr)
28622875
SD_BUS_PARAM(eid)
28632876
SD_BUS_PARAM(pool_start)
28642877
SD_BUS_PARAM(pool_size),
2865-
"yisb",
2878+
"yisbs",
28662879
SD_BUS_PARAM(eid)
28672880
SD_BUS_PARAM(net)
28682881
SD_BUS_PARAM(path)
2869-
SD_BUS_PARAM(new),
2882+
SD_BUS_PARAM(new)
2883+
SD_BUS_PARAM(msg),
28702884
method_assign_bridge_static,
28712885
0),
28722886
SD_BUS_VTABLE_END,
@@ -3943,6 +3957,122 @@ static void free_config(struct ctx *ctx)
39433957
free(ctx->config_filename);
39443958
}
39453959

3960+
static int endpoint_send_allocate_endpoint_id(struct peer *peer,
3961+
mctp_eid_t eid_start, uint8_t eid_pool_size, mctp_ctrl_cmd_alloc_eid_op oper,
3962+
uint8_t *allocated_pool_size, mctp_eid_t *allocated_pool_start)
3963+
{
3964+
struct sockaddr_mctp_ext addr;
3965+
struct mctp_ctrl_cmd_alloc_eid req = {0};
3966+
struct mctp_ctrl_resp_alloc_eid *resp = NULL;
3967+
uint8_t *buf = NULL;
3968+
size_t buf_size;
3969+
uint8_t iid, stat;
3970+
int rc;
3971+
3972+
iid = mctp_next_iid(peer->ctx);
3973+
req.ctrl_hdr.rq_dgram_inst = RQDI_REQ | iid;
3974+
req.ctrl_hdr.command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS;
3975+
req.alloc_eid_op = (uint8_t)(oper & 0x03);
3976+
req.pool_size = eid_pool_size;
3977+
req.start_eid = eid_start;
3978+
rc = endpoint_query_peer(peer, MCTP_CTRL_HDR_MSG_TYPE, &req, sizeof(req),
3979+
&buf, &buf_size, &addr);
3980+
if (rc < 0)
3981+
goto out;
3982+
3983+
rc = mctp_ctrl_validate_response(buf, buf_size, sizeof(*resp),
3984+
peer_tostr_short(peer), iid,
3985+
MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS);
3986+
3987+
if (rc)
3988+
goto out;
3989+
3990+
resp = (void *)buf;
3991+
if (!resp) {
3992+
warnx("%s Invalid response Buffer\n", __func__);
3993+
return -ENOMEM;
3994+
}
3995+
3996+
stat = resp->status & 0x03;
3997+
if (stat == 0x00) {
3998+
if(peer->ctx->verbose) {
3999+
fprintf(stderr, "%s Allocation Accepted \n", __func__);
4000+
}
4001+
}
4002+
else if (stat == 0x1) {
4003+
warnx("%s Allocation was rejected as it was Allocated by other bus \n", __func__);
4004+
}
4005+
4006+
*allocated_pool_size = resp->eid_pool_size;
4007+
*allocated_pool_start = resp->eid_set;
4008+
if(peer->ctx->verbose) {
4009+
fprintf(stderr, "%s Allocated size of %d, starting from EID %d\n", __func__,
4010+
resp->eid_pool_size, resp->eid_set);
4011+
}
4012+
4013+
return 0;
4014+
out:
4015+
free(buf);
4016+
return rc;
4017+
}
4018+
4019+
static mctp_eid_t get_pool_start (struct peer *peer, mctp_eid_t eid_start, uint8_t pool_size)
4020+
{
4021+
uint8_t count = 0;
4022+
mctp_eid_t pool_start = eid_alloc_max;
4023+
struct net *n = lookup_net(peer->ctx, peer->net);
4024+
4025+
if (!n) {
4026+
warnx("BUG: Unknown net %d : failed to get pool start\n", peer->net);
4027+
return eid_alloc_max;
4028+
}
4029+
4030+
for (mctp_eid_t e = eid_start; e <= eid_alloc_max; e++) {
4031+
if (n->peers[e] == NULL) {
4032+
if(pool_start == eid_alloc_max) {
4033+
pool_start = e;
4034+
}
4035+
count++;
4036+
if (count == pool_size) return pool_start;
4037+
} else {
4038+
pool_start = eid_alloc_max;
4039+
count = 0;
4040+
}
4041+
}
4042+
4043+
return eid_alloc_max;
4044+
}
4045+
4046+
static int endpoint_allocate_eid(struct peer* peer)
4047+
{
4048+
uint8_t allocated_pool_size = 0;
4049+
mctp_eid_t allocated_pool_start = 0;
4050+
4051+
/* Find pool sized contiguous unused eids to allocate on the bridge. */
4052+
peer->pool_start = get_pool_start(peer, peer->pool_start, peer->pool_size);
4053+
if (peer->pool_start == eid_alloc_max) {
4054+
warnx("%s failed to find contiguous EIDs of required size", __func__);
4055+
return 0;
4056+
} else {
4057+
if (peer->ctx->verbose)
4058+
fprintf(stderr, "%s Asking for contiguous EIDs for pool with start eid : %d\n", __func__, peer->pool_start);
4059+
}
4060+
4061+
int rc = endpoint_send_allocate_endpoint_id(peer, peer->pool_start, peer->pool_size,
4062+
mctp_ctrl_cmd_alloc_eid_alloc_eid, &allocated_pool_size, &allocated_pool_start);
4063+
if (rc) {
4064+
warnx("%s failed to allocate endpoints, returned %s %d\n",
4065+
__func__, strerror(-rc), rc);
4066+
} else {
4067+
peer->pool_size = allocated_pool_size;
4068+
peer->pool_start = allocated_pool_start;
4069+
4070+
// Polling logic for downstream EID
4071+
}
4072+
4073+
return 0;
4074+
}
4075+
39464076
int main(int argc, char **argv)
39474077
{
39484078
struct ctx ctxi = {0}, *ctx = &ctxi;

0 commit comments

Comments
 (0)