@@ -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 [];
@@ -2033,6 +2034,20 @@ static int method_setup_endpoint(sd_bus_message *call, void *data, sd_bus_error
20332034 if (ctx -> verbose )
20342035 fprintf (stderr , "%s returning from endpoint_assign_eid %s\n" ,
20352036 __func__ , peer_tostr (peer ));
2037+ if (peer -> pool_size > 0 ) {
2038+ // Dynamic pool EID starts after bridge's EID
2039+ peer -> pool_start = peer -> eid + 1 ;
2040+ // Call for Allocate EndpointID
2041+ rc = endpoint_allocate_eid (peer );
2042+ if (rc < 0 ) {
2043+ warnx ("Failed to allocate downstream EIDs" );
2044+ } else {
2045+ if (peer -> ctx -> verbose ) {
2046+ fprintf (stderr , "Downstream EIDs assigned from %d to %d : pool size %d\n" ,
2047+ peer -> pool_start , peer -> pool_start + peer -> pool_size - 1 , peer -> pool_size );
2048+ }
2049+ }
2050+ }
20362051 return sd_bus_reply_method_return (call , "yisb" ,
20372052 peer -> eid , peer -> net , peer_path , 1 );
20382053
@@ -2087,6 +2102,15 @@ static int method_assign_endpoint(sd_bus_message *call, void *data, sd_bus_error
20872102 // Dynamic pool EID starts after bridge's EID
20882103 peer -> pool_start = peer -> eid + 1 ;
20892104 // Call for Allocate EndpointID
2105+ rc = endpoint_allocate_eid (peer );
2106+ if (rc < 0 ) {
2107+ warnx ("Failed to allocate downstream EIDs" );
2108+ } else {
2109+ if (peer -> ctx -> verbose ) {
2110+ fprintf (stderr , "Downstream EIDs assigned from %d to %d : pool size %d\n" ,
2111+ peer -> pool_start , peer -> pool_start + peer -> pool_size - 1 , peer -> pool_size );
2112+ }
2113+ }
20902114 }
20912115
20922116 return sd_bus_reply_method_return (call , "yisb" ,
@@ -2164,6 +2188,15 @@ static int method_assign_endpoint_static(sd_bus_message *call, void *data,
21642188 // Dynamic pool EID starts after bridge's EID
21652189 peer -> pool_start = peer -> eid + 1 ;
21662190 // Call for Allocate EndpointID
2191+ rc = endpoint_allocate_eid (peer );
2192+ if (rc < 0 ) {
2193+ warnx ("Failed to allocate downstream EIDs" );
2194+ } else {
2195+ if (peer -> ctx -> verbose ) {
2196+ fprintf (stderr , "Downstream EIDs assigned from %d to %d : pool size %d\n" ,
2197+ peer -> pool_start , peer -> pool_start + peer -> pool_size - 1 , peer -> pool_size );
2198+ }
2199+ }
21672200 }
21682201
21692202 return sd_bus_reply_method_return (call , "yisb" ,
@@ -2196,7 +2229,6 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
21962229 if (rc < 0 )
21972230 return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
21982231 "Bad physaddr" );
2199-
22002232 rc = get_endpoint_peer (ctx , berr , dest , & peer , & eid );
22012233 if (rc == - EEXIST ) {
22022234 /* We have a conflict with an existing endpoint, so can't
@@ -2308,6 +2340,15 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
23082340 peer -> pool_size = min (peer -> pool_size , pool_size );
23092341
23102342 //call for Allocate EndpointID
2343+ rc = endpoint_allocate_eid (peer );
2344+ if (rc < 0 ) {
2345+ msg_len += snprintf (msg + msg_len , sizeof (msg ) - msg_len ,
2346+ ". Failed to allocate downstream EIDs" );
2347+ } else {
2348+ msg_len += snprintf (msg + msg_len , sizeof (msg ) - msg_len ,
2349+ ". Downstream EIDs assigned from %d to %d : pool size %d" ,
2350+ peer -> pool_start , peer -> pool_start + peer -> pool_size - 1 , peer -> pool_size );
2351+ }
23112352 }
23122353
23132354 return sd_bus_reply_method_return (call , "yisbs" ,
@@ -2876,6 +2917,7 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
28762917 SD_BUS_PARAM (found ),
28772918 method_learn_endpoint ,
28782919 0 ),
2920+
28792921 SD_BUS_METHOD_WITH_NAMES ("AssignBridgeStatic" ,
28802922 "ayyyy" ,
28812923 SD_BUS_PARAM (physaddr )
@@ -3964,6 +4006,124 @@ static void free_config(struct ctx *ctx)
39644006 free (ctx -> config_filename );
39654007}
39664008
4009+ static int endpoint_send_allocate_endpoint_id (struct peer * peer ,
4010+ mctp_eid_t eid_start , uint8_t eid_pool_size , mctp_ctrl_cmd_alloc_eid_op oper ,
4011+ uint8_t * allocated_pool_size , mctp_eid_t * allocated_pool_start )
4012+ {
4013+ struct sockaddr_mctp_ext addr ;
4014+ struct mctp_ctrl_cmd_alloc_eid req = {0 };
4015+ struct mctp_ctrl_resp_alloc_eid * resp = NULL ;
4016+ uint8_t * buf = NULL ;
4017+ size_t buf_size ;
4018+ uint8_t iid , stat ;
4019+ int rc ;
4020+
4021+ iid = mctp_next_iid (peer -> ctx );
4022+ req .ctrl_hdr .rq_dgram_inst = RQDI_REQ | iid ;
4023+ req .ctrl_hdr .command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS ;
4024+ req .alloc_eid_op = (uint8_t )(oper & 0x03 );
4025+ req .pool_size = eid_pool_size ;
4026+ req .start_eid = eid_start ;
4027+ rc = endpoint_query_peer (peer , MCTP_CTRL_HDR_MSG_TYPE , & req , sizeof (req ),
4028+ & buf , & buf_size , & addr );
4029+ if (rc < 0 )
4030+ goto out ;
4031+
4032+ rc = mctp_ctrl_validate_response (buf , buf_size , sizeof (* resp ),
4033+ peer_tostr_short (peer ), iid ,
4034+ MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS );
4035+
4036+ if (rc )
4037+ goto out ;
4038+
4039+ resp = (void * )buf ;
4040+ if (!resp ) {
4041+ warnx ("%s Invalid response Buffer\n" , __func__ );
4042+ return - ENOMEM ;
4043+ }
4044+
4045+ stat = resp -> status & 0x03 ;
4046+ if (stat == 0x00 ) {
4047+ if (peer -> ctx -> verbose ) {
4048+ fprintf (stderr , "%s Allocation Accepted \n" , __func__ );
4049+ }
4050+ }
4051+ else if (stat == 0x1 ) {
4052+ warnx ("%s Allocation was rejected as it was Allocated by other bus \n" , __func__ );
4053+ }
4054+
4055+ * allocated_pool_size = resp -> eid_pool_size ;
4056+ * allocated_pool_start = resp -> eid_set ;
4057+ if (peer -> ctx -> verbose ) {
4058+ fprintf (stderr , "%s Allocated size of %d, starting from EID %d\n" , __func__ ,
4059+ resp -> eid_pool_size , resp -> eid_set );
4060+ }
4061+
4062+ return 0 ;
4063+ out :
4064+ free (buf );
4065+ return rc ;
4066+ }
4067+
4068+ static mctp_eid_t get_pool_start (struct peer * peer , mctp_eid_t eid_start , uint8_t pool_size )
4069+ {
4070+ uint8_t count = 0 ;
4071+ mctp_eid_t pool_start = eid_alloc_max ;
4072+ struct net * n = lookup_net (peer -> ctx , peer -> net );
4073+
4074+ if (!n ) {
4075+ warnx ("BUG: Unknown net %d : failed to get pool start\n" , peer -> net );
4076+ return eid_alloc_max ;
4077+ }
4078+
4079+ for (mctp_eid_t e = eid_start ; e <= eid_alloc_max ; e ++ ) {
4080+ if (n -> peers [e ] == NULL ) {
4081+ if (pool_start == eid_alloc_max ) {
4082+ pool_start = e ;
4083+ }
4084+ count ++ ;
4085+ if (count == pool_size ) return pool_start ;
4086+ } else {
4087+ pool_start = eid_alloc_max ;
4088+ count = 0 ;
4089+ }
4090+ }
4091+
4092+ return eid_alloc_max ;
4093+ }
4094+
4095+ static int endpoint_allocate_eid (struct peer * peer )
4096+ {
4097+ uint8_t allocated_pool_size = 0 ;
4098+ mctp_eid_t allocated_pool_start = 0 ;
4099+ int rc = 0 ;
4100+
4101+ /* Find pool sized contiguous unused eids to allocate on the bridge. */
4102+ peer -> pool_start = get_pool_start (peer , peer -> pool_start , peer -> pool_size );
4103+ if (peer -> pool_start == eid_alloc_max ) {
4104+ warnx ("%s failed to find contiguous EIDs of required size" , __func__ );
4105+ return -1 ;
4106+ } else {
4107+ if (peer -> ctx -> verbose )
4108+ fprintf (stderr , "%s Asking for contiguous EIDs for pool with start eid : %d\n" , __func__ , peer -> pool_start );
4109+ }
4110+
4111+ rc = endpoint_send_allocate_endpoint_id (peer , peer -> pool_start , peer -> pool_size ,
4112+ mctp_ctrl_cmd_alloc_eid_alloc_eid , & allocated_pool_size , & allocated_pool_start );
4113+ if (rc ) {
4114+ warnx ("%s failed to allocate endpoints, returned %s %d\n" ,
4115+ __func__ , strerror (- rc ), rc );
4116+ } else {
4117+ peer -> pool_size = allocated_pool_size ;
4118+ peer -> pool_start = allocated_pool_start ;
4119+
4120+ // add Gateway route for all Bridge's downstream eids
4121+ // Polling logic for downstream EID
4122+ }
4123+
4124+ return rc ;
4125+ }
4126+
39674127int main (int argc , char * * argv )
39684128{
39694129 struct ctx ctxi = {0 }, * ctx = & ctxi ;
0 commit comments