Commit f102600e authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'mptcp-pm-in-kernel-fullmesh-endp-nb-bind-cases'

Matthieu Baerts says:

====================
mptcp: pm: in-kernel: fullmesh endp nb + bind cases

Here is a small optimisation for the in-kernel PM, joined by a small
behavioural change to avoid confusions, and followed by a few more
tests.

- Patch 1: record fullmesh endpoints numbers, not to iterate over all
  endpoints to check if one is marked as fullmesh.

- Patch 2: when at least one endpoint is marked as fullmesh, only use
  these endpoints when reacting to an ADD_ADDR, even if there are no
  endpoints for this IP family: this is less confusing.

- Patch 3: reduce duplicated code to prepare the next patch.

- Patch 4: extra "bind" cases: the listen socket restrict the bind to
  one IP address, not allowing MP_JOIN to extra IP addresses, except if
  another listening socket accepts them.
====================

Link: https://patch.msgid.link/20251101-net-next-mptcp-fm-endp-nb-bind-v1-0-b4166772d6bb@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents b117befe 5c59df12
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -70,7 +70,8 @@ struct mptcp_info {
	__u64	mptcpi_bytes_acked;
	__u8	mptcpi_subflows_total;
	__u8	mptcpi_endp_laminar_max;
	__u8	reserved[2];
	__u8	mptcpi_endp_fullmesh_max;
	__u8	reserved;
	__u32	mptcpi_last_data_sent;
	__u32	mptcpi_last_data_recv;
	__u32	mptcpi_last_ack_recv;
+32 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ struct pm_nl_pernet {
	u8			endp_signal_max;
	u8			endp_subflow_max;
	u8			endp_laminar_max;
	u8			endp_fullmesh_max;
	u8			limit_add_addr_accepted;
	u8			limit_extra_subflows;
	u8			next_id;
@@ -70,6 +71,14 @@ u8 mptcp_pm_get_endp_laminar_max(const struct mptcp_sock *msk)
}
EXPORT_SYMBOL_GPL(mptcp_pm_get_endp_laminar_max);

u8 mptcp_pm_get_endp_fullmesh_max(const struct mptcp_sock *msk)
{
	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);

	return READ_ONCE(pernet->endp_fullmesh_max);
}
EXPORT_SYMBOL_GPL(mptcp_pm_get_endp_fullmesh_max);

u8 mptcp_pm_get_limit_add_addr_accepted(const struct mptcp_sock *msk)
{
	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
@@ -600,12 +609,11 @@ fill_local_addresses_vec(struct mptcp_sock *msk, struct mptcp_addr_info *remote,
			 struct mptcp_pm_local *locals)
{
	bool c_flag_case = remote->id && mptcp_pm_add_addr_c_flag_case(msk);
	int i;

	/* If there is at least one MPTCP endpoint with a fullmesh flag */
	i = fill_local_addresses_vec_fullmesh(msk, remote, locals, c_flag_case);
	if (i)
		return i;
	if (mptcp_pm_get_endp_fullmesh_max(msk))
		return fill_local_addresses_vec_fullmesh(msk, remote, locals,
							 c_flag_case);

	/* If there is at least one MPTCP endpoint with a laminar flag */
	if (mptcp_pm_get_endp_laminar_max(msk))
@@ -790,6 +798,10 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
		addr_max = pernet->endp_laminar_max;
		WRITE_ONCE(pernet->endp_laminar_max, addr_max + 1);
	}
	if (entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) {
		addr_max = pernet->endp_fullmesh_max;
		WRITE_ONCE(pernet->endp_fullmesh_max, addr_max + 1);
	}

	pernet->endpoints++;
	if (!entry->addr.port)
@@ -1187,6 +1199,10 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
		addr_max = pernet->endp_laminar_max;
		WRITE_ONCE(pernet->endp_laminar_max, addr_max - 1);
	}
	if (entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) {
		addr_max = pernet->endp_fullmesh_max;
		WRITE_ONCE(pernet->endp_fullmesh_max, addr_max - 1);
	}

	pernet->endpoints--;
	list_del_rcu(&entry->list);
@@ -1502,6 +1518,18 @@ int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *local,
	changed = (local->flags ^ entry->flags) & mask;
	entry->flags = (entry->flags & ~mask) | (local->flags & mask);
	*local = *entry;

	if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH) {
		u8 addr_max = pernet->endp_fullmesh_max;

		if (entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH)
			addr_max++;
		else
			addr_max--;

		WRITE_ONCE(pernet->endp_fullmesh_max, addr_max);
	}

	spin_unlock_bh(&pernet->lock);

	mptcp_pm_nl_set_flags_all(net, local, changed);
+1 −0
Original line number Diff line number Diff line
@@ -1183,6 +1183,7 @@ void __mptcp_pm_kernel_worker(struct mptcp_sock *msk);
u8 mptcp_pm_get_endp_signal_max(const struct mptcp_sock *msk);
u8 mptcp_pm_get_endp_subflow_max(const struct mptcp_sock *msk);
u8 mptcp_pm_get_endp_laminar_max(const struct mptcp_sock *msk);
u8 mptcp_pm_get_endp_fullmesh_max(const struct mptcp_sock *msk);
u8 mptcp_pm_get_limit_add_addr_accepted(const struct mptcp_sock *msk);
u8 mptcp_pm_get_limit_extra_subflows(const struct mptcp_sock *msk);

+2 −0
Original line number Diff line number Diff line
@@ -982,6 +982,8 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
			mptcp_pm_get_endp_subflow_max(msk);
		info->mptcpi_endp_laminar_max =
			mptcp_pm_get_endp_laminar_max(msk);
		info->mptcpi_endp_fullmesh_max =
			mptcp_pm_get_endp_fullmesh_max(msk);
	}

	if (__mptcp_check_fallback(msk))
+9 −1
Original line number Diff line number Diff line
@@ -1064,6 +1064,8 @@ static void check_getpeername_connect(int fd)
	socklen_t salen = sizeof(ss);
	char a[INET6_ADDRSTRLEN];
	char b[INET6_ADDRSTRLEN];
	const char *iface;
	size_t len;

	if (getpeername(fd, (struct sockaddr *)&ss, &salen) < 0) {
		perror("getpeername");
@@ -1073,7 +1075,13 @@ static void check_getpeername_connect(int fd)
	xgetnameinfo((struct sockaddr *)&ss, salen,
		     a, sizeof(a), b, sizeof(b));

	if (strcmp(cfg_host, a) || strcmp(cfg_port, b))
	iface = strchr(cfg_host, '%');
	if (iface)
		len = iface - cfg_host;
	else
		len = strlen(cfg_host) + 1;

	if (strncmp(cfg_host, a, len) || strcmp(cfg_port, b))
		fprintf(stderr, "%s: %s vs %s, %s vs %s\n", __func__,
			cfg_host, a, cfg_port, b);
}
Loading