This patch adds netlink PM address entry refcont. Init refcont of
every address entry to 1, and init subflows of it to 0.
Increase both values in mptcp_pm_create_subflow_or_signal_addr() and
fill_local_addresses_vec(), and decrease refcont in
__mptcp_pm_release_addr_entry() according its subflows value.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
net/mptcp/pm_netlink.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 9661f3812682..09e632f72366 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -603,8 +603,12 @@ 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]);
+ local->subflows++;
+ }
+ }
spin_lock_bh(&msk->pm.lock);
}
mptcp_pm_nl_check_work_pending(msk);
@@ -644,9 +648,11 @@ 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;
+ entry->subflows++;
}
}
rcu_read_unlock();
@@ -895,6 +901,16 @@ static bool address_use_port(struct mptcp_pm_addr_entry *entry)
/* caller must ensure the RCU grace period is already elapsed */
static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry)
{
+ int i;
+
+ for (i = 0; i < entry->subflows; i++) {
+ if (!refcount_dec_not_one(&entry->refcnt)) {
+ pr_debug("netlink refcount error: refcnt=%d, subflows=%d",
+ refcount_read(&entry->refcnt), entry->subflows);
+ return;
+ }
+ }
+
if (entry->lsk)
sock_release(entry->lsk);
kfree(entry);
@@ -1087,6 +1103,8 @@ 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;
+ entry->subflows = 0;
+ refcount_set(&entry->refcnt, 1);
ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
if (ret < 0)
kfree(entry);
@@ -1337,6 +1355,7 @@ static int mptcp_nl_cmd_add_addr(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) {
--
2.35.3