@@ -252,6 +252,7 @@ static int del_local_eid(struct ctx *ctx, uint32_t net, int eid);
252
252
static int add_net (struct ctx * ctx , uint32_t net );
253
253
static void del_net (struct net * net );
254
254
static int add_interface (struct ctx * ctx , int ifindex );
255
+ static int endpoint_allocate_eid (struct peer * peer );
255
256
256
257
static const sd_bus_vtable bus_endpoint_obmc_vtable [];
257
258
static const sd_bus_vtable bus_endpoint_cc_vtable [];
@@ -2255,7 +2256,18 @@ static int method_assign_endpoint(sd_bus_message *call, void *data,
2255
2256
goto err ;
2256
2257
2257
2258
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
+ }
2259
2271
}
2260
2272
2261
2273
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)
2479
2491
return mctp_nl_route_add (peer -> ctx -> nl , peer -> eid , 0 ,
2480
2492
peer -> phys .ifindex , NULL , peer -> mtu );
2481
2493
} 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
+ }
2482
2508
return mctp_nl_route_del (peer -> ctx -> nl , peer -> eid , 0 ,
2483
2509
peer -> phys .ifindex , NULL );
2484
2510
}
@@ -4205,6 +4231,128 @@ static void free_config(struct ctx *ctx)
4205
4231
free (ctx -> config_filename );
4206
4232
}
4207
4233
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
+
4208
4356
int main (int argc , char * * argv )
4209
4357
{
4210
4358
struct ctx ctxi = { 0 }, * ctx = & ctxi ;
0 commit comments