@@ -250,6 +250,7 @@ static int del_local_eid(struct ctx *ctx, uint32_t net, int eid);
250
250
static int add_net (struct ctx * ctx , uint32_t net );
251
251
static void del_net (struct net * net );
252
252
static int add_interface (struct ctx * ctx , int ifindex );
253
+ static int endpoint_allocate_eid (struct peer * peer );
253
254
254
255
static const sd_bus_vtable bus_endpoint_obmc_vtable [];
255
256
static 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
2087
2088
// Dynamic pool EID starts after bridge's EID
2088
2089
peer -> pool_start = peer -> eid + 1 ;
2089
2090
// 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
+ }
2090
2100
}
2091
2101
2092
2102
return sd_bus_reply_method_return (call , "yisb" ,
@@ -2164,6 +2174,15 @@ static int method_assign_endpoint_static(sd_bus_message *call, void *data,
2164
2174
// Dynamic pool EID starts after bridge's EID
2165
2175
peer -> pool_start = peer -> eid + 1 ;
2166
2176
// 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
+ }
2167
2186
}
2168
2187
2169
2188
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
2196
2215
if (rc < 0 )
2197
2216
return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
2198
2217
"Bad physaddr" );
2199
-
2200
2218
rc = get_endpoint_peer (ctx , berr , dest , & peer , & eid );
2201
2219
if (rc == - EEXIST ) {
2202
2220
/* 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,
2308
2326
peer -> pool_size = min (peer -> pool_size , pool_size );
2309
2327
2310
2328
//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
+ }
2311
2338
}
2312
2339
2313
2340
return sd_bus_reply_method_return (call , "yisbs" ,
@@ -2876,6 +2903,7 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
2876
2903
SD_BUS_PARAM (found ),
2877
2904
method_learn_endpoint ,
2878
2905
0 ),
2906
+
2879
2907
SD_BUS_METHOD_WITH_NAMES ("AssignBridgeStatic" ,
2880
2908
"ayyyy" ,
2881
2909
SD_BUS_PARAM (physaddr )
@@ -3964,6 +3992,123 @@ static void free_config(struct ctx *ctx)
3964
3992
free (ctx -> config_filename );
3965
3993
}
3966
3994
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
+
3967
4112
int main (int argc , char * * argv )
3968
4113
{
3969
4114
struct ctx ctxi = {0 }, * ctx = & ctxi ;
0 commit comments