Skip to content

Commit

Permalink
mptcp: add netlink pm addr entry refcount
Browse files Browse the repository at this point in the history
This patch adds the refcount of address entry in netlink PM. Initiate
'refcont' of every address entry to 1.

Increase this refcount counter when a subflow connecting or an address
signaling in mptcp_pm_nl_add_addr_doit(), fill_local_addresses_vec() and
mptcp_pm_create_subflow_or_signal_addr().

Decrease it when deleting an address in mptcp_pm_nl_del_addr_doit().
When the counter reaches 1, then free this entry.

Signed-off-by: Geliang Tang <geliang.tang@suse.com>
  • Loading branch information
geliangtang authored and Geliang Tang committed May 30, 2024
1 parent 4b0d980 commit 89ad32c
Showing 1 changed file with 22 additions and 8 deletions.
30 changes: 22 additions & 8 deletions net/mptcp/pm_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,10 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
continue;

spin_unlock_bh(&msk->pm.lock);
for (i = 0; i < nr; i++)
__mptcp_subflow_connect(sk, &local->addr, &addrs[i]);
for (i = 0; i < nr; i++) {
if (refcount_inc_not_zero(&local->refcnt))
__mptcp_subflow_connect(sk, &local->addr, &addrs[i]);
}
spin_lock_bh(&msk->pm.lock);
}
mptcp_pm_nl_check_work_pending(msk);
Expand Down Expand Up @@ -639,7 +641,8 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
if (!mptcp_pm_addr_families_match(sk, &entry->addr, remote))
continue;

if (msk->pm.subflows < subflows_max) {
if (msk->pm.subflows < subflows_max &&
refcount_inc_not_zero(&entry->refcnt)) {
msk->pm.subflows++;
addrs[i++] = entry->addr;
}
Expand Down Expand Up @@ -1088,6 +1091,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
entry->ifindex = 0;
entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
entry->lsk = NULL;
refcount_set(&entry->refcnt, 1);
ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
if (ret < 0)
kfree(entry);
Expand Down Expand Up @@ -1327,6 +1331,7 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
}

*entry = addr;
refcount_set(&entry->refcnt, 1);
if (entry->addr.port) {
ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry);
if (ret) {
Expand All @@ -1341,7 +1346,8 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
goto out_free;
}

mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk));
if (refcount_inc_not_zero(&entry->refcnt))
mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk));
return 0;

out_free:
Expand Down Expand Up @@ -1480,6 +1486,7 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
struct mptcp_pm_addr_entry addr, *entry;
bool release_entry = false;
unsigned int addr_max;
int ret;

Expand Down Expand Up @@ -1511,14 +1518,21 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
WRITE_ONCE(pernet->local_addr_max, addr_max - 1);
}

pernet->addrs--;
list_del_rcu(&entry->list);
__clear_bit(entry->addr.id, pernet->id_bitmap);
if (refcount_dec_not_one(&entry->refcnt) &&
refcount_read(&entry->refcnt) == 1) {
pernet->addrs--;
list_del_rcu(&entry->list);
__clear_bit(entry->addr.id, pernet->id_bitmap);
release_entry = true;
}
spin_unlock_bh(&pernet->lock);

mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), entry);
synchronize_rcu();
__mptcp_pm_release_addr_entry(entry);
if (release_entry)
__mptcp_pm_release_addr_entry(entry);
else
entry->flags |= MPTCP_PM_ADDR_FLAG_IMPLICIT;

return ret;
}
Expand Down

0 comments on commit 89ad32c

Please sign in to comment.