@@ -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 [];
@@ -2250,6 +2251,18 @@ static int method_assign_endpoint(sd_bus_message *call, void *data,
2250
2251
2251
2252
if (peer -> pool_size > 0 ) {
2252
2253
// Call for Allocate EndpointID
2254
+ rc = endpoint_allocate_eid (peer );
2255
+ if (rc < 0 ) {
2256
+ warnx ("Failed to allocate downstream EIDs" );
2257
+ } else {
2258
+ if (peer -> ctx -> verbose ) {
2259
+ fprintf (stderr ,
2260
+ "Downstream EIDs assigned from %d to %d : pool size %d\n" ,
2261
+ peer -> pool_start ,
2262
+ peer -> pool_start + peer -> pool_size - 1 ,
2263
+ peer -> pool_size );
2264
+ }
2265
+ }
2253
2266
}
2254
2267
2255
2268
return sd_bus_reply_method_return (call , "yisb" , peer -> eid , peer -> net ,
@@ -4137,6 +4150,128 @@ static void free_config(struct ctx *ctx)
4137
4150
free (ctx -> config_filename );
4138
4151
}
4139
4152
4153
+ static int endpoint_send_allocate_endpoint_id (struct peer * peer ,
4154
+ mctp_eid_t eid_start ,
4155
+ uint8_t eid_pool_size ,
4156
+ mctp_ctrl_cmd_alloc_eid_op oper ,
4157
+ uint8_t * allocated_pool_size ,
4158
+ mctp_eid_t * allocated_pool_start )
4159
+ {
4160
+ struct sockaddr_mctp_ext addr ;
4161
+ struct mctp_ctrl_cmd_alloc_eid req = { 0 };
4162
+ struct mctp_ctrl_resp_alloc_eid * resp = NULL ;
4163
+ uint8_t * buf = NULL ;
4164
+ size_t buf_size ;
4165
+ uint8_t iid , stat ;
4166
+ int rc ;
4167
+
4168
+ iid = mctp_next_iid (peer -> ctx );
4169
+ req .ctrl_hdr .rq_dgram_inst = RQDI_REQ | iid ;
4170
+ req .ctrl_hdr .command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS ;
4171
+ req .alloc_eid_op = (uint8_t )(oper & 0x03 );
4172
+ req .pool_size = eid_pool_size ;
4173
+ req .start_eid = eid_start ;
4174
+ rc = endpoint_query_peer (peer , MCTP_CTRL_HDR_MSG_TYPE , & req ,
4175
+ sizeof (req ), & buf , & buf_size , & addr );
4176
+ if (rc < 0 )
4177
+ goto out ;
4178
+
4179
+ rc = mctp_ctrl_validate_response (buf , buf_size , sizeof (* resp ),
4180
+ peer_tostr_short (peer ), iid ,
4181
+ MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS );
4182
+
4183
+ if (rc )
4184
+ goto out ;
4185
+
4186
+ resp = (void * )buf ;
4187
+ if (!resp ) {
4188
+ warnx ("%s Invalid response Buffer\n" , __func__ );
4189
+ return - ENOMEM ;
4190
+ }
4191
+
4192
+ stat = resp -> status & 0x03 ;
4193
+ if (stat == 0x00 ) {
4194
+ if (peer -> ctx -> verbose ) {
4195
+ fprintf (stderr , "%s Allocation Accepted \n" , __func__ );
4196
+ }
4197
+ if (resp -> eid_pool_size != eid_pool_size ||
4198
+ resp -> eid_set != eid_start ) {
4199
+ warnx ("Unexpected pool start %d pool size %d" ,
4200
+ resp -> eid_set , resp -> eid_pool_size );
4201
+ rc = -1 ;
4202
+ goto out ;
4203
+ }
4204
+ } else {
4205
+ if (stat == 0x1 )
4206
+ warnx ("%s Allocation was rejected: already allocated by other bus"
4207
+ " pool start %d, pool size %d" ,
4208
+ __func__ , resp -> eid_pool_size , resp -> eid_set );
4209
+ rc = -1 ;
4210
+ goto out ;
4211
+ }
4212
+
4213
+ * allocated_pool_size = resp -> eid_pool_size ;
4214
+ * allocated_pool_start = resp -> eid_set ;
4215
+ if (peer -> ctx -> verbose ) {
4216
+ fprintf (stderr ,
4217
+ "%s Allocated size of %d, starting from EID %d\n" ,
4218
+ __func__ , resp -> eid_pool_size , resp -> eid_set );
4219
+ }
4220
+
4221
+ out :
4222
+ free (buf );
4223
+ return rc ;
4224
+ }
4225
+
4226
+ static int endpoint_allocate_eid (struct peer * peer )
4227
+ {
4228
+ uint8_t allocated_pool_size = 0 ;
4229
+ mctp_eid_t allocated_pool_start = 0 ;
4230
+ int rc = 0 ;
4231
+
4232
+ /* Find pool sized contiguous unused eids to allocate on the bridge. */
4233
+ if (peer -> pool_start >= eid_alloc_max || peer -> pool_start <= 0 ) {
4234
+ warnx ("%s Invalid Pool start %d" , __func__ , peer -> pool_start );
4235
+ return -1 ;
4236
+ }
4237
+ rc = endpoint_send_allocate_endpoint_id (
4238
+ peer , peer -> pool_start , peer -> pool_size ,
4239
+ mctp_ctrl_cmd_alloc_eid_alloc_eid , & allocated_pool_size ,
4240
+ & allocated_pool_start );
4241
+ if (rc ) {
4242
+ //reset peer pool
4243
+ peer -> pool_size = 0 ;
4244
+ peer -> pool_start = 0 ;
4245
+ } else {
4246
+ peer -> pool_size = allocated_pool_size ;
4247
+ peer -> pool_start = allocated_pool_start ;
4248
+
4249
+ // add Gateway route for all Bridge's downstream eids
4250
+ if (peer -> pool_size > 0 ) {
4251
+ struct mctp_fq_addr gw_addr ;
4252
+ gw_addr .net = peer -> net ;
4253
+ gw_addr .eid = peer -> eid ;
4254
+ rc = mctp_nl_route_add (peer -> ctx -> nl , peer -> pool_start ,
4255
+ peer -> pool_size - 1 ,
4256
+ peer -> phys .ifindex , & gw_addr ,
4257
+ peer -> mtu );
4258
+ if (rc < 0 ) {
4259
+ warnx ("Failed to add Gateway route for EID %d: %s" ,
4260
+ gw_addr .eid , strerror (- rc ));
4261
+ // If the route already exists, continue polling
4262
+ if (rc != - EEXIST ) {
4263
+ return rc ;
4264
+ } else {
4265
+ rc = 0 ;
4266
+ }
4267
+ }
4268
+ // TODO: Polling logic for downstream EID
4269
+ }
4270
+ }
4271
+
4272
+ return rc ;
4273
+ }
4274
+
4140
4275
int main (int argc , char * * argv )
4141
4276
{
4142
4277
struct ctx ctxi = { 0 }, * ctx = & ctxi ;
0 commit comments