[RFC PATCH 0/2] iproute: mptcp support
by Paolo Abeni
This is the first draft for iproute support.
Still lack a man-page (help more than welcome!!!)
Any feedback on [sub]commands name and syntax more than welcome - please
have a look at the usage() section in patch 2
Paolo Abeni (2):
uapi: update linux/mptcp.h
add support for mptcp netlink interface.
include/uapi/linux/mptcp.h | 88 ++++++++
ip/Makefile | 2 +-
ip/ip.c | 3 +-
ip/ip_common.h | 1 +
ip/ipmptcp.c | 446 +++++++++++++++++++++++++++++++++++++
5 files changed, 538 insertions(+), 2 deletions(-)
create mode 100644 include/uapi/linux/mptcp.h
create mode 100644 ip/ipmptcp.c
--
2.21.1
2 years, 1 month
[PATCH] mptcp: fix tcp fallback crash
by Florian Westphal
Christoph Paasch reports following crash:
general protection fault, probably for non-canonical address 0xfe85e717fe88a633: 0000 [#1] PREEMPT SMP
CPU: 0 PID: 2874 Comm: syz-executor072 Not tainted 5.6.0-rc5 #62
RIP: 0010:__pv_queued_spin_lock_slowpath+0x1b3/0x2f0 kernel/locking/qspinlock.c:471
[..]
queued_spin_lock_slowpath arch/x86/include/asm/qspinlock.h:50 [inline]
do_raw_spin_lock include/linux/spinlock.h:181 [inline]
spin_lock_bh include/linux/spinlock.h:343 [inline]
__mptcp_flush_join_list+0x44/0xb0 net/mptcp/protocol.c:278
mptcp_shutdown+0xb3/0x230 net/mptcp/protocol.c:1882
[..]
Problem is that mptcp_shutdown() socket isn't an mptcp socket,
its a plain tcp_sk. Thus, trying to access mptcp_sk specific
members accesses garbage.
Root cause is that accept() returns a fallback (tcp) socket,
not an mptcp one. There is code in getpeername to detect this
and override the sockets stream_ops. But this will only run when
accept() caller provided a sockaddr struct. "accept(fd, NULL, 0)"
will therefore result in mptcp stream ops, with sock->sk being a
tcp_sk. Update the existing fallback handling to detect this as well.
Moreover, mptcp_shutdown did not have fallback handling, and
mptcp_poll did it too late so add that there as well.
Reported-by: Christoph Paasch <cpaasch(a)apple.com>
Signed-off-by: Florian Westphal <fw(a)strlen.de>
---
net/mptcp/protocol.c | 50 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 46 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index a3523bc0739b..72f3176dc924 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -57,10 +57,43 @@ static bool __mptcp_needs_tcp_fallback(const struct mptcp_sock *msk)
return msk->first && !sk_is_mptcp(msk->first);
}
+static struct socket *mptcp_is_tcpsk(struct sock *sk)
+{
+ struct socket *sock = sk->sk_socket;
+
+ if (sock->sk != sk)
+ return NULL;
+
+ if (unlikely(sk->sk_prot == &tcp_prot)) {
+ /* we are being invoked after mptcp_accept() has
+ * accepted a non-mp-capable flow: sk is a tcp_sk,
+ * not an mptcp one.
+ *
+ * Hand the socket over to tcp so all further socket ops
+ * bypass mptcp.
+ */
+ sock->ops = &inet_stream_ops;
+ return sock;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+ } else if (unlikely(sk->sk_prot == &tcpv6_prot)) {
+ sock->ops = &inet6_stream_ops;
+ return sock;
+#endif
+ }
+
+ return NULL;
+}
+
static struct socket *__mptcp_tcp_fallback(struct mptcp_sock *msk)
{
+ struct socket *sock;
+
sock_owned_by_me((const struct sock *)msk);
+ sock = mptcp_is_tcpsk((struct sock *)msk);
+ if (unlikely(sock))
+ return sock;
+
if (likely(!__mptcp_needs_tcp_fallback(msk)))
return NULL;
@@ -84,6 +117,10 @@ static struct socket *__mptcp_socket_create(struct mptcp_sock *msk, int state)
struct socket *ssock;
int err;
+ ssock = __mptcp_tcp_fallback(msk);
+ if (unlikely(ssock))
+ return ssock;
+
ssock = __mptcp_nmpc_socket(msk);
if (ssock)
goto set_state;
@@ -1820,7 +1857,9 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
msk = mptcp_sk(sk);
lock_sock(sk);
- ssock = __mptcp_nmpc_socket(msk);
+ ssock = __mptcp_tcp_fallback(msk);
+ if (!ssock)
+ ssock = __mptcp_nmpc_socket(msk);
if (ssock) {
mask = ssock->ops->poll(file, ssock, wait);
release_sock(sk);
@@ -1830,9 +1869,6 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
release_sock(sk);
sock_poll_wait(file, sock, wait);
lock_sock(sk);
- ssock = __mptcp_tcp_fallback(msk);
- if (unlikely(ssock))
- return ssock->ops->poll(file, ssock, NULL);
if (test_bit(MPTCP_DATA_READY, &msk->flags))
mask = EPOLLIN | EPOLLRDNORM;
@@ -1851,11 +1887,17 @@ static int mptcp_shutdown(struct socket *sock, int how)
{
struct mptcp_sock *msk = mptcp_sk(sock->sk);
struct mptcp_subflow_context *subflow;
+ struct socket *ssock;
int ret = 0;
pr_debug("sk=%p, how=%d", msk, how);
lock_sock(sock->sk);
+ ssock = __mptcp_tcp_fallback(msk);
+ if (ssock) {
+ release_sock(sock->sk);
+ return inet_shutdown(ssock, how);
+ }
if (how == SHUT_WR || how == SHUT_RDWR)
inet_sk_state_store(sock->sk, TCP_FIN_WAIT1);
--
2.24.1
2 years, 1 month
[syzkaller] WARNING in warn_bad_map
by Christoph Paasch
Hello,
another syzkaller bug on top of yesterday's export at commit
150f17fea64a ("selftests:mptcp: fix failure due to whitespace damage")
No reproducers yet...
------------[ cut here ]------------
Bad mapping: ssn=163567 map_seq=163566 map_data_len=1
WARNING: CPU: 1 PID: 22583 at net/mptcp/subflow.c:477 warn_bad_map.isra.0.part.0+0x33/0x40 net/mptcp/subflow.c:477
Kernel panic - not syncing: panic_on_warn set ...
CPU: 1 PID: 22583 Comm: syz-executor.3 Not tainted 5.6.0 #63
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
Call Trace:
<IRQ>
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0xda/0x116 lib/dump_stack.c:118
panic+0x1ae/0x509 kernel/panic.c:221
__warn.cold+0x2a/0x2e kernel/panic.c:582
report_bug+0x1a9/0x1e0 lib/bug.c:195
fixup_bug arch/x86/kernel/traps.c:174 [inline]
fixup_bug arch/x86/kernel/traps.c:169 [inline]
do_error_trap+0x97/0xc0 arch/x86/kernel/traps.c:267
do_invalid_op+0x37/0x50 arch/x86/kernel/traps.c:286
invalid_op+0x1e/0x30 arch/x86/entry/entry_64.S:1027
RIP: 0010:warn_bad_map.isra.0.part.0+0x33/0x40 net/mptcp/subflow.c:477
Code: 41 54 41 89 d4 53 48 89 fb e8 69 8f 2e ff 41 8b 4d 00 44 89 e6 48 c7 c7 88 a1 85 82 8b 13 c6 05 2b fa b6 00 01 e8 4e 31 1d ff <0f> 0b 5b 41 5c 41 5d 5d c3 0f 1f 40 00 55 48 89 e5 41 56 41 55 41
RSP: 0018:ffffc900000bcae0 EFLAGS: 00010282
RAX: 0000000000000000 RBX: ffff88810dab353c RCX: ffffffff8120494e
RDX: 0000000000000100 RSI: ffffffff81205e32 RDI: 0000000000000006
RBP: ffffc900000bcaf8 R08: ffff888119934140 R09: 0000000000000035
R10: ffff8880860f3143 R11: ffff88813bd23143 R12: 0000000000027eef
R13: ffff88810dab3544 R14: ffff88810dab3500 R15: ffff8880279d5400
warn_bad_map net/mptcp/subflow.c:509 [inline]
validate_mapping net/mptcp/subflow.c:509 [inline]
get_mapping_status net/mptcp/subflow.c:622 [inline]
subflow_check_data_avail net/mptcp/subflow.c:660 [inline]
mptcp_subflow_data_available+0x83f/0x960 net/mptcp/subflow.c:756
subflow_state_change+0xd7/0x120 net/mptcp/subflow.c:991
tcp_fin+0x107/0x240 net/ipv4/tcp_input.c:4213
tcp_data_queue+0xc0c/0x15b0 net/ipv4/tcp_input.c:4813
tcp_rcv_established+0x302/0xae0 net/ipv4/tcp_input.c:5727
tcp_v4_do_rcv+0x231/0x350 net/ipv4/tcp_ipv4.c:1621
tcp_v4_rcv+0x10da/0x1220 net/ipv4/tcp_ipv4.c:2003
ip_protocol_deliver_rcu+0x20/0x130 net/ipv4/ip_input.c:204
ip_local_deliver_finish net/ipv4/ip_input.c:231 [inline]
NF_HOOK include/linux/netfilter.h:421 [inline]
ip_local_deliver+0xe0/0x100 net/ipv4/ip_input.c:252
dst_input include/net/dst.h:441 [inline]
ip_rcv_finish net/ipv4/ip_input.c:428 [inline]
ip_rcv_finish net/ipv4/ip_input.c:414 [inline]
NF_HOOK include/linux/netfilter.h:421 [inline]
ip_rcv+0x70/0xa0 net/ipv4/ip_input.c:538
__netif_receive_skb_one_core+0x68/0xa0 net/core/dev.c:5187
__netif_receive_skb+0x2a/0xa0 net/core/dev.c:5301
process_backlog+0x104/0x250 net/core/dev.c:6133
napi_poll net/core/dev.c:6571 [inline]
net_rx_action+0x14a/0x520 net/core/dev.c:6639
__do_softirq+0x115/0x33f kernel/softirq.c:292
invoke_softirq kernel/softirq.c:373 [inline]
irq_exit+0xbb/0xe0 kernel/softirq.c:413
exiting_irq arch/x86/include/asm/apic.h:546 [inline]
smp_apic_timer_interrupt+0x96/0x190 arch/x86/kernel/apic/apic.c:1146
apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:829
</IRQ>
RIP: 0010:check_stack_object+0xbf/0xf0 mm/usercopy.c:58
Code: 48 8b 1b 49 39 de 77 0a e8 9e f2 e7 ff 49 39 df 77 db 41 bc ff ff ff ff eb 03 45 31 e4 e8 89 f2 e7 ff 44 89 e0 48 83 c4 08 5b <41> 5c 41 5d 41 5e 41 5f 5d c3 e8 72 f2 e7 ff 48 8b 45 d0 41 bc 01
RSP: 0018:ffffc90001fd7908 EFLAGS: 00000296 ORIG_RAX: ffffffffffffff13
RAX: 0000000000000000 RBX: 0000000000001000 RCX: ffffc90006297000
RDX: 00000000000191ad RSI: ffffffff81418617 RDI: ffff8880923c0000
RBP: ffffc90001fd7928 R08: ffff888119934140 R09: ffff8880923c0000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: ffff8880923c0000 R14: ffffc90001fd4000 R15: 0000000007200000
__check_object_size mm/usercopy.c:269 [inline]
__check_object_size+0xa0/0x2c7 mm/usercopy.c:256
check_object_size include/linux/thread_info.h:119 [inline]
check_copy_size include/linux/thread_info.h:152 [inline]
copy_to_user include/linux/uaccess.h:151 [inline]
pagemap_read+0x18d/0x3c0 fs/proc/task_mmu.c:1601
do_loop_readv_writev fs/read_write.c:714 [inline]
do_loop_readv_writev fs/read_write.c:701 [inline]
do_iter_read+0x26b/0x2e0 fs/read_write.c:935
vfs_readv+0x8b/0xd0 fs/read_write.c:1053
kernel_readv fs/splice.c:365 [inline]
default_file_splice_read+0x20e/0x440 fs/splice.c:422
do_splice_to+0xbf/0xf0 fs/splice.c:892
splice_direct_to_actor+0x113/0x390 fs/splice.c:971
do_splice_direct+0xe8/0x150 fs/splice.c:1080
do_sendfile+0x2c4/0x610 fs/read_write.c:1520
__do_sys_sendfile64 fs/read_write.c:1581 [inline]
__se_sys_sendfile64 fs/read_write.c:1567 [inline]
__x64_sys_sendfile64+0xeb/0x100 fs/read_write.c:1567
do_syscall_64+0x91/0x2f0 arch/x86/entry/common.c:294
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x7f56623f5469
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:00007f5662ac4dd8 EFLAGS: 00000246 ORIG_RAX: 0000000000000028
RAX: ffffffffffffffda RBX: 000000000066bfa0 RCX: 00007f56623f5469
RDX: 0000000000000000 RSI: 0000000000000008 RDI: 0000000000000007
RBP: 00000000ffffffff R08: 0000000000000000 R09: 0000000000000000
R10: 0000000080000002 R11: 0000000000000246 R12: 00000000000008d4
R13: 000000000041c788 R14: 00007f5662ac55c0 R15: 0000000000000003
Dumping ftrace buffer:
(ftrace buffer empty)
Kernel Offset: disabled
Rebooting in 1 seconds..
Christoph
2 years, 1 month
[syzkaller] general protection fault in __mptcp_flush_join_list
by Christoph Paasch
Hello,
another one - on top of 402d1b0dc2e1 (yes, it's a week old - I wanted to
let syzkaller deep-dive a bit).
general protection fault, probably for non-canonical address 0xfe85e717fe88a633: 0000 [#1] PREEMPT SMP
CPU: 0 PID: 2874 Comm: syz-executor072 Not tainted 5.6.0-rc5 #62
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
RIP: 0010:__write_once_size include/linux/compiler.h:226 [inline]
RIP: 0010:__pv_queued_spin_lock_slowpath+0x1b3/0x2f0 kernel/locking/qspinlock.c:471
Code: c5 c1 ea 12 41 bf 01 00 00 00 8d 42 ff 41 83 e5 03 4c 8d 73 14 49 c1 e5 05 48 98 49 81 c5 00 bf 02 00 4c 03 2c c5 a0 11 86 82 <49> 89 5d 00 b8 00 80 00 00 eb 14 84 c0 75 09 41 0f b6 55 14 84 d2
RSP: 0018:ffffc9000017bdf8 EFLAGS: 00010286
RAX: 000000000000130d RBX: ffff88807dc2bf00 RCX: 0000000000000001
RDX: 000000000000130e RSI: 0000000000000000 RDI: 0000000000000005
RBP: ffffc9000017be30 R08: ffff88807b6a11c0 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffff88807b783844
R13: fe85e717fe88a633 R14: ffff88807dc2bf14 R15: 0000000000000001
FS: 00007f8886bbe700(0000) GS:ffff88807dc00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000558feddd6040 CR3: 000000007d668002 CR4: 0000000000160ef0
Call Trace:
pv_queued_spin_lock_slowpath arch/x86/include/asm/paravirt.h:645 [inline]
queued_spin_lock_slowpath arch/x86/include/asm/qspinlock.h:50 [inline]
queued_spin_lock include/asm-generic/qspinlock.h:81 [inline]
do_raw_spin_lock include/linux/spinlock.h:181 [inline]
__raw_spin_lock_bh include/linux/spinlock_api_smp.h:136 [inline]
_raw_spin_lock_bh+0x36/0x40 kernel/locking/spinlock.c:175
spin_lock_bh include/linux/spinlock.h:343 [inline]
__mptcp_flush_join_list+0x44/0xb0 net/mptcp/protocol.c:278
mptcp_shutdown+0xb3/0x230 net/mptcp/protocol.c:1882
__sys_shutdown+0x58/0xc0 net/socket.c:2206
__do_sys_shutdown net/socket.c:2214 [inline]
__se_sys_shutdown net/socket.c:2212 [inline]
__x64_sys_shutdown+0x1a/0x20 net/socket.c:2212
do_syscall_64+0x91/0x2f0 arch/x86/entry/common.c:294
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x7f88864cb469
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:00007ffe7ee181e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000030
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f88864cb469
RDX: 00007f88864cb469 RSI: 0000000000000000 RDI: 0000000000000005
RBP: 0000000000400720 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 000000000040063f
R13: 00007ffe7ee182d0 R14: 0000000000000000 R15: 0000000000000000
Modules linked in:
Dumping ftrace buffer:
(ftrace buffer empty)
---[ end trace 36f808cc99a201d3 ]---
RIP: 0010:__write_once_size include/linux/compiler.h:226 [inline]
RIP: 0010:__pv_queued_spin_lock_slowpath+0x1b3/0x2f0 kernel/locking/qspinlock.c:471
Code: c5 c1 ea 12 41 bf 01 00 00 00 8d 42 ff 41 83 e5 03 4c 8d 73 14 49 c1 e5 05 48 98 49 81 c5 00 bf 02 00 4c 03 2c c5 a0 11 86 82 <49> 89 5d 00 b8 00 80 00 00 eb 14 84 c0 75 09 41 0f b6 55 14 84 d2
RSP: 0018:ffffc9000017bdf8 EFLAGS: 00010286
RAX: 000000000000130d RBX: ffff88807dc2bf00 RCX: 0000000000000001
RDX: 000000000000130e RSI: 0000000000000000 RDI: 0000000000000005
RBP: ffffc9000017be30 R08: ffff88807b6a11c0 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffff88807b783844
R13: fe85e717fe88a633 R14: ffff88807dc2bf14 R15: 0000000000000001
FS: 00007f8886bbe700(0000) GS:ffff88807dc00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000558feddd6040 CR3: 000000007d668002 CR4: 0000000000160ef0
Syzkaller reproducer:
# {Threaded:false Collide:false Repeat:false RepeatTimes:0 Procs:1 Sandbox: Fault:false FaultCall:-1 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false UseTmpDir:false HandleSegv:false Repro:false Trace:false}
r0 = socket$inet_mptcp(0x2, 0x1, 0x106)
r1 = socket$inet_mptcp(0x2, 0x1, 0x106)
bind$inet(r1, &(0x7f00000013c0)={0x2, 0x4e20, @multicast2}, 0x10)
connect$inet(r1, &(0x7f0000000040)={0x2, 0x0, @loopback}, 0x10)
listen(r1, 0x0)
connect$inet(r0, &(0x7f0000000040)={0x2, 0x4e20, @loopback}, 0x10)
r2 = accept(r1, 0x0, 0x0)
shutdown(r2, 0x0)
C-repro:
// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff};
int main(void)
{
syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0ul);
intptr_t res = 0;
res = syscall(__NR_socket, 2ul, 1ul, 0x106);
if (res != -1)
r[0] = res;
res = syscall(__NR_socket, 2ul, 1ul, 0x106);
if (res != -1)
r[1] = res;
*(uint16_t*)0x200013c0 = 2;
*(uint16_t*)0x200013c2 = htobe16(0x4e20);
*(uint32_t*)0x200013c4 = htobe32(0xe0000002);
syscall(__NR_bind, r[1], 0x200013c0ul, 0x10ul);
*(uint16_t*)0x20000040 = 2;
*(uint16_t*)0x20000042 = htobe16(0);
*(uint32_t*)0x20000044 = htobe32(0x7f000001);
syscall(__NR_connect, r[1], 0x20000040ul, 0x10ul);
syscall(__NR_listen, r[1], 0);
*(uint16_t*)0x20000040 = 2;
*(uint16_t*)0x20000042 = htobe16(0x4e20);
*(uint32_t*)0x20000044 = htobe32(0x7f000001);
syscall(__NR_connect, r[0], 0x20000040ul, 0x10ul);
res = syscall(__NR_accept, r[1], 0ul, 0ul);
if (res != -1)
r[2] = res;
syscall(__NR_shutdown, r[2], 0ul);
return 0;
}
Cheers,
Christoph
2 years, 1 month
[PATCH net-next 0/1] selftests:mptcp: fix failure due to whitespace damage
by Matthieu Baerts
David: it seems that some trailing whitespaces were removed by one of
your scripts when applying eedbc685321b (selftests: add PM netlink
functional tests).
This causes a self test failure because the expected result in the
script has been modified.
We do think that it is best not having trailing whitespaces in the code
and that's why we are proposing here a new version without them. The
documentation also ask us not to leave unexepected trailing whitespace
at the end of lines.
But we simply want to ask you this question: Is it normal that these
trailing whitespaces are automatically removed? We understand if it is
and it would make sense somehow but just in case it is not normal, we
prefer to raise the question and avoid other people hitting the same
issue we had :)
Matthieu Baerts (1):
selftests:mptcp: fix failure due to whitespace damage
tools/testing/selftests/net/mptcp/pm_netlink.sh | 12 ++++++------
tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
--
2.25.1
2 years, 1 month
[RFC PATCH] selftests:mptcp:pm: rm trailing whitespace
by Matthieu Baerts
'pm_nl_ctl' was adding a trailing whitespace after having printed the
IP. But at the end, the IP element is currently always the last one.
The bash script launching 'pm_nl_ctl' had trailing whitespaces in the
expected result on purpose. But these whitespaces have been removed when
the patch has been applied upstream. To avoid trailing whitespaces in
the bash code, 'pm_nl_ctl' and expected results have now been adapted.
The MPTCP PM selftest can now pass again.
Fixes: eedbc685321b (selftests: add PM netlink functional tests)
Signed-off-by: Matthieu Baerts <matthieu.baerts(a)tessares.net>
---
tools/testing/selftests/net/mptcp/pm_netlink.sh | 12 ++++++------
tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/pm_netlink.sh b/tools/testing/selftests/net/mptcp/pm_netlink.sh
index 8c7bd722476e..9172746b6cf0 100755
--- a/tools/testing/selftests/net/mptcp/pm_netlink.sh
+++ b/tools/testing/selftests/net/mptcp/pm_netlink.sh
@@ -75,29 +75,29 @@ subflows 0" "defaults limits"
ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.1
ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.2 flags subflow dev lo
ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.3 flags signal,backup
-check "ip netns exec $ns1 ./pm_nl_ctl get 1" "id 1 flags 10.0.1.1 " "simple add/get addr"
+check "ip netns exec $ns1 ./pm_nl_ctl get 1" "id 1 flags 10.0.1.1" "simple add/get addr"
check "ip netns exec $ns1 ./pm_nl_ctl dump" \
"id 1 flags 10.0.1.1
id 2 flags subflow dev lo 10.0.1.2
-id 3 flags signal,backup 10.0.1.3 " "dump addrs"
+id 3 flags signal,backup 10.0.1.3" "dump addrs"
ip netns exec $ns1 ./pm_nl_ctl del 2
check "ip netns exec $ns1 ./pm_nl_ctl get 2" "" "simple del addr"
check "ip netns exec $ns1 ./pm_nl_ctl dump" \
"id 1 flags 10.0.1.1
-id 3 flags signal,backup 10.0.1.3 " "dump addrs after del"
+id 3 flags signal,backup 10.0.1.3" "dump addrs after del"
ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.3
check "ip netns exec $ns1 ./pm_nl_ctl get 4" "" "duplicate addr"
ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.4 id 10 flags signal
-check "ip netns exec $ns1 ./pm_nl_ctl get 4" "id 4 flags signal 10.0.1.4 " "id addr increment"
+check "ip netns exec $ns1 ./pm_nl_ctl get 4" "id 4 flags signal 10.0.1.4" "id addr increment"
for i in `seq 5 9`; do
ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.$i flags signal >/dev/null 2>&1
done
-check "ip netns exec $ns1 ./pm_nl_ctl get 9" "id 9 flags signal 10.0.1.9 " "hard addr limit"
+check "ip netns exec $ns1 ./pm_nl_ctl get 9" "id 9 flags signal 10.0.1.9" "hard addr limit"
check "ip netns exec $ns1 ./pm_nl_ctl get 10" "" "above hard addr limit"
for i in `seq 9 256`; do
@@ -110,7 +110,7 @@ id 4 flags signal 10.0.1.4
id 5 flags signal 10.0.1.5
id 6 flags signal 10.0.1.6
id 7 flags signal 10.0.1.7
-id 8 flags signal 10.0.1.8 " "id limit"
+id 8 flags signal 10.0.1.8" "id limit"
ip netns exec $ns1 ./pm_nl_ctl flush
check "ip netns exec $ns1 ./pm_nl_ctl dump" "" "flush addrs"
diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
index de9209305026..b24a2f17d415 100644
--- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
+++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
@@ -335,14 +335,14 @@ static void print_addr(struct rtattr *attrs, int len)
error(1, errno, "wrong IP (v4) for family %d",
family);
inet_ntop(AF_INET, RTA_DATA(attrs), str, sizeof(str));
- printf("%s ", str);
+ printf("%s", str);
}
if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ADDR6) {
if (family != AF_INET6)
error(1, errno, "wrong IP (v6) for family %d",
family);
inet_ntop(AF_INET6, RTA_DATA(attrs), str, sizeof(str));
- printf("%s ", str);
+ printf("%s", str);
}
if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ID) {
memcpy(&id, RTA_DATA(attrs), 1);
--
2.25.1
2 years, 1 month
Address change
by Peter Krystad
Just FYI my employment at Intel ends at the end of this month. I'll be
using this e-mail, pkrystad11(a)gmail.com, going forward. - Peter.
2 years, 1 month
[PATCH RFC iproute2-next] ss: allow dumping MPTCP subflow information
by Davide Caratti
[root@f31 packetdrill]# ss -tni
ESTAB 0 0 192.168.82.247:8080 192.0.2.1:35273
cubic wscale:7,8 [...] tcp-ulp-mptcp flags: Mec token:0000(id:0)/5f856c60(id:0) seq:b810457db34209a5 sfseq:1 ssnoff:0 maplen:190
Signed-off-by: Davide Caratti <dcaratti(a)redhat.com>
---
include/uapi/linux/inet_diag.h | 1 +
include/uapi/linux/mptcp.h | 89 ++++++++++++++++++++++++++++++++++
misc/ss.c | 62 +++++++++++++++++++++++
3 files changed, 152 insertions(+)
create mode 100644 include/uapi/linux/mptcp.h
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
index e045d170334b..0c1c781c0a60 100644
--- a/include/uapi/linux/inet_diag.h
+++ b/include/uapi/linux/inet_diag.h
@@ -166,6 +166,7 @@ enum {
INET_ULP_INFO_UNSPEC,
INET_ULP_INFO_NAME,
INET_ULP_INFO_TLS,
+ INET_ULP_INFO_MPTCP,
__INET_ULP_INFO_MAX,
};
#define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1)
diff --git a/include/uapi/linux/mptcp.h b/include/uapi/linux/mptcp.h
new file mode 100644
index 000000000000..5f2c77082d9e
--- /dev/null
+++ b/include/uapi/linux/mptcp.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+#ifndef _UAPI_MPTCP_H
+#define _UAPI_MPTCP_H
+
+#include <linux/const.h>
+#include <linux/types.h>
+
+#define MPTCP_SUBFLOW_FLAG_MCAP_REM _BITUL(0)
+#define MPTCP_SUBFLOW_FLAG_MCAP_LOC _BITUL(1)
+#define MPTCP_SUBFLOW_FLAG_JOIN_REM _BITUL(2)
+#define MPTCP_SUBFLOW_FLAG_JOIN_LOC _BITUL(3)
+#define MPTCP_SUBFLOW_FLAG_BKUP_REM _BITUL(4)
+#define MPTCP_SUBFLOW_FLAG_BKUP_LOC _BITUL(5)
+#define MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED _BITUL(6)
+#define MPTCP_SUBFLOW_FLAG_CONNECTED _BITUL(7)
+#define MPTCP_SUBFLOW_FLAG_MAPVALID _BITUL(8)
+
+enum {
+ MPTCP_SUBFLOW_ATTR_UNSPEC,
+ MPTCP_SUBFLOW_ATTR_TOKEN_REM,
+ MPTCP_SUBFLOW_ATTR_TOKEN_LOC,
+ MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ,
+ MPTCP_SUBFLOW_ATTR_MAP_SEQ,
+ MPTCP_SUBFLOW_ATTR_MAP_SFSEQ,
+ MPTCP_SUBFLOW_ATTR_SSN_OFFSET,
+ MPTCP_SUBFLOW_ATTR_MAP_DATALEN,
+ MPTCP_SUBFLOW_ATTR_FLAGS,
+ MPTCP_SUBFLOW_ATTR_ID_REM,
+ MPTCP_SUBFLOW_ATTR_ID_LOC,
+ MPTCP_SUBFLOW_ATTR_PAD,
+ __MPTCP_SUBFLOW_ATTR_MAX
+};
+
+#define MPTCP_SUBFLOW_ATTR_MAX (__MPTCP_SUBFLOW_ATTR_MAX - 1)
+
+/* netlink interface */
+#define MPTCP_PM_NAME "mptcp_pm"
+#define MPTCP_PM_CMD_GRP_NAME "mptcp_pm_cmds"
+#define MPTCP_PM_VER 0x1
+
+/*
+ * ATTR types defined for MPTCP
+ */
+enum {
+ MPTCP_PM_ATTR_UNSPEC,
+
+ MPTCP_PM_ATTR_ADDR, /* nested address */
+ MPTCP_PM_ATTR_RCV_ADD_ADDRS, /* u32 */
+ MPTCP_PM_ATTR_SUBFLOWS, /* u32 */
+
+ __MPTCP_PM_ATTR_MAX
+};
+
+#define MPTCP_PM_ATTR_MAX (__MPTCP_PM_ATTR_MAX - 1)
+
+enum {
+ MPTCP_PM_ADDR_ATTR_UNSPEC,
+
+ MPTCP_PM_ADDR_ATTR_FAMILY, /* u16 */
+ MPTCP_PM_ADDR_ATTR_ID, /* u8 */
+ MPTCP_PM_ADDR_ATTR_ADDR4, /* struct in_addr */
+ MPTCP_PM_ADDR_ATTR_ADDR6, /* struct in6_addr */
+ MPTCP_PM_ADDR_ATTR_PORT, /* u16 */
+ MPTCP_PM_ADDR_ATTR_FLAGS, /* u32 */
+ MPTCP_PM_ADDR_ATTR_IF_IDX, /* s32 */
+
+ __MPTCP_PM_ADDR_ATTR_MAX
+};
+
+#define MPTCP_PM_ADDR_ATTR_MAX (__MPTCP_PM_ADDR_ATTR_MAX - 1)
+
+#define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0)
+#define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1)
+#define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2)
+
+enum {
+ MPTCP_PM_CMD_UNSPEC,
+
+ MPTCP_PM_CMD_ADD_ADDR,
+ MPTCP_PM_CMD_DEL_ADDR,
+ MPTCP_PM_CMD_GET_ADDR,
+ MPTCP_PM_CMD_FLUSH_ADDRS,
+ MPTCP_PM_CMD_SET_LIMITS,
+ MPTCP_PM_CMD_GET_LIMITS,
+
+ __MPTCP_PM_CMD_AFTER_LAST
+};
+
+#endif /* _UAPI_MPTCP_H */
diff --git a/misc/ss.c b/misc/ss.c
index 3ef151fbf1f1..3fac4be88442 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -53,6 +53,7 @@
#include <linux/tipc_netlink.h>
#include <linux/tipc_sockets_diag.h>
#include <linux/tls.h>
+#include <linux/mptcp.h>
/* AF_VSOCK/PF_VSOCK is only provided since glibc 2.18 */
#ifndef PF_VSOCK
@@ -2836,6 +2837,59 @@ static void tcp_tls_conf(const char *name, struct rtattr *attr)
}
}
+static void mptcp_subflow_info(struct rtattr *tb[])
+{
+ u_int32_t flags = 0;
+
+ if (tb[MPTCP_SUBFLOW_ATTR_FLAGS]) {
+ char caps[32 + 1] = { 0 }, *cap = &caps[0];
+
+ flags = rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_FLAGS]);
+
+ if (flags & MPTCP_SUBFLOW_FLAG_MCAP_REM)
+ *cap++ = 'M';
+ if (flags & MPTCP_SUBFLOW_FLAG_MCAP_LOC)
+ *cap++ = 'm';
+ if (flags & MPTCP_SUBFLOW_FLAG_JOIN_REM)
+ *cap++ = 'J';
+ if (flags & MPTCP_SUBFLOW_FLAG_JOIN_LOC)
+ *cap++ = 'j';
+ if (flags & MPTCP_SUBFLOW_FLAG_BKUP_REM)
+ *cap++ = 'B';
+ if (flags & MPTCP_SUBFLOW_FLAG_BKUP_LOC)
+ *cap++ = 'b';
+ if (flags & MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED)
+ *cap++ = 'e';
+ if (flags & MPTCP_SUBFLOW_FLAG_CONNECTED)
+ *cap++ = 'c';
+ if (flags & MPTCP_SUBFLOW_FLAG_MAPVALID)
+ *cap++ = 'v';
+ if (flags)
+ out(" flags:%s", caps);
+ }
+ if (tb[MPTCP_SUBFLOW_ATTR_TOKEN_REM] &&
+ tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC] &&
+ tb[MPTCP_SUBFLOW_ATTR_ID_REM] &&
+ tb[MPTCP_SUBFLOW_ATTR_ID_LOC])
+ out(" token:%04x(id:%d)/%04x(id:%d)",
+ rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_REM]),
+ rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_REM]),
+ rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC]),
+ rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_LOC]));
+ if (tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ])
+ out(" seq:%llx",
+ rta_getattr_u64(tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ]));
+ if (tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ])
+ out(" sfseq:%x",
+ rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ]));
+ if (tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET])
+ out(" ssnoff:%x",
+ rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET]));
+ if (tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN])
+ out(" maplen:%x",
+ rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN]));
+}
+
#define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt))
static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
@@ -3012,6 +3066,14 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
tcp_tls_conf("rxconf", tlsinfo[TLS_INFO_RXCONF]);
tcp_tls_conf("txconf", tlsinfo[TLS_INFO_TXCONF]);
}
+ if (ulpinfo[INET_ULP_INFO_MPTCP]) {
+ struct rtattr *sfinfo[MPTCP_SUBFLOW_ATTR_MAX + 1] =
+ { 0 };
+
+ parse_rtattr_nested(sfinfo, MPTCP_SUBFLOW_ATTR_MAX,
+ ulpinfo[INET_ULP_INFO_MPTCP]);
+ mptcp_subflow_info(sfinfo);
+ }
}
}
--
2.25.1
2 years, 1 month
Part 3 review status
by Mat Martineau
Hello -
Part 3 version 3 of the upstream MPTCP implementation is currently under
review on the netdev list, after addressing davem's comment on v2.
It's currently delegated to David Ahern for additional review, presumably
to have a look at the netlink interface.
--
Mat Martineau
Intel
2 years, 1 month
[PATCH] squashto: mptcp: allow dumping subflow context to userspace
by Mat Martineau
Use bit macros appropriate for userspace.
Suggested-by: Davide Caratti <dcaratti(a)redhat.com>
Signed-off-by: Mat Martineau <mathew.j.martineau(a)linux.intel.com>
---
include/uapi/linux/mptcp.h | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/include/uapi/linux/mptcp.h b/include/uapi/linux/mptcp.h
index c564140d20f0..8acc78b7ca7c 100644
--- a/include/uapi/linux/mptcp.h
+++ b/include/uapi/linux/mptcp.h
@@ -4,15 +4,15 @@
#include <linux/types.h>
-#define MPTCP_SUBFLOW_FLAG_MCAP_REM BIT(0)
-#define MPTCP_SUBFLOW_FLAG_MCAP_LOC BIT(1)
-#define MPTCP_SUBFLOW_FLAG_JOIN_REM BIT(2)
-#define MPTCP_SUBFLOW_FLAG_JOIN_LOC BIT(3)
-#define MPTCP_SUBFLOW_FLAG_BKUP_REM BIT(4)
-#define MPTCP_SUBFLOW_FLAG_BKUP_LOC BIT(5)
-#define MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED BIT(6)
-#define MPTCP_SUBFLOW_FLAG_CONNECTED BIT(7)
-#define MPTCP_SUBFLOW_FLAG_MAPVALID BIT(8)
+#define MPTCP_SUBFLOW_FLAG_MCAP_REM _BITUL(0)
+#define MPTCP_SUBFLOW_FLAG_MCAP_LOC _BITUL(1)
+#define MPTCP_SUBFLOW_FLAG_JOIN_REM _BITUL(2)
+#define MPTCP_SUBFLOW_FLAG_JOIN_LOC _BITUL(3)
+#define MPTCP_SUBFLOW_FLAG_BKUP_REM _BITUL(4)
+#define MPTCP_SUBFLOW_FLAG_BKUP_LOC _BITUL(5)
+#define MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED _BITUL(6)
+#define MPTCP_SUBFLOW_FLAG_CONNECTED _BITUL(7)
+#define MPTCP_SUBFLOW_FLAG_MAPVALID _BITUL(8)
enum {
MPTCP_SUBFLOW_ATTR_UNSPEC,
--
2.26.0
2 years, 1 month