Commit graph

191 commits

Author SHA1 Message Date
Stefano Brivio
061519b562 test: Add CI/demo scripts
Not really quick, definitely dirty.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 15:10:35 +02:00
Stefano Brivio
ca325e7583 README: Add demo section
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 13:45:17 +02:00
Stefano Brivio
9657b6ed05 conf, tcp: Periodic detection of bound ports for pasta port forwarding
Detecting bound ports at start-up time isn't terribly useful: do this
periodically instead, if configured.

This is only implemented for TCP at the moment, UDP is somewhat more
complicated: leave a TODO there.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 11:23:44 +02:00
Stefano Brivio
e69e13671d util: Fix parsing of next option in ipv6_l4hdr()
We need to update next header and header length as soon as we meet
a new option header.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:09 +02:00
Stefano Brivio
904b86ade7 tcp: Rework window handling, timers, add SO_RCVLOWAT and pools for sockets/pipes
This introduces a number of fundamental changes that would be quite
messy to split. Summary:

- advertised window scaling can be as big as we want, we just need
  to clamp window sizes to avoid exceeding the size of our "discard"
  buffer for unacknowledged data from socket

- add macros to compare sequence numbers

- force sending ACK to guest/tap on PSH segments, always in pasta
  mode, whenever we see an overlapping segment, or when we reach a
  given threshold compared to our window

- we don't actually use recvmmsg() here, fix comments and label

- introduce pools for pre-opened sockets and pipes, to decrease
  latency on new connections

- set receiving and sending buffer sizes to the maximum allowed,
  kernel will clamp and round appropriately

- defer clean-up of spliced and non-spliced connection to timer

- in tcp_send_to_tap(), there's no need anymore to keep a large
  buffer, shrink it down to what we actually need

- introduce SO_RCVLOWAT setting and activity tracking for spliced
  connections, to coalesce data moved by splice() calls as much as
  possible

- as we now have a compacted connection table, there's no need to
  keep sparse bitmaps tracking connection activity -- simply go
  through active connections with a loop in the timer handler

- always clamp the advertised window to half our sending buffer,
  too, to minimise retransmissions from the guest/tap

- set TCP_QUICKACK for originating socket in spliced connections,
  there's no need to delay them

- fix up timeout for unacknowledged data from socket

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
3c839bfc46 tcp: Drop TODO about sequence collision attacks
A random initial sequence number based on a secret has already been
there for a while.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
f004de4a9d tap: Don't leak file descriptor used to bring up loopback interface
...and while at it, set the socket as non-blocking directly on open().

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
f1c1d40f90 tap: Fix comment for tap_sock_init_tun_ns()
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
8cc50c346b tap: Bring up tap device too, configure previous MAC address if any
In case we need to reinitialise the tap interface, make that
relatively transparent to processes running in the namespace.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
a491c8ee3c pcap: Drop O_DSYNC from pcap file descriptor
passt is stable enough, and dropping O_DSYNC makes reduces the impact
of capturing packets on timing, while running tests.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
11cc43feec pcap: Don't make pcap files world-readable
Even if it's just a debugging feature, it's not nice to leak packets
to everybody around.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
e4b94da0af pcap: Don't reinitialise packet capture if we already have one
If the guest disconnects, and a given name (without timestamp) for
the pcap file is passed, we would otherwise lose the packets
captured until that point.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
3943f20ef9 passt: Actually initialise timers for protocol handlers
The initial timestamp was not initialised, so timers for protocol
handlers wouldn't run at all sometimes.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
4b0ccb8323 ndp: Set router lifetime to 9000s instead of 3600s
Seen while testing: lifetime expires while we're flooding a tap
interface with UDP packets, the router advertisement comes too late,
and the kernel drops the default router in the namespace. This
should only affect testing, so go for the maximum allowed value,
that is, 9000 seconds.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
dd581730e5 tap: Completely de-serialise input message batches
Until now, messages would be passed to protocol handlers in a single
batch only if they happened to be dequeued in a row. Packets
interleaved between different connections would result in multiple
calls to the same protocol handler for a single connection.

Instead, keep track of incoming packet descriptors, arrange them in
sequences, and call protocol handlers only as we completely sorted
input messages in batches.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
dfc4513190 conf: Actually zero-terminate DNS and search list arrays
This worked pretty much by chance until now.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
2dbed699e7 passt: Align pkt_buf to PAGE_SIZE (start and size), try to fit in huge pages
If transparent huge pages are available, madvise() will do the trick.

