Commit graph

793 commits

Author SHA1 Message Date
David Gibson
d5b80ccc72 Fix widespread off-by-one error dealing with port numbers
Port numbers (for both TCP and UDP) are 16-bit, and so fit exactly into a
'short'.  USHRT_MAX is therefore the maximum port number and this is widely
used in the code.  Unfortunately, a lot of those places don't actually
want the maximum port number (USHRT_MAX == 65535), they want the total
number of ports (65536).  This leads to a number of potentially nasty
consequences:

 * We have buffer overruns on the port_fwd::delta array if we try to use
   port 65535
 * We have similar potential overruns for the tcp_sock_* arrays
 * Interestingly udp_act had the correct size, but we can calculate it in
   a more direct manner
 * We have a logical overrun of the ports bitmap as well, although it will
   just use an unused bit in the last byte so isnt harmful
 * Many loops don't consider port 65535 (which does mitigate some but not
   all of the buffer overruns above)
 * In udp_invert_portmap() we incorrectly compute the reverse port
   translation for return packets

Correct all these by using a new NUM_PORTS defined explicitly for this
purpose.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-24 14:48:35 +02:00
David Gibson
3ede07aac9 Treat port numbers as unsigned
Port numbers are unsigned values, but we're storing them in (signed) int
variables in some places.  This isn't actually harmful, because int is
large enough to hold the entire range of ports.  However in places we don't
want to use an in_port_t (usually to avoid overflow on the last iteration
of a loop) it makes more conceptual sense to use an unsigned int. This will
also avoid some problems with later cleanups.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-24 14:48:35 +02:00
David Gibson
0d1886dca0 Pass entire port forwarding configuration substructure to conf_ports()
conf_ports() switches on the optname argument to select the target array
for several updates.  Now that all these maps are in a common structure, we
can simplify by just passing in a pointer to the whole struct port_fwd to
update.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-24 14:48:35 +02:00
David Gibson
f5a31ee94c Don't use indirect remap functions for conf_ports()
Now that we've delayed initialization of the UDP specific "reverse" map
until udp_init(), the only difference between the various 'remap' functions
used in conf_ports() is which array they target.  So, simplify by open
coding the logic into conf_ports() with a pointer to the correct mapping
array.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-24 14:48:35 +02:00
David Gibson
1467a35b5a udp: Delay initialization of UDP reversed port mapping table
Because it's connectionless, when mapping UDP ports we need, in addition
to the table of deltas for destination ports needed by TCP, we need an
inverted table to translate the source ports on return packets.

Currently we fill out the inverted table at the same time we construct the
main table in udp_remap_to_tap() and udp_remap_to_init().  However, we
don't use either table until after we've initialized UDP, so we can delay
the construction of the reverse table to udp_init().  This makes the
configuration more symmetric between TCP and UDP which will enable further
cleanups.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-24 14:48:35 +02:00
David Gibson
163dc5f188 Consolidate port forwarding configuration into a common structure
The configuration for how to forward ports in and out of the guest/ns is
divided between several different variables.  For each connect direction
and protocol we have a mode in the udp/tcp context structure, a bitmap
of which ports to forward also in the context structure and an array of
deltas to apply if the outward facing and inward facing port numbers are
different.  This last is a separate global variable, rather than being in
the context structure, for no particular reason.  UDP also requires an
additional array which has the reverse mapping used for return packets.

Consolidate these into a re-used substructure in the context structure.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-24 14:48:35 +02:00
David Gibson
1128fa03fe Improve types and names for port forwarding configuration
enum conf_port_type is local to conf.c and is used to track the port
forwarding mode during configuration.  We don't keep it around in the
context structure, however the 'init_detect_ports' and 'ns_detect_ports'
fields in the context are based solely on this.  Rather than changing
encoding, just include the forwarding mode into the context structure.
Move the type definition to a new port_fwd.h, which is kind of trivial at
the moment but will have more stuff later.

While we're there, "conf_port_type" doesn't really convey that this enum is
describing how port forwarding is configured.  Rename it to port_fwd_mode.
The variables (now fields) of this type also have mildly confusing names
since it's not immediately obvious whether 'ns' and 'init' refer to the
source or destination of the packets.  Use "in" (host to guest / init to
ns) and "out" (guest to host / ns to init) instead.

This has the added bonus that we no longer have locals 'udp_init' and
'tcp_init' which shadow global functions.

In addition, add a typedef 'port_fwd_map' for a bitmap of each port number,
which is used in several places.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-24 14:48:35 +02:00
Vasiliy Ulyanov
11e285df8f Fix the name of the qemu-system-* executable
Define the target machine architecture in lowercase.

