All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH mptcp-net v3 0/2] mptcp: support MP_PRIO signals with userspace PMs
@ 2022-06-28 21:29 Kishen Maloor
  2022-06-28 21:29 ` [PATCH mptcp-net v3 1/2] mptcp: netlink: issue MP_PRIO signals from " Kishen Maloor
  2022-06-28 21:29 ` [PATCH mptcp-net v3 2/2] selftests: mptcp: userspace PM support for MP_PRIO signals Kishen Maloor
  0 siblings, 2 replies; 5+ messages in thread
From: Kishen Maloor @ 2022-06-28 21:29 UTC (permalink / raw)
  To: kishen.maloor, mptcp

This patch series updates MPTCP_PM_CMD_SET_FLAGS to allow userspace PMs
to issue MP_PRIO signals over a selected (by local and remote address+port)
subflow in a MPTCP connection. It also adds self tests for this
change.

This patch series has been rebased to the series (in review) titled
"Locking fixes for subflow flag changes".

v2:
-userspace_pm.sh: added a sleep after issuing the MP_PRIO signal.

v3:
-use local and remote address+port (instead of address ID) alongwith the
connection token to select a subflow.

Kishen Maloor (2):
  mptcp: netlink: issue MP_PRIO signals from userspace PMs
  selftests: mptcp: userspace PM support for MP_PRIO signals

 net/mptcp/pm_netlink.c                        | 30 ++++++--
 net/mptcp/pm_userspace.c                      | 30 ++++++++
 net/mptcp/protocol.h                          |  8 +-
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 73 ++++++++++++++++++-
 .../selftests/net/mptcp/userspace_pm.sh       | 32 ++++++++
 5 files changed, 165 insertions(+), 8 deletions(-)

--
2.31.1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH mptcp-net v3 1/2] mptcp: netlink: issue MP_PRIO signals from userspace PMs
  2022-06-28 21:29 [PATCH mptcp-net v3 0/2] mptcp: support MP_PRIO signals with userspace PMs Kishen Maloor
