@@ -2360,10 +2360,14 @@ static int method_setup_endpoint(sd_bus_message *call, void *data,
23602360 sd_bus_error * berr )
23612361{
23622362 dest_phys desti = { 0 }, * dest = & desti ;
2363+ uint8_t ep_type , medium_spec ;
23632364 const char * peer_path = NULL ;
23642365 struct link * link = data ;
23652366 struct ctx * ctx = link -> ctx ;
23662367 struct peer * peer = NULL ;
2368+ bool new = true;
2369+ mctp_eid_t eid ;
2370+ uint32_t net ;
23672371 int rc ;
23682372
23692373 dest -> ifindex = link -> ifindex ;
@@ -2380,53 +2384,89 @@ static int method_setup_endpoint(sd_bus_message *call, void *data,
23802384 return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
23812385 "Bad physaddr" );
23822386
2387+ net = mctp_nl_net_byindex (ctx -> nl , dest -> ifindex );
2388+ if (!net ) {
2389+ rc = - EINVAL ;
2390+ goto err ;
2391+ }
2392+
23832393 /* Get Endpoint ID */
2384- rc = get_endpoint_peer (ctx , berr , dest , & peer , NULL );
2385- if (rc >= 0 && peer ) {
2386- uint8_t ep_type = GET_MCTP_GET_EID_EP_TYPE (peer -> endpoint_type );
2387- if (ep_type == MCTP_GET_EID_EP_TYPE_BRIDGE ) {
2388- fprintf (stderr ,
2389- "SetupEndpoint, eid %d: Get EID "
2390- "response indicated a bridge with existing "
2391- "EID, reassigning\n" ,
2392- peer -> eid );
2393- remove_peer (peer );
2394- peer = NULL ;
2394+ rc = query_get_endpoint_id (ctx , dest , & eid , & ep_type , & medium_spec );
2395+ if (rc )
2396+ goto err ;
2397+
2398+ /* does it exist already? */
2399+ peer = find_peer_by_phys (ctx , dest );
2400+
2401+ /* we have a few cases:
2402+ *
2403+ * - no peer, no eid
2404+ * --> set up both
2405+ * - no peer, eid, not a bridge:
2406+ * --> create a peer with the given EID
2407+ * - no peer, eid, bridge:
2408+ * --> reassign, including bridge
2409+ * - peer, eid (but not matching)
2410+ * --> change EID if possible, or reassign
2411+ * - peer, no eid:
2412+ * --> remove peer, reassign
2413+ */
2414+
2415+ bool is_bridge = GET_MCTP_GET_EID_EP_TYPE (ep_type ) ==
2416+ MCTP_GET_EID_EP_TYPE_BRIDGE ;
2417+
2418+ printf ("%s: peer %p, eid %d, is_bridge %d ep type %x\n" , __func__ , peer ,
2419+ eid , is_bridge , ep_type );
2420+
2421+ if (peer ) {
2422+ /* TODO: we could check the bridge allocation through the
2423+ * Get Allocation Information op of Allocate Endpoint IDs,
2424+ * and be slightly more accurate with persisting the EID...
2425+ */
2426+ if (eid && peer -> eid == eid && is_bridge == !!peer -> pool_size ) {
2427+ /* all matching: no action required */
2428+ new = false;
2429+ goto out ;
2430+ }
2431+ /* we have some difference in EID / bridge config, remove and
2432+ * reassign */
2433+ remove_peer (peer );
2434+ peer = NULL ;
2435+ }
2436+
2437+ /* simple allocation: try to use existing EID */
2438+ if (eid && !is_bridge ) {
2439+ rc = add_peer (ctx , dest , eid , net , & peer , false);
2440+ if (rc == - EEXIST ) {
2441+ /* proposed EID already present on a different peer,
2442+ * fall back to assigning */
2443+ } else if (rc < 0 ) {
2444+ goto err ;
23952445 } else {
2396- if (ctx -> verbose )
2397- fprintf (stderr ,
2398- "%s returning from get_endpoint_peer %s\n" ,
2399- __func__ , peer_tostr (peer ));
2400- peer_path = path_from_peer (peer );
2401- if (!peer_path )
2446+ peer -> endpoint_type = ep_type ;
2447+ peer -> medium_spec = medium_spec ;
2448+ rc = setup_added_peer (peer );
2449+ if (rc )
24022450 goto err ;
2403- return sd_bus_reply_method_return (call , "yisb" ,
2404- peer -> eid , peer -> net ,
2405- peer_path , 0 );
2451+ goto out ;
24062452 }
2407- } else if (rc == - EEXIST ) {
2408- // EEXISTS is OK, we will assign a new eid instead.
2409- } else if (rc < 0 ) {
2410- // Unhandled error, fail.
2411- goto err ;
24122453 }
24132454
2414- /* Set Endpoint ID */
24152455 rc = endpoint_assign_eid (ctx , berr , dest , & peer , 0 , true);
24162456 if (rc < 0 )
24172457 goto err ;
24182458
24192459 if (peer -> pool_size )
24202460 endpoint_allocate_eids (peer );
24212461
2462+ out :
24222463 peer_path = path_from_peer (peer );
2423- if (!peer_path )
2464+ if (!peer_path ) {
2465+ rc = - EPROTO ;
24242466 goto err ;
2425- if (ctx -> verbose )
2426- fprintf (stderr , "%s returning from endpoint_assign_eid %s\n" ,
2427- __func__ , peer_tostr (peer ));
2467+ }
24282468 return sd_bus_reply_method_return (call , "yisb" , peer -> eid , peer -> net ,
2429- peer_path , 1 );
2469+ peer_path , new );
24302470
24312471err :
24322472 set_berr (ctx , rc , berr );
0 commit comments