The name of the executable qemu-system-* is defined from the build flags
and should be in lowercase:

    ( "qemu-system-" ARCH ),

I.e. qemu-system-x86_64 instead of qemu-system-X86_64. Otherwise, the
exec call will fail.

Signed-off-by: Vasiliy Ulyanov <vulyanov@suse.de>
Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
2022-09-24 09:12:35 +02:00
Stefano Brivio
8338135777 README: Add missing parenthesis in Try It section
Signed-off-by: Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 09:00:22 +02:00
Stefano Brivio
9232065641 README: Drop excess whitespace in Try It section
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 08:59:16 +02:00
Stefano Brivio
16ad76d680 README: Add legend for Features section
As suggested by David: those emojis might not be entirely obvious.

Suggested-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:33:15 +02:00
Stefano Brivio
715677b699 README: Fix paragraph in Try It section of passt
The qemu patch isn't mentioned there anymore: replace reference with
a link.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:28:52 +02:00
Stefano Brivio
229b16cba3 README: Fix indentation in "Try It" section
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:23:38 +02:00
Stefano Brivio
be41639c20 README: Point openSUSE links to Dario's OBS repository
...instead of my Copr. It's also not official yet, but surely more
appropriate now.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:18:40 +02:00
Stefano Brivio
8b3443c561 README: Fix misspellings of openSUSE
For some reason, I used a capital O everywhere.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:14:47 +02:00
Stefano Brivio
e0f415c025 test/lib: Don't try to write to perf.js when running demos
...it doesn't actually exist, and this error now causes the demo to
stop.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:11:10 +02:00
Stefano Brivio
2e93cb6ed8 test/lib: Drop perf_report_append() from perf_report
It's not used anymore. While at it, fix the function name in the
comment to perf_report_append_js().

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:09:23 +02:00
Stefano Brivio
b3549093f7 test/demo: Avoid using port 5201 on the host
That's the default port for iperf3, which also means that it's quite
likely in use on my test machine. Use different port numbers: recycle
the scheme we use in tests for passt and pasta's demo, use 5221-5224
(a bit shorter) for the slirp4netns container in Podman's demo.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:07:18 +02:00
Stefano Brivio
6d08bfc3e0 test/demo: Use relative paths to change directories when possible
A cd to __STATEDIR__ results in a rather long command, that's not
very readable. Jump between directories using .. and relative paths,
once we're there.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:05:20 +02:00
Stefano Brivio
57fa9dd4c9 hooks/pre_push: Fix upload of CI's logs and terminal capture file
The test_logs directory contains a directory: fix the wildcard so
that scp doesn't fail.

Terminal capture files are now deleted every time we re-run the
demo script: upload CI's .cast file before it's gone.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:01:39 +02:00
Stefano Brivio
bd3e6f373f contrib/podman: Rebase to latest upstream
One check moved from networking_linux.go to networking_common.go.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-24 00:00:32 +02:00
Stefano Brivio
85de88ff31 test/passt.mbuto: Don't fail on missing guest public key
We won't necessarily run mbuto as part of regular tests: it can also
be used for demos or out-of-tree tests.

To keep the profile simple, leave the whole sshd setup there, which
is otherwise harmless, but don't fail if guest-key.pub is missing in
the current directory.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-23 17:55:10 +02:00
Stefano Brivio
d6f865a40a test/distro: Update workarounds for Ubuntu 22.04 on s390x
If we use dhclient without creating a complete network configuration,
systemd-resolved will stop working after a while, and this sometimes
happens while we're still installing packages.

Disable it, together with systemd-networkd, while taking care of
removing the dhclient hook that prevents overriding /etc/resolv.conf.

While at it, it looks like removing snapd and needrestart actually
takes more time than keeping them: drop that line.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-23 02:46:24 +02:00
Stefano Brivio
cff565a1f6 test/lib: Wait for DHCPv4 before starting DHCPv6 client in two_guests test
I'm not sure why, but dhclient hangs otherwise. This reflects what we
do in the passt_in_ns setup steps.

Eventually, this whole block could go away if we let pasta configure
this network namespace with --config-net.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-23 02:46:24 +02:00
Stefano Brivio
1134ce88fe test/perf: Wait for neper servers in guest to be ready before starting client
Starting tcp_rr, tcp_crr, udp_rr servers in the guest takes a bit
longer than starting the corresponding clients on the host, and we
end up starting clients before servers unless we add a delay there.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-23 02:46:24 +02:00
Stefano Brivio
d1dbc4f992 test/lib: Wait for kernel to free up ports used by iperf3 before reusing them
If we start another server on the same port right away, we might fail
to bind the port. A small delay appears to be needed -- I'm not
entirely sure why at this point.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:54:09 +02:00
Stefano Brivio
856b04490a test/lib: Run also iperf3 clients in background, revert to time-based wait
Unfortunately, this partially counters recent efforts by David to
speed up these tests, but it looks like iperf3 clients don't reliably
terminate, in some rare cases I couldn't isolate yet.

