Skip to content

Commit ced6a95

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 <faizana@nvidia.com>
1 parent 04947a1 commit ced6a95

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);
@@ -1882,6 +1883,54 @@ static int check_peer_struct(const struct peer *peer, const struct net *n)
18821883
return 0;
18831884
}
18841885

1886+
/* Stops downstream endpoint polling and removes
1887+
* peer structure when bridge endpoint is being removed.
1888+
*/
1889+
static int remove_bridged_peers(struct peer *bridge)
1890+
{
1891+
mctp_eid_t ep, pool_start, pool_end;
1892+
struct poll_ctx *pctx = NULL;
1893+
struct peer *peer = NULL;
1894+
struct net *n = NULL;
1895+
int rc = 0;
1896+
1897+
pool_end = bridge->pool_start + bridge->pool_size - 1;
1898+
n = lookup_net(bridge->ctx, bridge->net);
1899+
pool_start = bridge->pool_start;
1900+
for (ep = pool_start; ep <= pool_end; ep++) {
1901+
// stop endpoint polling before removing peer
1902+
// else next trigger will create peer again.
1903+
int idx = ep - pool_start;
1904+
1905+
if (bridge->poll.sources && bridge->poll.sources[idx]) {
1906+
pctx = sd_event_source_get_userdata(
1907+
bridge->poll.sources[idx]);
1908+
rc = sd_event_source_set_enabled(
1909+
bridge->poll.sources[idx], SD_EVENT_OFF);
1910+
if (rc < 0) {
1911+
warnx("Failed to stop polling timer while removing peer %d: %s",
1912+
ep, strerror(-rc));
1913+
}
1914+
1915+
sd_event_source_unref(bridge->poll.sources[idx]);
1916+
bridge->poll.sources[idx] = NULL;
1917+
free(pctx);
1918+
}
1919+
peer = n->peers[ep];
1920+
if (!peer)
1921+
continue;
1922+
1923+
rc = remove_peer(peer);
1924+
if (rc < 0) {
1925+
warnx("Failed to remove peer %d from bridge eid %d pool [%d - %d]: %s",
1926+
ep, bridge->eid, pool_start, pool_end,
1927+
strerror(-rc));
1928+
}
1929+
}
1930+
1931+
return 0;
1932+
}
1933+
18851934
static int remove_peer(struct peer *peer)
18861935
{
18871936
struct ctx *ctx = peer->ctx;
@@ -1916,6 +1965,12 @@ static int remove_peer(struct peer *peer)
19161965
sd_event_source_unref(peer->recovery.source);
19171966
}
19181967

1968+
if (peer->pool_size) {
1969+
remove_bridged_peers(peer);
1970+
free(peer->poll.sources);
1971+
peer->poll.sources = NULL;
1972+
}
1973+
19191974
n->peers[peer->eid] = NULL;
19201975
free(peer->message_types);
19211976
free(peer->uuid);
@@ -1962,6 +2017,7 @@ static void free_peers(struct ctx *ctx)
19622017
free(peer->message_types);
19632018
free(peer->uuid);
19642019
free(peer->path);
2020+
free(peer->poll.sources);
19652021
sd_bus_slot_unref(peer->slot_obmc_endpoint);
19662022
sd_bus_slot_unref(peer->slot_cc_endpoint);
19672023
sd_bus_slot_unref(peer->slot_bridge);

0 commit comments

Comments
 (0)