[RFC PATCH 0/6] mptcp: add and use wmem accounting for rtx queue
by Florian Westphal
This series adds wmem accounting and makes mptcp sockets block once
the sndbuf size is reached. rtx cleanup is changed to wakeup any
blocked mptcp socket once enough wmem is available again.
sndbuf is set to the maximum allowed size of the tcp wmem.
There is no auto-tuning, I think we can add that later on as an
enhancement.
This is an RFC series in order to prevent the patches from getting
applied, I will send a v2 as soon as the open questions are sorted
out. Everthing continues to work for me.
I've tested these patches with an 4k-sized sndbuf, which results
in frequent wmem blocks and mptcp connection recovers once the acks
come in.
1. (see patch 5): add a new work queue or re-use existing one?
2. Should all patches get squashed or should there be a
"add wmem accouting" patch? A mix of both?
2, 3 and 4 would be squash candidates for example even if we add
a extra "wmem patch".
I will send the next iteration of the scheduler patches after the above
is sorted out.
The scheduler patches have no major changes aside from addressing a
comment from Paolo.
Meanwhile I am working on removal of __tcp_poll and on make the mptcp
socket conn list store tcp_sk structs rather than require a 'struct socket'.
Florian Westphal (6):
mptcp: add wmem_queued accounting
mptcp: allow partial cleaning of rtx head dfrag
subflow: store known available bytes in subflow
options: ack pending sequence
mptcp: add ack work queue
sendmsg: block until mptcp sk is writeable
net/mptcp/options.c | 13 ++++++--
net/mptcp/protocol.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++-----
net/mptcp/protocol.h | 5 +--
net/mptcp/subflow.c | 18 ++++++++---
4 files changed, 105 insertions(+), 17 deletions(-)
1 year, 2 months
[PATCH] mptcp: Add DATA_FIN transmission and handling
by Mat Martineau
Send and process received DATA_FIN options. This requires addition of a
state machine to the MPTCP socket to handle the closing process. DATA_FIN
is sent along with a DSS mapping for the final data transmitted, or on a
bare ACK if there is no data to transmit.
This is still a work in progress, including these areas:
* Need to finish handling of DSS_ACKs for the state machine.
* Need to double-check whether it's correct to bypass inet_shutdown
as the current code does.
* A DATA_FIN that arrives on a packet without data payload (unless it's
a TCP FIN) are discarded by tcp_data_queue() and not propagated to
the MPTCP socket. This is detected in mptcp_incoming_options() but
not yet handled. The skb with the DATA_FIN could be cloned and
placed in the subflow error queue, or a workqueue could handle it.
Signed-off-by: Mat Martineau <mathew.j.martineau(a)linux.intel.com>
---
net/mptcp/options.c | 52 ++++++++++++++++++++++--
net/mptcp/protocol.c | 96 ++++++++++++++++++++++++++++++++++++++++----
net/mptcp/protocol.h | 5 ++-
net/mptcp/subflow.c | 18 ++++-----
4 files changed, 149 insertions(+), 22 deletions(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 1b08e1193991..4f67826a4977 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -384,18 +384,43 @@ static bool mptcp_established_options_mp(struct sock *sk, unsigned int *size,
return false;
}
+static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow,
+ struct mptcp_ext *ext)
+{
+ struct mptcp_sock *msk = mptcp_sk(subflow->conn);
+
+ WARN_ONCE(!subflow->conn, "MPTCP: Missing MPTCP socket information");
+
+ /* Only send DATA_FIN if all data has been sent or this is the last
+ * mapping.
+ */
+ if (!ext->use_map) {
+ if (subflow->data_fin_seq == msk->write_seq) {
+ ext->use_map = 1;
+ ext->dsn64 = 1;
+ ext->data_seq = subflow->data_fin_seq;
+ ext->subflow_seq = 0;
+ ext->data_len = 1;
+ ext->data_fin = 1;
+ }
+ } else if (subflow->data_fin_seq == ext->data_seq + ext->data_len) {
+ ext->data_fin = 1;
+ }
+}
+
static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
unsigned int *size,
unsigned int remaining,
struct mptcp_out_options *opts)
{
+ struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
unsigned int dss_size = 0;
struct mptcp_ext *mpext;
unsigned int ack_size;
mpext = skb ? mptcp_get_ext(skb) : NULL;
- if (!skb || (mpext && mpext->use_map)) {
+ if (!skb || (mpext && mpext->use_map) || subflow->send_data_fin) {
unsigned int map_size;
map_size = TCPOLEN_MPTCP_DSS_BASE + TCPOLEN_MPTCP_DSS_MAP64;
@@ -405,6 +430,9 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
dss_size = map_size;
if (mpext)
opts->ext_copy = *mpext;
+
+ if (subflow->send_data_fin && skb)
+ mptcp_write_data_fin(subflow, &opts->ext_copy);
} else {
opts->ext_copy.use_map = 0;
WARN_ONCE(1, "MPTCP: Map dropped");
@@ -422,7 +450,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
dss_size += ack_size;
- msk = mptcp_sk(mptcp_subflow_ctx(sk)->conn);
+ msk = mptcp_sk(subflow->conn);
if (msk) {
opts->ext_copy.data_ack = msk->ack_seq;
} else {
@@ -441,6 +469,9 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
if (!dss_size)
return false;
+ if (opts->ext_copy.data_fin)
+ subflow->send_data_fin = 0;
+
*size = ALIGN(dss_size, 4);
return true;
}
@@ -632,6 +663,18 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
mpext->data_fin = mp_opt->data_fin;
+ if (mp_opt->data_fin &&
+ TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) {
+ /* The DATA_FIN is on a packet that will be discarded by
+ * tcp_data_queue() and will not get propagated to the MPTCP
+ * socket.
+ *
+ * Use workqueue or subflow error queue?
+ */
+ pr_warn("Ignored DATA_FIN");
+ }
+
+
if (msk)
mptcp_pm_fully_established(msk);
}
@@ -727,10 +770,11 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts)
* support for optional 32-bit mappings later.
*/
flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64;
- if (mpext->data_fin)
- flags |= MPTCP_DSS_DATA_FIN;
}
+ if (mpext->data_fin)
+ flags |= MPTCP_DSS_DATA_FIN;
+
*ptr++ = mptcp_option(MPTCPOPT_DSS, len, 0, flags);
if (mpext->use_ack) {
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 696f1d03a61d..6d3b4a0a8dc1 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -101,7 +101,7 @@ static struct sock *mptcp_subflow_recv_lookup(const struct mptcp_sock *msk)
sock_owned_by_me(sk);
mptcp_for_each_subflow(msk, subflow) {
- if (subflow->data_avail)
+ if (subflow->data_avail || subflow->incoming_data_fin)
return mptcp_subflow_tcp_socket(subflow)->sk;
receivers += !subflow->rx_eof;
@@ -383,6 +383,13 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
lock_sock(ssk);
mptcp_clean_una(sk);
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
+
+ if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) {
+ ret = sk_stream_wait_connect(sk, &timeo);
+ if (ret != 0)
+ goto put_out_subflow;
+ }
+
while (msg_data_left(msg)) {
ret = mptcp_sendmsg_frag(sk, ssk, msg, NULL, &timeo, &mss_now,
&size_goal);
@@ -403,6 +410,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
mptcp_reset_timer(sk);
}
+put_out_subflow:
release_sock(ssk);
out:
@@ -464,6 +472,41 @@ static void mptcp_wait_data(struct sock *sk, long *timeo)
remove_wait_queue(sk_sleep(sk), &wait);
}
+static int mptcp_close_state(int oldstate, bool fin, bool ack)
+{
+ switch (oldstate) {
+ case TCP_FIN_WAIT1:
+ if (fin && ack)
+ return TCP_TIME_WAIT;
+ else if (fin)
+ return TCP_FIN_WAIT2;
+ else
+ return TCP_CLOSING;
+ case TCP_FIN_WAIT2:
+ if (fin)
+ return TCP_TIME_WAIT;
+ else
+ return oldstate;
+ case TCP_CLOSING:
+ if (ack)
+ return TCP_TIME_WAIT;
+ else
+ return oldstate;
+ case TCP_TIME_WAIT:
+ return TCP_CLOSE;
+ case TCP_LAST_ACK:
+ if (ack)
+ return TCP_CLOSE;
+ else
+ return oldstate;
+ case TCP_ESTABLISHED:
+ return TCP_CLOSE_WAIT;
+ default:
+ pr_debug("Unexpected state with DATA_FIN: %d", oldstate);
+ return oldstate;
+ }
+}
+
static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int nonblock, int flags, int *addr_len)
{
@@ -545,6 +588,20 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
continue;
}
}
+
+ if (!subflow->map_valid && subflow->incoming_data_fin) {
+ int newstate;
+
+ // TODO: Send on all subflows?
+ newstate = mptcp_close_state(sk->sk_state, true, false);
+ msk->ack_seq++;
+ subflow->incoming_data_fin = 0;
+ subflow->send_data_fin = 1;
+ subflow->data_fin_seq = msk->write_seq;
+ inet_sk_state_store(sk, newstate);
+ tcp_send_ack(ssk);
+ }
+
release_sock(ssk);
continue;
@@ -747,11 +804,11 @@ static void mptcp_close(struct sock *sk, long timeout)
struct mptcp_sock *msk = mptcp_sk(sk);
struct socket *ssk = NULL;
- mptcp_token_destroy(msk->token);
- inet_sk_state_store(sk, TCP_CLOSE);
-
lock_sock(sk);
+ inet_sk_state_store(sk, TCP_CLOSE);
+ mptcp_token_destroy(msk->token);
+
if (msk->subflow) {
ssk = msk->subflow;
msk->subflow = NULL;
@@ -764,6 +821,8 @@ static void mptcp_close(struct sock *sk, long timeout)
list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) {
pr_debug("conn_list->subflow=%p", subflow);
+ subflow->send_data_fin = 1;
+ subflow->data_fin_seq = msk->write_seq;
sock_release(mptcp_subflow_tcp_socket(subflow));
}
@@ -930,6 +989,11 @@ static int mptcp_getsockopt(struct sock *sk, int level, int optname,
return -EOPNOTSUPP;
}
+static void mptcp_shutdown(struct sock *sock, int how)
+{
+ pr_err("Unexpected MPTCP shutdown call sock=%p how=%d", sock, how);
+}
+
#define MPTCP_DEFERRED_ALL TCPF_WRITE_TIMER_DEFERRED
/* this is very alike tcp_release_cb() but we must handle differently a
@@ -1055,7 +1119,7 @@ static struct proto mptcp_prot = {
.accept = mptcp_accept,
.setsockopt = mptcp_setsockopt,
.getsockopt = mptcp_getsockopt,
- .shutdown = tcp_shutdown,
+ .shutdown = mptcp_shutdown,
.destroy = mptcp_destroy,
.sendmsg = mptcp_sendmsg,
.recvmsg = mptcp_recvmsg,
@@ -1199,6 +1263,10 @@ static int mptcp_listen(struct socket *sock, int backlog)
err = inet_listen(ssock, backlog);
sock_put(ssock->sk);
+
+ if (!err)
+ inet_sk_state_store(sock->sk, TCP_LISTEN);
+
return err;
}
@@ -1252,7 +1320,7 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
return ret;
}
-static int mptcp_shutdown(struct socket *sock, int how)
+static int mptcp_stream_shutdown(struct socket *sock, int how)
{
struct mptcp_sock *msk = mptcp_sk(sock->sk);
struct mptcp_subflow_context *subflow;
@@ -1262,6 +1330,18 @@ static int mptcp_shutdown(struct socket *sock, int how)
pr_debug("sk=%p, how=%d", msk, how);
lock_sock(sock->sk);
+
+ if (sock->sk->sk_state == TCP_ESTABLISHED) {
+ inet_sk_state_store(sock->sk, TCP_FIN_WAIT1);
+ } else if (sock->sk->sk_state == TCP_CLOSE_WAIT) {
+ inet_sk_state_store(sock->sk, TCP_LAST_ACK);
+ } else if (sock->sk->sk_state != TCP_CLOSE) {
+ pr_warn("Shutdown from unexpected state %d",
+ sock->sk->sk_state);
+ release_sock(sock->sk);
+ return -EALREADY;
+ }
+
ssock = __mptcp_fallback_get_ref(msk);
if (ssock) {
release_sock(sock->sk);
@@ -1276,6 +1356,8 @@ static int mptcp_shutdown(struct socket *sock, int how)
tcp_socket = mptcp_subflow_tcp_socket(subflow);
pr_debug("conn_list->subflow=%p", subflow);
+ subflow->send_data_fin = 1;
+ subflow->data_fin_seq = msk->write_seq;
ret = kernel_sock_shutdown(tcp_socket, how);
}
release_sock(sock->sk);
@@ -1303,7 +1385,7 @@ void mptcp_proto_init(void)
mptcp_stream_ops.accept = mptcp_stream_accept;
mptcp_stream_ops.getname = mptcp_getname;
mptcp_stream_ops.listen = mptcp_listen;
- mptcp_stream_ops.shutdown = mptcp_shutdown;
+ mptcp_stream_ops.shutdown = mptcp_stream_shutdown;
if (percpu_counter_init(&mptcp_sockets_allocated, 0, GFP_KERNEL))
panic("Failed to allocate MPTCP pcpu counter\n");
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 8fe5f9383d38..cf90014974ea 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -217,9 +217,12 @@ struct mptcp_subflow_context {
map_valid : 1,
backup : 1,
data_avail : 1,
- rx_eof : 1;
+ rx_eof : 1,
+ incoming_data_fin : 1,
+ send_data_fin : 1;
u32 remote_nonce;
u64 thmac;
+ u64 data_fin_seq;
u32 local_nonce;
u32 remote_token;
u8 hmac[MPTCPOPT_HMAC_LEN];
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index f08c4b713978..e39b71094b12 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -315,7 +315,7 @@ enum mapping_status {
MAPPING_OK,
MAPPING_INVALID,
MAPPING_EMPTY,
- MAPPING_DATA_FIN
+ MAPPING_BARE_DATA_FIN
};
static u64 expand_seq(u64 old_seq, u16 old_data_len, u64 seq)
@@ -406,16 +406,13 @@ static enum mapping_status get_mapping_status(struct sock *ssk)
pr_err("Infinite mapping not handled");
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPRX);
return MAPPING_INVALID;
- } else if (mpext->subflow_seq == 0 &&
- mpext->data_fin == 1) {
- if (WARN_ON_ONCE(mpext->data_len != 1))
- return false;
+ }
- /* do not try hard to handle this any better, till we have
- * real data_fin support
- */
- pr_debug("DATA_FIN with no payload");
- return MAPPING_DATA_FIN;
+ if (mpext->data_fin && mpext->subflow_seq == 0 &&
+ mpext->data_len == 1) {
+ subflow->map_valid = 0;
+ subflow->incoming_data_fin = 1;
+ return MAPPING_BARE_DATA_FIN;
}
if (!mpext->dsn64) {
@@ -450,6 +447,7 @@ static enum mapping_status get_mapping_status(struct sock *ssk)
subflow->map_seq = map_seq;
subflow->map_subflow_seq = mpext->subflow_seq;
subflow->map_data_len = mpext->data_len;
+ subflow->incoming_data_fin = mpext->data_fin;
subflow->map_valid = 1;
pr_debug("new map seq=%llu subflow_seq=%u data_len=%u",
subflow->map_seq, subflow->map_subflow_seq,
--
2.24.0
1 year, 2 months
[PATCH v2 0/6] IPv6 support
by Peter Krystad
Implemented support for IPv6. selftests pass with ipv6=true, but
they take twice as long to run...
With re-factoring the addition of IPv6 is very clean but I did not
split files yet as it will be hard to squash any changes after the
such a split.
Still to do: multiple subflows, handling IPv4-mapped connections.
v2: Added further re-factoring that makes IPv6 change even smaller
Add mptcpv6_init() stub and verified build with IPv6=n and m
Kconfig changes submitted in earlier patch set, this set depends
on those changes being merged.
Squashing the final patch (6/6) so that IPv6 support occurs before
the kselftests commit will be complicated.
Peter Krystad (6):
mptcp: Reference icsk_af_ops routines through saved pointer
mptcp: Reference inet_stream_ops routines through socket->ops
mptcp: Re-factor mptcp_getname routine to be af-agnostic
mptcp: Re-factor subflow_v4_conn_request to be af-agnostic
mptcp: Export low-level routines for IPv6
mptcp: Add IPv6 support
include/net/mptcp.h | 10 ++++
include/net/tcp.h | 3 ++
net/ipv6/tcp_ipv6.c | 16 ++++--
net/mptcp/ctrl.c | 11 ++++
net/mptcp/protocol.c | 117 ++++++++++++++++++++++++++++++++-----------
net/mptcp/protocol.h | 7 +++
net/mptcp/subflow.c | 94 +++++++++++++++++++++++++++++-----
7 files changed, 213 insertions(+), 45 deletions(-)
--
2.17.2
1 year, 2 months
[PATCH mptcp 0/4] four small cleanups and fixes
by Florian Westphal
1. cleanup: mptcp_subflow_get_map_offset arg can be const.
2. fix: don't advance snd_una past the write sequence.
3. cleanup: use existing helper rather than open-coding it
4. fix: avoid blocking kworker forever when polling mptcp socket.
All paches can be squashed, I've added squashto hints.
The following changes since commit 512f0321ae8a2679c15915b68f8a5cd98f190288:
subflow: wake parent mptcp socket on subflow state change (2019-11-05 02:27:34 +0000)
are available in the Git repository at:
git://git.breakpoint.cc/fw/mptcp-next.git mptcp_fixes_04
for you to fetch changes up to 50a570bb03f61cb5e2344e1d3f8d959c40d7b520:
poll: release lock before waiting (2019-11-05 17:58:28 +0100)
----------------------------------------------------------------
Florian Westphal (4):
protocol.h: mptcp_subflow_get_map_offset arg can be const
options: ignore mptcp-level ack that is ahead of write_seq
protocol: use sk_wait_event helper
poll: release lock before waiting
net/mptcp/options.c | 6 ++++++
net/mptcp/protocol.c | 16 ++++------------
net/mptcp/protocol.h | 4 ++--
3 files changed, 12 insertions(+), 14 deletions(-)
1 year, 2 months
[Weekly meetings] MoM - 7th of November 2019
by Matthieu Baerts
Hello,
Yesterday, we had our 74rd meeting with Peter and Ossama (Intel OTC),
Christoph (Apple), Paolo, Florian and Davide (RedHat) and myself (Tessares).
Thanks again for this new good meeting!
Here are the minutes of the meeting:
Accepted patches:
- The list of accepted patches can be seen on PatchWork:
https://patchwork.ozlabs.org/project/mptcp/list/
ID State Name
-- ----- ----
1189048 Accepted mptcp: fix stray wake-up event
1189317 Accepted mptcp: Use sk_family field in the mptcp_sock for
address family.
1190120 Accepted [v2,1/6] mptcp: Reference icsk_af_ops routines
through saved pointer
1190118 Accepted [v2,2/6] mptcp: Reference inet_stream_ops routines
through socket->ops
1190116 Accepted [v2,3/6] mptcp: Re-factor mptcp_getname routine to
be af-agnostic
1190119 Accepted [v2,4/6] mptcp: Re-factor subflow_v4_conn_request
to be af-agnostic
1190122 Accepted [v2,5/6] mptcp: Export low-level routines for IPv6
1190121 Accepted [v2,6/6] mptcp: Add IPv6 support
Pending patches:
- The list of pending patches can be seen on PatchWork:
https://patchwork.ozlabs.org/project/mptcp/list/
ID State Name
-- ----- ----
1189850 Awaiting Upstream [0/4] four small cleanups and fixes
1189851 Awaiting Upstream [1/4] protocol.h: mptcp_subflow_get_map_offset
arg can be const
1189852 Awaiting Upstream [2/4] options: ignore mptcp-level ack that is
ahead of write_seq
1189853 Awaiting Upstream [3/4] protocol: use sk_wait_event helper
1189854 Awaiting Upstream [4/4] poll: release lock before waiting
1189894 Awaiting Upstream [1/5] mptcp: Make MPTCP IPv6 support depend on
CONFIG_IPV6=y
1189893 Awaiting Upstream [2/5] mptcp: Switch to CONFIG_MPTCP_IPV6
1189895 Awaiting Upstream [3/5] mptcp: Switch to CONFIG_MPTCP_IPV6
1189897 Awaiting Upstream [4/5] mptcp: Switch to CONFIG_MPTCP_IPV6
1189896 Awaiting Upstream [5/5] mptcp: Switch to CONFIG_MPTCP_IPV6
1190123 Changes Requested mptcp: Add DATA_FIN transmission and handling
1191205 New [1/2] mptcp: parse and emit MP_CAPABLE option
according to v1 spec.
1191206 New [2/2] mptcp: process MP_CAPABLE data option.
Remaining items for the initial submission: Update:
- IPv6 support:
- Peter is working on it
- everything seems OK for the initial submission
- Peter will look at supported v6mapped but that's not needed
for the 1st patch set
- We should squash the last one
→ *@Peter* to give instructions to Matt to know where to squash
it in multiple commits
- MPTCP v1 support:
- Christoph is working on it
- First patches shared on the ML
- one question also asked by Paolo on the ML:
- not enough room to send MPTCP options
- should be always OK with MP_CAPABLE
- we might have issues even with MP_CAPABLE, e.g. MD5
because it can use 18 bytes
- if we don't have enough space in MP_CAPABLE, we fallback
to TCP
- in mptcp.org, we don't try to use MPTCP if TCP_MD5 is
configured.
- but independent to MPTCPv1 support so Paolo will be able
to look at that
- question about 3rd packets with MP_CAPABLE. Christoph replied
on a separated email:
- if the draft is not very clear, we should not hesitate to
send an email on the IETF ML
- the first patch-set sent by Christoph is using SHA1. But it
should use SHA256:
- but how to apply it?
- As we plan to put v1 patches just after having introduced v0
- But if we squash, it means v0 will use SHA256 (even if we
drop it in the next patch)
- Or could be part of the patch introducing v1, but quite
"big" (3 patches)
- or as a new part 3, just after kselftests, would be sent
immediately after
- maybe difficult to review if it is in one big patch.
- or move other patches from before the kselftests (related
to multiple subflows support → MP_JOIN support, PM, ADD_ADDR handling):
→ maybe the only solution to keep the number of patches
under 20
→ seems to make sense
→ *@Matth*: move these commits just after the
introduction of the kselftests
- Wireshark support for v1 has just been merged
- TCPDump support is not planned yet
- DATA_FIN:
- Mat is working on it
- It seems still to be too big for the "initial submission"
with the minimal feature
- because sending the DATA_FIN might be required for some
implementations (not closing the MPTCP connections), it could be good to
at least send the DATA_FIN, without the full support.
- *@Mat*: maybe for the initial submission, part 2, where only
1 subflow is supported, could we send the DATA_FIN just before closing
the connection? With the minimal support.
- Shared recv window:
- work to be done
- Active backup support:
- Florian is working on it
- Patches (and winter) are coming
- optimisation of options in TCP "struct mptcp_options_received":
- Peter is working on it
- Note: in some code of .h files, some spaces/tabs are used
while it should be the opposite
- Peter will send patches soon
- if the peer never sends MPTCP-level ACK, a lot of memory will be
used:
- Florian is working on that
- MAINTAINERS file
kselftests:
- should we modify the default timeout (instead of 450s)?
- When you use -- make -C tools/testing/selftests
TARGETS=net/mptcp run_tests -- how do you pass arguments to
mptcp_connect.sh script?:
→ we need to run the script manually
→ or maybe env vars? Never tried
→ if ran manually, we don't depend on the timeout
- *TODO* IPv6 should be enabled by default
- *TODO* Timeout could be decreased but not under 45 seconds: we
still need to setup a different timeout
Patchwork:
- https://patchwork.ozlabs.org/project/mptcp/
- which status to use?:
- New → Waiting for review for anybody
- Under review → In review or waiting for precisions?
- Accepted → = applied? Or waiting to be applied? (but then no
longer visible)
- Rejected → we don't want that (at all)
- RFC
- Not applicable → to be rebased?
- Changes requested → we need a new version (no more an "Action
Required" state)
- Awaiting Upstream → waiting to be applied (more visible than
Accepted since it's an "Action Required" state, included by default in
the patch list)
- Superseded → replaced by another one? Very similar to
"Changes requested", we don't have to use it
- Deferred → for later?
- Needs review/ACKs → When assigned to something but the review
didn't start → we can also keep the "Under review" status
- When do we archive?:
- After each weekly meeting → yes to be able to discuss about
what has recently been changed
- Once it is applied? → then no
TODO Matth:
- CI: Check Kselftest in the commit where it is introduced
- Apply accepted patches
- test IPv6 in kselftests
- reduce timeout kselftests
- put on the wiki the meaning of patchwork status
Next meeting:
- We propose to have it next Thursday, the 14th of November.
- Usual time: 17:00 UTC (9am PST, 6pm CET)
- Still open to everyone!
- https://annuel2.framapad.org/p/mptcp_upstreaming_20191114
Feel free to comment on these points and propose new ones for the next
meeting!
Talk to you next week,
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
1 year, 2 months
question on MP_CAPABLE v1 handshake
by Paolo Abeni
hi,
while testing the v1 MP_CAPABLE handshake, I stumbled upon the
following scenario:
syn + MP_CAPABLE ->
<- syn + ack + MP_CAPABLE(sndr key)
ack + MP_CAPABLE(sndr key, rcvr key)
<- ack + DSS(map,data_ack)
At this point, is the client still supposed to send MP_CAPABLE(sndr
key, rcvr key, data_len)? or should it send a plain DSS? Since it
received a DSS from the peer, the client knows that the MP_CAPABLE
options has been successfully received, but reading
https://datatracker.ietf.org/doc/draft-ietf-mptcp-rfc6824bis/?include_text=1
from section 3.1.:
"""
If A does not
immediately have data to send, it MUST include the MP_CAPABLE on the
third ACK, but without the additional data parameters. When A does
have data to send, it must repeat the sending of the MP_CAPABLE
option from the third ACK, with additional data parameters.
"""
it looks like the client should always use MP_CAPABLE+data for the
first data packet, is that right?
Thanks,
Paolo
1 year, 2 months
Re: Weekly meeting - 7 November 2019 17:00 UTC (9am PST, 6pm CET)
by Matthieu Baerts
Hi Ossama,
Wed Nov 06 22:18:51 GMT+01:00 2019 Othman, Ossama :
> Hi Matthieu,
>
> Daylight Savings Time is over in the US. s/PDT/PST/ in the subject line. :)
Good catch!
I simply copy-pasted a previous email. The meeting will be at 5pm UTC, not 4pm, which is 9am PST or 6pm CET.
Cheers,
Matt
1 year, 2 months
[PATCH] mptcp: Use sk_family field in the mptcp_sock for address family.
by Peter Krystad
It was not necessary to add a family field to mptcp_sock as it is
a wrapper around a struct sock, and sk_family is set correctly when
the msk is created as a result of a socket() call.
squashto: Associate MPTCP context with TCP socket
mptcp: Implement basic path manager
Signed-off-by: Peter Krystad <peter.krystad(a)linux.intel.com>
---
net/mptcp/basic.c | 5 +++--
net/mptcp/protocol.c | 1 -
net/mptcp/protocol.h | 1 -
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/basic.c b/net/mptcp/basic.c
index 67a93aff500e..03afb1263f3d 100644
--- a/net/mptcp/basic.c
+++ b/net/mptcp/basic.c
@@ -185,6 +185,7 @@ static void announce_addr_worker(struct work_struct *work)
struct mptcp_pm_data *pm = container_of(work, struct mptcp_pm_data,
addr_work);
struct mptcp_sock *msk = container_of(pm, struct mptcp_sock, pm);
+ struct sock *sk = (struct sock *)msk;
struct basic_pernet *pernet;
pernet = net_generic(sock_net((struct sock *)msk), basic_pernet_id);
@@ -193,11 +194,11 @@ static void announce_addr_worker(struct work_struct *work)
* When the listening socket can accept connections from both
* families this restriction may be removed.
*/
- if (pernet->has_announce_v4 && msk->family == AF_INET)
+ if (pernet->has_announce_v4 && sk->sk_family == AF_INET)
mptcp_pm_announce_addr(pm->token, 1,
&pernet->announce_v4_addr);
#if IS_ENABLED(CONFIG_IPV6)
- else if (pernet->has_announce_v6 && msk->family == AF_INET6)
+ else if (pernet->has_announce_v6 && sk->sk_family == AF_INET6)
mptcp_pm_announce_addr6(pm->token, 1,
&pernet->announce_v6_addr);
#endif
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 3af5f121af9e..c2b29f8d0377 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1091,7 +1091,6 @@ static struct socket *mptcp_socket_create_get(struct mptcp_sock *msk)
}
msk->subflow = ssock;
- msk->family = ssock->sk->sk_family;
subflow = mptcp_subflow_ctx(msk->subflow->sk);
subflow->request_mptcp = 1; /* @@ if MPTCP enabled */
subflow->request_version = 0; /* currently only v0 supported */
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 8fe5f9383d38..791f2c19cfb8 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -133,7 +133,6 @@ struct mptcp_sock {
u32 token;
unsigned long flags;
u16 dport;
- sa_family_t family;
struct work_struct rtx_work;
struct list_head conn_list;
struct list_head rtx_queue;
--
2.17.2
1 year, 2 months
Re: [PATCH v2 5/6] mptcp: Export low-level routines for IPv6
by Matthieu Baerts
Hi Peter,
On 06/11/2019 16:16, Peter Krystad wrote:
>
> Matthieu -
>
> On Wed, 2019-11-06 at 11:09 +0100, Paolo Abeni wrote:
>> On Wed, 2019-11-06 at 10:37 +0100, Matthieu Baerts wrote:
>>> Hi Paolo,
>>>
>>> On 06/11/2019 10:03, Paolo Abeni wrote:
>>>> On Tue, 2019-11-05 at 20:41 -0800, Peter Krystad wrote:
>>>>> @@ -1111,7 +1111,8 @@ static void tcp_v6_restore_cb(struct sk_buff *skb)
>>>>> sizeof(struct inet6_skb_parm));
>>>>> }
>>>>>
>>>>> -static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
>>>>> +static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk,
>>>>> + struct sk_buff *skb,
>>>>> struct request_sock *req,
>>>>> struct dst_entry *dst,
>>>>> struct request_sock *req_unhash,
>>>>
>>>> Minor nit: it looks like this chunk is not needed[1].
>>>
>>> Peter replied this in the previous version of the patch:
>>>
>>> > It seemed like since I was in the neighborhood I would fix this
>>> > over-80 char line. If that's not appropriate we can drop this chunk.
>>
>> whoops, I missed that, sorry! And thank you for the head-up!
>>
>>> I guess we should not modify the style of non MPTCP code. Then better to
>>> drop this change, right?
>>
>> Yes, exactly. The above change should be in a separate, non mptcp-
>> related patch.
>
> Can you just drop this when you squash it?
Sure, I can do that!
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
1 year, 2 months