While at it, decrease EPOLL_EVENTS for the main loop from 10 to 8,
for slightly better socket fairness.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
cc8db1c5bc README: pasta mode, CI, performance, updated links, etc.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
b216df04a1 Makefile: Visually separate CFLAGS from input files in resulting cc commands
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
ec0bdc10b1 udp: Switch to new socket message after 32KiB instead of 64KiB
For some reason, this measurably improves performance with qemu and
virtio-net.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
c2d86b7475 udp: Decrease UDP_TAP_FRAMES to 16
Similarly to the decrease in TCP_TAP_FRAMES, this improves fairness,
with a very small impact on performance.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
522878e6bb tcp: Decrease TCP_TAP_FRAMES to 8
This significantly improves fairness in serving concurrent connections.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
e9961cecfc pasta, tcp: Update comment about spliced connection states
...we now have SPLICE_FIN_{FROM,TO,BOTH} too.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-27 01:28:02 +02:00
Stefano Brivio
e5c941b9f8 passt: Increase TAP_BUF_BYTES to 256 maximum-sized descriptors
...this actually improves performance.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-19 02:04:43 +02:00
Stefano Brivio
964b7e12da README: Source js
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-18 13:26:48 +02:00
Stefano Brivio
9b6769d53b tcp: Don't reset connection from ESTABLISHED state on EPOLLHUP
That might just mean we shut down the socket -- but we still have to
go through the other states to ensure a orderly shutdown guest-side.

While at it, drop the EPOLLHUP check for unhandled states: we should
never hit that, but if we do, resetting the connection at that point
is probably the wrong thing to do.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:50:02 +02:00
Stefano Brivio
62bace390b pasta, tcp: Mask EPOLLIN and EPOLLRDHUP after sending FIN
Now that we dropped EPOLLET, we'll keep getting EPOLLRDHUP, and
possibly EPOLLIN, even if there's nothing to read anymore.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:50:02 +02:00
Stefano Brivio
492b58d64b pasta, tcp: Break splice() loop once we've written everything that was read
That's a guarantee that we don't need to retry writing.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:50:02 +02:00
Stefano Brivio
34dd4b28b0 pasta, tcp: Don't set SPLICE_FIN_BOTH state on EPOLLHUP
EPOLLHUP just means we shut down one side of the connection on
*one* socket: remember, we have two sockets here.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:50:02 +02:00
Stefano Brivio
e8540b3f26 pasta, tcp: Don't reset 'never_read' flag on write retries
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:50:02 +02:00
Stefano Brivio
7ecf693297 pasta, tcp: Don't set TCP_CORK on spliced sockets
...throughput isn't everything: this leads (of course) to horrible
latency with small, sparse messages. As a consequence, there's no
need to set TCP_NODELAY either.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:49:58 +02:00
Stefano Brivio
a7eb8bb2f6 tcp: Fix setting window from maximum ACK sequence in batch
If we're at the first message in a batch, it's safe to get the
window value from it, and there's no need to subtract anything for
a comparison on that's not even done -- we'll override it later in
any case if we find messages with a higher ACK sequence number.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:20:50 +02:00
Stefano Brivio
3be131280d pasta, tcp: Set pipe descriptor numbers to -1 after closing
...so that we don't try to close them again, even if harmless.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:19:39 +02:00
Stefano Brivio
d481578882 pasta, tcp: Drop EPOLLET for spliced, established connections
...tcp_handler_splice() doesn't guarantee we read all the available
data, the sending buffer might be full.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:17:18 +02:00
Stefano Brivio
45d9b0000e tcp: Read SO_SNDBUF unconditionally
Checking it only when the cached value is smaller than the current
window of the receiver is not enough: it might shrink further while
the receiver window is growing.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-16 08:14:01 +02:00
Stefano Brivio
474b8e6fb7 pasta: Clean up FIN connection flags once a connection is deleted
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-15 10:43:59 +02:00
Stefano Brivio
57d17292f9 pasta: Set spliced connection flag in epoll reference on compaction
...otherwise, we'll mix indices with non-spliced connections.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-15 10:41:31 +02:00
Stefano Brivio
a041f6d920 pasta: Clean up namespace processes on exit, reap zombies from clone()
If pasta created the namespace, it's probably expected that processes
started in the same namespace are terminated once pasta exits. Scan
procfs namespace links for corresponding processes, send SIGQUIT and
SIGKILL (after one second) if found.