For the moment being, reintroduce the time-based wait approach, now
using the configurable test duration, and terminate the servers at
the end of it, in case they're stuck. There's no point in keeping
the 'sleep 2' later, so drop that, and while at it, make sure that
the stuck servers have time to flush the JSON output before we use
it.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:54:09 +02:00
Stefano Brivio
df29ebfe02 test/perf: Disable periodic throughput reports to avoid vhost hang
It appears that if we run throughput tests with one-second periodic
reports, the sending side of the vhost channel used for SSH-based
command dispatch occasionally stops working altogether. I haven't
investigated this further, all I see is that output is truncated
at some point, and doesn't resume.

If we use gzip compression (ssh -C) this happens less frequently,
but it still happens, seemingly indicating the issue is probably
related to vhost itself.

Disable periodic reports in iperf3 clients. The -i options were
actually redundant, so remove them from both test files as well as
from test_iperf3().

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:54:09 +02:00
Stefano Brivio
9f8b783d4a test/lib: Wait on iperf3 clients to be done, then send SIGINT to servers
An iperf3 client might fail to send the control message indicating
the end of the test, if the kernel buffer doesn't accept it, and exit
without having sent it, as the control socket is non-blocking. Should
this happen, the server will just wait forever for this message,
instead of terminating.

Restore some of the behaviour that went away with the
"test: Rewrite test_iperf3" patch: instead of waiting on servers to
terminate, wait on the clients. When they are done, wait 2 seconds,
and then send SIGINT to the servers, which make them still write
out the JSON report before terminating.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:54:09 +02:00
Stefano Brivio
119bb265a3 test/lib: Restore IFS while executing directives in def blocks
If we don't, guest command dispatch will fail altogether, given that
we use cat(1) on the enter file, which contains spaces.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:54:09 +02:00
Stefano Brivio
4a1b675278 conf, tcp, udp: Arrays for ports need 2^16 values, not 2^16-8
Reported by David but also by Coverity (CWE-119):

	In conf_ports: Out-of-bounds access to a buffer

...not in practice, because the allocation size is rounded up
anyway, but not nice either.

Reported-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:54:09 +02:00
Stefano Brivio
d30bde3181 tap: Check return value of accept4() before calling getsockopt()
Reported by Coverity (CWE-119):

	Negative value used as argument to a function expecting a
	positive value (for example, size of buffer or allocation)

and harmless, because getsockopt() would return -EBADF if the
socket is -1, so we wouldn't print anything.

Check if accept4() returns a valid socket before calling getsockopt()
on it.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-22 16:54:01 +02:00
Stefano Brivio
a39398e840 test/perf: Switch performance test duration to 10 seconds instead of 30
It looks like the workaround for the virtio_net TX hang issue is
working less reliably with the new command dispatch mechanism, I'm
not sure why. Switch to 10 seconds, at least for the moment.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-22 16:53:55 +02:00
Stefano Brivio
df3a35c203 test/perf: Always use /sbin/sysctl in tcp test
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-22 16:53:35 +02:00
Stefano Brivio
47d424d083 README: Update Availability and Try It sections with new packages
We now have official packages for Fedora, unofficial (Fedora Copr)
for other common RPM-based distributions, and the existing
packages with static builds for Debian, and for other RPM-based
distributions.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:53:35 +02:00
Stefano Brivio
fafdda083f test/passt_in_ns: Consistent sleep commands before starting socat client
There are some 'sleep 1' commands between starting the socat server
and its corresponding client to avoid races due to the server not
being ready as we start sending data.

However, those don't cover all the cases where we might need them,
and in some cases the sleep command actually ended up being before
the server even starts.

This fixes occasional failures in TCP and UDP simple transfer tests,
that became apparent with the new command dispatch mechanism.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:53:35 +02:00
Stefano Brivio
ae51d2dac1 test/perf: Check for /sbin/sysctl with which(1), not simply sysctl
Otherwise, we're depending on having /sbin in $PATH. For some reason
I didn't completely grasp, with the new command dispatch mechanism
that's not the case anymore, even if I have /sbin in $PATH in the
parent shell.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-22 16:53:35 +02:00
Stefano Brivio
8627a2da52 doc/demo: Clone and use mbuto in init namespace
...and not in pasta's namespace: the fakeroot(1) version shipping
with (at least) Fedora 36 assumes "nested" operation as it sees that
the UID is 0, and claims it's not supported.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:53:35 +02:00
Stefano Brivio
efd9d9b456 doc/demo: Drop /sbin from dhclient command, pass script file explicitly
dhclient might be in /usr/sbin on recent versions of Fedora, and
mbuto just adds it to the same location as it was on the host:
just call dhclient instead of /sbin/dhclient.

