@@ -485,20 +485,55 @@ int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
return ret;
}
-static int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb,
+static int mptcp_pm_dump_addr(mptcp_pm_addr_id_bitmap_t *bitmap,
const struct genl_info *info)
{
if (info->attrs[MPTCP_PM_ATTR_TOKEN])
- return mptcp_userspace_pm_dump_addr(msg, cb, info);
- return mptcp_pm_nl_dump_addr(msg, cb, info);
+ 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);
+ mptcp_pm_addr_id_bitmap_t *bitmap;
+ struct mptcp_pm_addr_entry entry;
+ int id = cb->args[0];
+ void *hdr;
+ int i;
+
+ bitmap = (mptcp_pm_addr_id_bitmap_t *)cb->ctx;
+
+ 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_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);
+ }
+ }
- return mptcp_pm_dump_addr(msg, cb, info);
+ cb->args[0] = id;
+ return msg->len;
}
static int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
@@ -1783,48 +1783,19 @@ int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
return ret;
}
-int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
- struct netlink_callback *cb,
+int mptcp_pm_nl_dump_addr(mptcp_pm_addr_id_bitmap_t *bitmap,
const struct genl_info *info)
{
struct net *net = genl_info_net(info);
- struct mptcp_pm_addr_entry *entry;
struct pm_nl_pernet *pernet;
- int id = cb->args[0];
- void *hdr;
- int i;
pernet = pm_nl_get_pernet(net);
rcu_read_lock();
- for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
- if (test_bit(i, pernet->id_bitmap)) {
- entry = __lookup_addr_by_id(pernet, i);
- if (!entry)
- break;
-
- if (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);
- }
- }
+ bitmap_copy(bitmap->map, pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
rcu_read_unlock();
- cb->args[0] = id;
- return msg->len;
+ return 0;
}
static int parse_limit(struct genl_info *info, int id, unsigned int *limit)
@@ -614,18 +614,25 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
return ret;
}
-int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
- struct netlink_callback *cb,
- const struct genl_info *info)
+static int mptcp_userspace_pm_reset_bitmap(struct mptcp_sock *msk,
+ mptcp_pm_addr_id_bitmap_t *bitmap)
{
- mptcp_pm_addr_id_bitmap_t *bitmap;
struct mptcp_pm_addr_entry *entry;
+
+ bitmap_zero(bitmap->map, MPTCP_PM_MAX_ADDR_ID + 1);
+
+ mptcp_for_each_userspace_pm_addr(msk, entry)
+ __set_bit(entry->addr.id, bitmap->map);
+
+ return 0;
+}
+
+int mptcp_userspace_pm_dump_addr(mptcp_pm_addr_id_bitmap_t *bitmap,
+ const struct genl_info *info)
+{
struct mptcp_sock *msk;
int ret = -EINVAL;
struct sock *sk;
- void *hdr;
-
- bitmap = (mptcp_pm_addr_id_bitmap_t *)cb->ctx;
msk = mptcp_userspace_pm_get_sock(info);
if (!msk)
@@ -635,27 +642,9 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
lock_sock(sk);
spin_lock_bh(&msk->pm.lock);
- mptcp_for_each_userspace_pm_addr(msk, entry) {
- if (test_bit(entry->addr.id, bitmap->map))
- 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;
- }
-
- __set_bit(entry->addr.id, bitmap->map);
- genlmsg_end(msg, hdr);
- }
+ ret = mptcp_userspace_pm_reset_bitmap(msk, bitmap);
spin_unlock_bh(&msk->pm.lock);
release_sock(sk);
- ret = msg->len;
sock_put(sk);
return ret;
@@ -1124,11 +1124,9 @@ 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_pm_nl_dump_addr(struct sk_buff *msg,
- struct netlink_callback *cb,
+int mptcp_pm_nl_dump_addr(mptcp_pm_addr_id_bitmap_t *bitmap,
const struct genl_info *info);
-int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
- struct netlink_callback *cb,
+int mptcp_userspace_pm_dump_addr(mptcp_pm_addr_id_bitmap_t *bitmap,
const struct genl_info *info);
int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
const struct genl_info *info);