Skip to content

Commit 1485838

Browse files
mctpd: remove downstream peer and stop polling
Remove all downstream endpoints as well if bridge is being removed. Also stop endpoint periodic polling. Signed-off-by: Faizan Ali <[email protected]>
1 parent 0e9705c commit 1485838

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

src/mctpd.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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);
278278
static int remove_peer(struct peer *peer);
279+
static int remove_bridged_peers(struct peer *bridge);
279280
static int query_peer_properties(struct peer *peer);
280281
static int setup_added_peer(struct peer *peer);
281282
static 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+
18841933
static 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

Comments
 (0)