@@ -1869,16 +1869,20 @@ static int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
{
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);
spin_lock_bh(&pernet->lock);
+ if (!id)
+ bitmap_copy(bitmap->map, pernet->id_bitmap.map, MPTCP_PM_MAX_ADDR_ID + 1);
for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
- if (test_bit(i, pernet->id_bitmap.map)) {
+ if (test_bit(i, bitmap->map)) {
entry = __lookup_addr_by_id(pernet, i);
if (!entry)
break;
@@ -583,6 +583,21 @@ int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info)
return ret;
}
+static int mptcp_userspace_pm_set_bitmap(struct mptcp_sock *msk,
+ struct mptcp_id_bitmap *bitmap)
+{
+ struct mptcp_pm_addr_entry *entry;
+
+ mptcp_for_each_address(msk, entry) {
+ if (test_bit(entry->addr.id, bitmap->map))
+ continue;
+
+ __set_bit(entry->addr.id, bitmap->map);
+ }
+
+ return 0;
+}
+
int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
struct netlink_callback *cb)
{
@@ -590,9 +605,11 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
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;
@@ -604,24 +621,33 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
lock_sock(sk);
spin_lock_bh(&msk->pm.lock);
- mptcp_for_each_address(msk, entry) {
- if (test_bit(entry->addr.id, bitmap->map))
- continue;
+ if (!id)
+ ret = mptcp_userspace_pm_set_bitmap(msk, bitmap);
+ for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
+ if (test_bit(i, bitmap->map)) {
+ entry = mptcp_userspace_pm_lookup_addr_by_id(msk, i);
+ if (!entry)
+ 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;
+ 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;
- }
+ if (mptcp_nl_fill_addr(msg, entry) < 0) {
+ genlmsg_cancel(msg, hdr);
+ break;
+ }
- __set_bit(entry->addr.id, bitmap->map);
- genlmsg_end(msg, hdr);
+ id = entry->addr.id;
+ genlmsg_end(msg, hdr);
+ }
}
+ cb->args[0] = id;
spin_unlock_bh(&msk->pm.lock);
release_sock(sk);
ret = msg->len;