@@ -253,6 +253,7 @@ static int del_local_eid(struct ctx *ctx, uint32_t net, int eid);
253
253
static int add_net (struct ctx * ctx , uint32_t net );
254
254
static void del_net (struct net * net );
255
255
static int add_interface (struct ctx * ctx , int ifindex );
256
+ static int endpoint_allocate_eid (struct peer * peer );
256
257
257
258
static const sd_bus_vtable bus_endpoint_obmc_vtable [];
258
259
static const sd_bus_vtable bus_endpoint_cc_vtable [];
@@ -2251,6 +2252,18 @@ static int method_assign_endpoint(sd_bus_message *call, void *data,
2251
2252
2252
2253
if (peer -> pool_size > 0 ) {
2253
2254
// 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
+ }
2254
2267
}
2255
2268
2256
2269
return sd_bus_reply_method_return (call , "yisb" , peer -> eid , peer -> net ,
@@ -4138,6 +4151,128 @@ static void free_config(struct ctx *ctx)
4138
4151
free (ctx -> config_filename );
4139
4152
}
4140
4153
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
+
4141
4276
int main (int argc , char * * argv )
4142
4277
{
4143
4278
struct ctx ctxi = { 0 }, * ctx = & ctxi ;
0 commit comments