Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mptcp: pm: in-kernel: record fullmesh endp nb

Instead of iterating over all endpoints, under RCU read lock, just to
check if one of them as the fullmesh flag, we can keep a counter of
fullmesh endpoint, similar to what is done with the other flags.

This counter is now checked, before iterating over all endpoints.

Similar to the other counters, this new one is also exposed. A userspace
app can then know when it is being used in a fullmesh mode, with
potentially (too) many subflows.

Reviewed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20251101-net-next-mptcp-fm-endp-nb-bind-v1-1-b4166772d6bb@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Matthieu Baerts (NGI0) and committed by
Jakub Kicinski
f88191c7 b117befe

+40 -4
+2 -1
include/uapi/linux/mptcp.h
··· 70 70 __u64 mptcpi_bytes_acked; 71 71 __u8 mptcpi_subflows_total; 72 72 __u8 mptcpi_endp_laminar_max; 73 - __u8 reserved[2]; 73 + __u8 mptcpi_endp_fullmesh_max; 74 + __u8 reserved; 74 75 __u32 mptcpi_last_data_sent; 75 76 __u32 mptcpi_last_data_recv; 76 77 __u32 mptcpi_last_ack_recv;
+35 -3
net/mptcp/pm_kernel.c
··· 22 22 u8 endp_signal_max; 23 23 u8 endp_subflow_max; 24 24 u8 endp_laminar_max; 25 + u8 endp_fullmesh_max; 25 26 u8 limit_add_addr_accepted; 26 27 u8 limit_extra_subflows; 27 28 u8 next_id; ··· 70 69 return READ_ONCE(pernet->endp_laminar_max); 71 70 } 72 71 EXPORT_SYMBOL_GPL(mptcp_pm_get_endp_laminar_max); 72 + 73 + u8 mptcp_pm_get_endp_fullmesh_max(const struct mptcp_sock *msk) 74 + { 75 + struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); 76 + 77 + return READ_ONCE(pernet->endp_fullmesh_max); 78 + } 79 + EXPORT_SYMBOL_GPL(mptcp_pm_get_endp_fullmesh_max); 73 80 74 81 u8 mptcp_pm_get_limit_add_addr_accepted(const struct mptcp_sock *msk) 75 82 { ··· 612 603 int i; 613 604 614 605 /* If there is at least one MPTCP endpoint with a fullmesh flag */ 615 - i = fill_local_addresses_vec_fullmesh(msk, remote, locals, c_flag_case); 616 - if (i) 617 - return i; 606 + if (mptcp_pm_get_endp_fullmesh_max(msk)) { 607 + i = fill_local_addresses_vec_fullmesh(msk, remote, locals, 608 + c_flag_case); 609 + if (i) 610 + return i; 611 + } 618 612 619 613 /* If there is at least one MPTCP endpoint with a laminar flag */ 620 614 if (mptcp_pm_get_endp_laminar_max(msk)) ··· 801 789 if (entry->flags & MPTCP_PM_ADDR_FLAG_LAMINAR) { 802 790 addr_max = pernet->endp_laminar_max; 803 791 WRITE_ONCE(pernet->endp_laminar_max, addr_max + 1); 792 + } 793 + if (entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) { 794 + addr_max = pernet->endp_fullmesh_max; 795 + WRITE_ONCE(pernet->endp_fullmesh_max, addr_max + 1); 804 796 } 805 797 806 798 pernet->endpoints++; ··· 1203 1187 addr_max = pernet->endp_laminar_max; 1204 1188 WRITE_ONCE(pernet->endp_laminar_max, addr_max - 1); 1205 1189 } 1190 + if (entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) { 1191 + addr_max = pernet->endp_fullmesh_max; 1192 + WRITE_ONCE(pernet->endp_fullmesh_max, addr_max - 1); 1193 + } 1206 1194 1207 1195 pernet->endpoints--; 1208 1196 list_del_rcu(&entry->list); ··· 1522 1502 changed = (local->flags ^ entry->flags) & mask; 1523 1503 entry->flags = (entry->flags & ~mask) | (local->flags & mask); 1524 1504 *local = *entry; 1505 + 1506 + if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH) { 1507 + u8 addr_max = pernet->endp_fullmesh_max; 1508 + 1509 + if (entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) 1510 + addr_max++; 1511 + else 1512 + addr_max--; 1513 + 1514 + WRITE_ONCE(pernet->endp_fullmesh_max, addr_max); 1515 + } 1516 + 1525 1517 spin_unlock_bh(&pernet->lock); 1526 1518 1527 1519 mptcp_pm_nl_set_flags_all(net, local, changed);
+1
net/mptcp/protocol.h
··· 1183 1183 u8 mptcp_pm_get_endp_signal_max(const struct mptcp_sock *msk); 1184 1184 u8 mptcp_pm_get_endp_subflow_max(const struct mptcp_sock *msk); 1185 1185 u8 mptcp_pm_get_endp_laminar_max(const struct mptcp_sock *msk); 1186 + u8 mptcp_pm_get_endp_fullmesh_max(const struct mptcp_sock *msk); 1186 1187 u8 mptcp_pm_get_limit_add_addr_accepted(const struct mptcp_sock *msk); 1187 1188 u8 mptcp_pm_get_limit_extra_subflows(const struct mptcp_sock *msk); 1188 1189
+2
net/mptcp/sockopt.c
··· 982 982 mptcp_pm_get_endp_subflow_max(msk); 983 983 info->mptcpi_endp_laminar_max = 984 984 mptcp_pm_get_endp_laminar_max(msk); 985 + info->mptcpi_endp_fullmesh_max = 986 + mptcp_pm_get_endp_fullmesh_max(msk); 985 987 } 986 988 987 989 if (__mptcp_check_fallback(msk))