@@ -276,6 +276,7 @@ static int add_peer_from_addr(struct ctx *ctx,
276276 const struct sockaddr_mctp_ext * addr ,
277277 struct peer * * ret_peer );
278278static int remove_peer (struct peer * peer );
279+ static int remove_bridged_peers (struct peer * bridge );
279280static int query_peer_properties (struct peer * peer );
280281static int setup_added_peer (struct peer * peer );
281282static void add_peer_route (struct peer * peer );
@@ -1881,6 +1882,54 @@ static int check_peer_struct(const struct peer *peer, const struct net *n)
18811882 return 0 ;
18821883}
18831884
1885+ /* Stops downstream endpoint polling and removes
1886+ * peer structure when bridge endpoint is being removed.
1887+ */
1888+ static int remove_bridged_peers (struct peer * bridge )
1889+ {
1890+ mctp_eid_t ep , pool_start , pool_end ;
1891+ struct poll_ctx * pctx = NULL ;
1892+ struct peer * peer = NULL ;
1893+ struct net * n = NULL ;
1894+ int rc = 0 ;
1895+
1896+ pool_end = bridge -> pool_start + bridge -> pool_size - 1 ;
1897+ n = lookup_net (bridge -> ctx , bridge -> net );
1898+ pool_start = bridge -> pool_start ;
1899+ for (ep = pool_end ; ep >= pool_start ; ep -- ) {
1900+ // stop endpoint polling before removing peer
1901+ // else next trigger will create peer again.
1902+ int idx = ep - pool_start ;
1903+
1904+ if (bridge -> poll .sources && bridge -> poll .sources [idx ]) {
1905+ pctx = sd_event_source_get_userdata (
1906+ bridge -> poll .sources [idx ]);
1907+ rc = sd_event_source_set_enabled (
1908+ bridge -> poll .sources [idx ], SD_EVENT_OFF );
1909+ if (rc < 0 ) {
1910+ warnx ("Failed to stop polling timer while removing peer %d: %s" ,
1911+ ep , strerror (- rc ));
1912+ }
1913+
1914+ sd_event_source_unref (bridge -> poll .sources [idx ]);
1915+ bridge -> poll .sources [idx ] = NULL ;
1916+ free (pctx );
1917+ }
1918+ peer = n -> peers [ep ];
1919+ if (!peer )
1920+ continue ;
1921+
1922+ rc = remove_peer (peer );
1923+ if (rc < 0 ) {
1924+ warnx ("Failed to remove peer %d from bridge eid %d pool [%d - %d]: %s" ,
1925+ ep , bridge -> eid , pool_start , pool_end ,
1926+ strerror (- rc ));
1927+ }
1928+ }
1929+
1930+ return 0 ;
1931+ }
1932+
18841933static int remove_peer (struct peer * peer )
18851934{
18861935 struct ctx * ctx = peer -> ctx ;
@@ -1915,6 +1964,12 @@ static int remove_peer(struct peer *peer)
19151964 sd_event_source_unref (peer -> recovery .source );
19161965 }
19171966
1967+ if (peer -> pool_size ) {
1968+ remove_bridged_peers (peer );
1969+ free (peer -> poll .sources );
1970+ peer -> poll .sources = NULL ;
1971+ }
1972+
19181973 n -> peers [peer -> eid ] = NULL ;
19191974 free (peer -> message_types );
19201975 free (peer -> uuid );
@@ -1961,6 +2016,7 @@ static void free_peers(struct ctx *ctx)
19612016 free (peer -> message_types );
19622017 free (peer -> uuid );
19632018 free (peer -> path );
2019+ free (peer -> poll .sources );
19642020 sd_bus_slot_unref (peer -> slot_obmc_endpoint );
19652021 sd_bus_slot_unref (peer -> slot_cc_endpoint );
19662022 sd_bus_slot_unref (peer -> slot_bridge );
0 commit comments