While at it, make the signal handler reap otherwise-zombies resulting
from clone().

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-15 00:32:23 +02:00
Stefano Brivio
7d81b3c646 checksum: Add checksum.h
I forgot to commit this.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-14 19:02:36 +02:00
Stefano Brivio
9af8e0a1a7 tcp: Request retransmission with updated sequence also on partial write to socket
If we couldn't write the whole batch of received packets to the socket,
and we have missing segments, we still need to request their
retransmission right away, otherwise it will take ages for the guest to
figure out we're missing them.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-14 16:57:50 +02:00
Stefano Brivio
a616357c86 tcp: In ESTABLISHED state, acknowledge segments as they're sent to the socket
...instead of waiting for the remote peer to do that -- it's
especially important in case we request retransmissions from the
guest, but it also helps speeding up slow start. This should
probably be a configurable behaviour in the future.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-14 16:57:50 +02:00
Stefano Brivio
621c589d36 tcp: Properly time out ACK wait from tap
Seen with iperf3: a control connection is established, no data flows
for a while, all segments are acknowledged. The socket starts closing
it, and we immediately time out because the last ACK from tap was one
minute before that.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-14 16:57:50 +02:00
Stefano Brivio
7c82ea4dd9 tcp: Don't mistake a FIN segment with no data for a Fast Retransmit request
It carries no data and usually duplicates the previous ACK sequence,
but it's just a FIN.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-14 16:57:50 +02:00
Stefano Brivio
c162f1e801 tcp: Check errno on sendmmsg() failure, not just the return value
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-14 16:57:50 +02:00
Stefano Brivio
2c009e8e6f tcp: Make sure sending window is initialised before sending to tap
Seen with iperf3: the first packet from socket (data connection) is
65520 bytes and doesn't fit in the window.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-14 16:57:50 +02:00
Stefano Brivio
e0530a802f qrap: Set x-txburst as temporary workaround for virtio-net TX stall
Flooding a virtio-net interface connected to a socket back-end results
in a TX stall I'm still debugging. The stall goes away by setting a
higher value for x-txburst (256 by default).

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-09 15:40:04 +02:00
Stefano Brivio
3994fc8f58 udp: Reset iov_base after sending partial message on sendmmsg() failure
We set the length while processing messges, but the starting address is
pre-initialised.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-09 15:40:04 +02:00
Stefano Brivio
ecf1f97564 udp: Fix comparison of seen IPv4 address for local connections
c->addr4_seen is stored in network order.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-09 15:40:04 +02:00
Stefano Brivio
e58828f340 tcp: Fixes for closing states, spliced connections, out-of-order packets, etc.
This fixes a number of issues found with some heavier testing with
uperf and neper:

- in most closing states, we can still accept data, check for EPOLLIN
  when appropriate

- introduce a new state, ESTABLISHED_SOCK_FIN_SENT, to track the fact
  we already sent a FIN segment to the tap device, for proper sequence
  number bookkeeping

- for pasta mode only: spliced connections also need tracking of
  (inferred) FIN segments and clean half-pipe shutdowns

- streamline resetting epoll_wait bitmaps with a new function,
  tcp_tap_epoll_mask(), instead of repeating the logic all over the
  place

- set EPOLLET for tap connections too, whenever we are waiting for
  EPOLLRDHUP or an event from the tap to proceed with data transfer,
  to avoid useless loops with EPOLLIN set

- impose an additional limit on the sending window advertised to the
  guest, given by SO_SNDBUF: it makes no sense to completely fill
  the sending buffer and send a zero window: stop a bit before we
  hit that

- handle *all* interrupted system calls as needed

- simplify the logic for reordering of out-of-order segments received
  from tap: it's not a corner case, and the previous logic allowed
  for deadloops

- fix comparison of seen IPv4 address when we get a new connection
  from a socket directed to the configured guest address

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-09 15:40:04 +02:00
Stefano Brivio
5e23b1ef44 tap: Fix calculation of number of tap scatter-gather IO messages
Messages are typically smaller than ETH_MAX_MTU.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-09 15:40:04 +02:00