@ 2022-06-28 21:29 ` Kishen Maloor
  2022-06-28 22:57   ` Mat Martineau
  2022-06-28 21:29 ` [PATCH mptcp-net v3 2/2] selftests: mptcp: userspace PM support for MP_PRIO signals Kishen Maloor
  1 sibling, 1 reply; 5+ messages in thread
From: Kishen Maloor @ 2022-06-28 21:29 UTC (permalink / raw)
  To: kishen.maloor, mptcp

This change updates MPTCP_PM_CMD_SET_FLAGS to allow userspace PMs
to issue MP_PRIO signals over a specific subflow selected by
the connection token, local and remote address+port.

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/286
Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment")
Signed-off-by: Kishen Maloor <kishen.maloor@intel.com>
---
v3:
-use local and remote address+port (instead of address ID) alongwith the
connection token to select a subflow.
---
 net/mptcp/pm_netlink.c   | 30 +++++++++++++++++++++++++-----
 net/mptcp/pm_userspace.c | 30 ++++++++++++++++++++++++++++++
 net/mptcp/protocol.h     |  8 +++++++-
 3 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 05c6a95e9c28..602892f2f921 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -717,9 +717,10 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
 	}
 }
 
-static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
-					struct mptcp_addr_info *addr,
-					u8 bkup)
+int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
+				 struct mptcp_addr_info *addr,
+				 struct mptcp_addr_info *rem,
+				 u8 bkup)
 {
 	struct mptcp_subflow_context *subflow;
 
@@ -728,7 +729,7 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
 	mptcp_for_each_subflow(msk, subflow) {
 		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
 		struct sock *sk = (struct sock *)msk;
-		struct mptcp_addr_info local;
+		struct mptcp_addr_info local, remote;
 		bool slow;
 
 		local_address((struct sock_common *)ssk, &local);
@@ -736,6 +737,12 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
 			continue;
 
 		slow = lock_sock_fast(ssk);
+		if (rem && rem->family != AF_UNSPEC) {
+			remote_address((struct sock_common *)ssk, &remote);
+			if (!mptcp_addresses_equal(&remote, rem, rem->port))
+				continue;
+		}
+
 		if (subflow->backup != bkup)
 			msk->last_snd = NULL;
 		subflow->backup = bkup;
@@ -1839,7 +1846,7 @@ static int mptcp_nl_set_flags(struct net *net,
 
 		lock_sock(sk);
 		if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
-			ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup);
+			ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup);
 		if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
 			mptcp_pm_nl_fullmesh(msk, addr);
 		release_sock(sk);
@@ -1855,6 +1862,9 @@ static int mptcp_nl_set_flags(struct net *net,
 static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
 {
 	struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, }, *entry;
+	struct mptcp_pm_addr_entry remote = { .addr = { .family = AF_UNSPEC }, };
+	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
+	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
 	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
 	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
 	u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
@@ -1867,6 +1877,12 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
 	if (ret < 0)
 		return ret;
 
+	if (attr_rem) {
+		ret = mptcp_pm_parse_entry(attr_rem, info, false, &remote);
+		if (ret < 0)
+			return ret;
+	}
+
 	if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
 		bkup = 1;
 	if (addr.addr.family == AF_UNSPEC) {
@@ -1875,6 +1891,10 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
 			return -EOPNOTSUPP;
 	}
 
+	if (token)
+		return mptcp_userspace_pm_set_flags(sock_net(skb->sk),
+						    token, &addr, &remote, bkup);
+
 	spin_lock_bh(&pernet->lock);
 	entry = __lookup_addr(pernet, &addr.addr, lookup_by_id);
 	if (!entry) {
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 26212bebc5ed..51e2f066d54f 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -420,3 +420,33 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
 	sock_put((struct sock *)msk);
 	return err;
 }
+
+int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
+				 struct mptcp_pm_addr_entry *loc,
+				 struct mptcp_pm_addr_entry *rem, u8 bkup)
+{
+	struct mptcp_sock *msk;
+	int ret = -EINVAL;
+	u32 token_val;
+
+	token_val = nla_get_u32(token);
+
+	msk = mptcp_token_get_sock(net, token_val);
+	if (!msk)
+		return ret;
+
+	if (!mptcp_pm_is_userspace(msk))
+		goto set_flags_err;
+
+	if (loc->addr.family == AF_UNSPEC ||
+	    rem->addr.family == AF_UNSPEC)
+		goto set_flags_err;
+
+	lock_sock((struct sock *)msk);
+	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup);
+	release_sock((struct sock *)msk);
+
+set_flags_err:
+	sock_put((struct sock *)msk);
+	return ret;
+}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 033c995772dc..480c5320b86e 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -772,6 +772,10 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
 			       const struct mptcp_rm_list *rm_list);
 void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);
 void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq);
+int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
+				 struct mptcp_addr_info *addr,
+				 struct mptcp_addr_info *rem,
+				 u8 bkup);
 bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
 			      const struct mptcp_pm_addr_entry *entry);
 void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
@@ -788,7 +792,9 @@ int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
 int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
 						   unsigned int id,
 						   u8 *flags, int *ifindex);
-
+int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
+				 struct mptcp_pm_addr_entry *loc,
+				 struct mptcp_pm_addr_entry *rem, u8 bkup);
 int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 			   const struct mptcp_addr_info *addr,
 			   bool echo);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH mptcp-net v3 2/2] selftests: mptcp: userspace PM support for MP_PRIO signals
  2022-06-28 21:29 [PATCH mptcp-net v3 0/2] mptcp: support MP_PRIO signals with userspace PMs Kishen Maloor
  2022-06-28 21:29 ` [PATCH mptcp-net v3 1/2] mptcp: netlink: issue MP_PRIO signals from " Kishen Maloor
