This patch adds userspace PM address entry refcount. Add a new filed
'refcont' in struct mptcp_pm_addr_entry, inited to 1.
Increase this counter in mptcp_nl_cmd_sf_create(), and decrease it in
mptcp_userspace_pm_delete_local_addr() according the subflows value.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
net/mptcp/pm_userspace.c | 21 +++++++++++++++------
net/mptcp/protocol.h | 2 ++
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 75c08375f6f4..d3846f2e8339 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -70,6 +70,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
1);
list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
msk->pm.local_addr_used++;
+ refcount_set(&e->refcnt, 1);
ret = e->addr.id;
} else if (match) {
ret = entry->addr.id;
@@ -107,9 +108,12 @@ static int mptcp_userspace_pm_delete_local_addr(struct mptcp_sock *msk,
if (!entry)
return -EINVAL;
- /* TODO: a refcount is needed because the entry can
- * be used multiple times (e.g. fullmesh mode).
- */
+ if (!refcount_dec_not_one(&entry->refcnt)) {
+ pr_debug("userspace refcount error: refcnt=%d",
+ refcount_read(&entry->refcnt));
+ return -EINVAL;
+ }
+
list_del_rcu(&entry->list);
kfree(entry);
msk->pm.local_addr_used--;
@@ -387,10 +391,15 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
release_sock(sk);
spin_lock_bh(&msk->pm.lock);
- if (err)
+ if (err) {
mptcp_userspace_pm_delete_local_addr(msk, &local);
- else
- msk->pm.subflows++;
+ } else {
+ struct mptcp_pm_addr_entry *entry;
+
+ entry = mptcp_userspace_pm_get_entry(msk, &addr_l);
+ if (entry && refcount_inc_not_zero(&entry->refcnt))
+ msk->pm.subflows++;
+ }
spin_unlock_bh(&msk->pm.lock);
create_err:
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 6ec1d967f22c..7adad41b5c1d 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -8,6 +8,7 @@
#define __MPTCP_PROTOCOL_H
#include <linux/random.h>
+#include <linux/refcount.h>
#include <net/tcp.h>
#include <net/inet_connection_sock.h>
#include <uapi/linux/mptcp.h>
@@ -241,6 +242,7 @@ struct mptcp_pm_addr_entry {
u8 flags;
int ifindex;
struct socket *lsk;
+ refcount_t refcnt;
};
struct mptcp_data_frag {
--
2.35.3