@@ -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 [];
@@ -2184,7 +2185,6 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
21842185 if (rc < 0 )
21852186 return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
21862187 "Bad physaddr" );
2187-
21882188 rc = get_endpoint_peer (ctx , berr , dest , & peer , & eid );
21892189 if (rc == - EEXIST ) {
21902190 /* We have a conflict with an existing endpoint, so can't
@@ -2211,15 +2211,19 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
22112211static int method_assign_bridge_static (sd_bus_message * call , void * data ,
22122212 sd_bus_error * berr )
22132213{
2214- char * peer_path = NULL ;
2214+ const char * peer_path = NULL ;
22152215 dest_phys desti , * dest = & desti ;
22162216 struct link * link = data ;
22172217 struct ctx * ctx = link -> ctx ;
22182218 struct peer * peer = NULL ;
22192219 uint8_t eid , pool_start , pool_size ;
2220+ char msg [200 ]; // Increased buffer size for multiple messages
2221+ int msg_len = 0 ;
22202222 int rc ;
22212223
22222224 dest -> ifindex = link -> ifindex ;
2225+ memset (msg , '\0' , sizeof (msg ));
2226+
22232227 if (dest -> ifindex <= 0 )
22242228 return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
22252229 "Unknown MCTP interface" );
@@ -2257,8 +2261,8 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
22572261 if (!peer_path )
22582262 goto err ;
22592263
2260- return sd_bus_reply_method_return (call , "yisb " ,
2261- peer -> eid , peer -> net , peer_path , 0 );
2264+ return sd_bus_reply_method_return (call , "yisbs " ,
2265+ peer -> eid , peer -> net , peer_path , 0 , msg );
22622266 } else {
22632267 uint32_t netid ;
22642268
@@ -2277,21 +2281,29 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
22772281 }
22782282
22792283 peer_path = path_from_peer (peer );
2284+ msg_len = snprintf (msg , sizeof (msg ), "Statically assigned Bridge %d" , peer -> eid );
22802285 if (!peer_path ) {
22812286 goto err ;
22822287 }
22832288
2284- if (peer -> pool_size > 0 ) {
2289+ if (peer -> pool_size > 0 ) {
22852290 peer -> pool_start = pool_start ;
2286- if (peer -> pool_size && peer -> pool_size > pool_size ) {
2287- peer -> pool_size = pool_size ;
2291+ peer -> pool_size = min (peer -> pool_size , pool_size );
22882292
2289- //call for Allocate EndpointID
2293+ //call for Allocate EndpointID
2294+ rc = endpoint_allocate_eid (peer );
2295+ if (rc < 0 ) {
2296+ msg_len += snprintf (msg + msg_len , sizeof (msg ) - msg_len ,
2297+ ". Failed to allocate downstream EIDs" );
2298+ } else {
2299+ msg_len += snprintf (msg + msg_len , sizeof (msg ) - msg_len ,
2300+ ". Downstream EIDs assigned from %d to %d : pool size %d" ,
2301+ peer -> pool_start , peer -> pool_start + peer -> pool_size - 1 , peer -> pool_size );
22902302 }
22912303 }
22922304
2293- return sd_bus_reply_method_return (call , "yisb " ,
2294- peer -> eid , peer -> net , peer_path , 1 );
2305+ return sd_bus_reply_method_return (call , "yisbs " ,
2306+ peer -> eid , peer -> net , peer_path , 1 , msg );
22952307err :
22962308 set_berr (ctx , rc , berr );
22972309 return rc ;
@@ -2856,17 +2868,19 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
28562868 SD_BUS_PARAM (found ),
28572869 method_learn_endpoint ,
28582870 0 ),
2871+
28592872 SD_BUS_METHOD_WITH_NAMES ("AssignBridgeStatic" ,
28602873 "ayyyy" ,
28612874 SD_BUS_PARAM (physaddr )
28622875 SD_BUS_PARAM (eid )
28632876 SD_BUS_PARAM (pool_start )
28642877 SD_BUS_PARAM (pool_size ),
2865- "yisb " ,
2878+ "yisbs " ,
28662879 SD_BUS_PARAM (eid )
28672880 SD_BUS_PARAM (net )
28682881 SD_BUS_PARAM (path )
2869- SD_BUS_PARAM (new ),
2882+ SD_BUS_PARAM (new )
2883+ SD_BUS_PARAM (msg ),
28702884 method_assign_bridge_static ,
28712885 0 ),
28722886 SD_BUS_VTABLE_END ,
@@ -3943,6 +3957,122 @@ static void free_config(struct ctx *ctx)
39433957 free (ctx -> config_filename );
39443958}
39453959
3960+ static int endpoint_send_allocate_endpoint_id (struct peer * peer ,
3961+ mctp_eid_t eid_start , uint8_t eid_pool_size , mctp_ctrl_cmd_alloc_eid_op oper ,
3962+ uint8_t * allocated_pool_size , mctp_eid_t * allocated_pool_start )
3963+ {
3964+ struct sockaddr_mctp_ext addr ;
3965+ struct mctp_ctrl_cmd_alloc_eid req = {0 };
3966+ struct mctp_ctrl_resp_alloc_eid * resp = NULL ;
3967+ uint8_t * buf = NULL ;
3968+ size_t buf_size ;
3969+ uint8_t iid , stat ;
3970+ int rc ;
3971+
3972+ iid = mctp_next_iid (peer -> ctx );
3973+ req .ctrl_hdr .rq_dgram_inst = RQDI_REQ | iid ;
3974+ req .ctrl_hdr .command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS ;
3975+ req .alloc_eid_op = (uint8_t )(oper & 0x03 );
3976+ req .pool_size = eid_pool_size ;
3977+ req .start_eid = eid_start ;
3978+ rc = endpoint_query_peer (peer , MCTP_CTRL_HDR_MSG_TYPE , & req , sizeof (req ),
3979+ & buf , & buf_size , & addr );
3980+ if (rc < 0 )
3981+ goto out ;
3982+
3983+ rc = mctp_ctrl_validate_response (buf , buf_size , sizeof (* resp ),
3984+ peer_tostr_short (peer ), iid ,
3985+ MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS );
3986+
3987+ if (rc )
3988+ goto out ;
3989+
3990+ resp = (void * )buf ;
3991+ if (!resp ) {
3992+ warnx ("%s Invalid response Buffer\n" , __func__ );
3993+ return - ENOMEM ;
3994+ }
3995+
3996+ stat = resp -> status & 0x03 ;
3997+ if (stat == 0x00 ) {
3998+ if (peer -> ctx -> verbose ) {
3999+ fprintf (stderr , "%s Allocation Accepted \n" , __func__ );
4000+ }
4001+ }
4002+ else if (stat == 0x1 ) {
4003+ warnx ("%s Allocation was rejected as it was Allocated by other bus \n" , __func__ );
4004+ }
4005+
4006+ * allocated_pool_size = resp -> eid_pool_size ;
4007+ * allocated_pool_start = resp -> eid_set ;
4008+ if (peer -> ctx -> verbose ) {
4009+ fprintf (stderr , "%s Allocated size of %d, starting from EID %d\n" , __func__ ,
4010+ resp -> eid_pool_size , resp -> eid_set );
4011+ }
4012+
4013+ return 0 ;
4014+ out :
4015+ free (buf );
4016+ return rc ;
4017+ }
4018+
4019+ static mctp_eid_t get_pool_start (struct peer * peer , mctp_eid_t eid_start , uint8_t pool_size )
4020+ {
4021+ uint8_t count = 0 ;
4022+ mctp_eid_t pool_start = eid_alloc_max ;
4023+ struct net * n = lookup_net (peer -> ctx , peer -> net );
4024+
4025+ if (!n ) {
4026+ warnx ("BUG: Unknown net %d : failed to get pool start\n" , peer -> net );
4027+ return eid_alloc_max ;
4028+ }
4029+
4030+ for (mctp_eid_t e = eid_start ; e <= eid_alloc_max ; e ++ ) {
4031+ if (n -> peers [e ] == NULL ) {
4032+ if (pool_start == eid_alloc_max ) {
4033+ pool_start = e ;
4034+ }
4035+ count ++ ;
4036+ if (count == pool_size ) return pool_start ;
4037+ } else {
4038+ pool_start = eid_alloc_max ;
4039+ count = 0 ;
4040+ }
4041+ }
4042+
4043+ return eid_alloc_max ;
4044+ }
4045+
4046+ static int endpoint_allocate_eid (struct peer * peer )
4047+ {
4048+ uint8_t allocated_pool_size = 0 ;
4049+ mctp_eid_t allocated_pool_start = 0 ;
4050+
4051+ /* Find pool sized contiguous unused eids to allocate on the bridge. */
4052+ peer -> pool_start = get_pool_start (peer , peer -> pool_start , peer -> pool_size );
4053+ if (peer -> pool_start == eid_alloc_max ) {
4054+ warnx ("%s failed to find contiguous EIDs of required size" , __func__ );
4055+ return 0 ;
4056+ } else {
4057+ if (peer -> ctx -> verbose )
4058+ fprintf (stderr , "%s Asking for contiguous EIDs for pool with start eid : %d\n" , __func__ , peer -> pool_start );
4059+ }
4060+
4061+ int rc = endpoint_send_allocate_endpoint_id (peer , peer -> pool_start , peer -> pool_size ,
4062+ mctp_ctrl_cmd_alloc_eid_alloc_eid , & allocated_pool_size , & allocated_pool_start );
4063+ if (rc ) {
4064+ warnx ("%s failed to allocate endpoints, returned %s %d\n" ,
4065+ __func__ , strerror (- rc ), rc );
4066+ } else {
4067+ peer -> pool_size = allocated_pool_size ;
4068+ peer -> pool_start = allocated_pool_start ;
4069+
4070+ // Polling logic for downstream EID
4071+ }
4072+
4073+ return 0 ;
4074+ }
4075+
39464076int main (int argc , char * * argv )
39474077{
39484078 struct ctx ctxi = {0 }, * ctx = & ctxi ;
0 commit comments