@ 2022-06-28 21:29 ` Kishen Maloor
  1 sibling, 0 replies; 5+ messages in thread
From: Kishen Maloor @ 2022-06-28 21:29 UTC (permalink / raw)
  To: kishen.maloor, mptcp

This change updates the testing sample (pm_nl_ctl) to exercise
the updated MPTCP_PM_CMD_SET_FLAGS command for userspace PMs to
issue MP_PRIO signals over the selected subflow.

E.g. ./pm_nl_ctl set 10.0.1.2 port 47234 flags backup token 823274047 rip 10.0.1.1 rport 50003

userspace_pm.sh has a new selftest that invokes this command.

Fixes: 259a834fadda ("selftests: mptcp: functional tests for the userspace PM type")
Signed-off-by: Kishen Maloor <kishen.maloor@intel.com>
---
v2:
-added a sleep after issuing the MP_PRIO signal in userspace_pm.sh.

v3:
-updated test to pass local and remote address+port to aid in selecting a
subflow.
---
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 73 ++++++++++++++++++-
 .../selftests/net/mptcp/userspace_pm.sh       | 32 ++++++++
 2 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
index 6a2f4b981e1d..cb79f0719e3b 100644
--- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
+++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
@@ -39,7 +39,7 @@ static void syntax(char *argv[])
 	fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n");
 	fprintf(stderr, "\tdel <id> [<ip>]\n");
 	fprintf(stderr, "\tget <id>\n");
-	fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>]\n");
+	fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>] [token <token>] [rip <ip>] [rport <port>]\n");
 	fprintf(stderr, "\tflush\n");
 	fprintf(stderr, "\tdump\n");
 	fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n");
@@ -1279,7 +1279,10 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
 	struct rtattr *rta, *nest;
 	struct nlmsghdr *nh;
 	u_int32_t flags = 0;
+	u_int32_t token = 0;
+	u_int16_t rport = 0;
 	u_int16_t family;
+	void *rip = NULL;
 	int nest_start;
 	int use_id = 0;
 	u_int8_t id;
@@ -1339,7 +1342,13 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
 		error(1, 0, " missing flags keyword");
 
 	for (; arg < argc; arg++) {
-		if (!strcmp(argv[arg], "flags")) {
+		if (!strcmp(argv[arg], "token")) {
+			if (++arg >= argc)
+				error(1, 0, " missing token value");
+
+			/* token */
+			token = atoi(argv[arg]);
+		} else if (!strcmp(argv[arg], "flags")) {
 			char *tok, *str;
 
 			/* flags */
@@ -1378,12 +1387,72 @@ int set_flags(int fd, int pm_family, int argc, char *argv[])
 			rta->rta_len = RTA_LENGTH(2);
 			memcpy(RTA_DATA(rta), &port, 2);
 			off += NLMSG_ALIGN(rta->rta_len);
+		} else if (!strcmp(argv[arg], "rport")) {
+			if (++arg >= argc)
+				error(1, 0, " missing remote port");
+
+			rport = atoi(argv[arg]);
+		} else if (!strcmp(argv[arg], "rip")) {
+			if (++arg >= argc)
+				error(1, 0, " missing remote ip");
+
+			rip = argv[arg];
 		} else {
 			error(1, 0, "unknown keyword %s", argv[arg]);
 		}
 	}
 	nest->rta_len = off - nest_start;
 
+	/* token */
+	if (token) {
+		rta = (void *)(data + off);
+		rta->rta_type = MPTCP_PM_ATTR_TOKEN;
+		rta->rta_len = RTA_LENGTH(4);
+		memcpy(RTA_DATA(rta), &token, 4);
+		off += NLMSG_ALIGN(rta->rta_len);
+	}
+
+	/* remote addr/port */
+	if (rip) {
+		nest_start = off;
+		nest = (void *)(data + off);
+		nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR_REMOTE;
+		nest->rta_len = RTA_LENGTH(0);
+		off += NLMSG_ALIGN(nest->rta_len);
+
+		/* addr data */
+		rta = (void *)(data + off);
+		if (inet_pton(AF_INET, rip, RTA_DATA(rta))) {
+			family = AF_INET;
+			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4;
+			rta->rta_len = RTA_LENGTH(4);
+		} else if (inet_pton(AF_INET6, rip, RTA_DATA(rta))) {
+			family = AF_INET6;
+			rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6;
+			rta->rta_len = RTA_LENGTH(16);
+		} else {
+			error(1, errno, "can't parse ip %s", (char *)rip);
+		}
+		off += NLMSG_ALIGN(rta->rta_len);
+
+		/* family */
+		rta = (void *)(data + off);
+		rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY;
+		rta->rta_len = RTA_LENGTH(2);
+		memcpy(RTA_DATA(rta), &family, 2);
+		off += NLMSG_ALIGN(rta->rta_len);
+
+		if (rport) {
+			rta = (void *)(data + off);
+			rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT;
+			rta->rta_len = RTA_LENGTH(2);
+			memcpy(RTA_DATA(rta), &rport, 2);
+			off += NLMSG_ALIGN(rta->rta_len);
+		}
+
+		nest->rta_len = off - nest_start;
+	}
+
 	do_nl_req(fd, nh, off, 0);
 	return 0;
 }
diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh
index 78d0bb640b11..abe3d4ebe554 100755
--- a/tools/testing/selftests/net/mptcp/userspace_pm.sh
+++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh
@@ -770,10 +770,42 @@ test_subflows()
 	rm -f "$evts"
 }
 
+test_prio()
+{
+	local count
+
+	# Send MP_PRIO signal from client to server machine
+	ip netns exec "$ns2" ./pm_nl_ctl set 10.0.1.2 port "$client4_port" flags backup token "$client4_token" rip 10.0.1.1 rport "$server4_port"
+	sleep 0.5
+
+	# Check TX
+	stdbuf -o0 -e0 printf "MP_PRIO TX                                                 \t"
+	count=$(ip netns exec "$ns2" nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}')
+	[ -z "$count" ] && count=0
+	if [ $count != 1 ]; then
+		stdbuf -o0 -e0 printf "[FAIL]\n"
+		exit 1
+	else
+		stdbuf -o0 -e0 printf "[OK]\n"
+	fi
+
+	# Check RX
+	stdbuf -o0 -e0 printf "MP_PRIO RX                                                 \t"
+	count=$(ip netns exec "$ns1" nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}')
+	[ -z "$count" ] && count=0
+	if [ $count != 1 ]; then
+		stdbuf -o0 -e0 printf "[FAIL]\n"
+		exit 1
+	else
+		stdbuf -o0 -e0 printf "[OK]\n"
+	fi
+}
+
 make_connection
 make_connection "v6"
 test_announce
 test_remove
 test_subflows
+test_prio
 
 exit 0
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH mptcp-net v3 1/2] mptcp: netlink: issue MP_PRIO signals from userspace PMs
  2022-06-28 21:29 ` [PATCH mptcp-net v3 1/2] mptcp: netlink: issue MP_PRIO signals from " Kishen Maloor
