Skip to content

Commit 2843ff6

Browse files
Geliang Tangdavem330
authored andcommitted
mptcp: remote addresses fullmesh
This patch added and managed a new per endpoint flag, named MPTCP_PM_ADDR_FLAG_FULLMESH. In mptcp_pm_create_subflow_or_signal_addr(), if such flag is set, instead of: remote_address((struct sock_common *)sk, &remote); fill a temporary allocated array of all known remote address. After releaseing the pm lock loop on such array and create a subflow for each remote address from the given local. Note that the we could still use an array even for non 'fullmesh' endpoint: with a single entry corresponding to the primary MPC subflow remote address. Suggested-by: Paolo Abeni <[email protected]> Signed-off-by: Geliang Tang <[email protected]> Signed-off-by: Mat Martineau <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ee28525 commit 2843ff6

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

include/uapi/linux/mptcp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ enum {
7373
#define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0)
7474
#define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1)
7575
#define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2)
76+
#define MPTCP_PM_ADDR_FLAG_FULLMESH (1 << 3)
7677

7778
enum {
7879
MPTCP_PM_CMD_UNSPEC,

net/mptcp/pm_netlink.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,55 @@ void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
410410
}
411411
}
412412

413+
static bool lookup_address_in_vec(struct mptcp_addr_info *addrs, unsigned int nr,
414+
struct mptcp_addr_info *addr)
415+
{
416+
int i;
417+
418+
for (i = 0; i < nr; i++) {
419+
if (addresses_equal(&addrs[i], addr, addr->port))
420+
return true;
421+
}
422+
423+
return false;
424+
}
425+
426+
/* Fill all the remote addresses into the array addrs[],
427+
* and return the array size.
428+
*/
429+
static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullmesh,
430+
struct mptcp_addr_info *addrs)
431+
{
432+
struct sock *sk = (struct sock *)msk, *ssk;
433+
struct mptcp_subflow_context *subflow;
434+
struct mptcp_addr_info remote = { 0 };
435+
unsigned int subflows_max;
436+
int i = 0;
437+
438+
subflows_max = mptcp_pm_get_subflows_max(msk);
439+
440+
/* Non-fullmesh endpoint, fill in the single entry
441+
* corresponding to the primary MPC subflow remote address
442+
*/
443+
if (!fullmesh) {
444+
remote_address((struct sock_common *)sk, &remote);
445+
msk->pm.subflows++;
446+
addrs[i++] = remote;
447+
} else {
448+
mptcp_for_each_subflow(msk, subflow) {
449+
ssk = mptcp_subflow_tcp_sock(subflow);
450+
remote_address((struct sock_common *)ssk, &remote);
451+
if (!lookup_address_in_vec(addrs, i, &remote) &&
452+
msk->pm.subflows < subflows_max) {
453+
msk->pm.subflows++;
454+
addrs[i++] = remote;
455+
}
456+
}
457+
}
458+
459+
return i;
460+
}
461+
413462
static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
414463
{
415464
struct sock *sk = (struct sock *)msk;
@@ -455,14 +504,16 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
455504
!READ_ONCE(msk->pm.remote_deny_join_id0)) {
456505
local = select_local_address(pernet, msk);
457506
if (local) {
458-
struct mptcp_addr_info remote = { 0 };
507+
bool fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
508+
struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX];
509+
int i, nr;
459510

460511
msk->pm.local_addr_used++;
461-
msk->pm.subflows++;
462512
check_work_pending(msk);
463-
remote_address((struct sock_common *)sk, &remote);
513+
nr = fill_remote_addresses_vec(msk, fullmesh, addrs);
464514
spin_unlock_bh(&msk->pm.lock);
465-
__mptcp_subflow_connect(sk, &local->addr, &remote);
515+
for (i = 0; i < nr; i++)
516+
__mptcp_subflow_connect(sk, &local->addr, &addrs[i]);
466517
spin_lock_bh(&msk->pm.lock);
467518
return;
468519
}

0 commit comments

Comments
 (0)