@@ -265,6 +265,7 @@ static int add_peer_from_addr(struct ctx *ctx,
265265 const struct sockaddr_mctp_ext * addr ,
266266 struct peer * * ret_peer );
267267static int remove_peer (struct peer * peer );
268+ static int remove_bridged_peers (struct peer * bridge );
268269static int query_peer_properties (struct peer * peer );
269270static int setup_added_peer (struct peer * peer );
270271static void add_peer_route (struct peer * peer );
@@ -1828,6 +1829,50 @@ static int check_peer_struct(const struct peer *peer, const struct net *n)
18281829 return 0 ;
18291830}
18301831
1832+ /* Stops downstream endpoint polling and removes
1833+ * peer structure when bridge endpoint is being removed.
1834+ */
1835+ static int remove_bridged_peers (struct peer * bridge )
1836+ {
1837+ struct net * n = NULL ;
1838+ struct peer * peer = NULL ;
1839+ mctp_eid_t ep , pool_start , pool_end ;
1840+ int rc = 0 ;
1841+
1842+ n = lookup_net (bridge -> ctx , bridge -> net );
1843+ pool_start = bridge -> pool_start ;
1844+ pool_end = bridge -> pool_start + bridge -> pool_size - 1 ;
1845+ for (ep = pool_end ; ep >= pool_start ; ep -- ) {
1846+ // stop endpoint polling before removing peer
1847+ // else next trigger will create peer again.
1848+ int idx = ep - pool_start ;
1849+
1850+ if (bridge -> poll .sources && bridge -> poll .sources [idx ]) {
1851+ rc = sd_event_source_set_enabled (
1852+ bridge -> poll .sources [idx ], SD_EVENT_OFF );
1853+ if (rc < 0 ) {
1854+ warnx ("Failed to stop polling timer while removing peer %d: %s" ,
1855+ ep , strerror (- rc ));
1856+ }
1857+
1858+ sd_event_source_unref (bridge -> poll .sources [idx ]);
1859+ bridge -> poll .sources [idx ] = NULL ;
1860+ }
1861+ peer = n -> peers [ep ];
1862+ if (!peer )
1863+ continue ;
1864+
1865+ rc = remove_peer (peer );
1866+ if (rc < 0 ) {
1867+ warnx ("Failed to remove peer %d from bridge eid %d pool [%d - %d]: %s" ,
1868+ ep , bridge -> eid , pool_start , pool_end ,
1869+ strerror (- rc ));
1870+ }
1871+ }
1872+
1873+ return 0 ;
1874+ }
1875+
18311876static int remove_peer (struct peer * peer )
18321877{
18331878 struct ctx * ctx = peer -> ctx ;
@@ -1862,6 +1907,13 @@ static int remove_peer(struct peer *peer)
18621907 sd_event_source_unref (peer -> recovery .source );
18631908 }
18641909
1910+ if (peer -> pool_size ) {
1911+ remove_bridged_peers (peer );
1912+ free (peer -> poll .sources );
1913+ peer -> poll .sources = NULL ;
1914+ }
1915+
1916+ free (peer -> poll .sources );
18651917 n -> peers [peer -> eid ] = NULL ;
18661918 free (peer -> message_types );
18671919 free (peer -> uuid );
@@ -1908,6 +1960,7 @@ static void free_peers(struct ctx *ctx)
19081960 free (peer -> message_types );
19091961 free (peer -> uuid );
19101962 free (peer -> path );
1963+ free (peer -> poll .sources );
19111964 sd_bus_slot_unref (peer -> slot_obmc_endpoint );
19121965 sd_bus_slot_unref (peer -> slot_cc_endpoint );
19131966 sd_bus_slot_unref (peer -> slot_bridge );
0 commit comments