@ 2022-06-28 22:57   ` Mat Martineau
  2022-06-28 23:53     ` Kishen Maloor
  0 siblings, 1 reply; 5+ messages in thread
From: Mat Martineau @ 2022-06-28 22:57 UTC (permalink / raw)
  To: Kishen Maloor; +Cc: mptcp

On Tue, 28 Jun 2022, Kishen Maloor wrote:

> This change updates MPTCP_PM_CMD_SET_FLAGS to allow userspace PMs
> to issue MP_PRIO signals over a specific subflow selected by
> the connection token, local and remote address+port.
>
> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/286
> Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment")
> Signed-off-by: Kishen Maloor <kishen.maloor@intel.com>
> ---
> v3:
> -use local and remote address+port (instead of address ID) alongwith the
> connection token to select a subflow.
> ---
> net/mptcp/pm_netlink.c   | 30 +++++++++++++++++++++++++-----
> net/mptcp/pm_userspace.c | 30 ++++++++++++++++++++++++++++++
> net/mptcp/protocol.h     |  8 +++++++-
> 3 files changed, 62 insertions(+), 6 deletions(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 05c6a95e9c28..602892f2f921 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -717,9 +717,10 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
> 	}
> }
>
> -static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
> -					struct mptcp_addr_info *addr,
> -					u8 bkup)
> +int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
> +				 struct mptcp_addr_info *addr,
> +				 struct mptcp_addr_info *rem,
> +				 u8 bkup)
> {
> 	struct mptcp_subflow_context *subflow;
>
> @@ -728,7 +729,7 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
> 	mptcp_for_each_subflow(msk, subflow) {
> 		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
> 		struct sock *sk = (struct sock *)msk;
> -		struct mptcp_addr_info local;
> +		struct mptcp_addr_info local, remote;
> 		bool slow;
>
> 		local_address((struct sock_common *)ssk, &local);
> @@ -736,6 +737,12 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
> 			continue;
>
> 		slow = lock_sock_fast(ssk);
> +		if (rem && rem->family != AF_UNSPEC) {
> +			remote_address((struct sock_common *)ssk, &remote);
> +			if (!mptcp_addresses_equal(&remote, rem, rem->port))
> +				continue;
> +		}

Hi Kishen -

Thanks for the v3!

The CI build failed because the ssk lock is not released before this 
'continue' statement. The sparse error message was pretty vague, though.

remote_address() is only checking sock_common fields that don't change, I 
don't think the ssk lock is required (it's used this way elsewhere in the 
code). So this new hunk of code should be before the lock_sock_fast() 
call.


- Mat



> +
> 		if (subflow->backup != bkup)
> 			msk->last_snd = NULL;
> 		subflow->backup = bkup;
> @@ -1839,7 +1846,7 @@ static int mptcp_nl_set_flags(struct net *net,
>
> 		lock_sock(sk);
> 		if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
> -			ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup);
> +			ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup);
> 		if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
> 			mptcp_pm_nl_fullmesh(msk, addr);
> 		release_sock(sk);
> @@ -1855,6 +1862,9 @@ static int mptcp_nl_set_flags(struct net *net,
> static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
> {
> 	struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, }, *entry;
> +	struct mptcp_pm_addr_entry remote = { .addr = { .family = AF_UNSPEC }, };
> +	struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
> +	struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
> 	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
> 	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
> 	u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
> @@ -1867,6 +1877,12 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
> 	if (ret < 0)
> 		return ret;
>
> +	if (attr_rem) {
> +		ret = mptcp_pm_parse_entry(attr_rem, info, false, &remote);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> 	if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
> 		bkup = 1;
> 	if (addr.addr.family == AF_UNSPEC) {
> @@ -1875,6 +1891,10 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
> 			return -EOPNOTSUPP;
> 	}
>
> +	if (token)
> +		return mptcp_userspace_pm_set_flags(sock_net(skb->sk),
> +						    token, &addr, &remote, bkup);
> +
> 	spin_lock_bh(&pernet->lock);
> 	entry = __lookup_addr(pernet, &addr.addr, lookup_by_id);
> 	if (!entry) {
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index 26212bebc5ed..51e2f066d54f 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -420,3 +420,33 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
> 	sock_put((struct sock *)msk);
> 	return err;
> }
> +
> +int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
> +				 struct mptcp_pm_addr_entry *loc,
> +				 struct mptcp_pm_addr_entry *rem, u8 bkup)
> +{
> +	struct mptcp_sock *msk;
> +	int ret = -EINVAL;
> +	u32 token_val;
> +
> +	token_val = nla_get_u32(token);
> +
> +	msk = mptcp_token_get_sock(net, token_val);
> +	if (!msk)
> +		return ret;
> +
> +	if (!mptcp_pm_is_userspace(msk))
> +		goto set_flags_err;
> +
> +	if (loc->addr.family == AF_UNSPEC ||
> +	    rem->addr.family == AF_UNSPEC)
> +		goto set_flags_err;
> +
> +	lock_sock((struct sock *)msk);
> +	ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup);
> +	release_sock((struct sock *)msk);
> +
> +set_flags_err:
> +	sock_put((struct sock *)msk);
> +	return ret;
> +}
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 033c995772dc..480c5320b86e 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -772,6 +772,10 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
> 			       const struct mptcp_rm_list *rm_list);
> void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);
> void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq);
> +int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
> +				 struct mptcp_addr_info *addr,
> +				 struct mptcp_addr_info *rem,
> +				 u8 bkup);
> bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
> 			      const struct mptcp_pm_addr_entry *entry);
> void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
> @@ -788,7 +792,9 @@ int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
> int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
> 						   unsigned int id,
> 						   u8 *flags, int *ifindex);
> -
> +int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
> +				 struct mptcp_pm_addr_entry *loc,
> +				 struct mptcp_pm_addr_entry *rem, u8 bkup);
> int mptcp_pm_announce_addr(struct mptcp_sock *msk,
> 			   const struct mptcp_addr_info *addr,
> 			   bool echo);
> -- 
> 2.31.1
>
>
>

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH mptcp-net v3 1/2] mptcp: netlink: issue MP_PRIO signals from userspace PMs
  2022-06-28 22:57   ` Mat Martineau
@ 2022-06-28 23:53     ` Kishen Maloor
  0 siblings, 0 replies; 5+ messages in thread
