@@ -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 [];
@@ -2184,7 +2185,6 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
2184
2185
if (rc < 0 )
2185
2186
return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
2186
2187
"Bad physaddr" );
2187
-
2188
2188
rc = get_endpoint_peer (ctx , berr , dest , & peer , & eid );
2189
2189
if (rc == - EEXIST ) {
2190
2190
/* 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
2211
2211
static int method_assign_bridge_static (sd_bus_message * call , void * data ,
2212
2212
sd_bus_error * berr )
2213
2213
{
2214
- char * peer_path = NULL ;
2214
+ const char * peer_path = NULL ;
2215
2215
dest_phys desti , * dest = & desti ;
2216
2216
struct link * link = data ;
2217
2217
struct ctx * ctx = link -> ctx ;
2218
2218
struct peer * peer = NULL ;
2219
2219
uint8_t eid , pool_start , pool_size ;
2220
+ char msg [200 ]; // Increased buffer size for multiple messages
2221
+ int msg_len = 0 ;
2220
2222
int rc ;
2221
2223
2222
2224
dest -> ifindex = link -> ifindex ;
2225
+ memset (msg , '\0' , sizeof (msg ));
2226
+
2223
2227
if (dest -> ifindex <= 0 )
2224
2228
return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
2225
2229
"Unknown MCTP interface" );
@@ -2257,8 +2261,8 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
2257
2261
if (!peer_path )
2258
2262
goto err ;
2259
2263
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 );
2262
2266
} else {
2263
2267
uint32_t netid ;
2264
2268
@@ -2277,21 +2281,29 @@ static int method_assign_bridge_static(sd_bus_message *call, void *data,
2277
2281
}
2278
2282
2279
2283
peer_path = path_from_peer (peer );
2284
+ msg_len = snprintf (msg , sizeof (msg ), "Statically assigned Bridge %d" , peer -> eid );
2280
2285
if (!peer_path ) {
2281
2286
goto err ;
2282
2287
}
2283
2288
2284
- if (peer -> pool_size > 0 ) {
2289
+ if (peer -> pool_size > 0 ) {
2285
2290
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 );
2288
2292
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 );
2290
2302
}
2291
2303
}
2292
2304
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 );
2295
2307
err :
2296
2308
set_berr (ctx , rc , berr );
2297
2309
return rc ;
@@ -2856,17 +2868,19 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
2856
2868
SD_BUS_PARAM (found ),
2857
2869
method_learn_endpoint ,
2858
2870
0 ),
2871
+
2859
2872
SD_BUS_METHOD_WITH_NAMES ("AssignBridgeStatic" ,
2860
2873
"ayyyy" ,
2861
2874
SD_BUS_PARAM (physaddr )
2862
2875
SD_BUS_PARAM (eid )
2863
2876
SD_BUS_PARAM (pool_start )
2864
2877
SD_BUS_PARAM (pool_size ),
2865
- "yisb " ,
2878
+ "yisbs " ,
2866
2879
SD_BUS_PARAM (eid )
2867
2880
SD_BUS_PARAM (net )
2868
2881
SD_BUS_PARAM (path )
2869
- SD_BUS_PARAM (new ),
2882
+ SD_BUS_PARAM (new )
2883
+ SD_BUS_PARAM (msg ),
2870
2884
method_assign_bridge_static ,
2871
2885
0 ),
2872
2886
SD_BUS_VTABLE_END ,
@@ -3943,6 +3957,122 @@ static void free_config(struct ctx *ctx)
3943
3957
free (ctx -> config_filename );
3944
3958
}
3945
3959
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
+
3946
4076
int main (int argc , char * * argv )
3947
4077
{
3948
4078
struct ctx ctxi = {0 }, * ctx = & ctxi ;
0 commit comments