@@ -253,6 +253,7 @@ static int del_local_eid(struct ctx *ctx, uint32_t net, int eid);
253253static int add_net (struct ctx * ctx , uint32_t net );
254254static void del_net (struct net * net );
255255static int add_interface (struct ctx * ctx , int ifindex );
256+ static int endpoint_allocate_eid (struct peer * peer );
256257
257258static const sd_bus_vtable bus_endpoint_obmc_vtable [];
258259static const sd_bus_vtable bus_endpoint_cc_vtable [];
@@ -2251,6 +2252,18 @@ static int method_assign_endpoint(sd_bus_message *call, void *data,
22512252
22522253 if (peer -> pool_size > 0 ) {
22532254 // 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+ }
22542267 }
22552268
22562269 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)
24732486 return mctp_nl_route_add (peer -> ctx -> nl , peer -> eid , 0 ,
24742487 peer -> phys .ifindex , NULL , peer -> mtu );
24752488 } 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+ }
24762503 return mctp_nl_route_del (peer -> ctx -> nl , peer -> eid , 0 ,
24772504 peer -> phys .ifindex , NULL );
24782505 }
@@ -4138,6 +4165,128 @@ static void free_config(struct ctx *ctx)
41384165 free (ctx -> config_filename );
41394166}
41404167
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+
41414290int main (int argc , char * * argv )
41424291{
41434292 struct ctx ctxi = { 0 }, * ctx = & ctxi ;
0 commit comments