This also applies for dhclient-script: given that we create the file
on boot, pass its explicit location with -sf.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-22 16:53:35 +02:00
Stefano Brivio
6655625c30 Makefile: Include seccomp.h in HEADERS and require it for static checkers
Targets running static checkers (cppcheck and clang-tidy) need
seccomp.h, but the latter is not included in HEADERS. Add it.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-22 16:53:35 +02:00
Stefano Brivio
512f5b1aab Makefile: Allow define overrides by prepending, not appending, CFLAGS
If we append CFLAGS to the ones passed via command line (if any),
-D options we append will override -D options passed on command line
(if any).

For example, OpenSUSE build flags include -D_FORTIFY_SOURCE=3, and we
want to have -D_FORTIFY_SOURCE=2, if and only if not overridden. The
current behaviour implies we redefine _FORTIFY_SOURCE as 2, though.

Instead of appending CFLAGS, prepend them by adding all the default
build flags to another variable, a simply expanded one (defined with
:=), named FLAGS, and pass that *before* CFLAGS in targets, so that
defines from command line can override default flags.

Reported-by: Dario Faggioli <dfaggioli@suse.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Tested-by: Dario Faggioli <dfaggioli@suse.com>
2022-09-22 16:53:09 +02:00
Stefano Brivio
b323e5f439 test: term: When checking if status line is a number, hide errors
We use the [ "$x" -eq "$x" ] syntax to check if $x is a number. The
behaviour is clearly implied by POSIX, but some shells might actually
report the (intended) error, and dash floods script.log with
"Illegal number" error messages. Hide them.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-14 20:49:08 +02:00
David Gibson
9fc476af6e test: Simpler termination handling for UDP tests
Because UDP is connectionless we don't have an in-built end-of-stream
signal for our connectivity tests.  We work around this by explicitly
adding an end marker to our sample data and killing the listening end once
it is seen.

However, socat has some built-in options - null-eof and shut-null - which
can be used to signal the end of stream with a zero-length UDP packet.
Use these to simplify how the UDP tests are implemented.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-13 11:14:29 +02:00
David Gibson
af9c98af5f udp: Don't drop zero-length outbound UDP packets
udp_tap_handler() currently skips outbound packets if they have a payload
length of zero.  This is not correct, since in a datagram protocol zero
length packets still have meaning.

Adjust this to correctly forward the zero-length packets by using a msghdr
with msg_iovlen == 0.

Bugzilla: https://bugs.passt.top/show_bug.cgi?id=19

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-13 11:14:29 +02:00
David Gibson
484652c632 udp: Don't pre-initialize msghdr array
In udp_tap_handler() the array of msghdr structures, mm[], is initialized
to zero.  Since UIO_MAXIOV is 1024, this can be quite a large zero, which
is expensive if we only end up using a few of its entries.  It also makes
it less obvious how we're setting all the control fields at the point we
actually invoke sendmmsg().

Rather than pre-initializing it, just initialize each element as we use it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-13 11:14:29 +02:00
David Gibson
6f2db0e34b test: Move perf.js report file to $LOGDIR/web
The tests generate a performance report in $BASEPATH/perf.js and
hooks/pre-push copies it to the website.  To avoid cluttering the working
directory, instead put perf.js in $LOGDIR/web, since it's a test output
artefact.  Update hooks/pre-push to copy from its new location.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-13 11:12:41 +02:00
David Gibson
4e9b50f7b6 test: Move video processing files to $STATEBASE
The asciinema video handling creates a number of temporary files (.uncat,
.start, .stop) which currently go into the source tree.  Put them in the
temporary state directory to avoid clutter.

The final processed output is now placed into test_logs/web/ along with the
corresponding .js file with links, since they're essentially test
artefacts.  hooks/pre-push is updated to look for those files in the new
location when updating the web site.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-13 11:12:41 +02:00
David Gibson
ec6af08ca7 demo: Move pidfiles to state directory
Avoiding putting them in bare /tmp means they will be automatically
cleaned up with everything else.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-13 11:12:41 +02:00
David Gibson
d813660107 test: Move pidfiles and nsholder sockets into state directory
Currently they go in the passt source tree with a fixed names, which means
their presence can mess with subsequent test runs.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-13 11:12:41 +02:00
David Gibson
b23adf7132 test: Store pcap files in $LOGDIR instead of /tmp
The capture files are more or less a different form of log output from the
tests, so place them in $LOGDIR.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2022-09-13 11:12:41 +02:00