mptcp: Enter quickack when receiving MPTCP out-of-order data

It may happen that a subflow is not sending quickacks, because of the
conditions in __tcp_ack_snd_check. In this function, a quickack will be
sent, if more than one MSS has been received between the last window
announcment AND the current rcv-next and additionally, the window
changes. In TCP this results in quick-acks when receiving in-order data
AND the window increases, which is good enough as it still allows the
sender to progress. Additionally, tcp_cleanup_rbuf will send acks if the
right edge of the window advances as well. Finally, quickacks are sent
for out-of-order data to allow quick recovery from a loss.

But, with MPTCP if we receive out-of-order data at the MPTCP-level, we do
not send a quickack. This, because it is not necessary for
loss-recovery. However, it might be that we are getting closer to the
right edge of the window. In this case, we should send acks so that the
sender can act accordingly (the NSDI algorithm). But, subflows may not
have their conditions in __tcp_ack_snd_check result in true, because
the window itself is not increasing.

What then will happen is that delayed acks are sent and the sender is
actually blocked during 40ms (the time for the quickack being sent).

We should send quickacks when we are getting close to the right edge of
the window. So, this patch changes it, so that if we receive
out-of-order data at the MPTCP-level, we go into quickack-mode. The
quickack mode will then send (at most) 16 quickacks.

Fixes: Zero-day bug
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Copy path_mask when fragmenting

We need to copy the path-mask, because the segment may be a reinjection.
In this case, we need to keep the path-masks consistent.

Fixes: Zero-day bug
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: TSQ is not handled at the meta-level

Since a105f1360b32 (mptcp: Remove tsq-limitation for MPTCP) a
TSQ-limitation can only happen at the subflow-level. So, we should not
set TSQ-bits on the meta in tcp_tasklet_func.

Fixes: a105f1360b32 (mptcp: Remove tsq-limitation for MPTCP)
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Disable nagle on subflows

Nagle is entirely handled at the MPTCP-layer. We should not wait for
more data at the subflows.

Fixes: Zero-day bug
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Do not schedule on tsq-throttled subflows

The default scheduler expects segments to exit as soon as possible. If
the subflow is blocked by tsq, we should choose the next one.

This patch adds the necessary limitation to mptcp_is_available.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Move call to mptcp_reinject_data

We want to call the reinjection after the data has actually been
retransmitted at the subflow-level. This is important, because otherwise
we risk sending the data again on the same subflow as it's
congestion-window is not fully used.

Doing it after the call to tcp_retransmit_skb ensures that the
congestion-window is full.
Also, it allows to group together, the calls to mptcp_set_rto with
mptcp_reinject_data.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Don't use tcp_cwnd_test in mptcp_is_available

Because, with the new mptcp_write_xmit, packets_out will not be
increased at each iteration in mptcp_write_xmit. We must rely on
write_seq - snd_nxt to get an estimation of how much has been queued.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Remove tcp_mtu_probe from mptcp_write_xmit

... and block it in tcp_write_xmit.
tcp_mtu_probe is only a subflow-level probing. We cannot do it at the
MPTCP-layer.

In the future this allows us to do pmtu-discovery. We just need to make
sure that only segments with the same DSS-mapping are used for the
discovery.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Rework mptcp_write_xmit

This is the major rework of mptcp_write_xmit. From now on, we just queue
segments on the subflow's send-queue and push them on the interface with
a call to __tcp_push_pending_frames.
This allows to reduce the code-duplication inside mptcp_write_xmit.

It allows to get rid of all changes to the TCP stack in
tcp_mss_split_point and tcp_tso_should_defer. These are now handled
entirely at the subflow-level.

We need to move part of the code from mptcp_event_new_data_sent to
mptcp_skb_entail. This code ensures that only in-order data is sent on
a not yet "fully-established" subflow.

We force gso_segs at the mptcp-level to 1. We do this, because we
actually do not care about the actual value of gso_segs at the
MPTCP-level. This variable is specific to each subflow as it depends on
the NIC.

The call to tcp_mss_split_point at the MPTCP-level only tries to find
where we should split the segment according to the receive-window. We
use UINT_MAX in the call, to make it independent of the MSS/gso-max-segs.
The MSS/gso-max-segs is specific to each subflow and thus should be
handled there.

Actually, this change allows to create bigger mappings, as we split the
mapping no more based on the NIC's TSO capabilities.

The magic with UINT_MAX is used to allow reusing the code of
tcp_set_skb_tso_segs and tcp_mss_split_point. In principle, we could
also simply reimplement the desired behavior in separate MPTCP
functions. But, then we would still need the "magic" for the call to
tcp_fragment and would duplicate a bit of code.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
Cleanup

Trivial...

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Return bool in mptcp_is_available

Trivial...

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Remove needless pointer-check in mptcp_reconstruct_mapping

mpdss is always pointing to the dss-field in tcp_skb_cb. It cannot be
null.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Use cond_resched() instead of yield()

See comment in kernel/sched/core.c.

We leave one yield in mptcp_send_fin, because tcp_send_fin also has this
one still there.

The other use-cases of yield are there to give the kernel a chance to
schedule other tasks, which is really what we want here.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Remove useless check for mapping_present

It is already checked at the beginning of mptcp_validate_mapping.
We do not need to check yet again.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>