From: Geliang Tang <tanggeliang@kylinos.cn>
With the previous commit, we can reuse the send_nlmsg() code in
dump_addr interfaces between the netlink PM and userspace PM.
They only need to implement their own dump_addr() interfaces to
hold the different locks, copy the different address lists to an
id bitmap, then release the locks.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/pm_netlink.c | 56 +++++++++++++++++++++-------------------
net/mptcp/pm_userspace.c | 50 +++++------------------------------
net/mptcp/protocol.h | 4 +--
3 files changed, 38 insertions(+), 72 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index bcee83306e40..15ec8a193279 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1863,33 +1863,50 @@ int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
return ret;
}
-static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
- struct netlink_callback *cb)
+static int mptcp_pm_nl_dump_addr(struct mptcp_id_bitmap *bitmap,
+ const struct genl_info *info)
+{
+ struct net *net = genl_info_net(info);
+ struct pm_nl_pernet *pernet;
+
+ pernet = pm_nl_get_pernet(net);
+
+ spin_lock_bh(&pernet->lock);
+ bitmap_copy(bitmap->map, pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
+ spin_unlock_bh(&pernet->lock);
+
+ return 0;
+}
+
+static int mptcp_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
+ const struct genl_info *info)
+{
+ if (info->attrs[MPTCP_PM_ATTR_TOKEN])
+ return mptcp_userspace_pm_dump_addr(bitmap, info);
+ return mptcp_pm_nl_dump_addr(bitmap, info);
+}
+
+int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
+ struct netlink_callback *cb)
{
const struct genl_info *info = genl_info_dump(cb);
- struct net *net = sock_net(msg->sk);
struct mptcp_pm_addr_entry entry;
struct mptcp_id_bitmap *bitmap;
- struct pm_nl_pernet *pernet;
int id = cb->args[0];
void *hdr;
int i;
bitmap = (struct mptcp_id_bitmap *)cb->ctx;
- pernet = pm_nl_get_pernet(net);
- if (!id) {
- spin_lock_bh(&pernet->lock);
- bitmap_copy(bitmap->map, pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
- spin_unlock_bh(&pernet->lock);
- }
+ if (!id)
+ mptcp_pm_dump_addr(bitmap, info);
for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
if (test_bit(i, bitmap->map)) {
- if (mptcp_pm_nl_get_addr(i, &entry, info))
+ if (mptcp_pm_get_addr(i, &entry, info))
break;
- if (entry.addr.id <= id)
+ if (id && entry.addr.id <= id)
continue;
hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
@@ -1912,21 +1929,6 @@ static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
return msg->len;
}
-static int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb)
-{
- const struct genl_info *info = genl_info_dump(cb);
-
- if (info->attrs[MPTCP_PM_ATTR_TOKEN])
- return mptcp_userspace_pm_dump_addr(msg, cb);
- return mptcp_pm_nl_dump_addr(msg, cb);
-}
-
-int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
- struct netlink_callback *cb)
-{
- return mptcp_pm_dump_addr(msg, cb);
-}
-
static int parse_limit(struct genl_info *info, int id, unsigned int *limit)
{
struct nlattr *attr = info->attrs[id];
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index ad011a4fad4e..8858877d82b0 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -597,20 +597,12 @@ static int mptcp_userspace_pm_set_bitmap(struct mptcp_sock *msk,
return 0;
}
-int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
- struct netlink_callback *cb)
+int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
+ const struct genl_info *info)
{
- const struct genl_info *info = genl_info_dump(cb);
- struct mptcp_pm_addr_entry entry;
- struct mptcp_id_bitmap *bitmap;
struct mptcp_sock *msk;
- int id = cb->args[0];
int ret = -EINVAL;
struct sock *sk;
- void *hdr;
- int i;
-
- bitmap = (struct mptcp_id_bitmap *)cb->ctx;
msk = mptcp_userspace_pm_get_sock(info);
if (!msk)
@@ -618,39 +610,11 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
sk = (struct sock *)msk;
- if (!id) {
- lock_sock(sk);
- spin_lock_bh(&msk->pm.lock);
- ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
- spin_unlock_bh(&msk->pm.lock);
- release_sock(sk);
- }
-
- for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
- if (test_bit(i, bitmap->map)) {
- if (mptcp_userspace_pm_get_addr(i, &entry, info))
- break;
-
- if (id && entry.addr.id <= id)
- continue;
-
- hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
- cb->nlh->nlmsg_seq, &mptcp_genl_family,
- NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
- if (!hdr)
- break;
-
- if (mptcp_nl_fill_addr(msg, &entry) < 0) {
- genlmsg_cancel(msg, hdr);
- break;
- }
-
- id = entry.addr.id;
- genlmsg_end(msg, hdr);
- }
- }
- cb->args[0] = id;
- ret = msg->len;
+ lock_sock(sk);
+ spin_lock_bh(&msk->pm.lock);
+ ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
+ spin_unlock_bh(&msk->pm.lock);
+ release_sock(sk);
sock_put(sk);
return ret;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index be2028ffebde..0a4edb7ee1ed 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1125,8 +1125,8 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_in
bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
-int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
- struct netlink_callback *cb);
+int mptcp_userspace_pm_dump_addr(struct mptcp_id_bitmap *bitmap,
+ const struct genl_info *info);
int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
const struct genl_info *info);
--
2.43.0