force existing service to use MPTCP
by Paolo Abeni
hello,
reviving this old topic.
I've experimented a bit with the LD_PRELOAD thing.
Looks like at least nginx and apache can be forced to use MPTCP instead
of TCP with a crafted unit file created automatically from the distro-
provided one.
e.g. for nginx, adding:
Conflicts=nginx.service
After=nginx.service
into the [unit] section, and:
Environment="LD_PRELOAD=/usr/lib64/use_mptcp.so"
ExecStartPre=sysctl -w net.mptcp.enabled=1
into the [Service] section.
Then I had to fight a bit with selinux. I did not really investigate
the issue, I think/fear selinux misunderstood mptcp sockets as raw
ones, so default policy fails. A bunch of:
ausearch -c 'nginx' --raw | audit2allow -M my-nginx
semodule -i my-nginx.pp
solved the problem.
Bottom line:
- the above looks tecnically viable [at least for some services]. I'm
looking for a more extended service/daemon list to investigate
fourther. I think we could/should really consider package the above in
mptcpd or the like.
- selinux (surprise, surprise!) can be a problem. Worth looking at it
(that is independent from the system we will pick to force MPTCP socket
usage)
Cheers,
Paolo
3 months
[PATCH v3] mptcp: let MPTCP create max size skbs
by Paolo Abeni
Currently the xmit path of the MPTCP protocol creates smaller-
than-max-size skbs, which is suboptimal for the performances.
There are a few things to improve:
- when coalescing to an existing skb, must clear the PUSH flag
- tcp_build_frag() expect the available space as an argument.
When coalescing is enable MPTCP already subtracted the
to-be-coalesced skb len. We must increment said argument
accordingly.
Before:
./use_mptcp.sh netperf -H 127.0.0.1 -t TCP_STREAM
[...]
131072 16384 16384 30.00 24414.86
After:
./use_mptcp.sh netperf -H 127.0.0.1 -t TCP_STREAM
[...]
131072 16384 16384 30.05 28357.69
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
---
use_mptcp.sh forces exiting app to create MPTCP instead of TCP
ones via LD_PRELOAD of crafter socket() implementation.
https://github.com/pabeni/mptcp-tools/tree/master/use_mptcp
---
v2 -> v3:
- drop the tcp bits. They caused stream corruption which
could not be easily set, and dropping them does not affect
the performance in a visible way, since that code path is
hit only on corner cases
v1 -> v2:
- prevent splitting if from_ext is frozen: should never happen
but is cheap
- provide dummy mptcp_skb_split() for non MPTCP build
---
net/mptcp/protocol.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 2a8174a7e630..82525d454c5e 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1256,6 +1256,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
struct mptcp_ext *mpext = NULL;
struct sk_buff *skb, *tail;
bool can_collapse = false;
+ int size_bias = 0;
int avail_size;
size_t ret = 0;
@@ -1277,10 +1278,12 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
mpext = skb_ext_find(skb, SKB_EXT_MPTCP);
can_collapse = (info->size_goal - skb->len > 0) &&
mptcp_skb_can_collapse_to(data_seq, skb, mpext);
- if (!can_collapse)
+ if (!can_collapse) {
TCP_SKB_CB(skb)->eor = 1;
- else
+ } else {
+ size_bias = skb->len;
avail_size = info->size_goal - skb->len;
+ }
}
/* Zero window and all data acked? Probe. */
@@ -1300,8 +1303,8 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
return 0;
ret = info->limit - info->sent;
- tail = tcp_build_frag(ssk, avail_size, info->flags, dfrag->page,
- dfrag->offset + info->sent, &ret);
+ tail = tcp_build_frag(ssk, avail_size + size_bias, info->flags,
+ dfrag->page, dfrag->offset + info->sent, &ret);
if (!tail) {
tcp_remove_empty_skb(sk, tcp_write_queue_tail(ssk));
return -ENOMEM;
@@ -1310,8 +1313,9 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
/* if the tail skb is still the cached one, collapsing really happened.
*/
if (skb == tail) {
- WARN_ON_ONCE(!can_collapse);
+ TCP_SKB_CB(tail)->tcp_flags &= ~TCPHDR_PSH;
mpext->data_len += ret;
+ WARN_ON_ONCE(!can_collapse);
WARN_ON_ONCE(zero_window_probe);
goto out;
}
--
2.26.2
3 months
[MPTCP][PATCH mptcp-next] mptcp: use MPTCPOPT_HMAC_LEN macro
by Geliang Tang
Use the macro MPTCPOPT_HMAC_LEN instead of a constant in struct
mptcp_options_received.
Signed-off-by: Geliang Tang <geliangtang(a)gmail.com>
---
net/mptcp/protocol.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 6933cdc2e605..4e922620ee56 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -122,7 +122,7 @@ struct mptcp_options_received {
u32 token;
u32 nonce;
u64 thmac;
- u8 hmac[20];
+ u8 hmac[MPTCPOPT_HMAC_LEN];
u8 join_id;
u8 use_map:1,
dsn64:1,
--
2.26.2
3 months
[PATCH net-next] mptcp: pm: simplify select_local_address()
by Paolo Abeni
There is no need to unconditionally acquire the join list
lock, we can simply splice the join list into the subflow
list and traverse only the latter.
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
---
net/mptcp/pm_netlink.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 5151cfcd6962..e34a0d57947d 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -135,7 +135,7 @@ select_local_address(const struct pm_nl_pernet *pernet,
struct mptcp_pm_addr_entry *entry, *ret = NULL;
rcu_read_lock();
- spin_lock_bh(&msk->join_list_lock);
+ __mptcp_flush_join_list(msk);
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
continue;
@@ -144,13 +144,11 @@ select_local_address(const struct pm_nl_pernet *pernet,
* pending join
*/
if (entry->addr.family == ((struct sock *)msk)->sk_family &&
- !lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) &&
- !lookup_subflow_by_saddr(&msk->join_list, &entry->addr)) {
+ !lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) {
ret = entry;
break;
}
}
- spin_unlock_bh(&msk->join_list_lock);
rcu_read_unlock();
return ret;
}
--
2.26.2
3 months
[PATCH mptcp-next] mptcp: plug subflow context memory leak
by Paolo Abeni
When a MPTCP listener socket is closed with unaccepted
children pending, the ULP release callback will be invoked,
but nobody will call into __mptcp_close_ssk() on the
corresponding subflow.
As a consequence, at ULP release time, the 'disposable' flag
will be cleared and the subflow context memory will be leaked.
This change addresses the issue always freeing the context if
the subflow is still in the accept queue at ULP release time.
Additionally, this fixes an incorrect code reference in the
related comment.
Note: this fix leverages the changes introduced by the previous
commit.
Fixes: e16163b6e2b7 ("mptcp: refactor shutdown and close")
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
---
Note: I plan to push this upstream together with:
mptcp: link MPC subflow into msk only after accept
since this depends on the above changes, as note in the commit
message.
This closes for me at one of the splat reported in issues/108.
I could not reproduce the others. @Christoph could you please
give it a spin?
---
net/mptcp/subflow.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index fe3bc73aa39d..2e111f039ecc 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1334,9 +1334,10 @@ static void subflow_ulp_release(struct sock *ssk)
sk = ctx->conn;
if (sk) {
/* if the msk has been orphaned, keep the ctx
- * alive, will be freed by mptcp_done()
+ * alive, will be freed by __mptcp_close_ssk(),
+ * when the subflow is still unaccepted
*/
- release = ctx->disposable;
+ release = ctx->disposable || list_empty(&ctx->node);
sock_put(sk);
}
--
2.26.2
3 months
[PATCH mptcp-next] mptcp: link MPC subflow into msk only after accept
by Paolo Abeni
Christoph reported the following splat:
WARNING: CPU: 0 PID: 4615 at net/ipv4/inet_connection_sock.c:1031 inet_csk_listen_stop+0x8e8/0xad0 net/ipv4/inet_connection_sock.c:1031
Modules linked in:
CPU: 0 PID: 4615 Comm: syz-executor.4 Not tainted 5.9.0 #37
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:inet_csk_listen_stop+0x8e8/0xad0 net/ipv4/inet_connection_sock.c:1031
Code: 03 00 00 00 e8 79 b2 3d ff e9 ad f9 ff ff e8 1f 76 ba fe be 02 00 00 00 4c 89 f7 e8 62 b2 3d ff e9 14 f9 ff ff e8 08 76 ba fe <0f> 0b e9 97 f8 ff ff e8 fc 75 ba fe be 03 00 00 00 4c 89 f7 e8 3f
RSP: 0018:ffffc900037f7948 EFLAGS: 00010293
RAX: ffff88810a349c80 RBX: ffff888114ee1b00 RCX: ffffffff827b14cd
RDX: 0000000000000000 RSI: ffffffff827b1c38 RDI: 0000000000000005
RBP: ffff88810a2a8000 R08: ffff88810a349c80 R09: fffff520006fef1f
R10: 0000000000000003 R11: fffff520006fef1e R12: ffff888114ee2d00
R13: dffffc0000000000 R14: 0000000000000001 R15: ffff888114ee1d68
FS: 00007f2ac1945700(0000) GS:ffff88811b400000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffd44798bc0 CR3: 0000000109810002 CR4: 0000000000170ef0
Call Trace:
__tcp_close+0xd86/0x1110 net/ipv4/tcp.c:2433
__mptcp_close_ssk+0x256/0x430 net/mptcp/protocol.c:1761
__mptcp_destroy_sock+0x49b/0x770 net/mptcp/protocol.c:2127
mptcp_close+0x62d/0x910 net/mptcp/protocol.c:2184
inet_release+0xe9/0x1f0 net/ipv4/af_inet.c:434
__sock_release+0xd2/0x280 net/socket.c:596
sock_close+0x15/0x20 net/socket.c:1277
__fput+0x276/0x960 fs/file_table.c:281
task_work_run+0x109/0x1d0 kernel/task_work.c:151
get_signal+0xe8f/0x1d40 kernel/signal.c:2561
arch_do_signal+0x88/0x1b60 arch/x86/kernel/signal.c:811
exit_to_user_mode_loop kernel/entry/common.c:161 [inline]
exit_to_user_mode_prepare+0x9b/0xf0 kernel/entry/common.c:191
syscall_exit_to_user_mode+0x22/0x150 kernel/entry/common.c:266
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x7f2ac1254469
Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d ff 49 2b 00 f7 d8 64 89 01 48
RSP: 002b:00007f2ac1944dc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffbf RBX: 000000000069bf00 RCX: 00007f2ac1254469
RDX: 0000000000000000 RSI: 0000000000008982 RDI: 0000000000000003
RBP: 000000000069bf00 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 000000000069bf0c
R13: 00007ffeb53f178f R14: 00000000004668b0 R15: 0000000000000003
After commit 0397c6d85f9c ("mptcp: keep unaccepted MPC subflow into
join list"), the msk's workqueue and/or PM can touch the MPC
subflow - and acquire its socket lock - even if it's still unaccepted.
If the above event races with the relevant listener socket close, we
can end-up with the above splat.
This change addresses the issue delaying the MPC socket insertion
in conn_list at accept time - that is, partially reverting the
blamed commit.
We must additionally ensure that mptcp_pm_fully_established()
happens after accept() time, or the PM will not be able to
handle properly such event - conn_list could be empty otherwise.
In the receive path, we check the subflow list node to ensure
it is out of the listener queue. Be sure client subflows do
not match transiently such condition moving them into the join
list earlier at creation time.
Since we now have multiple mptcp_pm_fully_established() call sites
from different code-paths, said helper can now race with itself.
Use an additional PM status bit to avoid multiple notifications.
Reported-by: Christoph Paasch <cpaasch(a)apple.com>
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/103
Fixes: 0397c6d85f9c ("mptcp: keep unaccepted MPC subflow into join list"),
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
---
net/mptcp/options.c | 7 ++++++-
net/mptcp/pm.c | 8 +++++++-
net/mptcp/protocol.c | 11 +++++++++++
net/mptcp/protocol.h | 1 +
net/mptcp/subflow.c | 14 ++++++++++----
tools/testing/selftests/net/mptcp/mptcp_connect.sh | 4 ++--
6 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 6088fc80db75..17d5ea163ca2 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -811,7 +811,12 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
mptcp_subflow_fully_established(subflow, mp_opt);
fully_established:
- if (likely(subflow->pm_notified))
+ /* if the subflow is not already linked into the conn_list, we can't
+ * notify the PM: this subflow is still on the listener queue
+ * and the PM possibly acquiring the subflow lock could race with
+ * the listener close
+ */
+ if (likely(subflow->pm_notified) || list_empty(&subflow->node))
return true;
subflow->pm_notified = 1;
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 9256bd5d02ed..da2ed576f289 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -126,8 +126,14 @@ void mptcp_pm_fully_established(struct mptcp_sock *msk)
spin_lock_bh(&pm->lock);
- if (READ_ONCE(pm->work_pending))
+ /* mptcp_pm_fully_established() can be invoked by multiple
+ * racing paths - accept() and check_fully_established()
+ * be sure to serve this event only once.
+ */
+ if (READ_ONCE(pm->work_pending) &&
+ !(msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)))
mptcp_pm_schedule_work(msk, MPTCP_PM_ESTABLISHED);
+ msk->pm.status |= BIT(MPTCP_PM_ALREADY_ESTABLISHED);
spin_unlock_bh(&pm->lock);
}
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 54c1ed735eef..d619eb291479 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3255,6 +3255,17 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
bool slowpath;
slowpath = lock_sock_fast(newsk);
+
+ /* PM/worker can now acquire the first subflow socket
+ * lock without racing with listener queue cleanup,
+ * we can notify it, if needed.
+ */
+ subflow = mptcp_subflow_ctx(msk->first);
+ list_add(&subflow->node, &msk->conn_list);
+ sock_hold(msk->first);
+ if (mptcp_is_fully_established(newsk))
+ mptcp_pm_fully_established(msk);
+
mptcp_copy_inaddrs(newsk, msk->first);
mptcp_rcv_space_init(msk, msk->first);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 9d8f01aac91c..8b268c617910 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -169,6 +169,7 @@ enum mptcp_pm_status {
MPTCP_PM_ADD_ADDR_SEND_ACK,
MPTCP_PM_RM_ADDR_RECEIVED,
MPTCP_PM_ESTABLISHED,
+ MPTCP_PM_ALREADY_ESTABLISHED, /* persistent status, set after ESTABLISHED event */
MPTCP_PM_SUBFLOW_ESTABLISHED,
};
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 96c585f003f8..fe3bc73aa39d 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -582,8 +582,9 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
*/
inet_sk_state_store((void *)new_msk, TCP_ESTABLISHED);
- /* link the newly created socket to the msk */
- mptcp_add_pending_subflow(mptcp_sk(new_msk), ctx);
+ /* record the newly created socket as the first msk
+ * subflow, but don't link it yet into conn_list
+ */
WRITE_ONCE(mptcp_sk(new_msk)->first, child);
/* new mpc subflow takes ownership of the newly
@@ -1116,13 +1117,18 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
subflow->request_bkup = !!(loc->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
mptcp_info2sockaddr(remote, &addr);
+ mptcp_add_pending_subflow(msk, subflow);
err = kernel_connect(sf, (struct sockaddr *)&addr, addrlen, O_NONBLOCK);
if (err && err != -EINPROGRESS)
- goto failed;
+ goto failed_unlink;
- mptcp_add_pending_subflow(msk, subflow);
return err;
+failed_unlink:
+ spin_lock_bh(&msk->join_list_lock);
+ list_del(&subflow->node);
+ spin_unlock_bh(&msk->join_list_lock);
+
failed:
subflow->disposable = 1;
sock_release(sf);
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index 2cfd87d94db8..63e522602b4c 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -604,9 +604,9 @@ run_tests()
make_file "$cin" "client"
make_file "$sin" "server"
-check_mptcp_disabled
+# check_mptcp_disabled
-check_mptcp_ulp_setsockopt
+# check_mptcp_ulp_setsockopt
echo "INFO: validating network environment with pings"
for sender in "$ns1" "$ns2" "$ns3" "$ns4";do
--
2.26.2
3 months
[MPTCP][PATCH mptcp-next 0/5] MP_PRIO support
by Geliang Tang
v1:
- add MP_PRIO PM netlink support
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/51
Geliang Tang (5):
mptcp: add the outgoing MP_PRIO support
mptcp: add the incoming MP_PRIO support
mptcp: deal with MPTCP_PM_ADDR_FLAG_BACKUP in PM netlink
mptcp: add the mibs for MP_PRIO
selftests: mptcp: add the MP_PRIO testcases
net/mptcp/mib.c | 2 +
net/mptcp/mib.h | 2 +
net/mptcp/options.c | 56 +++++++++++++
net/mptcp/pm.c | 19 +++++
net/mptcp/pm_netlink.c | 81 +++++++++++++++++++
net/mptcp/protocol.h | 11 +++
.../testing/selftests/net/mptcp/mptcp_join.sh | 81 ++++++++++++++++++-
7 files changed, 251 insertions(+), 1 deletion(-)
--
2.26.2
3 months
[MPTCP][PATCH mptcp-next] mptcp: enable use_port when invoke addresses_equal
by Geliang Tang
When dealing with the addresses list local_addr_list or anno_list, we
should enables the function addresses_equal's parameter use_port.
Signed-off-by: Geliang Tang <geliangtang(a)gmail.com>
---
The patch should be inserted into the "ADD_ADDR: ports support" patchset
after the 3rd patch "mptcp: add port number announced check".
---
net/mptcp/pm_netlink.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 119d7abdc997..54c6b6359144 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -122,7 +122,7 @@ static bool lookup_subflow_by_saddr(const struct list_head *list,
skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);
local_address(skc, &cur);
- if (addresses_equal(&cur, saddr, false))
+ if (addresses_equal(&cur, saddr, saddr->port))
return true;
}
@@ -195,7 +195,7 @@ lookup_anno_list_by_saddr(struct mptcp_sock *msk,
struct mptcp_pm_add_entry *entry;
list_for_each_entry(entry, &msk->pm.anno_list, list) {
- if (addresses_equal(&entry->addr, addr, false))
+ if (addresses_equal(&entry->addr, addr, true))
return entry;
}
@@ -604,7 +604,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
rcu_read_lock();
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
- if (addresses_equal(&entry->addr, &skc_local, false)) {
+ if (addresses_equal(&entry->addr, &skc_local, entry->addr.port)) {
ret = entry->addr.id;
break;
}
--
2.26.2
3 months
[MPTCP][PATCH mptcp-next] Squash to "[MPTCP][PATCH v7 mptcp-next 3/7] mptcp: add port number announced check"
by Geliang Tang
Drop source_address helper.
Signed-off-by: Geliang Tang <geliangtang(a)gmail.com>
---
net/mptcp/pm_netlink.c | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 4f1b7f44c03b..119d7abdc997 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -88,8 +88,8 @@ static bool address_zero(const struct mptcp_addr_info *addr)
static void local_address(const struct sock_common *skc,
struct mptcp_addr_info *addr)
{
- addr->port = 0;
addr->family = skc->skc_family;
+ addr->port = htons(skc->skc_num);
if (addr->family == AF_INET)
addr->addr.s_addr = skc->skc_rcv_saddr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
@@ -111,19 +111,6 @@ static void remote_address(const struct sock_common *skc,
#endif
}
-static void source_address(struct sock_common *skc,
- struct mptcp_addr_info *addr)
-{
- addr->family = skc->skc_family;
- addr->port = htons(skc->skc_num);
- if (addr->family == AF_INET)
- addr->addr.s_addr = skc->skc_rcv_saddr;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
- else if (addr->family == AF_INET6)
- addr->addr6 = skc->skc_v6_rcv_saddr;
-#endif
-}
-
static bool lookup_subflow_by_saddr(const struct list_head *list,
struct mptcp_addr_info *saddr)
{
@@ -221,7 +208,7 @@ bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk)
struct mptcp_addr_info saddr;
bool ret = false;
- source_address((struct sock_common *)sk, &saddr);
+ local_address((struct sock_common *)sk, &saddr);
spin_lock_bh(&msk->pm.lock);
list_for_each_entry(entry, &msk->pm.anno_list, list) {
--
2.26.2
3 months
[PATCH net-next 0/3] mptcp: reject invalid mp_join requests right away
by Florian Westphal
At the moment MPTCP can detect an invalid join request (invalid token,
max number of subflows reached, and so on) right away but cannot reject
the connection until the 3WHS has completed.
Instead the connection will complete and the subflow is reset afterwards.
To send the reset most information is already available, but we don't have
good spot where the reset could be sent:
1. The ->init_req callback is too early and also doesn't allow to return an
error that could be used to inform the TCP stack that the SYN should be
dropped.
2. The ->route_req callback lacks the skb needed to send a reset.
3. The ->send_synack callback is the best fit from the available hooks,
but its called after the request socket has been inserted into the queue
already. This means we'd have to remove it again right away.
From a technical point of view, the second hook would be best:
1. Its before insertion into listener queue.
2. If it returns NULL TCP will drop the packet for us.
Problem is that we'd have to pass the skb to the function just for MPTCP.
Paolo suggested to merge init_req and route_req callbacks instead:
This makes all info available to MPTCP -- a return value of NULL drops the
packet and MPTCP can send the reset if needed.
Because 'route_req' has a 'const struct sock *', this means either removal
of const qualifier, or a bit of code churn to pass 'const' in security land.
This does the latter; I did not find any spots that need write access to struct
sock.
To recap, the two alternatives are:
1. Solve it entirely in MPTCP: use the ->send_synack callback to
unlink the request socket from the listener & drop it.
2. Avoid 'security' churn by removing the const qualifier.
3 months