@@ -250,6 +250,7 @@ static int del_local_eid(struct ctx *ctx, uint32_t net, int eid);
250250static int add_net (struct ctx * ctx , uint32_t net );
251251static void del_net (struct net * net );
252252static int add_interface (struct ctx * ctx , int ifindex );
253+ static int endpoint_allocate_eid (struct peer * peer );
253254
254255static const sd_bus_vtable bus_endpoint_obmc_vtable [];
255256static const sd_bus_vtable bus_endpoint_cc_vtable [];
@@ -2087,6 +2088,15 @@ static int method_assign_endpoint(sd_bus_message *call, void *data, sd_bus_error
20872088 // Dynamic pool EID starts after bridge's EID
20882089 peer -> pool_start = peer -> eid + 1 ;
20892090 // Call for Allocate EndpointID
2091+ rc = endpoint_allocate_eid (peer );
2092+ if (rc < 0 ) {
2093+ warnx ("Failed to allocate downstream EIDs" );
2094+ } else {
2095+ if (peer -> ctx -> verbose ) {
2096+ printf ("Downstream EIDs assigned from %d to %d : pool size %d\n" ,
2097+ peer -> pool_start , peer -> pool_start + peer -> pool_size - 1 , peer -> pool_size );
2098+ }
2099+ }
20902100 }
20912101
20922102 return sd_bus_reply_method_return (call , "yisb" ,
@@ -2164,6 +2174,15 @@ static int method_assign_endpoint_static(sd_bus_message *call, void *data,
21642174 // Dynamic pool EID starts after bridge's EID
21652175 peer -> pool_start = peer -> eid + 1 ;
21662176 // Call for Allocate EndpointID
2177+ rc = endpoint_allocate_eid (peer );
2178+ if (rc < 0 ) {
2179+ warnx ("Failed to allocate downstream EIDs" );
2180+ } else {
2181+ if (peer -> ctx -> verbose ) {
2182+ printf ("Downstream EIDs assigned from %d to %d : pool size %d\n" ,
2183+ peer -> pool_start , peer -> pool_start + peer -> pool_size - 1 , peer -> pool_size );
2184+ }
2185+ }
21672186 }
21682187
21692188 return sd_bus_reply_method_return (call , "yisb" ,
@@ -2196,7 +2215,6 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
21962215 if (rc < 0 )
21972216 return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
21982217 "Bad physaddr" );
2199-
22002218 rc = get_endpoint_peer (ctx , berr , dest , & peer , & eid );
22012219 if (rc == - EEXIST ) {
22022220 /* We have a conflict with an existing endpoint, so can't
@@ -2308,6 +2326,15 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
23082326 peer -> pool_size = min (peer -> pool_size , pool_size );
23092327
23102328 //call for Allocate EndpointID
2329+ rc = endpoint_allocate_eid (peer );
2330+ if (rc < 0 ) {
2331+ msg_len += snprintf (msg + msg_len , sizeof (msg ) - msg_len ,
2332+ ". Failed to allocate downstream EIDs" );
2333+ } else {
2334+ msg_len += snprintf (msg + msg_len , sizeof (msg ) - msg_len ,
2335+ ". Downstream EIDs assigned from %d to %d : pool size %d" ,
2336+ peer -> pool_start , peer -> pool_start + peer -> pool_size - 1 , peer -> pool_size );
2337+ }
23112338 }
23122339
23132340 return sd_bus_reply_method_return (call , "yisbs" ,
@@ -2876,6 +2903,7 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
28762903 SD_BUS_PARAM (found ),
28772904 method_learn_endpoint ,
28782905 0 ),
2906+
28792907 SD_BUS_METHOD_WITH_NAMES ("AssignBridgeStatic" ,
28802908 "ayyyy" ,
28812909 SD_BUS_PARAM (physaddr )
@@ -3964,6 +3992,123 @@ static void free_config(struct ctx *ctx)
39643992 free (ctx -> config_filename );
39653993}
39663994
3995+ static int endpoint_send_allocate_endpoint_id (struct peer * peer ,
3996+ mctp_eid_t eid_start , uint8_t eid_pool_size , mctp_ctrl_cmd_alloc_eid_op oper ,
3997+ uint8_t * allocated_pool_size , mctp_eid_t * allocated_pool_start )
3998+ {
3999+ struct sockaddr_mctp_ext addr ;
4000+ struct mctp_ctrl_cmd_alloc_eid req = {0 };
4001+ struct mctp_ctrl_resp_alloc_eid * resp = NULL ;
4002+ uint8_t * buf = NULL ;
4003+ size_t buf_size ;
4004+ uint8_t iid , stat ;
4005+ int rc ;
4006+
4007+ iid = mctp_next_iid (peer -> ctx );
4008+ req .ctrl_hdr .rq_dgram_inst = RQDI_REQ | iid ;
4009+ req .ctrl_hdr .command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS ;
4010+ req .alloc_eid_op = (uint8_t )(oper & 0x03 );
4011+ req .pool_size = eid_pool_size ;
4012+ req .start_eid = eid_start ;
4013+ rc = endpoint_query_peer (peer , MCTP_CTRL_HDR_MSG_TYPE , & req , sizeof (req ),
4014+ & buf , & buf_size , & addr );
4015+ if (rc < 0 )
4016+ goto out ;
4017+
4018+ rc = mctp_ctrl_validate_response (buf , buf_size , sizeof (* resp ),
4019+ peer_tostr_short (peer ), iid ,
4020+ MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS );
4021+
4022+ if (rc )
4023+ goto out ;
4024+
4025+ resp = (void * )buf ;
4026+ if (!resp ) {
4027+ warnx ("%s Invalid response Buffer\n" , __func__ );
4028+ return - ENOMEM ;
4029+ }
4030+
4031+ stat = resp -> status & 0x03 ;
4032+ if (stat == 0x00 ) {
4033+ if (peer -> ctx -> verbose ) {
4034+ fprintf (stderr , "%s Allocation Accepted \n" , __func__ );
4035+ }
4036+ }
4037+ else if (stat == 0x1 ) {
4038+ warnx ("%s Allocation was rejected as it was Allocated by other bus \n" , __func__ );
4039+ }
4040+
4041+ * allocated_pool_size = resp -> eid_pool_size ;
4042+ * allocated_pool_start = resp -> eid_set ;
4043+ if (peer -> ctx -> verbose ) {
4044+ fprintf (stderr , "%s Allocated size of %d, starting from EID %d\n" , __func__ ,
4045+ resp -> eid_pool_size , resp -> eid_set );
4046+ }
4047+
4048+ return 0 ;
4049+ out :
4050+ free (buf );
4051+ return rc ;
4052+ }
4053+
4054+ static mctp_eid_t get_pool_start (struct peer * peer , mctp_eid_t eid_start , uint8_t pool_size )
4055+ {
4056+ uint8_t count = 0 ;
4057+ mctp_eid_t pool_start = eid_alloc_max ;
4058+ struct net * n = lookup_net (peer -> ctx , peer -> net );
4059+
4060+ if (!n ) {
4061+ warnx ("BUG: Unknown net %d : failed to get pool start\n" , peer -> net );
4062+ return eid_alloc_max ;
4063+ }
4064+
4065+ for (mctp_eid_t e = eid_start ; e <= eid_alloc_max ; e ++ ) {
4066+ if (n -> peers [e ] == NULL ) {
4067+ if (pool_start == eid_alloc_max ) {
4068+ pool_start = e ;
4069+ }
4070+ count ++ ;
4071+ if (count == pool_size ) return pool_start ;
4072+ } else {
4073+ pool_start = eid_alloc_max ;
4074+ count = 0 ;
4075+ }
4076+ }
4077+
4078+ return eid_alloc_max ;
4079+ }
4080+
4081+ static int endpoint_allocate_eid (struct peer * peer )
4082+ {
4083+ uint8_t allocated_pool_size = 0 ;
4084+ mctp_eid_t allocated_pool_start = 0 ;
4085+ int rc = 0 ;
4086+
4087+ /* Find pool sized contiguous unused eids to allocate on the bridge. */
4088+ peer -> pool_start = get_pool_start (peer , peer -> pool_start , peer -> pool_size );
4089+ if (peer -> pool_start == eid_alloc_max ) {
4090+ warnx ("%s failed to find contiguous EIDs of required size" , __func__ );
4091+ return -1 ;
4092+ } else {
4093+ if (peer -> ctx -> verbose )
4094+ fprintf (stderr , "%s Asking for contiguous EIDs for pool with start eid : %d\n" , __func__ , peer -> pool_start );
4095+ }
4096+
4097+ rc = endpoint_send_allocate_endpoint_id (peer , peer -> pool_start , peer -> pool_size ,
4098+ mctp_ctrl_cmd_alloc_eid_alloc_eid , & allocated_pool_size , & allocated_pool_start );
4099+ if (rc ) {
4100+ warnx ("%s failed to allocate endpoints, returned %s %d\n" ,
4101+ __func__ , strerror (- rc ), rc );
4102+ } else {
4103+ peer -> pool_size = allocated_pool_size ;
4104+ peer -> pool_start = allocated_pool_start ;
4105+
4106+ // Polling logic for downstream EID
4107+ }
4108+
4109+ return rc ;
4110+ }
4111+
39674112int main (int argc , char * * argv )
39684113{
39694114 struct ctx ctxi = {0 }, * ctx = & ctxi ;
0 commit comments