RFCv3 for netdev: todo list
by Matthieu Baerts
Hi,
At the last meeting, we agreed on this planning for the RFCv3 for netdev:
- Wait for Florian comment about that → *Done*
- Matth does the rebase → *Done*
- We let half to one day for the review → *In progress*
- Paolo sends coffee to Mat → *In preparation*
- Mat sends that to Netdev as a non RFC → *Waiting*
- (maybe: Mat, may you already send a new draft for the
cover-letter for this first batch?)
I guess for the last one, if Mat, you have the opportunity to start it,
feel free to already share it.
Regarding the cover-letter, here is what we said after the meeting:
> In the cover-letter, we would say that we would like to know:
> - if there are any objections on the changes made in the TCP core.
> - the goal is to send this patch-set as a non RFC one when we are
> ready with our initial patch-set that we called "part 2".
Ideally, if everything goes well, we could have:
- Today in the US and also tomorrow in Europe, we review the new tree
- We can also review the cover-letter if available
- If no objections and everything read, we tag the new version tomorrow
- Once it is tagged and cover-letter ready, we send the 11th first
patches of the new series.
Feel free to react if you need more time or if something needs to be
changed.
WDYT?
Cheers,
Matt
--
Matthieu Baerts | R&D Engineer
matthieu.baerts(a)tessares.net
Tessares SA | Hybrid Access Solutions
www.tessares.net
1 Avenue Jean Monnet, 1348 Louvain-la-Neuve, Belgium
2 years, 7 months
[PATCH] mptcp: fix kbuild warning
by Matthieu Baerts
The warning:
net//mptcp/protocol.c:440:4: warning: format '%ld' expects argument of
type 'long int', but argument 4 has type
'size_t' [-Wformat=]
'%zu' should be used with size_t.
Reported-by: kbuild test robot <lkp(a)intel.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts(a)tessares.net>
---
Notes:
To squash in "mptcp: Implement MPTCP receive path"
net/mptcp/protocol.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 508d5a83866b..8743b74dc1a1 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -466,7 +466,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
arg.msg = NULL;
desc.count = min_t(size_t, old_ack - ack_seq,
map_remaining);
- pr_debug("Dup data, map len=%d acked=%lld dropped=%ld",
+ pr_debug("Dup data, map len=%d acked=%lld dropped=%zu",
map_remaining, old_ack - ack_seq, desc.count);
} else {
arg.msg = msg;
--
2.20.1
2 years, 7 months
[PATCH mptcp] mptcp: mib: fix sparse warnings
by Florian Westphal
squashto: mptcp: add MIB counter infrastructure
get rid of:
mib.c:31:33: sparse: warning: incorrect type in initializer (different address spaces)
mib.c:31:33: sparse: expected struct mptcp_mib *mib
mib.c:31:33: sparse: got struct mptcp_mib [noderef] <asn:3> *
mib.c:36:13: sparse: warning: incorrect type in initializer (different address spaces)
mib.c:36:13: sparse: expected struct mptcp_mib [noderef] <asn:3> *__new
mib.c:36:13: sparse: got struct mptcp_mib *mib
mib.c:37:29: sparse: warning: incorrect type in argument 1 (different address spaces)
mib.c:37:29: sparse: expected void [noderef] <asn:3> *__pdata
mib.c:37:29: sparse: got struct mptcp_mib *mib
mib.c:42:6: sparse: warning: symbol 'mptcp_seq_show' was not declared. Should it be static?
Signed-off-by: Florian Westphal <fw(a)strlen.de>
---
net/mptcp/mib.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
index 38f6e63335bf..4ab627e877d1 100644
--- a/net/mptcp/mib.c
+++ b/net/mptcp/mib.c
@@ -2,6 +2,7 @@
#include <linux/seq_file.h>
#include <net/ip.h>
+#include <net/mptcp.h>
#include <net/snmp.h>
#include <net/net_namespace.h>
@@ -28,7 +29,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
*/
bool mptcp_mib_alloc(struct net *net)
{
- struct mptcp_mib *mib = alloc_percpu(struct mptcp_mib);
+ struct mptcp_mib __percpu *mib = alloc_percpu(struct mptcp_mib);
if (!mib)
return false;
--
2.21.0
2 years, 7 months
[PATCH] mptcp: timout delta must be signed
by Paolo Abeni
otherwise later 'tout <= 0' check will give unexpected results
Squash-to "mptcp: introduce MPTCP retransmission timer"
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
---
net/mptcp/protocol.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 12a9051f3922..b5287bc40c59 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -24,12 +24,12 @@ static struct percpu_counter mptcp_sockets_allocated;
static void mptcp_set_timeout(const struct sock *sk, const struct sock *ssk)
{
- unsigned long tout = ssk && inet_csk(ssk)->icsk_pending ?
- inet_csk(ssk)->icsk_timeout - jiffies : 0;
+ long tout = ssk && inet_csk(ssk)->icsk_pending ?
+ inet_csk(ssk)->icsk_timeout - jiffies : 0;
if (tout <= 0)
tout = mptcp_sk(sk)->timer_ival;
- mptcp_sk(sk)->timer_ival = tout > 0 ? tout : TCP_RTO_MIN;
+ mptcp_sk(sk)->timer_ival = tout > 0 ? tout : TCP_RTO_MIN;
}
bool mptcp_timer_pending(struct sock *sk)
--
2.21.0
2 years, 7 months
Patent-question
by Christoph Paasch
Hello,
regarding the patent-question. From https://lwn.net/Articles/783673/, I see:
"
It looks like a fairly typical battle between a protocol pushed by the
largest Internet service providers, and one with a rather more grass-roots
origin. There is, however, another important thing to know about L4S:
Alcatel-Lucent claims a patent on the dual-queue algorithm. The company has
generously offered to make that patent available under "fair, reasonable,
and non-discriminatory" terms; such terms are, of course, highly
discriminatory against free software implementations. They make it
impossible to merge the affected code into a GPL-licensed kernel.
"
Is that true?
Christoph
2 years, 7 months
Yet another rebase/squash/cleanup proposal
by Florian Westphal
Hi.
Here is yet another rebase proposal, I've pushed it here:
https://git.breakpoint.cc/cgit/fw/mptcp-next.git/log/?h=export_sendmsg_re...
Its also accessible via
git fetch git://git.breakpoint.cc/fw/mptcp-next.git export_sendmsg_rebase_13
In short:
- folds two commits
- fixes the kbuild warnings we got with rfcv2
- gets rid of refcounting in mptcp_subflow_get_ref
A full diff between export and this new branch is below.
I have no more suggestions for rebases/squashes with the current patches
we have.
Here is a walkthrough of those patches that have been altered and
a changelog:
mptcp: Add MPTCP to skb extensions
... gains a #include linux/types.h
I added this include because the header uses u16, u64 and so on.
Without this, one can see
include/net/mptcp.h:13:2: error: unknown type name 'u16'
error when HEADER_TEST is enabled in .config.
tcp: Prevent coalesce/collapse when skb has MPTCP extensions
adds skbuff.h include to avoid:
include/net/mptcp.h:36:53: warning: 'struct sk_buff' declared inside parameter list will not be visible outside of this definition or declaration
mptcp: Add MPTCP socket stubs:
adds ...
+ if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL))
+ return -EOPNOTSUPP;
It makes sense to do it here as part of the boilerplate change.
The current export branch did this check after lock_sock, so we also avoid
the exta unlock if we test the flags first.
mptcp: Handle MPTCP TCP options
adds linux/tcp.h include to avoid
'struct tcp_options_received' declared inside parameter list... warning.
While a forward declaration is enough, followup patches add more
warnings such as
struct sock' declared inside parameter list ..
As we later use tcp_sk() helper here anyway, just add such include now.
mptcp: Handle MP_CAPABLE options for outgoing.
In tcp_output.c, 'opt_size' is now inited to 0 to avoid changing
this line in a followup patch, i.e. this change isn't visible in the
final diff.
The major change in this patch however is
mptcp_subflow_get_ref -> mptcp_subflow_get.
This helper will not increment sk reference count anymore.
As Paolo pointed out, the mptcp socket lock is held in all cases (we even
have an assertion inside the helper already) and we never keep the ssk
around after we've released the ssk lock. So, simplify this:
no sock_hold, no more sock_put(ssk).
This results in several followup changes because of this, e.g.
in mptcp: Create SUBFLOW socket for incoming connections
... to account for the changed name and dropping sock_put(ssk).
mptcp: Write MPTCP DSS headers to outgoing data packets
... now folds both
mptcp: use sk_page_frag() in sendmsg and
mptcp: sendmsg() do spool all the provided data
... with only a *tiny* increase in patch size.
Old was: 257 inserts, 12 deletions
After: 267 inserts, 11 deletions
I think thats a pretty good hint that the squashing is good
and reduces code churn (addition of code in patch x only to remove
it in y). I've modified the commit message to mention this folding.
The only other change is a 'seq_file' forward declaration in the MIB
skeleton patch, again because of a kbuild robot report:
'warning: 'struct seq_file' declared inside parameter list will not be visible
outside of this definition or declaration'.
mib.c has the needed seq_file.h include, so adding a forward declaration is
enough to silence gcc for other .c files that include mptcp.h.
Full diff of current export (ab35f6c5d8e3ed7a3c9603028d3b67c931af51b0)
and this branch:
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 8b0d062912d2..eba39a881767 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -8,6 +8,12 @@
#ifndef __NET_MPTCP_H
#define __NET_MPTCP_H
+#include <linux/skbuff.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+
+struct seq_file;
+
/* MPTCP sk_buff extension data */
struct mptcp_ext {
u64 data_ack;
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 14543aaa29bd..272fe90adfbb 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -79,18 +79,14 @@ static struct socket *mptcp_fallback_get_ref(const struct mptcp_sock *msk)
return ssock;
}
-static struct sock *mptcp_subflow_get_ref(const struct mptcp_sock *msk)
+static struct sock *mptcp_subflow_get(const struct mptcp_sock *msk)
{
struct mptcp_subflow_context *subflow;
sock_owned_by_me((const struct sock *)msk);
mptcp_for_each_subflow(msk, subflow) {
- struct sock *sk;
-
- sk = mptcp_subflow_tcp_socket(subflow)->sk;
- sock_hold(sk);
- return sk;
+ return mptcp_subflow_tcp_socket(subflow)->sk;
}
return NULL;
@@ -336,7 +332,9 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
struct sock *ssk;
long timeo;
- pr_debug("msk=%p", msk);
+ if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL))
+ return -EOPNOTSUPP;
+
lock_sock(sk);
ssock = __mptcp_fallback_get_ref(msk);
if (ssock) {
@@ -347,7 +345,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
return ret;
}
- ssk = mptcp_subflow_get_ref(msk);
+ ssk = mptcp_subflow_get(msk);
if (!ssk) {
release_sock(sk);
return -ENOTCONN;
@@ -356,16 +354,11 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (!msg_data_left(msg)) {
pr_debug("empty send");
ret = sock_sendmsg(ssk->sk_socket, msg);
- goto put_out;
+ goto out;
}
pr_debug("conn_list->subflow=%p", ssk);
- if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL)) {
- ret = -ENOTSUPP;
- goto put_out;
- }
-
lock_sock(ssk);
mptcp_clean_una(sk);
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
@@ -391,9 +384,8 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
release_sock(ssk);
-put_out:
+out:
release_sock(sk);
- sock_put(ssk);
return ret;
}
@@ -588,7 +580,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
return copied;
}
- ssk = mptcp_subflow_get_ref(msk);
+ ssk = mptcp_subflow_get(msk);
if (!ssk) {
release_sock(sk);
return -ENOTCONN;
@@ -752,8 +744,6 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
release_sock(ssk);
release_sock(sk);
- sock_put(ssk);
-
return copied;
}
@@ -808,7 +798,7 @@ static void mptcp_retransmit(struct work_struct *work)
if (!dfrag)
goto unlock;
- ssk = mptcp_subflow_get_ref(msk);
+ ssk = mptcp_subflow_get(msk);
if (!ssk)
goto reset_unlock;
@@ -838,7 +828,6 @@ static void mptcp_retransmit(struct work_struct *work)
mptcp_set_timeout(sk, ssk);
release_sock(ssk);
- sock_put(ssk);
reset_unlock:
if (!mptcp_timer_pending(sk))
@@ -1010,7 +999,6 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
__MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVEACK);
local_bh_enable();
-
inet_sk_state_store(newsk, TCP_ESTABLISHED);
release_sock(sk);
} else {
@@ -1326,7 +1314,7 @@ static int mptcp_getname(struct socket *sock, struct sockaddr *uaddr,
* is connected and there are multiple subflows is not defined.
* For now just use the first subflow on the list.
*/
- ssk = mptcp_subflow_get_ref(msk);
+ ssk = mptcp_subflow_get(msk);
if (!ssk) {
release_sock(sock->sk);
return -ENOTCONN;
@@ -1334,7 +1322,6 @@ static int mptcp_getname(struct socket *sock, struct sockaddr *uaddr,
ret = inet_getname(ssk->sk_socket, uaddr, peer);
release_sock(sock->sk);
- sock_put(ssk);
return ret;
}
2 years, 7 months
[GIT] move TCP-related commits to the beginning
by Matthieu Baerts
Hi,
I just did a rebase to have these commits at the top:
net: Make sock protocol value checks more specific
sock: Make sk_protocol a 16-bit value
tcp: Define IPPROTO_MPTCP
# new # tcp: Add MPTCP option number
tcp, ulp: Add clone operation to tcp_ulp_ops
# new # mptcp: Add MPTCP to skb extensions
tcp: Prevent coalesce/collapse when skb has MPTCP extensions (requires
MPTCP skb extensions)
tcp: Export low-level TCP functions
tcp: Check for filled TCP option space before SACK
tcp: clean ext on tx recycle
tcp: Expose tcp struct and routine for MPTCP
The work is visible in my repo, branch "rebase-net-tcp-first"
https://github.com/matttbe/mptcp_net-next/commits/rebase-net-tcp-first
Here is the new order:
ac0ee9246e87 net: Make sock protocol value checks more specific
62ea284edd7e sock: Make sk_protocol a 16-bit value
62f49d1713cd tcp: Define IPPROTO_MPTCP
4897684a3794 tcp: Add MPTCP option number
497c810b48ad tcp, ulp: Add clone operation to tcp_ulp_ops
8d38f78f68e0 mptcp: Add MPTCP to skb extensions
e71e2810b8de tcp: Prevent coalesce/collapse when skb has MPTCP extensions
a341f52a58d9 tcp: Export low-level TCP functions
f77bcc800d76 tcp: Check for filled TCP option space before SACK
20fe333f058b tcp: clean ext on tx recycle
6c20bbf7fd48 tcp: Expose tcp struct and routine for MPTCP
83f671162941 mptcp: Add MPTCP socket stubs
c51eb8f5898a mptcp: Handle MPTCP TCP options
4dc03ca8e947 mptcp: Associate MPTCP context with TCP socket
4c208a048fe1 mptcp: Handle MP_CAPABLE options for outgoing connections
c6a16a92d620 mptcp: add mptcp_poll
b4e7e8423e10 mptcp: Create SUBFLOW socket for incoming connections
7a392ff80b6e mptcp: Add key generation and token tree
df0d374fce8c mptcp: Add shutdown() socket operation
92ec7f781536 mptcp: Add setsockopt()/getsockopt() socket operations
dde2a56add38 mptcp: Write MPTCP DSS headers to outgoing data packets
50da2ff90d38 mptcp: Implement MPTCP receive path
2e5d9249a612 mptcp: use sk_page_frag() in sendmsg
71e3c5425dd5 mptcp: sendmsg() do spool all the provided data
17a875f7d2da mptcp: allow collapsing consecutive sendpages on the same
substream
03ebbf9b8b16 mptcp: Add path manager interface
a7960fdb3eee mptcp: Add ADD_ADDR handling
3518ae0b4f00 mptcp: Add handling of incoming MP_JOIN requests
3bf4d9b9fec6 mptcp: harmonize locking on all socket operations.
b9993fcfb4e2 mptcp: new sysctl to control the activation per NS
7c481ffdc7c9 mptcp: add basic kselftest for mptcp
268c2a3744c3 mptcp: Add handling of outgoing MP_JOIN requests
ae6f7b5628ed mptcp: Implement path manager interface commands
28b2727556c8 mptcp: Make MPTCP socket block/wakeup ignore sk_receive_queue
547e3d1e878d mptcp: update per unacked sequence on pkt reception
9a9abd186272 mptcp: queue data for mptcp level retransmission
c6c0172a3db5 mptcp: introduce MPTCP retransmission timer
79fd45ef6a7b mptcp: implement memory accounting for mptcp rtx queue
ebe996148315 mptcp: rework mptcp_sendmsg_frag to accept optional dfrag
37e551284043 mptcp: implement and use MPTCP-level retransmission
ac97373b2fba mptcp: allow dumping subflow context to userspace
8f991f422f4c mptcp: add MIB counter infrastructure
966eb30045b9 mptcp: increment MIB counters in a few places
The biggest change is in:
8d38f78f68e0 mptcp: Add MPTCP to skb extensions
This commit now introduces include/net/mptcp.h. The modifications in
net/mptcp/Kconfig file is now done in:
83f671162941 mptcp: Add MPTCP socket stubs
(select SKB_EXTENSIONS)
At the end, everything is the same, with a small fix to have all exposed
functions related to "_options" together:
$ diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 0f28bf05d7f5..8b0d062912d2 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -71,13 +71,13 @@ bool mptcp_established_options(struct sock *sk,
struct sk_buff *skb,
void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
struct tcp_options_received *opt_rx);
+void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
+
static inline bool mptcp_skb_ext_exist(const struct sk_buff *skb)
{
return skb_ext_exist(skb, SKB_EXT_MPTCP);
}
-void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
-
bool mptcp_sk_is_subflow(const struct sock *sk);
void mptcp_seq_show(struct seq_file *seq);
Last thing to share: I checked that each commit can still compile with
and without CONFIG_MPTCP:
git rebase -i --exec "./.compile.sh" net-next
Tell me if it is OK for you and if I can replace the current tree with
these commits.
Cheers,
Matt
--
Matthieu Baerts | R&D Engineer
matthieu.baerts(a)tessares.net
Tessares SA | Hybrid Access Solutions
www.tessares.net
1 Avenue Jean Monnet, 1348 Louvain-la-Neuve, Belgium
2 years, 7 months
[PATCH] mptcp: allow dumping subflow context to userspace
by Davide Caratti
add ulp-specific diagnostic functions, so that subflow information can be
dumped to userspace programs like 'ss'.
Signed-off-by: Davide Caratti <dcaratti(a)redhat.com>
---
Notes:
changes since RFC:
- dump all subflow-related infos except keys
include/uapi/linux/inet_diag.h | 1 +
include/uapi/linux/mptcp.h | 34 ++++++++++++
net/mptcp/Makefile | 2 +-
net/mptcp/diag.c | 95 ++++++++++++++++++++++++++++++++++
net/mptcp/protocol.h | 3 ++
net/mptcp/subflow.c | 2 +
6 files changed, 136 insertions(+), 1 deletion(-)
create mode 100644 include/uapi/linux/mptcp.h
create mode 100644 net/mptcp/diag.c
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
index a1ff345b3f33..13d16b887512 100644
--- a/include/uapi/linux/inet_diag.h
+++ b/include/uapi/linux/inet_diag.h
@@ -163,6 +163,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..2856b89cc36e
--- /dev/null
+++ b/include/uapi/linux/mptcp.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+#ifndef _UAPI_MPTCP_H
+#define _UAPI_MPTCP_H
+
+#include <linux/types.h>
+
+#define SUBFLOW_FLAGS_MCAP_REM BIT(0)
+#define SUBFLOW_FLAGS_MCAP_LOC BIT(1)
+#define SUBFLOW_FLAGS_JOIN_REM BIT(2)
+#define SUBFLOW_FLAGS_JOIN_LOC BIT(3)
+#define SUBFLOW_FLAGS_BKUP_REM BIT(4)
+#define SUBFLOW_FLAGS_BKUP_LOC BIT(5)
+#define SUBFLOW_FLAGS_4THACK BIT(6)
+#define SUBFLOW_FLAGS_CONNECTED BIT(7)
+#define SUBFLOW_FLAGS_MAPVALID BIT(8)
+
+enum {
+ MPTCP_SUBFLOW_UNSPEC,
+ MPTCP_SUBFLOW_TOKEN_REM,
+ MPTCP_SUBFLOW_TOKEN_LOC,
+ MPTCP_SUBFLOW_RELWRITE_SEQ,
+ MPTCP_SUBFLOW_MAP_SEQ,
+ MPTCP_SUBFLOW_MAP_SFSEQ,
+ MPTCP_SUBFLOW_SSN_OFFSET,
+ MPTCP_SUBFLOW_MAP_DATALEN,
+ MPTCP_SUBFLOW_FLAGS,
+ MPTCP_SUBFLOW_ID_REM,
+ MPTCP_SUBFLOW_ID_LOC,
+ MPTCP_SUBFLOW_PAD,
+ __MPTCP_SUBFLOW_MAX
+};
+
+#define MPTCP_SUBFLOW_MAX (__MPTCP_SUBFLOW_MAX - 1)
+#endif /* _UAPI_MPTCP_H */
diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile
index 289fdf4339c1..6b556e2995ec 100644
--- a/net/mptcp/Makefile
+++ b/net/mptcp/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_MPTCP) += mptcp.o
-mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o
+mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o diag.o
diff --git a/net/mptcp/diag.c b/net/mptcp/diag.c
new file mode 100644
index 000000000000..a42c96619faa
--- /dev/null
+++ b/net/mptcp/diag.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/* MPTCP socket monitoring support
+ *
+ * Copyright (c) 2019 Red Hat
+ *
+ * Author: Davide Caratti <dcaratti(a)redhat.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/net.h>
+#include <linux/inet_diag.h>
+#include <net/netlink.h>
+#include <uapi/linux/mptcp.h>
+#include "protocol.h"
+
+int subflow_get_info(const struct sock *sk, struct sk_buff *skb)
+{
+ struct subflow_context *sf;
+ struct nlattr *start;
+ u32 flags = 0;
+ int err;
+
+ start = nla_nest_start_noflag(skb, INET_ULP_INFO_MPTCP);
+ if (!start)
+ return -EMSGSIZE;
+
+ rcu_read_lock();
+ sf = rcu_dereference(inet_csk(sk)->icsk_ulp_data);
+ if (!sf) {
+ err = 0;
+ goto nla_failure;
+ }
+
+ if (sf->mp_capable)
+ flags |= SUBFLOW_FLAGS_MCAP_REM;
+ if (sf->request_mptcp)
+ flags |= SUBFLOW_FLAGS_MCAP_LOC;
+ if (sf->mp_join)
+ flags |= SUBFLOW_FLAGS_JOIN_REM;
+ if (sf->request_join)
+ flags |= SUBFLOW_FLAGS_JOIN_LOC;
+ if (sf->backup)
+ flags |= SUBFLOW_FLAGS_BKUP_REM;
+ if (sf->request_bkup)
+ flags |= SUBFLOW_FLAGS_BKUP_LOC;
+ if (sf->fourth_ack)
+ flags |= SUBFLOW_FLAGS_4THACK;
+ if (sf->conn_finished)
+ flags |= SUBFLOW_FLAGS_CONNECTED;
+ if (sf->map_valid)
+ flags |= SUBFLOW_FLAGS_MAPVALID;
+
+ if (nla_put_u32(skb, MPTCP_SUBFLOW_TOKEN_REM, sf->remote_token) ||
+ nla_put_u32(skb, MPTCP_SUBFLOW_TOKEN_LOC, sf->token) ||
+ nla_put_u32(skb, MPTCP_SUBFLOW_RELWRITE_SEQ, sf->rel_write_seq) ||
+ nla_put_u64_64bit(skb, MPTCP_SUBFLOW_MAP_SEQ, sf->map_seq,
+ MPTCP_SUBFLOW_PAD) ||
+ nla_put_u32(skb, MPTCP_SUBFLOW_MAP_SFSEQ, sf->map_subflow_seq) ||
+ nla_put_u32(skb, MPTCP_SUBFLOW_SSN_OFFSET, sf->ssn_offset) ||
+ nla_put_u16(skb, MPTCP_SUBFLOW_MAP_DATALEN, sf->map_data_len) ||
+ nla_put_u32(skb, MPTCP_SUBFLOW_FLAGS, flags) ||
+ nla_put_u8(skb, MPTCP_SUBFLOW_ID_REM, sf->remote_id) ||
+ nla_put_u8(skb, MPTCP_SUBFLOW_ID_LOC, sf->local_id)) {
+ err = -EMSGSIZE;
+ goto nla_failure;
+ }
+
+ rcu_read_unlock();
+ nla_nest_end(skb, start);
+ return 0;
+
+nla_failure:
+ rcu_read_unlock();
+ nla_nest_cancel(skb, start);
+ return err;
+}
+
+size_t subflow_get_info_size(const struct sock *sk)
+{
+ size_t size = 0;
+
+ size += nla_total_size(0) + /* INET_ULP_INFO_MPTCP */
+ nla_total_size(4) + /* MPTCP_SUBFLOW_TOKEN_REM */
+ nla_total_size(4) + /* MPTCP_SUBFLOW_TOKEN_LOC */
+ nla_total_size(4) + /* MPTCP_SUBFLOW_RELWRITE_SEQ */
+ nla_total_size_64bit(8) + /* MPTCP_SUBFLOW_MAP_SEQ */
+ nla_total_size(4) + /* MPTCP_SUBFLOW_MAP_SFSEQ */
+ nla_total_size(2) + /* MPTCP_SUBFLOW_SSN_OFFSET */
+ nla_total_size(2) + /* MPTCP_SUBFLOW_MAP_DATALEN */
+ nla_total_size(4) + /* MPTCP_SUBFLOW_FLAGS */
+ nla_total_size(1) + /* MPTCP_SUBFLOW_ID_REM */
+ nla_total_size(1) + /* MPTCP_SUBFLOW_ID_LOC */
+ 0;
+ return size;
+}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index f3f293c82058..f38639cc35b4 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -314,4 +314,7 @@ static inline bool before64(__u64 seq1, __u64 seq2)
#define after64(seq2, seq1) before64(seq1, seq2)
+size_t subflow_get_info_size(const struct sock *sk);
+int subflow_get_info(const struct sock *sk, struct sk_buff *skb);
+
#endif /* __MPTCP_PROTOCOL_H */
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 80d297ce11d2..9c860fcc4232 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -495,6 +495,8 @@ static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = {
.init = subflow_ulp_init,
.release = subflow_ulp_release,
.clone = subflow_ulp_clone,
+ .get_info = subflow_get_info,
+ .get_info_size = subflow_get_info_size,
};
static int subflow_ops_init(struct request_sock_ops *subflow_ops)
--
2.21.0
2 years, 7 months