Skip to content

Commit

Permalink
mptcp: split id_avail_bitmap per target
Browse files Browse the repository at this point in the history
Up to the 'Fixes' commit, having an endpoint with both the 'signal' and
'subflow' flags, resulted in the creation of a subflow and an address
announcement using the address linked to this endpoint. After this
commit, only the address announcement was done, ignoring the 'subflow'
flag.

That's because the same bitmap was used for the two flags. It is easy to
split it in two: one for 'signal', and one for 'subflow'.

It is unusual to set the two flags together: creating a new subflow
using a new local address will implicitly advertise it to the other
peer. So in theory, no need to advertise it explicitly as well. Maybe
there are use-cases -- the subflow might not reach the other peer that
way, we can ask the other peer to try initiating the new subflow without
delay -- or very likely the user is confused, and put both flags "just
to be sure at least the right one is set". Still, the kernel should do
what has been asked: using this endpoint to announce the address and to
create a new subflow from it.

An alternative is to forbid the use of the two flags together, but
that's probably too late, and there are maybe use-cases. This patch will
avoid people complaining subflows are not created using the endpoint
they added with the 'subflow' and 'signal' flag.

Fixes: 86e39e0 ("mptcp: keep track of local endpoint still available for each msk")
Signed-off-by: Matthieu Baerts (NGI0) <[email protected]>
  • Loading branch information
matttbe authored and intel-lab-lkp committed Jun 25, 2024
1 parent 01cefe4 commit c7c8d95
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 11 deletions.
3 changes: 2 additions & 1 deletion net/mptcp/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,8 @@ void mptcp_pm_data_reset(struct mptcp_sock *msk)
WRITE_ONCE(pm->addr_signal, 0);
WRITE_ONCE(pm->remote_deny_join_id0, false);
pm->status = 0;
bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
bitmap_fill(msk->pm.id_avail_signals_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
bitmap_fill(msk->pm.id_avail_subflows_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
}

void mptcp_pm_data_init(struct mptcp_sock *msk)
Expand Down
20 changes: 12 additions & 8 deletions net/mptcp/pm_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ select_local_address(const struct pm_nl_pernet *pernet,
if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
continue;

if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
if (!test_bit(entry->addr.id, msk->pm.id_avail_subflows_bitmap))
continue;

ret = entry;
Expand All @@ -178,10 +178,10 @@ select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk)
* can lead to additional addresses not being announced.
*/
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
continue;

if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
if (!test_bit(entry->addr.id, msk->pm.id_avail_signals_bitmap))
continue;

ret = entry;
Expand Down Expand Up @@ -228,7 +228,9 @@ bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk)
struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);

if (msk->pm.subflows == mptcp_pm_get_subflows_max(msk) ||
(find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_bitmap,
(find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_signals_bitmap,
MPTCP_PM_MAX_ADDR_ID + 1, 0) == MPTCP_PM_MAX_ADDR_ID + 1) ||
(find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_subflows_bitmap,
MPTCP_PM_MAX_ADDR_ID + 1, 0) == MPTCP_PM_MAX_ADDR_ID + 1)) {
WRITE_ONCE(msk->pm.work_pending, false);
return false;
Expand Down Expand Up @@ -537,7 +539,8 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
rcu_read_lock();
entry = __lookup_addr(pernet, &mpc_addr);
if (entry) {
__clear_bit(entry->addr.id, msk->pm.id_avail_bitmap);
__clear_bit(entry->addr.id, msk->pm.id_avail_signals_bitmap);
__clear_bit(entry->addr.id, msk->pm.id_avail_subflows_bitmap);
msk->mpc_endpoint_id = entry->addr.id;
backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
}
Expand Down Expand Up @@ -570,7 +573,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)

if (local) {
if (mptcp_pm_alloc_anno_list(msk, &local->addr)) {
__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
__clear_bit(local->addr.id, msk->pm.id_avail_signals_bitmap);
msk->pm.add_addr_signaled++;
mptcp_pm_announce_addr(msk, &local->addr, false);
mptcp_pm_nl_addr_send_ack(msk);
Expand All @@ -592,7 +595,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH);

msk->pm.local_addr_used++;
__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
__clear_bit(local->addr.id, msk->pm.id_avail_subflows_bitmap);
nr = fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs);
if (nr == 0)
continue;
Expand Down Expand Up @@ -822,7 +825,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
__MPTCP_INC_STATS(sock_net(sk), rm_type);
}
if (rm_type == MPTCP_MIB_RMSUBFLOW)
__set_bit(rm_id ? rm_id : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap);
__set_bit(rm_id ? rm_id : msk->mpc_endpoint_id,
msk->pm.id_avail_subflows_bitmap);
else if (rm_type == MPTCP_MIB_RMADDR)
__MPTCP_INC_STATS(sock_net(sk), rm_type);
if (!removed)
Expand Down
5 changes: 3 additions & 2 deletions net/mptcp/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ enum mptcp_pm_status {
MPTCP_PM_SUBFLOW_ESTABLISHED,
MPTCP_PM_ALREADY_ESTABLISHED, /* persistent status, set after ESTABLISHED event */
MPTCP_PM_MPC_ENDPOINT_ACCOUNTED /* persistent status, set after MPC local address is
* accounted int id_avail_bitmap
* accounted in id_avail_*_bitmap
*/
};

Expand Down Expand Up @@ -231,7 +231,8 @@ struct mptcp_pm_data {
u8 pm_type;
u8 subflows;
u8 status;
DECLARE_BITMAP(id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
DECLARE_BITMAP(id_avail_signals_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
DECLARE_BITMAP(id_avail_subflows_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
struct mptcp_rm_list rm_list_tx;
struct mptcp_rm_list rm_list_rx;
};
Expand Down

0 comments on commit c7c8d95

Please sign in to comment.