* [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags
@ 2024-07-22 19:35 Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 01/23] mptcp: fully established after ADD_ADDR echo on MPJ Matthieu Baerts (NGI0)
` (24 more replies)
0 siblings, 25 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
When looking at improving the user experience around the MPTCP endpoints
setup, I noticed that setting an endpoint with both the 'signal' and the
'subflow' flags -- as it has been done in the past by users according to
bug reports we got -- were resulting on only announcing the endpoint,
but not using it to create subflows: the 'subflow' flag was then
ignored.
My initial thought was to modify IPRoute2 to warn the user when the two
flags were set, but it doesn't sound normal to ignore one of them. I
then looked at modifying the kernel not to allow having the two flags
set, but when discussing about that with Mat, we thought it was maybe
not ideal to do that, as there might be use-cases, we might break some
configs, and it was working before apparently. So instead, I fixed the
support on the kernel side (patch 5) using Paolo's suggestion. This also
includes a fix on the options side (patch 1), an explicit deny of some
options combinations (patch 2), and some refactoring (patches 3 and 4).
While at it, I added a new selftest (patch 7) to validate this case --
including a modification of the chk_add_nr helper to inverse the sides
were the counters are checked (patch 6) -- and allowed ADD_ADDR echo
just after the MP_JOIN 3WHS.
While working on that, I also noticed that re-using IDs were not
possible in some cases -- see patches 8, 10 and 12 -- and the accounting
was not correct in some other cases -- see patches 14 to 17.
The selftests modification have the same Fixes tag as the previous
commit, but they should not get the 'Cc: Stable' one later: if the
backport can work, that's not, if not, no need to worry, many CIs will
use the selftests from the last stable version to validate previous
stable releases.
The last patches don't have any modifications of the selftests attached
to them, because the current ones were producing the new WARN() that
have just been added.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Changes in v4:
- Patch 19: check for msk->first != NULL
- New patches 21-22
- Imported patch 23: might be easier to review all of them, then this
single one alone, while it depends on the previous ones.
- Link to v3: https://lore.kernel.org/r/20240719-mptcp-pm-avail-v3-0-e96b5591ced3@kernel.org
Changes in v3:
- Small changes in patches 10 and 14, see individual changelog (Geliang)
- New patches 18-20: small fixes
- Link to v2: https://lore.kernel.org/r/20240715-mptcp-pm-avail-v2-0-fc5153bd1f6e@kernel.org
Changes in v2:
- Do not split id_avail_bitmap per target in patch 5 (Paolo)
- Explicit deny (patch 2), reduce indentation (patch 3), stop earlier
(patch 4) (Paolo)
- New fixes and tests (patches 8-17).
- Link to v1: https://lore.kernel.org/r/20240621-mptcp-pm-avail-v1-0-b692d5eb89b5@kernel.org
---
Matthieu Baerts (NGI0) (23):
mptcp: fully established after ADD_ADDR echo on MPJ
mptcp: pm: deny endp with signal + subflow + port
mptcp: pm: reduce indentation blocks
mptcp: pm: don't try to create sf if alloc failed
mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set
selftests: mptcp: join: ability to invert ADD_ADDR check
selftests: mptcp: join: test both signal & subflow
mptcp: pm: re-using ID of unused removed ADD_ADDR
selftests: mptcp: join: check re-using ID of unused ADD_ADDR
mptcp: pm: re-using ID of unused removed subflows
selftests: mptcp: join: check re-using ID of closed subflow
mptcp: pm: re-using ID of unused flushed subflows
selftests: mptcp: join: test for flush/re-add endpoints
mptcp: pm: remove mptcp_pm_remove_subflow()
mptcp: pm: only mark 'subflow' endp as available
mptcp: pm: only decrement add_addr_accepted for MPJ req
mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR
mptcp: pm: only in-kernel cannot have entries with ID 0
mptcp: pm: fullmesh: select the right ID later
selftests: mptcp: join: validate fullmesh endp on 1st sf
mptcp: pm: avoid possible UaF whend selecting endp
mptcp: pm: reuse ID 0 after delete and re-add
mptcp: pm: reduce entries iterations on connect
net/mptcp/options.c | 3 +-
net/mptcp/pm.c | 24 ---
net/mptcp/pm_netlink.c | 210 +++++++++++++++---------
net/mptcp/pm_userspace.c | 19 +--
net/mptcp/protocol.h | 13 +-
net/mptcp/subflow.c | 29 ++--
tools/testing/selftests/net/mptcp/mptcp_join.sh | 131 ++++++++++++---
7 files changed, 258 insertions(+), 171 deletions(-)
---
base-commit: 140ff27ee47286bb0a270f3aa275fc319724da8d
change-id: 20240620-mptcp-pm-avail-f5e3957be441
Best regards,
--
Matthieu Baerts (NGI0) <matttbe@kernel.org>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 01/23] mptcp: fully established after ADD_ADDR echo on MPJ
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 02/23] mptcp: pm: deny endp with signal + subflow + port Matthieu Baerts (NGI0)
` (23 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
Before this patch, receiving an ADD_ADDR echo on the just connected
MP_JOIN subflow -- initiator side, after the MP_JOIN 3WHS -- was
resulting in an MP_RESET. That's because only ACKs with a DSS or
ADD_ADDRs without the echo bit were allowed.
Not allowing the ADD_ADDR echo after an MP_CAPABLE 3WHS makes sense, as
we are not supposed to send an ADD_ADDR before because it requires to be
in full established mode first. For the MP_JOIN 3WHS, that's different:
the ADD_ADDR can be sent on a previous subflow, and the ADD_ADDR echo
can be received on the recently created one. The other peer will already
be in fully established, so it is allowed to send that.
We can then relax the conditions here to accept the ADD_ADDR echo for
MPJ subflows.
Fixes: 67b12f792d5e ("mptcp: full fully established support after ADD_ADDR")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/options.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index c0832df3b0a3..4ee2e3605f5b 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -958,7 +958,8 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
if (subflow->remote_key_valid &&
(((mp_opt->suboptions & OPTION_MPTCP_DSS) && mp_opt->use_ack) ||
- ((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) && !mp_opt->echo))) {
+ ((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) &&
+ (!mp_opt->echo || subflow->mp_join)))) {
/* subflows are fully established as soon as we get any
* additional ack, including ADD_ADDR.
*/
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 02/23] mptcp: pm: deny endp with signal + subflow + port
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 01/23] mptcp: fully established after ADD_ADDR echo on MPJ Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 03/23] mptcp: pm: reduce indentation blocks Matthieu Baerts (NGI0)
` (22 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
As mentioned in the 'Fixes' commit, the port flag is only supported by
the 'signal' flag, and not by the 'subflow' one. Then if both the
'signal' and 'subflow' flags are set, the problem is the same: the
feature cannot work with the 'subflow' flag.
Technically, if both the 'signal' and 'subflow' flags are set, it will
be possible to create the listening socket, but not to establish a
subflow using this source port. So better to explicitly deny it, not to
create some confusions because the expected behaviour is not possible.
Fixes: 09f12c3ab7a5 ("mptcp: allow to use port and non-signal in set_flags")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index f65831de5c1a..c44b0ae51cdf 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1311,8 +1311,8 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
if (ret < 0)
return ret;
- if (addr.addr.port && !(addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
- GENL_SET_ERR_MSG(info, "flags must have signal when using port");
+ if (addr.addr.port && !address_use_port(&addr)) {
+ GENL_SET_ERR_MSG(info, "flags must have signal and not subflow when using port");
return -EINVAL;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 03/23] mptcp: pm: reduce indentation blocks
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 01/23] mptcp: fully established after ADD_ADDR echo on MPJ Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 02/23] mptcp: pm: deny endp with signal + subflow + port Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 04/23] mptcp: pm: don't try to create sf if alloc failed Matthieu Baerts (NGI0)
` (21 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
That will simplify the following commits.
No functional changes intended.
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index c44b0ae51cdf..adc0183b8d3f 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -568,16 +568,19 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL))
return;
- if (local) {
- if (mptcp_pm_alloc_anno_list(msk, &local->addr)) {
- __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
- msk->pm.add_addr_signaled++;
- mptcp_pm_announce_addr(msk, &local->addr, false);
- mptcp_pm_nl_addr_send_ack(msk);
- }
- }
+ if (!local)
+ goto subflow;
+
+ if (!mptcp_pm_alloc_anno_list(msk, &local->addr))
+ goto subflow;
+
+ __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
+ msk->pm.add_addr_signaled++;
+ mptcp_pm_announce_addr(msk, &local->addr, false);
+ mptcp_pm_nl_addr_send_ack(msk);
}
+subflow:
/* check if should create a new subflow */
while (msk->pm.local_addr_used < local_addr_max &&
msk->pm.subflows < subflows_max) {
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 04/23] mptcp: pm: don't try to create sf if alloc failed
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (2 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 03/23] mptcp: pm: reduce indentation blocks Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 05/23] mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set Matthieu Baerts (NGI0)
` (20 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
It sounds better to avoid wasting cycles and / or put extreme memory
pressure on the system by trying to create new subflows if it was not
possible to add a new item in the announce list.
While at it, a warning is now printed if the entry was already in the
list as it should not happen with the in-kernel path-manager. With this
PM, mptcp_pm_alloc_anno_list() should only fail in case of memory
pressure.
Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index adc0183b8d3f..0ca6b358ab51 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -348,7 +348,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
add_entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
if (add_entry) {
- if (mptcp_pm_is_kernel(msk))
+ if (WARN_ON_ONCE(mptcp_pm_is_kernel(msk)))
return false;
sk_reset_timer(sk, &add_entry->add_timer,
@@ -556,8 +556,6 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
/* check first for announce */
if (msk->pm.add_addr_signaled < add_addr_signal_max) {
- local = select_signal_address(pernet, msk);
-
/* due to racing events on both ends we can reach here while
* previous add address is still running: if we invoke now
* mptcp_pm_announce_addr(), that will fail and the
@@ -568,11 +566,15 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL))
return;
+ local = select_signal_address(pernet, msk);
if (!local)
goto subflow;
+ /* If the alloc fails, we are on memory pressure, not worth
+ * continuing, and trying to create subflows.
+ */
if (!mptcp_pm_alloc_anno_list(msk, &local->addr))
- goto subflow;
+ return;
__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
msk->pm.add_addr_signaled++;
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 05/23] mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (3 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 04/23] mptcp: pm: don't try to create sf if alloc failed Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 06/23] selftests: mptcp: join: ability to invert ADD_ADDR check Matthieu Baerts (NGI0)
` (19 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
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 is used for the two flags. It is OK to
keep this single bitmap, the already selected local endpoint simply have
to be re-used, but not via select_local_address() not to look at the
just modified bitmap.
Note that 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, if it is
allowed, 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, there are maybe use-cases, and it was working
before. This patch will avoid people complaining subflows are not
created using the endpoint they added with the 'subflow' and 'signal'
flag.
Note that with the current patch, the subflow might not be created in
some corner cases, e.g. if the 'subflows' limit was reached when sending
the ADD_ADDR, but changed later on. It is probably not worth splitting
id_avail_bitmap per target ('signal', 'subflow'), which will add another
large field to the msk "just" to track (again) endpoints. Anyway,
currently when the limits are changed, the kernel doesn't check if new
subflows can be created or removed, because we would need to keep track
of the received ADD_ADDR, and more. It sounds OK to assume that the
limits should be properly configured before establishing new
connections.
Fixes: 86e39e04482b ("mptcp: keep track of local endpoint still available for each msk")
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Notes:
- v2: re-use the same bitmap instead of duplicating it for each target
(Paolo)
---
net/mptcp/pm_netlink.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 0ca6b358ab51..2e94f2a9f2a6 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -513,8 +513,8 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
{
+ struct mptcp_pm_addr_entry *local, *signal_and_subflow = NULL;
struct sock *sk = (struct sock *)msk;
- struct mptcp_pm_addr_entry *local;
unsigned int add_addr_signal_max;
unsigned int local_addr_max;
struct pm_nl_pernet *pernet;
@@ -580,6 +580,9 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
msk->pm.add_addr_signaled++;
mptcp_pm_announce_addr(msk, &local->addr, false);
mptcp_pm_nl_addr_send_ack(msk);
+
+ if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
+ signal_and_subflow = local;
}
subflow:
@@ -590,9 +593,14 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
bool fullmesh;
int i, nr;
- local = select_local_address(pernet, msk);
- if (!local)
- break;
+ if (signal_and_subflow) {
+ local = signal_and_subflow;
+ signal_and_subflow = NULL;
+ } else {
+ local = select_local_address(pernet, msk);
+ if (!local)
+ break;
+ }
fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 06/23] selftests: mptcp: join: ability to invert ADD_ADDR check
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (4 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 05/23] mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 07/23] selftests: mptcp: join: test both signal & subflow Matthieu Baerts (NGI0)
` (18 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
In the following commit, the client will initiate the ADD_ADDR, instead
of the server. We need to way to verify the ADD_ADDR have been correctly
sent.
Note: the default expected counters for when the port number is given
are never changed by the caller, no need to accept them as parameter
then.
The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests,
but it validates the previous fix for an issue introduced by this commit
ID.
Fixes: 86e39e04482b ("mptcp: keep track of local endpoint still available for each msk")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_join.sh | 40 ++++++++++++++++---------
1 file changed, 26 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 55d84a1bde15..55ccc4fdf18a 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -1415,18 +1415,28 @@ chk_add_nr()
local add_nr=$1
local echo_nr=$2
local port_nr=${3:-0}
- local syn_nr=${4:-$port_nr}
- local syn_ack_nr=${5:-$port_nr}
- local ack_nr=${6:-$port_nr}
- local mis_syn_nr=${7:-0}
- local mis_ack_nr=${8:-0}
+ local ns_invert=${4:-""}
+ local syn_nr=$port_nr
+ local syn_ack_nr=$port_nr
+ local ack_nr=$port_nr
+ local mis_syn_nr=0
+ local mis_ack_nr=0
+ local ns_tx=$ns1
+ local ns_rx=$ns2
+ local extra_msg=""
local count
local timeout
- timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout)
+ if [[ $ns_invert = "invert" ]]; then
+ ns_tx=$ns2
+ ns_rx=$ns1
+ extra_msg="invert"
+ fi
+
+ timeout=$(ip netns exec ${ns_tx} sysctl -n net.mptcp.add_addr_timeout)
print_check "add"
- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtAddAddr")
+ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtAddAddr")
if [ -z "$count" ]; then
print_skip
# if the test configured a short timeout tolerate greater then expected
@@ -1438,7 +1448,7 @@ chk_add_nr()
fi
print_check "echo"
- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtEchoAdd")
+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtEchoAdd")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$echo_nr" ]; then
@@ -1449,7 +1459,7 @@ chk_add_nr()
if [ $port_nr -gt 0 ]; then
print_check "pt"
- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtPortAdd")
+ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtPortAdd")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$port_nr" ]; then
@@ -1459,7 +1469,7 @@ chk_add_nr()
fi
print_check "syn"
- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortSynRx")
+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortSynRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$syn_nr" ]; then
@@ -1470,7 +1480,7 @@ chk_add_nr()
fi
print_check "synack"
- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinPortSynAckRx")
+ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPJoinPortSynAckRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$syn_ack_nr" ]; then
@@ -1481,7 +1491,7 @@ chk_add_nr()
fi
print_check "ack"
- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortAckRx")
+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortAckRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$ack_nr" ]; then
@@ -1492,7 +1502,7 @@ chk_add_nr()
fi
print_check "syn"
- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortSynRx")
+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortSynRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$mis_syn_nr" ]; then
@@ -1503,7 +1513,7 @@ chk_add_nr()
fi
print_check "ack"
- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortAckRx")
+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortAckRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$mis_ack_nr" ]; then
@@ -1513,6 +1523,8 @@ chk_add_nr()
print_ok
fi
fi
+
+ print_info "$extra_msg"
}
chk_add_tx_nr()
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 07/23] selftests: mptcp: join: test both signal & subflow
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (5 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 06/23] selftests: mptcp: join: ability to invert ADD_ADDR check Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 08/23] mptcp: pm: re-using ID of unused removed ADD_ADDR Matthieu Baerts (NGI0)
` (17 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
It should be quite uncommon to set both the subflow and the signal
flags: the initiator of the connection is typically the one creating new
subflows, not the other peer, then no need to announce additional local
addresses, and use it to create subflows.
But some people might be confused about the flags, and set both "just to
be sure at least the right one is set". To verify the previous fix, and
avoid future regressions, this specific case is now validated: the
client announces a new address, and initiates a new subflow from the
same address.
While working on this, another bug has been noticed, where the client
reset the new subflow because an ADD_ADDR echo got received as the 3rd
ACK: this new test also explicitly checks that no RST have been sent by
the client and server.
The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests,
but it validates the previous fix for an issue introduced by this commit
ID.
Fixes: 86e39e04482b ("mptcp: keep track of local endpoint still available for each msk")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_join.sh | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 55ccc4fdf18a..d25ac561e050 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -1967,6 +1967,21 @@ signal_address_tests()
chk_add_nr 1 1
fi
+ # uncommon: subflow and signal flags on the same endpoint
+ # or because the user wrongly picked both, but still expects the client
+ # to create additional subflows
+ if reset "subflow and signal together"; then
+ pm_nl_set_limits $ns1 0 2
+ pm_nl_set_limits $ns2 0 2
+ pm_nl_add_endpoint $ns2 10.0.3.2 flags signal,subflow
+ run_tests $ns1 $ns2 10.0.1.1
+ chk_join_nr 1 1 1
+ chk_add_nr 1 1 0 invert # only initiated by ns2
+ chk_add_nr 0 0 0 # none initiated by ns1
+ chk_rst_nr 0 0 invert # no RST sent by the client
+ chk_rst_nr 0 0 # no RST sent by the server
+ fi
+
# accept and use add_addr with additional subflows
if reset "multiple subflows and signal"; then
pm_nl_set_limits $ns1 0 3
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 08/23] mptcp: pm: re-using ID of unused removed ADD_ADDR
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (6 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 07/23] selftests: mptcp: join: test both signal & subflow Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 09/23] selftests: mptcp: join: check re-using ID of unused ADD_ADDR Matthieu Baerts (NGI0)
` (16 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
If no subflow is attached to the 'signal' endpoint that is being
removed, the addr ID will not be marked as available again.
Mark the linked ID as available when removing the address entry from the
list to cover this case.
Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 2e94f2a9f2a6..d44d318dce03 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1394,6 +1394,11 @@ static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
entry = mptcp_pm_del_add_timer(msk, addr, false);
if (entry) {
+ spin_lock_bh(&msk->pm.lock);
+ __set_bit(entry->addr.id ? : msk->mpc_endpoint_id,
+ msk->pm.id_avail_bitmap);
+ spin_unlock_bh(&msk->pm.lock);
+
list_del(&entry->list);
kfree(entry);
return true;
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 09/23] selftests: mptcp: join: check re-using ID of unused ADD_ADDR
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (7 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 08/23] mptcp: pm: re-using ID of unused removed ADD_ADDR Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 10/23] mptcp: pm: re-using ID of unused removed subflows Matthieu Baerts (NGI0)
` (15 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
This test extends "delete re-add signal" to validate the previous
commit. An extra address is announced by the server, but this address
cannot be used by the client. The result is that no subflow will be
established to this address.
Later, the server will delete this extra endpoint, and set a new one,
with a valid address, but re-using the same ID. Before the previous
commit, the server would not have been able to announce this new
address.
While at it, extra checks have been added to validate the expected
numbers of MPJ, ADD_ADDR and RM_ADDR.
The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests,
but it validates the previous fix for an issue introduced by this commit
ID.
Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_join.sh | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index d25ac561e050..b4dc5f2772dc 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -3557,9 +3557,11 @@ endpoint_tests()
# remove and re-add
if reset "delete re-add signal" &&
mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
- pm_nl_set_limits $ns1 1 1
- pm_nl_set_limits $ns2 1 1
+ pm_nl_set_limits $ns1 0 2
+ pm_nl_set_limits $ns2 2 2
pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal
+ # broadcast IP: no packet for this address will be received on ns1
+ pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal
test_linkfail=4 speed=20 \
run_tests $ns1 $ns2 10.0.1.1 &
local tests_pid=$!
@@ -3571,15 +3573,21 @@ endpoint_tests()
chk_mptcp_info subflows 1 subflows 1
pm_nl_del_endpoint $ns1 1 10.0.2.1
+ pm_nl_del_endpoint $ns1 2 224.0.0.1
sleep 0.5
chk_subflow_nr "after delete" 1
chk_mptcp_info subflows 0 subflows 0
- pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
+ pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal
+ pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal
wait_mpj $ns2
- chk_subflow_nr "after re-add" 2
- chk_mptcp_info subflows 1 subflows 1
+ chk_subflow_nr "after re-add" 3
+ chk_mptcp_info subflows 2 subflows 2
mptcp_lib_kill_wait $tests_pid
+
+ chk_join_nr 3 3 3
+ chk_add_nr 4 4
+ chk_rm_nr 2 1 invert
fi
}
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 10/23] mptcp: pm: re-using ID of unused removed subflows
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (8 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 09/23] selftests: mptcp: join: check re-using ID of unused ADD_ADDR Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 11/23] selftests: mptcp: join: check re-using ID of closed subflow Matthieu Baerts (NGI0)
` (14 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
If no subflow is attached to the 'subflow' endpoint that is being
removed, the addr ID will not be marked as available again.
Mark the linked ID as available when removing the 'subflow' endpoint if
no subflow is attached to it.
While at it, the local_addr_used counter is decremented if the ID was
marked as being used to reflect the reality, but also to allow adding
new endpoints after that.
Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Notes:
- v3:
- Add new line before 'if (remove_subflow) {' block. (Geliang)
---
net/mptcp/pm_netlink.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index d44d318dce03..bdbf27fe89e0 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1454,8 +1454,17 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
remove_subflow = lookup_subflow_by_saddr(&msk->conn_list, addr);
mptcp_pm_remove_anno_addr(msk, addr, remove_subflow &&
!(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
- if (remove_subflow)
+
+ if (remove_subflow) {
mptcp_pm_remove_subflow(msk, &list);
+ } else if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
+ /* If the subflow has been used, but now closed */
+ spin_lock_bh(&msk->pm.lock);
+ if (!__test_and_set_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+ msk->pm.local_addr_used--;
+ spin_unlock_bh(&msk->pm.lock);
+ }
+
release_sock(sk);
next:
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 11/23] selftests: mptcp: join: check re-using ID of closed subflow
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (9 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 10/23] mptcp: pm: re-using ID of unused removed subflows Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-24 17:14 ` Mat Martineau
2024-07-22 19:35 ` [PATCH mptcp-net v4 12/23] mptcp: pm: re-using ID of unused flushed subflows Matthieu Baerts (NGI0)
` (13 subsequent siblings)
24 siblings, 1 reply; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
This test extends "delete and re-add" to validate the previous commit. A
new 'subflow' endpoint is added, but the subflow request will be
rejected. The result is that no subflow will be established from this
address.
Later, the endpoint is removed and re-added after having cleared the
firewall rule. Before the previous commit, the client would not have
been able to create this new subflow.
While at it, extra checks have been added to validate the expected
numbers of MPJ and RM_ADDR.
The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests,
but it validates the previous fix for an issue introduced by this commit
ID.
Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_join.sh | 27 ++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index b4dc5f2772dc..c5aa745a36f5 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -436,9 +436,10 @@ reset_with_tcp_filter()
local ns="${!1}"
local src="${2}"
local target="${3}"
+ local chain="${4:-INPUT}"
if ! ip netns exec "${ns}" ${iptables} \
- -A INPUT \
+ -A "${chain}" \
-s "${src}" \
-p tcp \
-j "${target}"; then
@@ -3527,10 +3528,10 @@ endpoint_tests()
mptcp_lib_kill_wait $tests_pid
fi
- if reset "delete and re-add" &&
+ if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT &&
mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
- pm_nl_set_limits $ns1 1 1
- pm_nl_set_limits $ns2 1 1
+ pm_nl_set_limits $ns1 0 2
+ pm_nl_set_limits $ns2 0 2
pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow
test_linkfail=4 speed=20 \
run_tests $ns1 $ns2 10.0.1.1 &
@@ -3547,11 +3548,27 @@ endpoint_tests()
chk_subflow_nr "after delete" 1
chk_mptcp_info subflows 0 subflows 0
- pm_nl_add_endpoint $ns2 10.0.2.2 dev ns2eth2 flags subflow
+ pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow
wait_mpj $ns2
chk_subflow_nr "after re-add" 2
chk_mptcp_info subflows 1 subflows 1
+
+ pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
+ wait_attempt_fail $ns2
+ chk_subflow_nr "after new reject" 2
+ chk_mptcp_info subflows 1 subflows 1
+
+ ip netns exec "${ns2}" ${iptables} -D OUTPUT -s "10.0.3.2" -p tcp -j REJECT
+ pm_nl_del_endpoint $ns2 3 10.0.3.2
+ pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
+ wait_mpj $ns2
+ chk_subflow_nr "after no reject" 3
+ chk_mptcp_info subflows 2 subflows 2
+
mptcp_lib_kill_wait $tests_pid
+
+ chk_join_nr 3 3 3
+ chk_rm_nr 1 1
fi
# remove and re-add
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 12/23] mptcp: pm: re-using ID of unused flushed subflows
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (10 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 11/23] selftests: mptcp: join: check re-using ID of closed subflow Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-23 22:00 ` Mat Martineau
2024-07-22 19:35 ` [PATCH mptcp-net v4 13/23] selftests: mptcp: join: test for flush/re-add endpoints Matthieu Baerts (NGI0)
` (12 subsequent siblings)
24 siblings, 1 reply; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
If no subflows are attached to the 'subflow' endpoints that are being
flushed, the corresponding addr IDs will not be marked as available
again.
Mark all ID as being available when flushing all the 'subflow'
endpoints, and reset local_addr_used counter to cover these cases.
While at it, renamed the helpers linked to the flushing operations to
make it clear that the intention is to flush all created subflows, and
remove all announced addresses, not just a "random" selection.
Fixes: 06faa2271034 ("mptcp: remove multi addresses and subflows in PM")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index bdbf27fe89e0..4045e5cc6298 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1586,8 +1586,8 @@ void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
}
}
-static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
- struct list_head *rm_list)
+static void mptcp_pm_flush_addrs_and_subflows(struct mptcp_sock *msk,
+ struct list_head *rm_list)
{
struct mptcp_rm_list alist = { .nr = 0 }, slist = { .nr = 0 };
struct mptcp_pm_addr_entry *entry;
@@ -1608,12 +1608,19 @@ static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
mptcp_pm_remove_addr(msk, &alist);
spin_unlock_bh(&msk->pm.lock);
}
+
if (slist.nr)
mptcp_pm_remove_subflow(msk, &slist);
+
+ /* Reset counters: maybe some subflows have been removed before */
+ spin_lock_bh(&msk->pm.lock);
+ bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+ msk->pm.local_addr_used = 0;
+ spin_unlock_bh(&msk->pm.lock);
}
-static void mptcp_nl_remove_addrs_list(struct net *net,
- struct list_head *rm_list)
+static void mptcp_nl_flush_addrs_list(struct net *net,
+ struct list_head *rm_list)
{
long s_slot = 0, s_num = 0;
struct mptcp_sock *msk;
@@ -1626,7 +1633,7 @@ static void mptcp_nl_remove_addrs_list(struct net *net,
if (!mptcp_pm_is_userspace(msk)) {
lock_sock(sk);
- mptcp_pm_remove_addrs_and_subflows(msk, rm_list);
+ mptcp_pm_flush_addrs_and_subflows(msk, rm_list);
release_sock(sk);
}
@@ -1667,7 +1674,7 @@ int mptcp_pm_nl_flush_addrs_doit(struct sk_buff *skb, struct genl_info *info)
pernet->next_id = 1;
bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
spin_unlock_bh(&pernet->lock);
- mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
+ mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list);
synchronize_rcu();
__flush_addrs(&free_list);
return 0;
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 13/23] selftests: mptcp: join: test for flush/re-add endpoints
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (11 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 12/23] mptcp: pm: re-using ID of unused flushed subflows Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 14/23] mptcp: pm: remove mptcp_pm_remove_subflow() Matthieu Baerts (NGI0)
` (11 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
After having flushed endpoints that didn't cause the creation of new
subflows, it is important to check endpoints can be re-created, re-using
previously used IDs.
Before the previous commit, the client would not have been able to
re-create the subflow that was previously rejected.
The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests,
but it validates the previous fix for an issue introduced by this commit
ID.
Fixes: 06faa2271034 ("mptcp: remove multi addresses and subflows in PM")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_join.sh | 30 +++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index c5aa745a36f5..3565d8b48125 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -3607,6 +3607,36 @@ endpoint_tests()
chk_rm_nr 2 1 invert
fi
+ # flush and re-add
+ if reset_with_tcp_filter "flush re-add" ns2 10.0.3.2 REJECT OUTPUT &&
+ mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
+ pm_nl_set_limits $ns1 0 2
+ pm_nl_set_limits $ns2 1 2
+ # broadcast IP: no packet for this address will be received on ns1
+ pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal
+ pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
+ test_linkfail=4 speed=20 \
+ run_tests $ns1 $ns2 10.0.1.1 &
+ local tests_pid=$!
+
+ wait_attempt_fail $ns2
+ chk_subflow_nr "before flush" 1
+ chk_mptcp_info subflows 0 subflows 0
+
+ pm_nl_flush_endpoint $ns2
+ pm_nl_flush_endpoint $ns1
+ wait_rm_addr $ns2 0
+ ip netns exec "${ns2}" ${iptables} -D OUTPUT -s "10.0.3.2" -p tcp -j REJECT
+ pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
+ wait_mpj $ns2
+ pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal
+ wait_mpj $ns2
+ mptcp_lib_kill_wait $tests_pid
+
+ chk_join_nr 2 2 2
+ chk_add_nr 2 2
+ chk_rm_nr 1 0 invert
+ fi
}
# [$1: error message]
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 14/23] mptcp: pm: remove mptcp_pm_remove_subflow()
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (12 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 13/23] selftests: mptcp: join: test for flush/re-add endpoints Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 15/23] mptcp: pm: only mark 'subflow' endp as available Matthieu Baerts (NGI0)
` (10 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
This helper is confusing. It is in pm.c, but it is specific to the
in-kernel PM and it cannot be used by the userspace one. Also, it simply
calls one in-kernel specific function with the PM lock, while the
similar mptcp_pm_remove_addr() helper requires the PM lock.
What's left is the pr_debug(), which is not that useful, because a
similar one is present in the only function called by this helper:
mptcp_pm_nl_rm_subflow_received()
After these modifications, this helper can be marked as 'static', and
the lock can be taken only once in mptcp_pm_flush_addrs_and_subflows().
Note that it is not a bug fix, but it will help backporting the
following commits.
Fixes: 0ee4261a3681 ("mptcp: implement mptcp_pm_remove_subflow")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Notes:
- v3:
- New line before 'if (remove_subflow) {' moved to patch 10 (Geliang)
- One PM spin lock to remove address and subflows (Geliang)
---
net/mptcp/pm.c | 10 ----------
net/mptcp/pm_netlink.c | 16 +++++++---------
net/mptcp/protocol.h | 3 ---
3 files changed, 7 insertions(+), 22 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 55406720c607..1f1b2617d0f5 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -60,16 +60,6 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
return 0;
}
-int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list)
-{
- pr_debug("msk=%p, rm_list_nr=%d", msk, rm_list->nr);
-
- spin_lock_bh(&msk->pm.lock);
- mptcp_pm_nl_rm_subflow_received(msk, rm_list);
- spin_unlock_bh(&msk->pm.lock);
- return 0;
-}
-
/* path manager event handlers */
void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 4045e5cc6298..a653ecc9e9ad 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -858,8 +858,8 @@ static void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
mptcp_pm_nl_rm_addr_or_subflow(msk, &msk->pm.rm_list_rx, MPTCP_MIB_RMADDR);
}
-void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
- const struct mptcp_rm_list *rm_list)
+static void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
+ const struct mptcp_rm_list *rm_list)
{
mptcp_pm_nl_rm_addr_or_subflow(msk, rm_list, MPTCP_MIB_RMSUBFLOW);
}
@@ -1456,7 +1456,9 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
!(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
if (remove_subflow) {
- mptcp_pm_remove_subflow(msk, &list);
+ spin_lock_bh(&msk->pm.lock);
+ mptcp_pm_nl_rm_subflow_received(msk, &list);
+ spin_unlock_bh(&msk->pm.lock);
} else if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
/* If the subflow has been used, but now closed */
spin_lock_bh(&msk->pm.lock);
@@ -1602,18 +1604,14 @@ static void mptcp_pm_flush_addrs_and_subflows(struct mptcp_sock *msk,
alist.ids[alist.nr++] = entry->addr.id;
}
+ spin_lock_bh(&msk->pm.lock);
if (alist.nr) {
- spin_lock_bh(&msk->pm.lock);
msk->pm.add_addr_signaled -= alist.nr;
mptcp_pm_remove_addr(msk, &alist);
- spin_unlock_bh(&msk->pm.lock);
}
-
if (slist.nr)
- mptcp_pm_remove_subflow(msk, &slist);
-
+ mptcp_pm_nl_rm_subflow_received(msk, &slist);
/* Reset counters: maybe some subflows have been removed before */
- spin_lock_bh(&msk->pm.lock);
bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
msk->pm.local_addr_used = 0;
spin_unlock_bh(&msk->pm.lock);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 19d60b6d5b45..f2eb5273d752 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1030,7 +1030,6 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
const struct mptcp_addr_info *addr,
bool echo);
int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
-int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list);
void mptcp_free_local_addr_list(struct mptcp_sock *msk);
@@ -1134,8 +1133,6 @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo
void __init mptcp_pm_nl_init(void);
void mptcp_pm_nl_work(struct mptcp_sock *msk);
-void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
- const struct mptcp_rm_list *rm_list);
unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk);
unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);
unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk);
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 15/23] mptcp: pm: only mark 'subflow' endp as available
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (13 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 14/23] mptcp: pm: remove mptcp_pm_remove_subflow() Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 16/23] mptcp: pm: only decrement add_addr_accepted for MPJ req Matthieu Baerts (NGI0)
` (9 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
Adding the following warning ...
WARN_ON_ONCE(msk->pm.local_addr_used == 0)
... before decrementing the local_addr_used counter helped to find a bug
when running the "remove single address" subtest from the mptcp_join.sh
selftests.
Removing a 'signal' endpoint will trigger the removal of all subflows
linked to this endpoint via mptcp_pm_nl_rm_addr_or_subflow() with
rm_type == MPTCP_MIB_RMSUBFLOW. This will decrement the local_addr_used
counter, which is wrong in this case because this counter is linked to
'subflow' endpoints, and here it is a 'signal' endpoint that is being
removed.
Now, the counter is decremented, only if the ID is being used outside
of mptcp_pm_nl_rm_addr_or_subflow(), only for 'subflow' endpoints, and
if the ID is not 0 -- local_addr_used is not taking into account these
ones. This marking of the ID as being available, and the decrement is
done no matter if a subflow using this ID is currently available,
because the subflow could have been closed before.
Fixes: 06faa2271034 ("mptcp: remove multi addresses and subflows in PM")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index a653ecc9e9ad..ea942c9f998f 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -834,10 +834,10 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
if (rm_type == MPTCP_MIB_RMSUBFLOW)
__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);
- else if (rm_type == MPTCP_MIB_RMADDR)
+
+ if (rm_type == MPTCP_MIB_RMADDR)
__MPTCP_INC_STATS(sock_net(sk), rm_type);
+
if (!removed)
continue;
@@ -847,8 +847,6 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
if (rm_type == MPTCP_MIB_RMADDR) {
msk->pm.add_addr_accepted--;
WRITE_ONCE(msk->pm.accept_addr, true);
- } else if (rm_type == MPTCP_MIB_RMSUBFLOW) {
- msk->pm.local_addr_used--;
}
}
}
@@ -1426,6 +1424,14 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
return ret;
}
+static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
+{
+ /* If it was marked as used, and not ID 0, decrement local_addr_used */
+ if (!__test_and_set_bit(id ? : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap) &&
+ id && !WARN_ON_ONCE(msk->pm.local_addr_used == 0))
+ msk->pm.local_addr_used--;
+}
+
static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
const struct mptcp_pm_addr_entry *entry)
{
@@ -1459,11 +1465,11 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
spin_lock_bh(&msk->pm.lock);
mptcp_pm_nl_rm_subflow_received(msk, &list);
spin_unlock_bh(&msk->pm.lock);
- } else if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
- /* If the subflow has been used, but now closed */
+ }
+
+ if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
spin_lock_bh(&msk->pm.lock);
- if (!__test_and_set_bit(entry->addr.id, msk->pm.id_avail_bitmap))
- msk->pm.local_addr_used--;
+ __mark_subflow_endp_available(msk, entry->addr.id);
spin_unlock_bh(&msk->pm.lock);
}
@@ -1501,6 +1507,7 @@ static int mptcp_nl_remove_id_zero_address(struct net *net,
spin_lock_bh(&msk->pm.lock);
mptcp_pm_remove_addr(msk, &list);
mptcp_pm_nl_rm_subflow_received(msk, &list);
+ __mark_subflow_endp_available(msk, 0);
spin_unlock_bh(&msk->pm.lock);
release_sock(sk);
@@ -1902,6 +1909,7 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
spin_lock_bh(&msk->pm.lock);
mptcp_pm_nl_rm_subflow_received(msk, &list);
+ __mark_subflow_endp_available(msk, addr->id);
mptcp_pm_create_subflow_or_signal_addr(msk);
spin_unlock_bh(&msk->pm.lock);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 16/23] mptcp: pm: only decrement add_addr_accepted for MPJ req
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (14 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 15/23] mptcp: pm: only mark 'subflow' endp as available Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 17/23] mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR Matthieu Baerts (NGI0)
` (8 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
Adding the following warning ...
WARN_ON_ONCE(msk->pm.add_addr_accepted == 0)
... before decrementing the add_addr_accepted counter helped to find a
bug when running the "remove single subflow" subtest from the
mptcp_join.sh selftest.
Removing a 'subflow' endpoint will first trigger a RM_ADDR, then the
subflow closure. Before this patch, and upon the reception of the
RM_ADDR, the other peer will then try to decrement this
add_addr_accepted. That's not correct because the attached subflows have
not been created upon the reception of an ADD_ADDR.
A way to solve that is to decrement the counter only if the attached
subflow was an MP_JOIN to a remote id that was not 0, and initiated by
the host receiving the RM_ADDR.
Fixes: d0876b2284cf ("mptcp: add the incoming RM_ADDR support")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index ea942c9f998f..d040cf8af412 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -830,7 +830,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
mptcp_close_ssk(sk, ssk, subflow);
spin_lock_bh(&msk->pm.lock);
- removed = true;
+ removed |= subflow->request_join;
if (rm_type == MPTCP_MIB_RMSUBFLOW)
__MPTCP_INC_STATS(sock_net(sk), rm_type);
}
@@ -844,7 +844,11 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
if (!mptcp_pm_is_kernel(msk))
continue;
- if (rm_type == MPTCP_MIB_RMADDR) {
+ if (rm_type == MPTCP_MIB_RMADDR && rm_id &&
+ !WARN_ON_ONCE(msk->pm.add_addr_accepted == 0)) {
+ /* Note: if the subflow has been closed before, this
+ * add_addr_accepted counter will not be decremented.
+ */
msk->pm.add_addr_accepted--;
WRITE_ONCE(msk->pm.accept_addr, true);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 17/23] mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (15 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 16/23] mptcp: pm: only decrement add_addr_accepted for MPJ req Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 18/23] mptcp: pm: only in-kernel cannot have entries with ID 0 Matthieu Baerts (NGI0)
` (7 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
The limits might have changed in between, it is best to check them
before accepting new ADD_ADDR.
Fixes: d0876b2284cf ("mptcp: add the incoming RM_ADDR support")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index d040cf8af412..b6086e9c7fc8 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -849,8 +849,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
/* Note: if the subflow has been closed before, this
* add_addr_accepted counter will not be decremented.
*/
- msk->pm.add_addr_accepted--;
- WRITE_ONCE(msk->pm.accept_addr, true);
+ if (--msk->pm.add_addr_accepted < mptcp_pm_get_add_addr_accept_max(msk))
+ WRITE_ONCE(msk->pm.accept_addr, true);
}
}
}
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 18/23] mptcp: pm: only in-kernel cannot have entries with ID 0
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (16 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 17/23] mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 19/23] mptcp: pm: fullmesh: select the right ID later Matthieu Baerts (NGI0)
` (6 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
The ID 0 is specific per MPTCP connections. The per netns entries cannot
have this special ID 0 then.
But that's different for the userspace PM where the entries are per
connection, they can then use this special ID 0.
Fixes: f40be0db0b76 ("mptcp: unify pm get_flags_and_ifindex_by_id")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm.c | 3 ---
net/mptcp/pm_netlink.c | 4 ++++
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 1f1b2617d0f5..ddad51210971 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -422,9 +422,6 @@ int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id
*flags = 0;
*ifindex = 0;
- if (!id)
- return 0;
-
if (mptcp_pm_is_userspace(msk))
return mptcp_userspace_pm_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
return mptcp_pm_nl_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index b6086e9c7fc8..ec23bb32862f 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1378,6 +1378,10 @@ int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int
struct sock *sk = (struct sock *)msk;
struct net *net = sock_net(sk);
+ /* No entries with ID 0 */
+ if (id == 0)
+ return 0;
+
rcu_read_lock();
entry = __lookup_addr_by_id(pm_nl_get_pernet(net), id);
if (entry) {
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 19/23] mptcp: pm: fullmesh: select the right ID later
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (17 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 18/23] mptcp: pm: only in-kernel cannot have entries with ID 0 Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 20/23] selftests: mptcp: join: validate fullmesh endp on 1st sf Matthieu Baerts (NGI0)
` (5 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
When reacting upon the reception of an ADD_ADDR, the in-kernel PM first
looks for fullmesh endpoints. If there are some, it will pick them,
using their entry ID.
It should set the ID 0 when using the endpoint corresponding to the
initial subflow, it is a special case imposed by the MPTCP specs.
Note that msk->mpc_endpoint_id might not be set when receiving the first
ADD_ADDR from the server. So better to compare the addresses.
Fixes: 1a0d6136c5f0 ("mptcp: local addresses fullmesh")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Notes:
- v4:
- Check that msk->first is not NULL.
---
net/mptcp/pm_netlink.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index ec23bb32862f..2c335202aafb 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -637,6 +637,7 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
{
struct sock *sk = (struct sock *)msk;
struct mptcp_pm_addr_entry *entry;
+ struct mptcp_addr_info mpc_addr;
struct pm_nl_pernet *pernet;
unsigned int subflows_max;
int i = 0;
@@ -644,6 +645,9 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
pernet = pm_nl_get_pernet_from_msk(msk);
subflows_max = mptcp_pm_get_subflows_max(msk);
+ if (msk->first)
+ mptcp_local_address((struct sock_common *)msk->first, &mpc_addr);
+
rcu_read_lock();
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
if (!(entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH))
@@ -654,7 +658,14 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
if (msk->pm.subflows < subflows_max) {
msk->pm.subflows++;
- addrs[i++] = entry->addr;
+ addrs[i] = entry->addr;
+
+ /* Special case for ID0: set the correct ID */
+ if (msk->first &&
+ mptcp_addresses_equal(&entry->addr, &mpc_addr, entry->addr.port))
+ addrs[i].id = 0;
+
+ i++;
}
}
rcu_read_unlock();
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 20/23] selftests: mptcp: join: validate fullmesh endp on 1st sf
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (18 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 19/23] mptcp: pm: fullmesh: select the right ID later Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 21/23] mptcp: pm: avoid possible UaF whend selecting endp Matthieu Baerts (NGI0)
` (4 subsequent siblings)
24 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
This case was not covered, and the wrong ID was set before the previous
commit.
The rest is not modified, it is just that it will increase the code
coverage.
The right address ID can be verified by looking at the packet traces. We
could automate that using Netfilter with some cBPF code for example, but
that's always a bit cryptic. Packetdrill seems better fitted for that.
Fixes: 4f49d63352da ("selftests: mptcp: add fullmesh testcases")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_join.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 3565d8b48125..c4bb390933d6 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -3014,6 +3014,7 @@ fullmesh_tests()
if reset "fullmesh test 1x1"; then
pm_nl_set_limits $ns1 1 3
pm_nl_set_limits $ns2 1 3
+ pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,fullmesh
pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
fullmesh=1 speed=slow \
run_tests $ns1 $ns2 10.0.1.1
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 21/23] mptcp: pm: avoid possible UaF whend selecting endp
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (19 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 20/23] selftests: mptcp: join: validate fullmesh endp on 1st sf Matthieu Baerts (NGI0)
@ 2024-07-22 19:35 ` Matthieu Baerts (NGI0)
2024-07-23 22:01 ` Mat Martineau
2024-07-25 15:43 ` Paolo Abeni
2024-07-22 19:36 ` [PATCH mptcp-net v4 22/23] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0)
` (3 subsequent siblings)
24 siblings, 2 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:35 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
select_local_address() and select_signal_address() both select an
endpoint entry from the list inside an RCU protected section, but return
a reference to it, to be read later on. If the entry is dereferenced
after the RCU unlock, reading info could cause a Use-after-Free.
A simple solution is to copy the required info while inside the RCU
protected section to avoid any risk of UaF later. The address ID might
need to be modified later to handle the ID0 case later, so a copy seems
OK to deal with.
Reported-by: Paolo Abeni <pabeni@redhat.com>
Closes: https://lore.kernel.org/45cd30d3-7710-491c-ae4d-a1368c00beb1@redhat.com
Fixes: 01cacb00b35c ("mptcp: add netlink-based PM")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 64 +++++++++++++++++++++++++++-----------------------
1 file changed, 34 insertions(+), 30 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 2c335202aafb..8f25690a5edc 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -143,11 +143,13 @@ static bool lookup_subflow_by_daddr(const struct list_head *list,
return false;
}
-static struct mptcp_pm_addr_entry *
+static bool
select_local_address(const struct pm_nl_pernet *pernet,
- const struct mptcp_sock *msk)
+ const struct mptcp_sock *msk,
+ struct mptcp_pm_addr_entry *new_entry)
{
- struct mptcp_pm_addr_entry *entry, *ret = NULL;
+ struct mptcp_pm_addr_entry *entry;
+ bool found = false;
msk_owned_by_me(msk);
@@ -159,17 +161,21 @@ select_local_address(const struct pm_nl_pernet *pernet,
if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
continue;
- ret = entry;
+ memcpy(new_entry, entry, sizeof(struct mptcp_pm_addr_entry));
+ found = true;
break;
}
rcu_read_unlock();
- return ret;
+
+ return found;
}
-static struct mptcp_pm_addr_entry *
-select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk)
+static bool
+select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
+ struct mptcp_pm_addr_entry *new_entry)
{
- struct mptcp_pm_addr_entry *entry, *ret = NULL;
+ struct mptcp_pm_addr_entry *entry;
+ bool found = false;
rcu_read_lock();
/* do not keep any additional per socket state, just signal
@@ -184,11 +190,13 @@ select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk)
if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
continue;
- ret = entry;
+ memcpy(new_entry, entry, sizeof(struct mptcp_pm_addr_entry));
+ found = true;
break;
}
rcu_read_unlock();
- return ret;
+
+ return found;
}
unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk)
@@ -513,9 +521,10 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
{
- struct mptcp_pm_addr_entry *local, *signal_and_subflow = NULL;
struct sock *sk = (struct sock *)msk;
+ struct mptcp_pm_addr_entry local;
unsigned int add_addr_signal_max;
+ bool signal_and_subflow = false;
unsigned int local_addr_max;
struct pm_nl_pernet *pernet;
unsigned int subflows_max;
@@ -566,23 +575,22 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL))
return;
- local = select_signal_address(pernet, msk);
- if (!local)
+ if (!select_signal_address(pernet, msk, &local))
goto subflow;
/* If the alloc fails, we are on memory pressure, not worth
* continuing, and trying to create subflows.
*/
- if (!mptcp_pm_alloc_anno_list(msk, &local->addr))
+ if (!mptcp_pm_alloc_anno_list(msk, &local.addr))
return;
- __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
+ __clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
msk->pm.add_addr_signaled++;
- mptcp_pm_announce_addr(msk, &local->addr, false);
+ mptcp_pm_announce_addr(msk, &local.addr, false);
mptcp_pm_nl_addr_send_ack(msk);
- if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
- signal_and_subflow = local;
+ if (local.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
+ signal_and_subflow = true;
}
subflow:
@@ -593,26 +601,22 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
bool fullmesh;
int i, nr;
- if (signal_and_subflow) {
- local = signal_and_subflow;
- signal_and_subflow = NULL;
- } else {
- local = select_local_address(pernet, msk);
- if (!local)
- break;
- }
+ if (signal_and_subflow)
+ signal_and_subflow = false;
+ else if (!select_local_address(pernet, msk, &local))
+ break;
- fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
+ fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
msk->pm.local_addr_used++;
- __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
- nr = fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs);
+ __clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
+ nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs);
if (nr == 0)
continue;
spin_unlock_bh(&msk->pm.lock);
for (i = 0; i < nr; i++)
- __mptcp_subflow_connect(sk, &local->addr, &addrs[i]);
+ __mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
spin_lock_bh(&msk->pm.lock);
}
mptcp_pm_nl_check_work_pending(msk);
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 22/23] mptcp: pm: reuse ID 0 after delete and re-add
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (20 preceding siblings ...)
2024-07-22 19:35 ` [PATCH mptcp-net v4 21/23] mptcp: pm: avoid possible UaF whend selecting endp Matthieu Baerts (NGI0)
@ 2024-07-22 19:36 ` Matthieu Baerts (NGI0)
2024-07-23 22:02 ` Mat Martineau
2024-07-22 19:36 ` [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect Matthieu Baerts (NGI0)
` (2 subsequent siblings)
24 siblings, 1 reply; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:36 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
When the endpoint used by the initial subflow is removed and re-added
later, the PM has to force the ID 0, it is a special case imposed by the
MPTCP specs.
Note that the endpoint should then need to be re-added reusing the same
ID.
Fixes: 3ad14f54bd74 ("mptcp: more accurate MPC endpoint tracking")
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
net/mptcp/pm_netlink.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 8f25690a5edc..45a1aa0a40bf 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -586,6 +586,11 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
msk->pm.add_addr_signaled++;
+
+ /* Special case for ID0: set the correct */
+ if (local.addr.id == msk->mpc_endpoint_id)
+ local.addr.id = 0;
+
mptcp_pm_announce_addr(msk, &local.addr, false);
mptcp_pm_nl_addr_send_ack(msk);
@@ -614,6 +619,10 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
if (nr == 0)
continue;
+ /* Special case for ID0: set the correct ID */
+ if (local.addr.id == msk->mpc_endpoint_id)
+ local.addr.id = 0;
+
spin_unlock_bh(&msk->pm.lock);
for (i = 0; i < nr; i++)
__mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (21 preceding siblings ...)
2024-07-22 19:36 ` [PATCH mptcp-net v4 22/23] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0)
@ 2024-07-22 19:36 ` Matthieu Baerts (NGI0)
2024-07-23 2:56 ` kernel test robot
` (2 more replies)
2024-07-22 20:32 ` [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags MPTCP CI
2024-07-23 22:04 ` Mat Martineau
24 siblings, 3 replies; 35+ messages in thread
From: Matthieu Baerts (NGI0) @ 2024-07-22 19:36 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni, Matthieu Baerts (NGI0)
__mptcp_subflow_connect() is currently called from the path-managers,
which have all the required information to create subflows. No need to
call the PM again to re-iterate over the list of entries with RCU lock
to get more info.
Instead, it is possible to pass a mptcp_pm_addr_entry structure, instead
of a mptcp_addr_info one. The former contains the ifindex and the flags
that are required when creating the new subflow.
This is a partial revert of commit ee285257a9c1 ("mptcp: drop flags and
ifindex arguments").
While at it, the local ID can also be set if it is known and 0, to avoid
having to set it in the 'rebuild_header' hook, which will cause a new
iteration of the endpoint entries.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Notes:
- This patch is for net-next
- v4:
- Avoid multiple copies of an addr entry in
fill_local_addresses_vec().
- Rebased on top of "mptcp: fix endpoints with 'signal' and 'subflow'
flags", v4.
---
net/mptcp/pm.c | 11 -----------
net/mptcp/pm_netlink.c | 48 ++++++++++++------------------------------------
net/mptcp/pm_userspace.c | 19 +------------------
net/mptcp/protocol.h | 10 +---------
net/mptcp/subflow.c | 29 ++++++++++++++++++-----------
5 files changed, 32 insertions(+), 85 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index ddad51210971..54fabd386b04 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -416,17 +416,6 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
return mptcp_pm_nl_get_local_id(msk, &skc_local);
}
-int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
- u8 *flags, int *ifindex)
-{
- *flags = 0;
- *ifindex = 0;
-
- if (mptcp_pm_is_userspace(msk))
- return mptcp_userspace_pm_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
- return mptcp_pm_nl_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
-}
-
int mptcp_pm_get_addr(struct sk_buff *skb, struct genl_info *info)
{
if (info->attrs[MPTCP_PM_ATTR_TOKEN])
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 45a1aa0a40bf..a316951f8762 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -625,7 +625,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
spin_unlock_bh(&msk->pm.lock);
for (i = 0; i < nr; i++)
- __mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
+ __mptcp_subflow_connect(sk, &local, &addrs[i]);
spin_lock_bh(&msk->pm.lock);
}
mptcp_pm_nl_check_work_pending(msk);
@@ -646,7 +646,7 @@ static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
*/
static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
struct mptcp_addr_info *remote,
- struct mptcp_addr_info *addrs)
+ struct mptcp_pm_addr_entry *entries)
{
struct sock *sk = (struct sock *)msk;
struct mptcp_pm_addr_entry *entry;
@@ -670,14 +670,14 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
continue;
if (msk->pm.subflows < subflows_max) {
- msk->pm.subflows++;
- addrs[i] = entry->addr;
+ memcpy(&entries[i], entry, sizeof(entries[i]));
/* Special case for ID0: set the correct ID */
if (msk->first &&
mptcp_addresses_equal(&entry->addr, &mpc_addr, entry->addr.port))
- addrs[i].id = 0;
+ entries[i].addr.id = 0;
+ msk->pm.subflows++;
i++;
}
}
@@ -687,21 +687,19 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
* 'IPADDRANY' local address
*/
if (!i) {
- struct mptcp_addr_info local;
-
- memset(&local, 0, sizeof(local));
- local.family =
+ memset(&entries[i], 0, sizeof(entries[i]));
+ entries[i].addr.family =
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
remote->family == AF_INET6 &&
ipv6_addr_v4mapped(&remote->addr6) ? AF_INET :
#endif
remote->family;
- if (!mptcp_pm_addr_families_match(sk, &local, remote))
+ if (!mptcp_pm_addr_families_match(sk, &entries[i].addr, remote))
return 0;
msk->pm.subflows++;
- addrs[i++] = local;
+ i++;
}
return i;
@@ -709,7 +707,7 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
{
- struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX];
+ struct mptcp_pm_addr_entry entries[MPTCP_PM_ADDR_MAX];
struct sock *sk = (struct sock *)msk;
unsigned int add_addr_accept_max;
struct mptcp_addr_info remote;
@@ -738,13 +736,13 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
/* connect to the specified remote address, using whatever
* local address the routing configuration will pick.
*/
- nr = fill_local_addresses_vec(msk, &remote, addrs);
+ nr = fill_local_addresses_vec(msk, &remote, entries);
if (nr == 0)
return;
spin_unlock_bh(&msk->pm.lock);
for (i = 0; i < nr; i++)
- if (__mptcp_subflow_connect(sk, &addrs[i], &remote) == 0)
+ if (__mptcp_subflow_connect(sk, &entries[i], &remote) == 0)
sf_created = true;
spin_lock_bh(&msk->pm.lock);
@@ -1395,28 +1393,6 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
return ret;
}
-int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
- u8 *flags, int *ifindex)
-{
- struct mptcp_pm_addr_entry *entry;
- struct sock *sk = (struct sock *)msk;
- struct net *net = sock_net(sk);
-
- /* No entries with ID 0 */
- if (id == 0)
- return 0;
-
- rcu_read_lock();
- entry = __lookup_addr_by_id(pm_nl_get_pernet(net), id);
- if (entry) {
- *flags = entry->flags;
- *ifindex = entry->ifindex;
- }
- rcu_read_unlock();
-
- return 0;
-}
-
static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
const struct mptcp_addr_info *addr)
{
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index f0a4590506c6..97b09dffff6d 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -119,23 +119,6 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
return NULL;
}
-int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
- unsigned int id,
- u8 *flags, int *ifindex)
-{
- struct mptcp_pm_addr_entry *match;
-
- spin_lock_bh(&msk->pm.lock);
- match = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
- spin_unlock_bh(&msk->pm.lock);
- if (match) {
- *flags = match->flags;
- *ifindex = match->ifindex;
- }
-
- return 0;
-}
-
int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
struct mptcp_addr_info *skc)
{
@@ -394,7 +377,7 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
lock_sock(sk);
- err = __mptcp_subflow_connect(sk, &local.addr, &addr_r);
+ err = __mptcp_subflow_connect(sk, &local, &addr_r);
release_sock(sk);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index f2eb5273d752..259e247b0862 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -722,7 +722,7 @@ bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
void mptcp_local_address(const struct sock_common *skc, struct mptcp_addr_info *addr);
/* called with sk socket lock held */
-int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
+int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_addr_entry *local,
const struct mptcp_addr_info *remote);
int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
struct socket **new_sock);
@@ -1015,14 +1015,6 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
struct mptcp_pm_add_entry *
mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
const struct mptcp_addr_info *addr);
-int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
- unsigned int id,
- u8 *flags, int *ifindex);
-int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
- u8 *flags, int *ifindex);
-int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
- unsigned int id,
- u8 *flags, int *ifindex);
int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info);
int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 39e2cbdf3801..0835e71118b9 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1544,26 +1544,24 @@ void mptcp_info2sockaddr(const struct mptcp_addr_info *info,
#endif
}
-int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
+int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_addr_entry *local,
const struct mptcp_addr_info *remote)
{
struct mptcp_sock *msk = mptcp_sk(sk);
struct mptcp_subflow_context *subflow;
+ int local_id = local->addr.id;
struct sockaddr_storage addr;
int remote_id = remote->id;
- int local_id = loc->id;
int err = -ENOTCONN;
struct socket *sf;
struct sock *ssk;
u32 remote_token;
int addrlen;
- int ifindex;
- u8 flags;
if (!mptcp_is_fully_established(sk))
goto err_out;
- err = mptcp_subflow_create_socket(sk, loc->family, &sf);
+ err = mptcp_subflow_create_socket(sk, local->addr.family, &sf);
if (err)
goto err_out;
@@ -1573,23 +1571,32 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
get_random_bytes(&subflow->local_nonce, sizeof(u32));
} while (!subflow->local_nonce);
- if (local_id)
+ /* if 'IPADDRANY', the ID will be set later, after the routing */
+ if (local->addr.family == AF_INET) {
+ if (!local->addr.addr.s_addr)
+ local_id = -1;
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (sk->sk_family == AF_INET6) {
+ if (ipv6_addr_any(&local->addr.addr6))
+ local_id = -1;
+#endif
+ }
+
+ if (local_id >= 0)
subflow_set_local_id(subflow, local_id);
- mptcp_pm_get_flags_and_ifindex_by_id(msk, local_id,
- &flags, &ifindex);
subflow->remote_key_valid = 1;
subflow->remote_key = READ_ONCE(msk->remote_key);
subflow->local_key = READ_ONCE(msk->local_key);
subflow->token = msk->token;
- mptcp_info2sockaddr(loc, &addr, ssk->sk_family);
+ mptcp_info2sockaddr(&local->addr, &addr, ssk->sk_family);
addrlen = sizeof(struct sockaddr_in);
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
if (addr.ss_family == AF_INET6)
addrlen = sizeof(struct sockaddr_in6);
#endif
- ssk->sk_bound_dev_if = ifindex;
+ ssk->sk_bound_dev_if = local->ifindex;
err = kernel_bind(sf, (struct sockaddr *)&addr, addrlen);
if (err)
goto failed;
@@ -1600,7 +1607,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
subflow->remote_token = remote_token;
WRITE_ONCE(subflow->remote_id, remote_id);
subflow->request_join = 1;
- subflow->request_bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+ subflow->request_bkup = !!(local->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
subflow->subflow_id = msk->subflow_id++;
mptcp_info2sockaddr(remote, &addr, ssk->sk_family);
--
2.45.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (22 preceding siblings ...)
2024-07-22 19:36 ` [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect Matthieu Baerts (NGI0)
@ 2024-07-22 20:32 ` MPTCP CI
2024-07-23 22:04 ` Mat Martineau
24 siblings, 0 replies; 35+ messages in thread
From: MPTCP CI @ 2024-07-22 20:32 UTC (permalink / raw)
To: Matthieu Baerts; +Cc: mptcp
Hi Matthieu,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal: Success! ✅
- KVM Validation: debug: Success! ✅
- KVM Validation: btf (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/10047466924
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/86bf23fada47
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=873047
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect
2024-07-22 19:36 ` [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect Matthieu Baerts (NGI0)
@ 2024-07-23 2:56 ` kernel test robot
2024-07-23 5:52 ` kernel test robot
2024-07-23 10:19 ` Matthieu Baerts
2 siblings, 0 replies; 35+ messages in thread
From: kernel test robot @ 2024-07-23 2:56 UTC (permalink / raw)
To: Matthieu Baerts (NGI0), mptcp
Cc: oe-kbuild-all, Paolo Abeni, Matthieu Baerts (NGI0)
Hi Matthieu,
kernel test robot noticed the following build errors:
[auto build test ERROR on 140ff27ee47286bb0a270f3aa275fc319724da8d]
url: https://github.com/intel-lab-lkp/linux/commits/Matthieu-Baerts-NGI0/mptcp-fully-established-after-ADD_ADDR-echo-on-MPJ/20240723-035843
base: 140ff27ee47286bb0a270f3aa275fc319724da8d
patch link: https://lore.kernel.org/r/20240722-mptcp-pm-avail-v4-23-15bfd73de384%40kernel.org
patch subject: [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20240723/202407231046.JRpmrtkT-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240723/202407231046.JRpmrtkT-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407231046.JRpmrtkT-lkp@intel.com/
All errors (new ones prefixed by >>):
net/mptcp/subflow.c: In function '__mptcp_subflow_connect':
>> net/mptcp/subflow.c:1580:48: error: 'const struct mptcp_addr_info' has no member named 'addr6'; did you mean 'addr'?
1580 | if (ipv6_addr_any(&local->addr.addr6))
| ^~~~~
| addr
vim +1580 net/mptcp/subflow.c
1546
1547 int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_addr_entry *local,
1548 const struct mptcp_addr_info *remote)
1549 {
1550 struct mptcp_sock *msk = mptcp_sk(sk);
1551 struct mptcp_subflow_context *subflow;
1552 int local_id = local->addr.id;
1553 struct sockaddr_storage addr;
1554 int remote_id = remote->id;
1555 int err = -ENOTCONN;
1556 struct socket *sf;
1557 struct sock *ssk;
1558 u32 remote_token;
1559 int addrlen;
1560
1561 if (!mptcp_is_fully_established(sk))
1562 goto err_out;
1563
1564 err = mptcp_subflow_create_socket(sk, local->addr.family, &sf);
1565 if (err)
1566 goto err_out;
1567
1568 ssk = sf->sk;
1569 subflow = mptcp_subflow_ctx(ssk);
1570 do {
1571 get_random_bytes(&subflow->local_nonce, sizeof(u32));
1572 } while (!subflow->local_nonce);
1573
1574 /* if 'IPADDRANY', the ID will be set later, after the routing */
1575 if (local->addr.family == AF_INET) {
1576 if (!local->addr.addr.s_addr)
1577 local_id = -1;
1578 #if IS_ENABLED(CONFIG_IPV6)
1579 } else if (sk->sk_family == AF_INET6) {
> 1580 if (ipv6_addr_any(&local->addr.addr6))
1581 local_id = -1;
1582 #endif
1583 }
1584
1585 if (local_id >= 0)
1586 subflow_set_local_id(subflow, local_id);
1587
1588 subflow->remote_key_valid = 1;
1589 subflow->remote_key = READ_ONCE(msk->remote_key);
1590 subflow->local_key = READ_ONCE(msk->local_key);
1591 subflow->token = msk->token;
1592 mptcp_info2sockaddr(&local->addr, &addr, ssk->sk_family);
1593
1594 addrlen = sizeof(struct sockaddr_in);
1595 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
1596 if (addr.ss_family == AF_INET6)
1597 addrlen = sizeof(struct sockaddr_in6);
1598 #endif
1599 ssk->sk_bound_dev_if = local->ifindex;
1600 err = kernel_bind(sf, (struct sockaddr *)&addr, addrlen);
1601 if (err)
1602 goto failed;
1603
1604 mptcp_crypto_key_sha(subflow->remote_key, &remote_token, NULL);
1605 pr_debug("msk=%p remote_token=%u local_id=%d remote_id=%d", msk,
1606 remote_token, local_id, remote_id);
1607 subflow->remote_token = remote_token;
1608 WRITE_ONCE(subflow->remote_id, remote_id);
1609 subflow->request_join = 1;
1610 subflow->request_bkup = !!(local->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
1611 subflow->subflow_id = msk->subflow_id++;
1612 mptcp_info2sockaddr(remote, &addr, ssk->sk_family);
1613
1614 sock_hold(ssk);
1615 list_add_tail(&subflow->node, &msk->conn_list);
1616 err = kernel_connect(sf, (struct sockaddr *)&addr, addrlen, O_NONBLOCK);
1617 if (err && err != -EINPROGRESS)
1618 goto failed_unlink;
1619
1620 /* discard the subflow socket */
1621 mptcp_sock_graft(ssk, sk->sk_socket);
1622 iput(SOCK_INODE(sf));
1623 WRITE_ONCE(msk->allow_infinite_fallback, false);
1624 mptcp_stop_tout_timer(sk);
1625 return 0;
1626
1627 failed_unlink:
1628 list_del(&subflow->node);
1629 sock_put(mptcp_subflow_tcp_sock(subflow));
1630
1631 failed:
1632 subflow->disposable = 1;
1633 sock_release(sf);
1634
1635 err_out:
1636 /* we account subflows before the creation, and this failures will not
1637 * be caught by sk_state_change()
1638 */
1639 mptcp_pm_close_subflow(msk);
1640 return err;
1641 }
1642
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect
2024-07-22 19:36 ` [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect Matthieu Baerts (NGI0)
2024-07-23 2:56 ` kernel test robot
@ 2024-07-23 5:52 ` kernel test robot
2024-07-23 10:19 ` Matthieu Baerts
2 siblings, 0 replies; 35+ messages in thread
From: kernel test robot @ 2024-07-23 5:52 UTC (permalink / raw)
To: Matthieu Baerts (NGI0), mptcp
Cc: llvm, oe-kbuild-all, Paolo Abeni, Matthieu Baerts (NGI0)
Hi Matthieu,
kernel test robot noticed the following build errors:
[auto build test ERROR on 140ff27ee47286bb0a270f3aa275fc319724da8d]
url: https://github.com/intel-lab-lkp/linux/commits/Matthieu-Baerts-NGI0/mptcp-fully-established-after-ADD_ADDR-echo-on-MPJ/20240723-035843
base: 140ff27ee47286bb0a270f3aa275fc319724da8d
patch link: https://lore.kernel.org/r/20240722-mptcp-pm-avail-v4-23-15bfd73de384%40kernel.org
patch subject: [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect
config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20240723/202407231303.CsUy96BP-lkp@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project ad154281230d83ee551e12d5be48bb956ef47ed3)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240723/202407231303.CsUy96BP-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407231303.CsUy96BP-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from net/mptcp/subflow.c:10:
In file included from include/linux/module.h:19:
In file included from include/linux/elf.h:6:
In file included from arch/s390/include/asm/elf.h:181:
In file included from arch/s390/include/asm/mmu_context.h:11:
In file included from arch/s390/include/asm/pgalloc.h:18:
In file included from include/linux/mm.h:2258:
include/linux/vmstat.h:500:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
500 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
501 | item];
| ~~~~
include/linux/vmstat.h:507:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
507 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
508 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmstat.h:514:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
514 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
include/linux/vmstat.h:519:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
519 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
520 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmstat.h:528:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
528 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
529 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
In file included from net/mptcp/subflow.c:11:
In file included from include/linux/netdevice.h:38:
In file included from include/net/net_namespace.h:43:
In file included from include/linux/skbuff.h:28:
In file included from include/linux/dma-mapping.h:11:
In file included from include/linux/scatterlist.h:9:
In file included from arch/s390/include/asm/io.h:93:
include/asm-generic/io.h:548:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
548 | val = __raw_readb(PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:561:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
561 | val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/big_endian.h:37:59: note: expanded from macro '__le16_to_cpu'
37 | #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
| ^
include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
| ^
In file included from net/mptcp/subflow.c:11:
In file included from include/linux/netdevice.h:38:
In file included from include/net/net_namespace.h:43:
In file included from include/linux/skbuff.h:28:
In file included from include/linux/dma-mapping.h:11:
In file included from include/linux/scatterlist.h:9:
In file included from arch/s390/include/asm/io.h:93:
include/asm-generic/io.h:574:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
574 | val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/big_endian.h:35:59: note: expanded from macro '__le32_to_cpu'
35 | #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
| ^
include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
115 | #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
| ^
In file included from net/mptcp/subflow.c:11:
In file included from include/linux/netdevice.h:38:
In file included from include/net/net_namespace.h:43:
In file included from include/linux/skbuff.h:28:
In file included from include/linux/dma-mapping.h:11:
In file included from include/linux/scatterlist.h:9:
In file included from arch/s390/include/asm/io.h:93:
include/asm-generic/io.h:585:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
585 | __raw_writeb(value, PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:595:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
595 | __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:605:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
605 | __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:693:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
693 | readsb(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:701:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
701 | readsw(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:709:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
709 | readsl(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:718:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
718 | writesb(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:727:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
727 | writesw(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:736:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
736 | writesl(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
>> net/mptcp/subflow.c:1580:34: error: no member named 'addr6' in 'struct mptcp_addr_info'; did you mean 'addr'?
1580 | if (ipv6_addr_any(&local->addr.addr6))
| ^~~~~
| addr
include/net/mptcp.h:55:18: note: 'addr' declared here
55 | struct in_addr addr;
| ^
17 warnings and 1 error generated.
vim +1580 net/mptcp/subflow.c
1546
1547 int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_addr_entry *local,
1548 const struct mptcp_addr_info *remote)
1549 {
1550 struct mptcp_sock *msk = mptcp_sk(sk);
1551 struct mptcp_subflow_context *subflow;
1552 int local_id = local->addr.id;
1553 struct sockaddr_storage addr;
1554 int remote_id = remote->id;
1555 int err = -ENOTCONN;
1556 struct socket *sf;
1557 struct sock *ssk;
1558 u32 remote_token;
1559 int addrlen;
1560
1561 if (!mptcp_is_fully_established(sk))
1562 goto err_out;
1563
1564 err = mptcp_subflow_create_socket(sk, local->addr.family, &sf);
1565 if (err)
1566 goto err_out;
1567
1568 ssk = sf->sk;
1569 subflow = mptcp_subflow_ctx(ssk);
1570 do {
1571 get_random_bytes(&subflow->local_nonce, sizeof(u32));
1572 } while (!subflow->local_nonce);
1573
1574 /* if 'IPADDRANY', the ID will be set later, after the routing */
1575 if (local->addr.family == AF_INET) {
1576 if (!local->addr.addr.s_addr)
1577 local_id = -1;
1578 #if IS_ENABLED(CONFIG_IPV6)
1579 } else if (sk->sk_family == AF_INET6) {
> 1580 if (ipv6_addr_any(&local->addr.addr6))
1581 local_id = -1;
1582 #endif
1583 }
1584
1585 if (local_id >= 0)
1586 subflow_set_local_id(subflow, local_id);
1587
1588 subflow->remote_key_valid = 1;
1589 subflow->remote_key = READ_ONCE(msk->remote_key);
1590 subflow->local_key = READ_ONCE(msk->local_key);
1591 subflow->token = msk->token;
1592 mptcp_info2sockaddr(&local->addr, &addr, ssk->sk_family);
1593
1594 addrlen = sizeof(struct sockaddr_in);
1595 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
1596 if (addr.ss_family == AF_INET6)
1597 addrlen = sizeof(struct sockaddr_in6);
1598 #endif
1599 ssk->sk_bound_dev_if = local->ifindex;
1600 err = kernel_bind(sf, (struct sockaddr *)&addr, addrlen);
1601 if (err)
1602 goto failed;
1603
1604 mptcp_crypto_key_sha(subflow->remote_key, &remote_token, NULL);
1605 pr_debug("msk=%p remote_token=%u local_id=%d remote_id=%d", msk,
1606 remote_token, local_id, remote_id);
1607 subflow->remote_token = remote_token;
1608 WRITE_ONCE(subflow->remote_id, remote_id);
1609 subflow->request_join = 1;
1610 subflow->request_bkup = !!(local->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
1611 subflow->subflow_id = msk->subflow_id++;
1612 mptcp_info2sockaddr(remote, &addr, ssk->sk_family);
1613
1614 sock_hold(ssk);
1615 list_add_tail(&subflow->node, &msk->conn_list);
1616 err = kernel_connect(sf, (struct sockaddr *)&addr, addrlen, O_NONBLOCK);
1617 if (err && err != -EINPROGRESS)
1618 goto failed_unlink;
1619
1620 /* discard the subflow socket */
1621 mptcp_sock_graft(ssk, sk->sk_socket);
1622 iput(SOCK_INODE(sf));
1623 WRITE_ONCE(msk->allow_infinite_fallback, false);
1624 mptcp_stop_tout_timer(sk);
1625 return 0;
1626
1627 failed_unlink:
1628 list_del(&subflow->node);
1629 sock_put(mptcp_subflow_tcp_sock(subflow));
1630
1631 failed:
1632 subflow->disposable = 1;
1633 sock_release(sf);
1634
1635 err_out:
1636 /* we account subflows before the creation, and this failures will not
1637 * be caught by sk_state_change()
1638 */
1639 mptcp_pm_close_subflow(msk);
1640 return err;
1641 }
1642
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect
2024-07-22 19:36 ` [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect Matthieu Baerts (NGI0)
2024-07-23 2:56 ` kernel test robot
2024-07-23 5:52 ` kernel test robot
@ 2024-07-23 10:19 ` Matthieu Baerts
2 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts @ 2024-07-23 10:19 UTC (permalink / raw)
To: mptcp; +Cc: Paolo Abeni
On 22/07/2024 21:36, Matthieu Baerts (NGI0) wrote:
> __mptcp_subflow_connect() is currently called from the path-managers,
> which have all the required information to create subflows. No need to
> call the PM again to re-iterate over the list of entries with RCU lock
> to get more info.
>
> Instead, it is possible to pass a mptcp_pm_addr_entry structure, instead
> of a mptcp_addr_info one. The former contains the ifindex and the flags
> that are required when creating the new subflow.
>
> This is a partial revert of commit ee285257a9c1 ("mptcp: drop flags and
> ifindex arguments").
>
> While at it, the local ID can also be set if it is known and 0, to avoid
> having to set it in the 'rebuild_header' hook, which will cause a new
> iteration of the endpoint entries.
>
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
> Notes:
> - This patch is for net-next
> - v4:
> - Avoid multiple copies of an addr entry in
> fill_local_addresses_vec().
> - Rebased on top of "mptcp: fix endpoints with 'signal' and 'subflow'
> flags", v4.
> ---
> net/mptcp/pm.c | 11 -----------
> net/mptcp/pm_netlink.c | 48 ++++++++++++------------------------------------
> net/mptcp/pm_userspace.c | 19 +------------------
> net/mptcp/protocol.h | 10 +---------
> net/mptcp/subflow.c | 29 ++++++++++++++++++-----------
> 5 files changed, 32 insertions(+), 85 deletions(-)
>
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index ddad51210971..54fabd386b04 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -416,17 +416,6 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
> return mptcp_pm_nl_get_local_id(msk, &skc_local);
> }
>
> -int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
> - u8 *flags, int *ifindex)
> -{
> - *flags = 0;
> - *ifindex = 0;
> -
> - if (mptcp_pm_is_userspace(msk))
> - return mptcp_userspace_pm_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
> - return mptcp_pm_nl_get_flags_and_ifindex_by_id(msk, id, flags, ifindex);
> -}
> -
> int mptcp_pm_get_addr(struct sk_buff *skb, struct genl_info *info)
> {
> if (info->attrs[MPTCP_PM_ATTR_TOKEN])
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 45a1aa0a40bf..a316951f8762 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -625,7 +625,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
>
> spin_unlock_bh(&msk->pm.lock);
> for (i = 0; i < nr; i++)
> - __mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
> + __mptcp_subflow_connect(sk, &local, &addrs[i]);
> spin_lock_bh(&msk->pm.lock);
> }
> mptcp_pm_nl_check_work_pending(msk);
> @@ -646,7 +646,7 @@ static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
> */
> static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
> struct mptcp_addr_info *remote,
> - struct mptcp_addr_info *addrs)
> + struct mptcp_pm_addr_entry *entries)
> {
> struct sock *sk = (struct sock *)msk;
> struct mptcp_pm_addr_entry *entry;
> @@ -670,14 +670,14 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
> continue;
>
> if (msk->pm.subflows < subflows_max) {
> - msk->pm.subflows++;
> - addrs[i] = entry->addr;
> + memcpy(&entries[i], entry, sizeof(entries[i]));
>
> /* Special case for ID0: set the correct ID */
> if (msk->first &&
> mptcp_addresses_equal(&entry->addr, &mpc_addr, entry->addr.port))
> - addrs[i].id = 0;
> + entries[i].addr.id = 0;
>
> + msk->pm.subflows++;
> i++;
> }
> }
> @@ -687,21 +687,19 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
> * 'IPADDRANY' local address
> */
> if (!i) {
> - struct mptcp_addr_info local;
> -
> - memset(&local, 0, sizeof(local));
> - local.family =
> + memset(&entries[i], 0, sizeof(entries[i]));
> + entries[i].addr.family =
> #if IS_ENABLED(CONFIG_MPTCP_IPV6)
> remote->family == AF_INET6 &&
> ipv6_addr_v4mapped(&remote->addr6) ? AF_INET :
> #endif
> remote->family;
>
> - if (!mptcp_pm_addr_families_match(sk, &local, remote))
> + if (!mptcp_pm_addr_families_match(sk, &entries[i].addr, remote))
> return 0;
>
> msk->pm.subflows++;
> - addrs[i++] = local;
> + i++;
> }
>
> return i;
> @@ -709,7 +707,7 @@ static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
>
> static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
> {
> - struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX];
> + struct mptcp_pm_addr_entry entries[MPTCP_PM_ADDR_MAX];
> struct sock *sk = (struct sock *)msk;
> unsigned int add_addr_accept_max;
> struct mptcp_addr_info remote;
> @@ -738,13 +736,13 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
> /* connect to the specified remote address, using whatever
> * local address the routing configuration will pick.
> */
> - nr = fill_local_addresses_vec(msk, &remote, addrs);
> + nr = fill_local_addresses_vec(msk, &remote, entries);
> if (nr == 0)
> return;
>
> spin_unlock_bh(&msk->pm.lock);
> for (i = 0; i < nr; i++)
> - if (__mptcp_subflow_connect(sk, &addrs[i], &remote) == 0)
> + if (__mptcp_subflow_connect(sk, &entries[i], &remote) == 0)
> sf_created = true;
> spin_lock_bh(&msk->pm.lock);
>
> @@ -1395,28 +1393,6 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
> return ret;
> }
>
> -int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
> - u8 *flags, int *ifindex)
> -{
> - struct mptcp_pm_addr_entry *entry;
> - struct sock *sk = (struct sock *)msk;
> - struct net *net = sock_net(sk);
> -
> - /* No entries with ID 0 */
> - if (id == 0)
> - return 0;
> -
> - rcu_read_lock();
> - entry = __lookup_addr_by_id(pm_nl_get_pernet(net), id);
> - if (entry) {
> - *flags = entry->flags;
> - *ifindex = entry->ifindex;
> - }
> - rcu_read_unlock();
> -
> - return 0;
> -}
> -
> static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
> const struct mptcp_addr_info *addr)
> {
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index f0a4590506c6..97b09dffff6d 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -119,23 +119,6 @@ mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
> return NULL;
> }
>
> -int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
> - unsigned int id,
> - u8 *flags, int *ifindex)
> -{
> - struct mptcp_pm_addr_entry *match;
> -
> - spin_lock_bh(&msk->pm.lock);
> - match = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
> - spin_unlock_bh(&msk->pm.lock);
> - if (match) {
> - *flags = match->flags;
> - *ifindex = match->ifindex;
> - }
> -
> - return 0;
> -}
> -
> int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
> struct mptcp_addr_info *skc)
> {
> @@ -394,7 +377,7 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
>
> lock_sock(sk);
>
> - err = __mptcp_subflow_connect(sk, &local.addr, &addr_r);
> + err = __mptcp_subflow_connect(sk, &local, &addr_r);
>
> release_sock(sk);
>
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index f2eb5273d752..259e247b0862 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -722,7 +722,7 @@ bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
> void mptcp_local_address(const struct sock_common *skc, struct mptcp_addr_info *addr);
>
> /* called with sk socket lock held */
> -int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
> +int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_addr_entry *local,
> const struct mptcp_addr_info *remote);
> int mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
> struct socket **new_sock);
> @@ -1015,14 +1015,6 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
> struct mptcp_pm_add_entry *
> mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
> const struct mptcp_addr_info *addr);
> -int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
> - unsigned int id,
> - u8 *flags, int *ifindex);
> -int mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
> - u8 *flags, int *ifindex);
> -int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
> - unsigned int id,
> - u8 *flags, int *ifindex);
> int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
> int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info);
> int mptcp_userspace_pm_set_flags(struct sk_buff *skb, struct genl_info *info);
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index 39e2cbdf3801..0835e71118b9 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -1544,26 +1544,24 @@ void mptcp_info2sockaddr(const struct mptcp_addr_info *info,
> #endif
> }
>
> -int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
> +int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_pm_addr_entry *local,
> const struct mptcp_addr_info *remote)
> {
> struct mptcp_sock *msk = mptcp_sk(sk);
> struct mptcp_subflow_context *subflow;
> + int local_id = local->addr.id;
> struct sockaddr_storage addr;
> int remote_id = remote->id;
> - int local_id = loc->id;
> int err = -ENOTCONN;
> struct socket *sf;
> struct sock *ssk;
> u32 remote_token;
> int addrlen;
> - int ifindex;
> - u8 flags;
>
> if (!mptcp_is_fully_established(sk))
> goto err_out;
>
> - err = mptcp_subflow_create_socket(sk, loc->family, &sf);
> + err = mptcp_subflow_create_socket(sk, local->addr.family, &sf);
> if (err)
> goto err_out;
>
> @@ -1573,23 +1571,32 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
> get_random_bytes(&subflow->local_nonce, sizeof(u32));
> } while (!subflow->local_nonce);
>
> - if (local_id)
> + /* if 'IPADDRANY', the ID will be set later, after the routing */
> + if (local->addr.family == AF_INET) {
> + if (!local->addr.addr.s_addr)
> + local_id = -1;
> +#if IS_ENABLED(CONFIG_IPV6)
As reported by kbot, it should be
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
I will not send a v5 just for that, I think there are already enough
versions and the series became too large :)
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 12/23] mptcp: pm: re-using ID of unused flushed subflows
2024-07-22 19:35 ` [PATCH mptcp-net v4 12/23] mptcp: pm: re-using ID of unused flushed subflows Matthieu Baerts (NGI0)
@ 2024-07-23 22:00 ` Mat Martineau
0 siblings, 0 replies; 35+ messages in thread
From: Mat Martineau @ 2024-07-23 22:00 UTC (permalink / raw)
To: Matthieu Baerts (NGI0); +Cc: mptcp, Paolo Abeni
On Mon, 22 Jul 2024, Matthieu Baerts (NGI0) wrote:
> If no subflows are attached to the 'subflow' endpoints that are being
> flushed, the corresponding addr IDs will not be marked as available
> again.
>
> Mark all ID as being available when flushing all the 'subflow'
> endpoints, and reset local_addr_used counter to cover these cases.
>
> While at it, renamed the helpers linked to the flushing operations to
> make it clear that the intention is to flush all created subflows, and
> remove all announced addresses, not just a "random" selection.
Hi Matthieu -
Considering that this series is getting quite large for -net, a separate
net-next patch looks preferable to me.
- Mat
>
> Fixes: 06faa2271034 ("mptcp: remove multi addresses and subflows in PM")
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
> net/mptcp/pm_netlink.c | 19 +++++++++++++------
> 1 file changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index bdbf27fe89e0..4045e5cc6298 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1586,8 +1586,8 @@ void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
> }
> }
>
> -static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
> - struct list_head *rm_list)
> +static void mptcp_pm_flush_addrs_and_subflows(struct mptcp_sock *msk,
> + struct list_head *rm_list)
> {
> struct mptcp_rm_list alist = { .nr = 0 }, slist = { .nr = 0 };
> struct mptcp_pm_addr_entry *entry;
> @@ -1608,12 +1608,19 @@ static void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
> mptcp_pm_remove_addr(msk, &alist);
> spin_unlock_bh(&msk->pm.lock);
> }
> +
> if (slist.nr)
> mptcp_pm_remove_subflow(msk, &slist);
> +
> + /* Reset counters: maybe some subflows have been removed before */
> + spin_lock_bh(&msk->pm.lock);
> + bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
> + msk->pm.local_addr_used = 0;
> + spin_unlock_bh(&msk->pm.lock);
> }
>
> -static void mptcp_nl_remove_addrs_list(struct net *net,
> - struct list_head *rm_list)
> +static void mptcp_nl_flush_addrs_list(struct net *net,
> + struct list_head *rm_list)
> {
> long s_slot = 0, s_num = 0;
> struct mptcp_sock *msk;
> @@ -1626,7 +1633,7 @@ static void mptcp_nl_remove_addrs_list(struct net *net,
>
> if (!mptcp_pm_is_userspace(msk)) {
> lock_sock(sk);
> - mptcp_pm_remove_addrs_and_subflows(msk, rm_list);
> + mptcp_pm_flush_addrs_and_subflows(msk, rm_list);
> release_sock(sk);
> }
>
> @@ -1667,7 +1674,7 @@ int mptcp_pm_nl_flush_addrs_doit(struct sk_buff *skb, struct genl_info *info)
> pernet->next_id = 1;
> bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
> spin_unlock_bh(&pernet->lock);
> - mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
> + mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list);
> synchronize_rcu();
> __flush_addrs(&free_list);
> return 0;
>
> --
> 2.45.2
>
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 21/23] mptcp: pm: avoid possible UaF whend selecting endp
2024-07-22 19:35 ` [PATCH mptcp-net v4 21/23] mptcp: pm: avoid possible UaF whend selecting endp Matthieu Baerts (NGI0)
@ 2024-07-23 22:01 ` Mat Martineau
2024-07-25 15:43 ` Paolo Abeni
1 sibling, 0 replies; 35+ messages in thread
From: Mat Martineau @ 2024-07-23 22:01 UTC (permalink / raw)
To: Matthieu Baerts (NGI0); +Cc: mptcp, Paolo Abeni
On Mon, 22 Jul 2024, Matthieu Baerts (NGI0) wrote:
> select_local_address() and select_signal_address() both select an
> endpoint entry from the list inside an RCU protected section, but return
> a reference to it, to be read later on. If the entry is dereferenced
> after the RCU unlock, reading info could cause a Use-after-Free.
>
> A simple solution is to copy the required info while inside the RCU
> protected section to avoid any risk of UaF later. The address ID might
> need to be modified later to handle the ID0 case later, so a copy seems
> OK to deal with.
>
> Reported-by: Paolo Abeni <pabeni@redhat.com>
> Closes: https://lore.kernel.org/45cd30d3-7710-491c-ae4d-a1368c00beb1@redhat.com
> Fixes: 01cacb00b35c ("mptcp: add netlink-based PM")
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Hi Matthieu -
Minor subject line typo - "whend"
- Mat
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 22/23] mptcp: pm: reuse ID 0 after delete and re-add
2024-07-22 19:36 ` [PATCH mptcp-net v4 22/23] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0)
@ 2024-07-23 22:02 ` Mat Martineau
0 siblings, 0 replies; 35+ messages in thread
From: Mat Martineau @ 2024-07-23 22:02 UTC (permalink / raw)
To: Matthieu Baerts (NGI0); +Cc: mptcp, Paolo Abeni
On Mon, 22 Jul 2024, Matthieu Baerts (NGI0) wrote:
> When the endpoint used by the initial subflow is removed and re-added
> later, the PM has to force the ID 0, it is a special case imposed by the
> MPTCP specs.
>
> Note that the endpoint should then need to be re-added reusing the same
> ID.
>
> Fixes: 3ad14f54bd74 ("mptcp: more accurate MPC endpoint tracking")
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
> net/mptcp/pm_netlink.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 8f25690a5edc..45a1aa0a40bf 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -586,6 +586,11 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
>
> __clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
> msk->pm.add_addr_signaled++;
> +
> + /* Special case for ID0: set the correct */
"set the correct ID" ?
> + if (local.addr.id == msk->mpc_endpoint_id)
> + local.addr.id = 0;
> +
> mptcp_pm_announce_addr(msk, &local.addr, false);
> mptcp_pm_nl_addr_send_ack(msk);
>
> @@ -614,6 +619,10 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
> if (nr == 0)
> continue;
>
> + /* Special case for ID0: set the correct ID */
> + if (local.addr.id == msk->mpc_endpoint_id)
> + local.addr.id = 0;
> +
> spin_unlock_bh(&msk->pm.lock);
> for (i = 0; i < nr; i++)
> __mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
>
> --
> 2.45.2
>
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
` (23 preceding siblings ...)
2024-07-22 20:32 ` [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags MPTCP CI
@ 2024-07-23 22:04 ` Mat Martineau
24 siblings, 0 replies; 35+ messages in thread
From: Mat Martineau @ 2024-07-23 22:04 UTC (permalink / raw)
To: Matthieu Baerts (NGI0); +Cc: mptcp, Paolo Abeni
On Mon, 22 Jul 2024, Matthieu Baerts (NGI0) wrote:
> When looking at improving the user experience around the MPTCP endpoints
> setup, I noticed that setting an endpoint with both the 'signal' and the
> 'subflow' flags -- as it has been done in the past by users according to
> bug reports we got -- were resulting on only announcing the endpoint,
> but not using it to create subflows: the 'subflow' flag was then
> ignored.
>
> My initial thought was to modify IPRoute2 to warn the user when the two
> flags were set, but it doesn't sound normal to ignore one of them. I
> then looked at modifying the kernel not to allow having the two flags
> set, but when discussing about that with Mat, we thought it was maybe
> not ideal to do that, as there might be use-cases, we might break some
> configs, and it was working before apparently. So instead, I fixed the
> support on the kernel side (patch 5) using Paolo's suggestion. This also
> includes a fix on the options side (patch 1), an explicit deny of some
> options combinations (patch 2), and some refactoring (patches 3 and 4).
>
> While at it, I added a new selftest (patch 7) to validate this case --
> including a modification of the chk_add_nr helper to inverse the sides
> were the counters are checked (patch 6) -- and allowed ADD_ADDR echo
> just after the MP_JOIN 3WHS.
>
> While working on that, I also noticed that re-using IDs were not
> possible in some cases -- see patches 8, 10 and 12 -- and the accounting
> was not correct in some other cases -- see patches 14 to 17.
>
> The selftests modification have the same Fixes tag as the previous
> commit, but they should not get the 'Cc: Stable' one later: if the
> backport can work, that's not, if not, no need to worry, many CIs will
> use the selftests from the last stable version to validate previous
> stable releases.
>
> The last patches don't have any modifications of the selftests attached
> to them, because the current ones were producing the new WARN() that
> have just been added.
>
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
> Changes in v4:
> - Patch 19: check for msk->first != NULL
> - New patches 21-22
> - Imported patch 23: might be easier to review all of them, then this
> single one alone, while it depends on the previous ones.
> - Link to v3: https://lore.kernel.org/r/20240719-mptcp-pm-avail-v3-0-e96b5591ced3@kernel.org
Hi Matthieu -
I had a few typo comments, and one suggestion to split off some
refactoring in to a net-next patch. But the functionality in the series
looks good to me. I think we should discuss how to deal with the size of
the series in the meeting tomorrow!
- Mat
>
> Changes in v3:
> - Small changes in patches 10 and 14, see individual changelog (Geliang)
> - New patches 18-20: small fixes
> - Link to v2: https://lore.kernel.org/r/20240715-mptcp-pm-avail-v2-0-fc5153bd1f6e@kernel.org
>
> Changes in v2:
> - Do not split id_avail_bitmap per target in patch 5 (Paolo)
> - Explicit deny (patch 2), reduce indentation (patch 3), stop earlier
> (patch 4) (Paolo)
> - New fixes and tests (patches 8-17).
> - Link to v1: https://lore.kernel.org/r/20240621-mptcp-pm-avail-v1-0-b692d5eb89b5@kernel.org
>
> ---
> Matthieu Baerts (NGI0) (23):
> mptcp: fully established after ADD_ADDR echo on MPJ
> mptcp: pm: deny endp with signal + subflow + port
> mptcp: pm: reduce indentation blocks
> mptcp: pm: don't try to create sf if alloc failed
> mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set
> selftests: mptcp: join: ability to invert ADD_ADDR check
> selftests: mptcp: join: test both signal & subflow
> mptcp: pm: re-using ID of unused removed ADD_ADDR
> selftests: mptcp: join: check re-using ID of unused ADD_ADDR
> mptcp: pm: re-using ID of unused removed subflows
> selftests: mptcp: join: check re-using ID of closed subflow
> mptcp: pm: re-using ID of unused flushed subflows
> selftests: mptcp: join: test for flush/re-add endpoints
> mptcp: pm: remove mptcp_pm_remove_subflow()
> mptcp: pm: only mark 'subflow' endp as available
> mptcp: pm: only decrement add_addr_accepted for MPJ req
> mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR
> mptcp: pm: only in-kernel cannot have entries with ID 0
> mptcp: pm: fullmesh: select the right ID later
> selftests: mptcp: join: validate fullmesh endp on 1st sf
> mptcp: pm: avoid possible UaF whend selecting endp
> mptcp: pm: reuse ID 0 after delete and re-add
> mptcp: pm: reduce entries iterations on connect
>
> net/mptcp/options.c | 3 +-
> net/mptcp/pm.c | 24 ---
> net/mptcp/pm_netlink.c | 210 +++++++++++++++---------
> net/mptcp/pm_userspace.c | 19 +--
> net/mptcp/protocol.h | 13 +-
> net/mptcp/subflow.c | 29 ++--
> tools/testing/selftests/net/mptcp/mptcp_join.sh | 131 ++++++++++++---
> 7 files changed, 258 insertions(+), 171 deletions(-)
> ---
> base-commit: 140ff27ee47286bb0a270f3aa275fc319724da8d
> change-id: 20240620-mptcp-pm-avail-f5e3957be441
>
> Best regards,
> --
> Matthieu Baerts (NGI0) <matttbe@kernel.org>
>
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 11/23] selftests: mptcp: join: check re-using ID of closed subflow
2024-07-22 19:35 ` [PATCH mptcp-net v4 11/23] selftests: mptcp: join: check re-using ID of closed subflow Matthieu Baerts (NGI0)
@ 2024-07-24 17:14 ` Mat Martineau
2024-07-26 10:38 ` Matthieu Baerts
0 siblings, 1 reply; 35+ messages in thread
From: Mat Martineau @ 2024-07-24 17:14 UTC (permalink / raw)
To: Matthieu Baerts (NGI0); +Cc: mptcp, Paolo Abeni
On Mon, 22 Jul 2024, Matthieu Baerts (NGI0) wrote:
> This test extends "delete and re-add" to validate the previous commit. A
> new 'subflow' endpoint is added, but the subflow request will be
> rejected. The result is that no subflow will be established from this
> address.
>
> Later, the endpoint is removed and re-added after having cleared the
> firewall rule. Before the previous commit, the client would not have
> been able to create this new subflow.
>
> While at it, extra checks have been added to validate the expected
> numbers of MPJ and RM_ADDR.
>
> The 'Fixes' tag here below is the same as the one from the previous
> commit: this patch here is not fixing anything wrong in the selftests,
> but it validates the previous fix for an issue introduced by this commit
> ID.
>
> Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
> tools/testing/selftests/net/mptcp/mptcp_join.sh | 27 ++++++++++++++++++++-----
> 1 file changed, 22 insertions(+), 5 deletions(-)
As we discussed in the meeting today, for patches 1-11:
Reviewed-by: Mat Martineau <martineau@kernel.org>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 21/23] mptcp: pm: avoid possible UaF whend selecting endp
2024-07-22 19:35 ` [PATCH mptcp-net v4 21/23] mptcp: pm: avoid possible UaF whend selecting endp Matthieu Baerts (NGI0)
2024-07-23 22:01 ` Mat Martineau
@ 2024-07-25 15:43 ` Paolo Abeni
1 sibling, 0 replies; 35+ messages in thread
From: Paolo Abeni @ 2024-07-25 15:43 UTC (permalink / raw)
To: Matthieu Baerts (NGI0), mptcp
On 7/22/24 21:35, Matthieu Baerts (NGI0) wrote:
> @@ -159,17 +161,21 @@ select_local_address(const struct pm_nl_pernet *pernet,
> if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
> continue;
>
> - ret = entry;
> + memcpy(new_entry, entry, sizeof(struct mptcp_pm_addr_entry));
Minor nit: why don't:
*new_entry = *entry;
?
> + found = true;
> break;
> }
> rcu_read_unlock();
> - return ret;
> +
> + return found;
> }
>
> -static struct mptcp_pm_addr_entry *
> -select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk)
> +static bool
> +select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
> + struct mptcp_pm_addr_entry *new_entry)
> {
> - struct mptcp_pm_addr_entry *entry, *ret = NULL;
> + struct mptcp_pm_addr_entry *entry;
> + bool found = false;
>
> rcu_read_lock();
> /* do not keep any additional per socket state, just signal
> @@ -184,11 +190,13 @@ select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk)
> if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
> continue;
>
> - ret = entry;
> + memcpy(new_entry, entry, sizeof(struct mptcp_pm_addr_entry));
Same here.
> + found = true;
> break;
> }
> rcu_read_unlock();
> - return ret;
> +
> + return found;
> }
No need to resend just for this, can be addressed incrementally.
Cheers,
Paolo
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH mptcp-net v4 11/23] selftests: mptcp: join: check re-using ID of closed subflow
2024-07-24 17:14 ` Mat Martineau
@ 2024-07-26 10:38 ` Matthieu Baerts
0 siblings, 0 replies; 35+ messages in thread
From: Matthieu Baerts @ 2024-07-26 10:38 UTC (permalink / raw)
To: Mat Martineau; +Cc: mptcp, Paolo Abeni
Hi Mat,
On 24/07/2024 19:14, Mat Martineau wrote:
> On Mon, 22 Jul 2024, Matthieu Baerts (NGI0) wrote:
>
>> This test extends "delete and re-add" to validate the previous commit. A
>> new 'subflow' endpoint is added, but the subflow request will be
>> rejected. The result is that no subflow will be established from this
>> address.
>>
>> Later, the endpoint is removed and re-added after having cleared the
>> firewall rule. Before the previous commit, the client would not have
>> been able to create this new subflow.
>>
>> While at it, extra checks have been added to validate the expected
>> numbers of MPJ and RM_ADDR.
>>
>> The 'Fixes' tag here below is the same as the one from the previous
>> commit: this patch here is not fixing anything wrong in the selftests,
>> but it validates the previous fix for an issue introduced by this commit
>> ID.
>>
>> Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
>> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
>> ---
>> tools/testing/selftests/net/mptcp/mptcp_join.sh | 27 +++++++++++++++++
>> +++-----
>> 1 file changed, 22 insertions(+), 5 deletions(-)
>
> As we discussed in the meeting today, for patches 1-11:
Thank you for the review!
These first 11 patches are now in our tree (fixes for -net):
New patches for t/upstream-net and t/upstream:
- 0810e3bfd645: mptcp: fully established after ADD_ADDR echo on MPJ
- fa82905dad6c: mptcp: pm: deny endp with signal + subflow + port
- 0bcd8eb5baf3: mptcp: pm: reduce indentation blocks
- 4446f3ce0f45: mptcp: pm: don't try to create sf if alloc failed
- 23dcae2e002f: mptcp: pm: do not ignore 'subflow' if 'signal' flag is
also set
- 8396284e59ae: selftests: mptcp: join: ability to invert ADD_ADDR check
- 97c32986ea33: selftests: mptcp: join: test both signal & subflow
- 1624f3f439c1: mptcp: pm: re-using ID of unused removed ADD_ADDR
- e85c614f5dae: selftests: mptcp: join: check re-using ID of unused ADD_ADDR
- 887b2064d1c1: mptcp: pm: re-using ID of unused removed subflows
- 6d8031641325: selftests: mptcp: join: check re-using ID of closed subflow
- Results: 0e547869a341..35d7208999c3 (export-net)
- Results: 9a749f3dd928..a9a9b3b154d1 (export)
Tests are now in progress:
- export-net:
https://github.com/multipath-tcp/mptcp_net-next/commit/a2e8f006417d01deb51431292ae03179641b1e20/checks
- export:
https://github.com/multipath-tcp/mptcp_net-next/commit/70a0d0dafa76f55e2d2e1ba5ae6067f832b1bcb0/checks
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2024-07-26 10:38 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-22 19:35 [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 01/23] mptcp: fully established after ADD_ADDR echo on MPJ Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 02/23] mptcp: pm: deny endp with signal + subflow + port Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 03/23] mptcp: pm: reduce indentation blocks Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 04/23] mptcp: pm: don't try to create sf if alloc failed Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 05/23] mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 06/23] selftests: mptcp: join: ability to invert ADD_ADDR check Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 07/23] selftests: mptcp: join: test both signal & subflow Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 08/23] mptcp: pm: re-using ID of unused removed ADD_ADDR Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 09/23] selftests: mptcp: join: check re-using ID of unused ADD_ADDR Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 10/23] mptcp: pm: re-using ID of unused removed subflows Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 11/23] selftests: mptcp: join: check re-using ID of closed subflow Matthieu Baerts (NGI0)
2024-07-24 17:14 ` Mat Martineau
2024-07-26 10:38 ` Matthieu Baerts
2024-07-22 19:35 ` [PATCH mptcp-net v4 12/23] mptcp: pm: re-using ID of unused flushed subflows Matthieu Baerts (NGI0)
2024-07-23 22:00 ` Mat Martineau
2024-07-22 19:35 ` [PATCH mptcp-net v4 13/23] selftests: mptcp: join: test for flush/re-add endpoints Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 14/23] mptcp: pm: remove mptcp_pm_remove_subflow() Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 15/23] mptcp: pm: only mark 'subflow' endp as available Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 16/23] mptcp: pm: only decrement add_addr_accepted for MPJ req Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 17/23] mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 18/23] mptcp: pm: only in-kernel cannot have entries with ID 0 Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 19/23] mptcp: pm: fullmesh: select the right ID later Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 20/23] selftests: mptcp: join: validate fullmesh endp on 1st sf Matthieu Baerts (NGI0)
2024-07-22 19:35 ` [PATCH mptcp-net v4 21/23] mptcp: pm: avoid possible UaF whend selecting endp Matthieu Baerts (NGI0)
2024-07-23 22:01 ` Mat Martineau
2024-07-25 15:43 ` Paolo Abeni
2024-07-22 19:36 ` [PATCH mptcp-net v4 22/23] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0)
2024-07-23 22:02 ` Mat Martineau
2024-07-22 19:36 ` [PATCH mptcp-net v4 23/23] mptcp: pm: reduce entries iterations on connect Matthieu Baerts (NGI0)
2024-07-23 2:56 ` kernel test robot
2024-07-23 5:52 ` kernel test robot
2024-07-23 10:19 ` Matthieu Baerts
2024-07-22 20:32 ` [PATCH mptcp-net v4 00/23] mptcp: fix endpoints with 'signal' and 'subflow' flags MPTCP CI
2024-07-23 22:04 ` Mat Martineau
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.