Commit graph

42 commits

Author SHA1 Message Date
Laurent Vivier
324bd46782 util: move IP stuff from util.[ch] to ip.[ch]
Introduce ip.[ch] file to encapsulate IP protocol handling functions and
structures.  Modify various files to include the new header ip.h when
it's needed.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Message-ID: <20240303135114.1023026-5-lvivier@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2024-03-06 08:03:38 +01:00
David Gibson
a179ca6707 treewide: Make a bunch of pointer variables pointers to const
Sufficiently recent cppcheck (I'm using 2.13.0) seems to have added another
warning for pointer variables which could be pointer to const but aren't.
Use this to make a bunch of variables const pointers where they previously
weren't for no particular reason.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2024-01-16 21:49:27 +01:00
Stefano Brivio
ca2749e1bd passt: Relicense to GPL 2.0, or any later version
In practical terms, passt doesn't benefit from the additional
protection offered by the AGPL over the GPL, because it's not
suitable to be executed over a computer network.

Further, restricting the distribution under the version 3 of the GPL
wouldn't provide any practical advantage either, as long as the passt
codebase is concerned, and might cause unnecessary compatibility
dilemmas.

Change licensing terms to the GNU General Public License Version 2,
or any later version, with written permission from all current and
past contributors, namely: myself, David Gibson, Laine Stump, Andrea
Bolognani, Paul Holzinger, Richard W.M. Jones, Chris Kuhn, Florian
Weimer, Giuseppe Scrivano, Stefan Hajnoczi, and Vasiliy Ulyanov.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2023-04-06 18:00:33 +02:00
Andrea Bolognani
0d547a5b0f qrap: Generate -netdev as JSON
While generating -device as JSON when JSON is in use is
mandatory, because not doing so can often prevent the VM from
starting up, using JSON for -netdev simply makes things a bit
nicer. No reason not to do it, though.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2023-02-27 18:56:29 +01:00
Andrea Bolognani
4f2341f31d qrap: Introduce machine-specific PCI address base
For pc machines, devices are placed directly on pci.0 with
addresses like

  bus=pci.0,addr=0xa

and in this case the existing code works correctly.

For q35 machines, however, a separate PCI bus is created for
each devices using a pcie-root-port, and the resulting
addresses look like

  bus=pci.9,addr=0x0

In this case, we need to treat PCI addresses as decimal, not
hexadecimal, both when parsing and generating them.

This issue has gone unnoticed for a long time because it only
shows up when enough PCI devices are present: for small
numbers, decimal and hexadecimal overlap, masking the issue.

Reported-by: Alona Paz <alkaplan@redhat.com>
Fixes: 5307faa059 ("qrap: Strip network devices from command line, set them up according to machine")
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2023-02-27 18:56:24 +01:00
Andrea Bolognani
8828a637ba qrap: Drop args in JSON format
When JSON support was introduced, the drop_args array has
not been updated accordingly.

Fixes: b944ca1855 ("qrap: Support JSON syntax for -device")
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2023-02-27 18:56:22 +01:00
Andrea Bolognani
16f19c87f5 qrap: Fix support for pc machines
The JSON version of the template is incorrect, making qrap
completely unusable when JSON arguments are used together
with the pc machine type.

Fixes: b944ca1855 ("qrap: Support JSON syntax for -device")
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2023-02-27 18:56:20 +01:00
Andrea Bolognani
9cec4309c9 qrap: Fix limits for PCI addresses
The pci.0 bus on a pc machine has 32 slots.

For q35 machines, we don't expect devices to be plugged into
pcie.0 directly, so technically we could have a very large
number of slots by adding many pcie-root-ports, but even in
this scenario 32 is a reasonable number.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2023-02-27 18:56:07 +01:00
Stefano Brivio
11efaefa1e passt, qrap, README: Update notes and documentation for AF_UNIX support in qemu
We can't get rid of qrap quite yet, but at least we should start
telling users it's not going to be needed anymore starting from qemu
7.2.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-11-04 12:04:32 +01:00
Andrea Bolognani
b944ca1855 qrap: Support JSON syntax for -device
Starting with version 8.1.0, libvirt uses JSON syntax when
generating the arguments to -device, so they will now look like

  {"driver":"virtio-scsi-pci","bus":"pci.3","addr":"0x0"}

instead of

  virtio-scsi-pci,bus=pci.3,addr=0x0

qrap needs to parse these arguments and extract the bus number
in order to figure out what address to use for the virtio-net
device it adds, and the libvirt change described above has
broken this parsing logic.

Tweak the code so that both styles are accepted and handled
correctly.

Note that, when JSON is in use, qrap needs to generate its own
command line options in that format as well or things will not
work as expected.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-10-21 11:43:45 +02:00
David Gibson
740ea28f29 qrap: Handle case of PATH environment variable being unset
clang-tidy warns that in passing getenv("PATH") to strncpy() we could be
passing a NULL pointer.  While it's unusual for PATH to be unset, it's not
impossible and this would indeed cause getenv() to return NULL.

Handle this case by never recognizing argv[2] as a qemu binary name if
PATH is not set.  This is... no flakier than the detection of whether
it's a binary name already is.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-29 12:22:28 +02:00
David Gibson
6aca100469 cppcheck: Use inline suppressions for qrap.c
qrap.c uses several old-fashioned functions that cppcheck complains about.
Since it's headed for obselesence anyway, just suppress these rather than
attempting to modernize the code.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-29 12:22:17 +02:00
David Gibson
a668d87e7e Don't shadow global function names
cppcheck points out that qrap's main shadows the global err() function with
a local.  Rename it to rc to avoid the clash.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-09-29 12:22:07 +02:00
Stefano Brivio
9af2e5d5fc qrap: Add a neighbour solicitation to probe frames, instead of just ARP
For a while now, passt disables ARP functionality completely if IPv4
is disabled. If qrap sends an ARP request as a probe in that case, it
will receive no answer and move on, trying to find another instance.

Add a second probe frame, a hardcoded neighbour solicitation, so that
we get a neighbour advertisement if IPv6 is enabled.

Without this change, IPv6-only operation is completely broken.

Reported-by: Wenli Quan <wquan@redhat.com>
Reported-by: Alona Paz <alkaplan@redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2106257
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-07-20 18:19:57 +02:00
Stefano Brivio
27aec5911a qrap: Don't rely on errno after perror(), and reset it before usage
In commit fca5e11773 ("qrap: Add probe retry on connection reset
from passt for KubeVirt integration") I just used errno to check if
the connection was reset on recv(), but perror() might set it to
EINVAL if e.g. an underlying logging mechanism fails, so we won't
actually catch the connection reset.

And in case recv() returns 0, errno won't be set, but we're still
using it without resetting it first, which leads to unpredictable
results in that case.

Reset errno before probing with connect(), send() and recv(), and
save it for later checks before calling perror().

Fixes: fca5e11773 ("qrap: Add probe retry on connection reset from passt for KubeVirt integration")
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-07-06 08:10:55 +02:00
Stefano Brivio
2757d3c0b6 qrap: Increase number of retries on connection reset even further
...if there are two or more instances of libvirt in a KubeVirt
scenario using a number of instances of passt, the overlap period
with probing instances of qemu becomes much longer. Switch to 50
retries instead of 5.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-06-27 15:05:45 +02:00
Stefano Brivio
ad6a00e9e6 qrap: Change number of retries and delay on connection reset
One retry after 100ms was enough for static builds, where qrap
takes a while to start, but it's sometimes not enough with
regular builds. Switch that to five retries with 50ms delay.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-06-27 12:11:07 +02:00
Stefano Brivio
fca5e11773 qrap: Add probe retry on connection reset from passt for KubeVirt integration
KubeVirt uses libvirt to start qrap in its current draft integration
(https://github.com/kubevirt/kubevirt/pull/7849/), and libvirtd
starts qrap three times every time a new virtual machine is created:
once on domain creation, and twice on domain start (for "probing")
and to finally start it for real.

Very often, a subsequent invocation of qrap happen before the
previously running instance of qemu terminates, which means that
passt will refuse the new connection as the old one is still active.

Introduce a single retry with a 100ms delay to work around this. This
should be checked again once native libvirt support is there, and
that point qrap will have no reason to exist anymore.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-06-18 09:06:00 +02:00
Stefano Brivio
eb3d3f367e treewide: Argument cannot be negative, CWE-687
Actually harmless. Reported by Coverity.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-04-07 11:44:35 +02:00
Stefano Brivio
22ed4467a4 treewide: Unchecked return value from library, CWE-252
All instances were harmless, but it might be useful to have some
debug messages here and there. Reported by Coverity.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-04-07 11:44:35 +02:00
Stefano Brivio
292c185553 passt: Address new clang-tidy warnings from LLVM 13.0.1
clang-tidy from LLVM 13.0.1 reports some new warnings from these
checkers:

- altera-unroll-loops, altera-id-dependent-backward-branch: ignore
  for the moment being, add a TODO item

- bugprone-easily-swappable-parameters: ignore, nothing to do about
  those

- readability-function-cognitive-complexity: ignore for the moment
  being, add a TODO item

- altera-struct-pack-align: ignore, alignment is forced in protocol
  headers

- concurrency-mt-unsafe: ignore for the moment being, add a TODO
  item

Fix bugprone-implicit-widening-of-multiplication-result warnings,
though, that's doable and they seem to make sense.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-01-30 02:59:12 +01:00
Stefano Brivio
b93c2c1713 passt: Drop <linux/ipv6.h> include, carry own ipv6hdr and opt_hdr definitions
This is the only remaining Linux-specific include -- drop it to avoid
clang-tidy warnings and to make code more portable.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-01-26 07:57:09 +01:00
Stefano Brivio
a620de294d qrap: Silence bogus clang-tidy bugprone-suspicious-missing-comma warning
This is actually a concatenation -- mark it with an extra pair
of parentheses.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-10-21 12:16:16 +02:00
Stefano Brivio
627e18fa8a passt: Add cppcheck target, test, and address resulting warnings
...mostly false positives, but a number of very relevant ones too,
in tcp_get_sndbuf(), tcp_conn_from_tap(), and siphash PREAMBLE().

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-10-21 09:41:13 +02:00
Stefano Brivio
dd942eaa48 passt: Fix build with gcc 7, use std=c99, enable some more Clang checkers
Unions and structs, you all have names now.

Take the chance to enable bugprone-reserved-identifier,
cert-dcl37-c, and cert-dcl51-cpp checkers in clang-tidy.

Provide a ffsl() weak declaration using gcc built-in.

Start reordering includes, but that's not enough for the
llvm-include-order checker yet.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-10-21 04:26:08 +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
04d62bb013 qrap: Drop debugging left-overs, enable timeout for connect() too
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-09 15:40:04 +02:00
Stefano Brivio
05432945bb qrap: Minor fixes in comments and usage message
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-01 17:00:27 +02:00
Stefano Brivio
1e49d194d0 passt, pasta: Introduce command-line options and port re-mapping
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-09-01 17:00:27 +02:00
Stefano Brivio
28fca04eb9 qrap: Skip pci.2 bus for pc-q35, add proper error reporting for probing
On pc-q35, pci.2 is usually configured by libvirt as a hotplug bus,
so we can't use address 0x0 there. Look for free busses starting from
pci.3 instead.

While at it, add proper error reporting for passt probing, and add
some comments to structs that were previously missing.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-07-17 08:28:38 +02:00
Stefano Brivio
ad4a85c860 qrap: Connect to the first available instance of passt, probe via ARP request
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 11:14:52 +02:00
Stefano Brivio
af243857fa qrap: Silence gcc -O3 warning about strncpy() buffer length
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 11:14:49 +02:00
Stefano Brivio
59182924f0 qrap: Also drop -device e1000e,... from qemu command line
As libvirt can pass e1000e (not just e1000) devices as well,
make sure we also drop those network devices from the command
line before adding the parameters we need.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 11:14:48 +02:00
Stefano Brivio
8358400b3f qrap: Lowest usable PCI bus number for pc-q35 is actually 1
...3 was a left-over from a test.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-12 16:20:56 +02:00
Stefano Brivio
5307faa059 qrap: Strip network devices from command line, set them up according to machine
The previous approach wasn't really robust: adding a -netdev option
without libvirt knowing could result in clashes with other devices.

Drop network devices from command line, check the available busses
and addresses from all -device options according to the -machine
parameter, and add a virtio-net device using an available address
or bus. Then, add a corresponding -netdev socket option.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-12 08:35:36 +02:00
Stefano Brivio
7503332a1e qrap: Adapt -net/-netdev command-line mangling to existing arguments
If a socket netdev parameter is already passed, don't touch the command
line. If it's not, add it, taking the id= reference from a netdev=
parameter, if any.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-11 17:08:15 +02:00
Stefano Brivio
f98e3589b4 qrap: Fix qemu name-guessing loop, add /usr/libexec/qemu-kvm as full path too
The name-guessing loop should iterate over names, not single
characters. Also add /usr/libexec/qemu-kvm as full path for
execvp(): execvp() won't find it if it's not in $PATH, which
is the reason why it shouldn't be under /usr/libexec/, but this
seems to be the case for some current version of Fedora.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-10 14:00:30 +02:00
Stefano Brivio
6f89dc3650 qrap: Find qemu command if not passed, patch command line
It might be impractical to pass options to qrap when using libvirt,
because the <emulator/> tag expects a path to an executable, without
further arguments.

If the first argument is not a plausible socket number, and the
second argument is not a valid executable, look up a qemu command
from a list of possible names, then start it patching the command line
to include the -netdev fd= parameter corresponding to the AF_UNIX
domain socket we just opened.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-10 12:38:50 +02:00
Stefano Brivio
105b916361 passt: New design and implementation with native Layer 4 sockets
This is a reimplementation, partially building on the earlier draft,
that uses L4 sockets (SOCK_DGRAM, SOCK_STREAM) instead of SOCK_RAW,
providing L4-L2 translation functionality without requiring any
security capability.

Conceptually, this follows the design presented at:
	https://gitlab.com/abologna/kubevirt-and-kvm/-/blob/master/Networking.md

The most significant novelty here comes from TCP and UDP translation
layers. In particular, the TCP state and translation logic follows
the intent of being minimalistic, without reimplementing a full TCP
stack in either direction, and synchronising as much as possible the
TCP dynamic and flows between guest and host kernel.

Another important introduction concerns addressing, port translation
and forwarding. The Layer 4 implementations now attempt to bind on
all unbound ports, in order to forward connections in a transparent
way.

While at it:
- the qemu 'tap' back-end can't be used as-is by qrap anymore,
  because of explicit checks now introduced in qemu to ensure that
  the corresponding file descriptor is actually a tap device. For
  this reason, qrap now operates on a 'socket' back-end type,
  accounting for and building the additional header reporting
  frame length

- provide a demo script that sets up namespaces, addresses and
  routes, and starts the daemon. A virtual machine started in the
  network namespace, wrapped by qrap, will now directly interface
  with passt and communicate using Layer 4 sockets provided by the
  host kernel.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-02-16 09:28:55 +01:00
Stefano Brivio
d02e059ddc passt: Add IPv6 and NDP support, further fixes for IPv4 CT
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-02-16 07:58:05 +01:00
Stefano Brivio
6709ade2bd merd: Rename to PASST
Plug A Simple Socket Transport.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-02-16 07:58:01 +01:00
Stefano Brivio
fa2d20908d merd: Switch to AF_UNIX for qemu tap, provide wrapper
We can bypass a full-fledged network interface between qemu and merd by
connecting the qemu tap file descriptor to a provided UNIX domain
socket: this could be implemented in qemu eventually, qrap covers this
meanwhile.

This also avoids the need for the AF_PACKET socket towards the guest.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-02-16 07:57:51 +01:00