@@ -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 ,
@@ -2473,6 +2486,20 @@ static int peer_route_update(struct peer *peer, uint16_t type)
2473
2486
return mctp_nl_route_add (peer -> ctx -> nl , peer -> eid , 0 ,
2474
2487
peer -> phys .ifindex , NULL , peer -> mtu );
2475
2488
} else if (type == RTM_DELROUTE ) {
2489
+ if (peer -> pool_size > 0 ) {
2490
+ int rc = 0 ;
2491
+ struct mctp_fq_addr gw_addr = { 0 };
2492
+ gw_addr .net = peer -> net ;
2493
+ gw_addr .eid = peer -> eid ;
2494
+ rc = mctp_nl_route_del (peer -> ctx -> nl , peer -> pool_start ,
2495
+ peer -> pool_size - 1 ,
2496
+ peer -> phys .ifindex , & gw_addr );
2497
+ if (rc < 0 )
2498
+ warnx ("failed to delete route for peer pool eids %d-%d %s" ,
2499
+ peer -> pool_start ,
2500
+ peer -> pool_start + peer -> pool_size - 1 ,
2501
+ strerror (- rc ));
2502
+ }
2476
2503
return mctp_nl_route_del (peer -> ctx -> nl , peer -> eid , 0 ,
2477
2504
peer -> phys .ifindex , NULL );
2478
2505
}
@@ -4138,6 +4165,128 @@ static void free_config(struct ctx *ctx)
4138
4165
free (ctx -> config_filename );
4139
4166
}
4140
4167
4168
+ static int endpoint_send_allocate_endpoint_id (struct peer * peer ,
4169
+ mctp_eid_t eid_start ,
4170
+ uint8_t eid_pool_size ,
4171
+ mctp_ctrl_cmd_alloc_eid_op oper ,
4172
+ uint8_t * allocated_pool_size ,
4173
+ mctp_eid_t * allocated_pool_start )
4174
+ {
4175
+ struct sockaddr_mctp_ext addr ;
4176
+ struct mctp_ctrl_cmd_alloc_eid req = { 0 };
4177
+ struct mctp_ctrl_resp_alloc_eid * resp = NULL ;
4178
+ uint8_t * buf = NULL ;
4179
+ size_t buf_size ;
4180
+ uint8_t iid , stat ;
4181
+ int rc ;
4182
+
4183
+ iid = mctp_next_iid (peer -> ctx );
4184
+ req .ctrl_hdr .rq_dgram_inst = RQDI_REQ | iid ;
4185
+ req .ctrl_hdr .command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS ;
4186
+ req .alloc_eid_op = (uint8_t )(oper & 0x03 );
4187
+ req .pool_size = eid_pool_size ;
4188
+ req .start_eid = eid_start ;
4189
+ rc = endpoint_query_peer (peer , MCTP_CTRL_HDR_MSG_TYPE , & req ,
4190
+ sizeof (req ), & buf , & buf_size , & addr );
4191
+ if (rc < 0 )
4192
+ goto out ;
4193
+
4194
+ rc = mctp_ctrl_validate_response (buf , buf_size , sizeof (* resp ),
4195
+ peer_tostr_short (peer ), iid ,
4196
+ MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS );
4197
+
4198
+ if (rc )
4199
+ goto out ;
4200
+
4201
+ resp = (void * )buf ;
4202
+ if (!resp ) {
4203
+ warnx ("%s Invalid response Buffer\n" , __func__ );
4204
+ return - ENOMEM ;
4205
+ }
4206
+
4207
+ stat = resp -> status & 0x03 ;
4208
+ if (stat == 0x00 ) {
4209
+ if (peer -> ctx -> verbose ) {
4210
+ fprintf (stderr , "%s Allocation Accepted \n" , __func__ );
4211
+ }
4212
+ if (resp -> eid_pool_size != eid_pool_size ||
4213
+ resp -> eid_set != eid_start ) {
4214
+ warnx ("Unexpected pool start %d pool size %d" ,
4215
+ resp -> eid_set , resp -> eid_pool_size );
4216
+ rc = -1 ;
4217
+ goto out ;
4218
+ }
4219
+ } else {
4220
+ if (stat == 0x1 )
4221
+ warnx ("%s Allocation was rejected: already allocated by other bus"
4222
+ " pool start %d, pool size %d" ,
4223
+ __func__ , resp -> eid_pool_size , resp -> eid_set );
4224
+ rc = -1 ;
4225
+ goto out ;
4226
+ }
4227
+
4228
+ * allocated_pool_size = resp -> eid_pool_size ;
4229
+ * allocated_pool_start = resp -> eid_set ;
4230
+ if (peer -> ctx -> verbose ) {
4231
+ fprintf (stderr ,
4232
+ "%s Allocated size of %d, starting from EID %d\n" ,
4233
+ __func__ , resp -> eid_pool_size , resp -> eid_set );
4234
+ }
4235
+
4236
+ out :
4237
+ free (buf );
4238
+ return rc ;
4239
+ }
4240
+
4241
+ static int endpoint_allocate_eid (struct peer * peer )
4242
+ {
4243
+ uint8_t allocated_pool_size = 0 ;
4244
+ mctp_eid_t allocated_pool_start = 0 ;
4245
+ int rc = 0 ;
4246
+
4247
+ /* Find pool sized contiguous unused eids to allocate on the bridge. */
4248
+ if (peer -> pool_start >= eid_alloc_max || peer -> pool_start <= 0 ) {
4249
+ warnx ("%s Invalid Pool start %d" , __func__ , peer -> pool_start );
4250
+ return -1 ;
4251
+ }
4252
+ rc = endpoint_send_allocate_endpoint_id (
4253
+ peer , peer -> pool_start , peer -> pool_size ,
4254
+ mctp_ctrl_cmd_alloc_eid_alloc_eid , & allocated_pool_size ,
4255
+ & allocated_pool_start );
4256
+ if (rc ) {
4257
+ //reset peer pool
4258
+ peer -> pool_size = 0 ;
4259
+ peer -> pool_start = 0 ;
4260
+ } else {
4261
+ peer -> pool_size = allocated_pool_size ;
4262
+ peer -> pool_start = allocated_pool_start ;
4263
+
4264
+ // add Gateway route for all Bridge's downstream eids
4265
+ if (peer -> pool_size > 0 ) {
4266
+ struct mctp_fq_addr gw_addr = { 0 };
4267
+ gw_addr .net = peer -> net ;
4268
+ gw_addr .eid = peer -> eid ;
4269
+ rc = mctp_nl_route_add (peer -> ctx -> nl , peer -> pool_start ,
4270
+ peer -> pool_size - 1 ,
4271
+ peer -> phys .ifindex , & gw_addr ,
4272
+ peer -> mtu );
4273
+ if (rc < 0 ) {
4274
+ warnx ("Failed to add Gateway route for EID %d: %s" ,
4275
+ gw_addr .eid , strerror (- rc ));
4276
+ // If the route already exists, continue polling
4277
+ if (rc != - EEXIST ) {
4278
+ return rc ;
4279
+ } else {
4280
+ rc = 0 ;
4281
+ }
4282
+ }
4283
+ // TODO: Polling logic for downstream EID
4284
+ }
4285
+ }
4286
+
4287
+ return rc ;
4288
+ }
4289
+
4141
4290
int main (int argc , char * * argv )
4142
4291
{
4143
4292
struct ctx ctxi = { 0 }, * ctx = & ctxi ;
0 commit comments