@@ -189,6 +189,11 @@ struct peer {
189189 uint8_t endpoint_type ;
190190 uint8_t medium_spec ;
191191 } recovery ;
192+
193+ // Pool size
194+ uint8_t pool_size ;
195+ uint8_t pool_start ;
196+
192197};
193198
194199struct ctx {
@@ -1299,7 +1304,7 @@ static int endpoint_query_phys(struct ctx *ctx, const dest_phys *dest,
12991304}
13001305
13011306/* returns -ECONNREFUSED if the endpoint returns failure. */
1302- static int endpoint_send_set_endpoint_id (const struct peer * peer , mctp_eid_t * new_eid )
1307+ static int endpoint_send_set_endpoint_id (struct peer * peer , mctp_eid_t * new_eid )
13031308{
13041309 struct sockaddr_mctp_ext addr ;
13051310 struct mctp_ctrl_cmd_set_eid req = {0 };
@@ -1346,9 +1351,11 @@ static int endpoint_send_set_endpoint_id(const struct peer *peer, mctp_eid_t *ne
13461351
13471352 alloc = resp -> status & 0x3 ;
13481353 if (alloc != 0 ) {
1349- // TODO for bridges
1350- warnx ("%s requested allocation pool, unimplemented" ,
1351- dest_phys_tostr (dest ));
1354+ peer -> pool_size = resp -> eid_pool_size ;
1355+ if (peer -> ctx -> verbose ) {
1356+ warnx ("%s requested allocation of pool size = %d" ,
1357+ dest_phys_tostr (dest ), peer -> pool_size );
1358+ }
13521359 }
13531360
13541361 rc = 0 ;
@@ -2076,6 +2083,12 @@ static int method_assign_endpoint(sd_bus_message *call, void *data, sd_bus_error
20762083 if (!peer_path )
20772084 goto err ;
20782085
2086+ if (peer -> pool_size > 0 ) {
2087+ // Dynamic pool EID starts after bridge's EID
2088+ peer -> pool_start = peer -> eid + 1 ;
2089+ // Call for Allocate EndpointID
2090+ }
2091+
20792092 return sd_bus_reply_method_return (call , "yisb" ,
20802093 peer -> eid , peer -> net , peer_path , 1 );
20812094err :
@@ -2147,6 +2160,12 @@ static int method_assign_endpoint_static(sd_bus_message *call, void *data,
21472160 if (!peer_path )
21482161 goto err ;
21492162
2163+ if (peer -> pool_size > 0 ) {
2164+ // Dynamic pool EID starts after bridge's EID
2165+ peer -> pool_start = peer -> eid + 1 ;
2166+ // Call for Allocate EndpointID
2167+ }
2168+
21502169 return sd_bus_reply_method_return (call , "yisb" ,
21512170 peer -> eid , peer -> net , peer_path , 1 );
21522171err :
@@ -2201,6 +2220,103 @@ static int method_learn_endpoint(sd_bus_message *call, void *data, sd_bus_error
22012220 return rc ;
22022221}
22032222
2223+ static int method_assign_bridge_static (sd_bus_message * call , void * data ,
2224+ sd_bus_error * berr )
2225+ {
2226+ const char * peer_path = NULL ;
2227+ dest_phys desti , * dest = & desti ;
2228+ struct link * link = data ;
2229+ struct ctx * ctx = link -> ctx ;
2230+ struct peer * peer = NULL ;
2231+ uint8_t eid , pool_start , pool_size ;
2232+ char msg [200 ];
2233+ int msg_len = 0 ;
2234+ int rc ;
2235+
2236+ dest -> ifindex = link -> ifindex ;
2237+ memset (msg , '\0' , sizeof (msg ));
2238+
2239+ if (dest -> ifindex <= 0 )
2240+ return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
2241+ "Unknown MCTP interface" );
2242+
2243+ rc = message_read_hwaddr (call , dest );
2244+ if (rc < 0 )
2245+ goto err ;
2246+
2247+ rc = sd_bus_message_read (call , "y" , & eid );
2248+ if (rc < 0 )
2249+ goto err ;
2250+
2251+ rc = sd_bus_message_read (call , "y" , & pool_start );
2252+ if (rc < 0 )
2253+ goto err ;
2254+
2255+ rc = sd_bus_message_read (call , "y" , & pool_size );
2256+ if (rc < 0 )
2257+ goto err ;
2258+
2259+ rc = validate_dest_phys (ctx , dest );
2260+ if (rc < 0 )
2261+ return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
2262+ "Bad physaddr" );
2263+
2264+ if (pool_start < eid ) {
2265+ return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
2266+ "Bridge Pool EIDs must start after Bridge's EID" );
2267+ }
2268+
2269+ peer = find_peer_by_phys (ctx , dest );
2270+ if (peer ) {
2271+ if (peer -> eid != eid ) {
2272+ return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
2273+ "Already assigned a different Bridge EID, Downstream EIDs must be already allocated" );
2274+ }
2275+
2276+ // Return existing record.
2277+ peer_path = path_from_peer (peer );
2278+ if (!peer_path )
2279+ goto err ;
2280+
2281+ return sd_bus_reply_method_return (call , "yisbs" ,
2282+ peer -> eid , peer -> net , peer_path , 0 , "Already assigned same Bridge EID, Downstream EIDs must be already allocated" );
2283+ } else {
2284+ uint32_t netid ;
2285+
2286+ // is the requested EID already in use? if so, reject
2287+ netid = mctp_nl_net_byindex (ctx -> nl , dest -> ifindex );
2288+ peer = find_peer_by_addr (ctx , eid , netid );
2289+ if (peer ) {
2290+ return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
2291+ "Address in use" );
2292+ }
2293+ }
2294+
2295+ rc = endpoint_assign_eid (ctx , berr , dest , & peer , eid );
2296+ if (rc < 0 ) {
2297+ goto err ;
2298+ }
2299+
2300+ peer_path = path_from_peer (peer );
2301+ msg_len = snprintf (msg , sizeof (msg ), "Statically assigned Bridge %d" , peer -> eid );
2302+ if (!peer_path ) {
2303+ goto err ;
2304+ }
2305+
2306+ if (peer -> pool_size > 0 ) {
2307+ peer -> pool_start = pool_start ;
2308+ peer -> pool_size = min (peer -> pool_size , pool_size );
2309+
2310+ //call for Allocate EndpointID
2311+ }
2312+
2313+ return sd_bus_reply_method_return (call , "yisbs" ,
2314+ peer -> eid , peer -> net , peer_path , 1 , msg );
2315+ err :
2316+ set_berr (ctx , rc , berr );
2317+ return rc ;
2318+ }
2319+
22042320// Query various properties of a peer.
22052321// To be called when a new peer is discovered/assigned, once an EID is known
22062322// and routable.
@@ -2760,6 +2876,20 @@ static const sd_bus_vtable bus_link_owner_vtable[] = {
27602876 SD_BUS_PARAM (found ),
27612877 method_learn_endpoint ,
27622878 0 ),
2879+ SD_BUS_METHOD_WITH_NAMES ("AssignBridgeStatic" ,
2880+ "ayyyy" ,
2881+ SD_BUS_PARAM (physaddr )
2882+ SD_BUS_PARAM (eid )
2883+ SD_BUS_PARAM (pool_start )
2884+ SD_BUS_PARAM (pool_size ),
2885+ "yisbs" ,
2886+ SD_BUS_PARAM (eid )
2887+ SD_BUS_PARAM (net )
2888+ SD_BUS_PARAM (path )
2889+ SD_BUS_PARAM (new )
2890+ SD_BUS_PARAM (msg ),
2891+ method_assign_bridge_static ,
2892+ 0 ),
27632893 SD_BUS_VTABLE_END ,
27642894
27652895};
0 commit comments