From: Kishen Maloor @ 2022-06-28 23:53 UTC (permalink / raw)
  To: Mat Martineau; +Cc: mptcp

On 6/28/22 3:57 PM, Mat Martineau wrote:
> On Tue, 28 Jun 2022, Kishen Maloor wrote:
> 
>> This change updates MPTCP_PM_CMD_SET_FLAGS to allow userspace PMs
>> to issue MP_PRIO signals over a specific subflow selected by
>> the connection token, local and remote address+port.
>>
>> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/286
>> Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment")
>> Signed-off-by: Kishen Maloor <kishen.maloor@intel.com>
>> ---
>> v3:
>> -use local and remote address+port (instead of address ID) alongwith the
>> connection token to select a subflow.
>> ---
>> net/mptcp/pm_netlink.c   | 30 +++++++++++++++++++++++++-----
>> net/mptcp/pm_userspace.c | 30 ++++++++++++++++++++++++++++++
>> net/mptcp/protocol.h     |  8 +++++++-
>> 3 files changed, 62 insertions(+), 6 deletions(-)
>>
>> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
>> index 05c6a95e9c28..602892f2f921 100644
>> --- a/net/mptcp/pm_netlink.c
>> +++ b/net/mptcp/pm_netlink.c
>> @@ -717,9 +717,10 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
>>     }
>> }
>>
>> -static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
>> -                    struct mptcp_addr_info *addr,
>> -                    u8 bkup)
>> +int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
>> +                 struct mptcp_addr_info *addr,
>> +                 struct mptcp_addr_info *rem,
>> +                 u8 bkup)
>> {
>>     struct mptcp_subflow_context *subflow;
>>
>> @@ -728,7 +729,7 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
>>     mptcp_for_each_subflow(msk, subflow) {
>>         struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
>>         struct sock *sk = (struct sock *)msk;
>> -        struct mptcp_addr_info local;
>> +        struct mptcp_addr_info local, remote;
>>         bool slow;
>>
>>         local_address((struct sock_common *)ssk, &local);
>> @@ -736,6 +737,12 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
>>             continue;
>>
>>         slow = lock_sock_fast(ssk);
>> +        if (rem && rem->family != AF_UNSPEC) {
>> +            remote_address((struct sock_common *)ssk, &remote);
>> +            if (!mptcp_addresses_equal(&remote, rem, rem->port))
>> +                continue;
>> +        }
> 
> Hi Kishen -
> 
> Thanks for the v3!
> 
> The CI build failed because the ssk lock is not released before this 'continue' statement. The sparse error message was pretty vague, though.
> 
> remote_address() is only checking sock_common fields that don't change, I don't think the ssk lock is required (it's used this way elsewhere in the code). So this new hunk of code should be before the lock_sock_fast() call.

Thanks, Mat. I just happened to miss this while resolving conflicts here during my rebase to your series.
I shall post a v4 shortly.

> 
> 
> - Mat
> 
> 
> 
>> +
>>         if (subflow->backup != bkup)
>>             msk->last_snd = NULL;
>>         subflow->backup = bkup;
>> @@ -1839,7 +1846,7 @@ static int mptcp_nl_set_flags(struct net *net,
>>
>>         lock_sock(sk);
>>         if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
>> -            ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup);
>> +            ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup);
>>         if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
>>             mptcp_pm_nl_fullmesh(msk, addr);
>>         release_sock(sk);
>> @@ -1855,6 +1862,9 @@ static int mptcp_nl_set_flags(struct net *net,
>> static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
>> {
>>     struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, }, *entry;
>> +    struct mptcp_pm_addr_entry remote = { .addr = { .family = AF_UNSPEC }, };
>> +    struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
>> +    struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
>>     struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
>>     struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
>>     u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
>> @@ -1867,6 +1877,12 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
>>     if (ret < 0)
>>         return ret;
>>
>> +    if (attr_rem) {
>> +        ret = mptcp_pm_parse_entry(attr_rem, info, false, &remote);
>> +        if (ret < 0)
>> +            return ret;
>> +    }
>> +
>>     if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
>>         bkup = 1;
>>     if (addr.addr.family == AF_UNSPEC) {
>> @@ -1875,6 +1891,10 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
>>             return -EOPNOTSUPP;
>>     }
>>
>> +    if (token)
>> +        return mptcp_userspace_pm_set_flags(sock_net(skb->sk),
>> +                            token, &addr, &remote, bkup);
>> +
>>     spin_lock_bh(&pernet->lock);
>>     entry = __lookup_addr(pernet, &addr.addr, lookup_by_id);
>>     if (!entry) {
>> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
>> index 26212bebc5ed..51e2f066d54f 100644
>> --- a/net/mptcp/pm_userspace.c
>> +++ b/net/mptcp/pm_userspace.c
>> @@ -420,3 +420,33 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
>>     sock_put((struct sock *)msk);
>>     return err;
>> }
>> +
>> +int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
>> +                 struct mptcp_pm_addr_entry *loc,
>> +                 struct mptcp_pm_addr_entry *rem, u8 bkup)
>> +{
>> +    struct mptcp_sock *msk;
>> +    int ret = -EINVAL;
>> +    u32 token_val;
>> +
>> +    token_val = nla_get_u32(token);
>> +
>> +    msk = mptcp_token_get_sock(net, token_val);
>> +    if (!msk)
>> +        return ret;
>> +
>> +    if (!mptcp_pm_is_userspace(msk))
>> +        goto set_flags_err;
>> +
>> +    if (loc->addr.family == AF_UNSPEC ||
>> +        rem->addr.family == AF_UNSPEC)
>> +        goto set_flags_err;
>> +
>> +    lock_sock((struct sock *)msk);
>> +    ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup);
>> +    release_sock((struct sock *)msk);
>> +
>> +set_flags_err:
>> +    sock_put((struct sock *)msk);
>> +    return ret;
>> +}
>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
>> index 033c995772dc..480c5320b86e 100644
>> --- a/net/mptcp/protocol.h
>> +++ b/net/mptcp/protocol.h
>> @@ -772,6 +772,10 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
>>                    const struct mptcp_rm_list *rm_list);
>> void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);
>> void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq);
>> +int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
>> +                 struct mptcp_addr_info *addr,
>> +                 struct mptcp_addr_info *rem,
>> +                 u8 bkup);
>> bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
>>                   const struct mptcp_pm_addr_entry *entry);
>> void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
>> @@ -788,7 +792,9 @@ int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
>> int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
>>                            unsigned int id,
>>                            u8 *flags, int *ifindex);
>> -
>> +int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
>> +                 struct mptcp_pm_addr_entry *loc,
>> +                 struct mptcp_pm_addr_entry *rem, u8 bkup);
>> int mptcp_pm_announce_addr(struct mptcp_sock *msk,
>>                const struct mptcp_addr_info *addr,
>>                bool echo);
>> -- 
>> 2.31.1
>>
>>
>>
> 
> -- 
> Mat Martineau
> Intel


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-06-28 23:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-28 21:29 [PATCH mptcp-net v3 0/2] mptcp: support MP_PRIO signals with userspace PMs Kishen Maloor
2022-06-28 21:29 ` [PATCH mptcp-net v3 1/2] mptcp: netlink: issue MP_PRIO signals from " Kishen Maloor
2022-06-28 22:57   ` Mat Martineau
2022-06-28 23:53     ` Kishen Maloor
2022-06-28 21:29 ` [PATCH mptcp-net v3 2/2] selftests: mptcp: userspace PM support for MP_PRIO signals Kishen Maloor

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.