aboutgitcodebugslistschat
path: root/Makefile
Commit message (Collapse)AuthorAgeFilesLines
* cppcheck: Add target specific headersDavid Gibson2022-09-291-1/+1
| | | | | | | | | Debian and similar distros put target specific header files in /usr/include/<arch-vendor-os>, rather than directly in /usr/include. Add this directory to the includes for cppcheck so it can find them. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Simplify getting target triple for compilerDavid Gibson2022-09-291-2/+2
| | | | | | | | | | We do some manipulation of the output of cc -v to get the target triple for the platform, to locate headers for cppcheck. However, we can get this more easily with cc -dumpmachine - and in fact we do so elsewhere in the Makefile. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* cppcheck: Run quietlyDavid Gibson2022-09-291-1/+1
| | | | | | | | Adding the --quiet option to cppcheck makes the actual errors and warnings easier to find. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* cppcheck: Avoid excessive scanning due to system headersDavid Gibson2022-09-291-14/+6
| | | | | | | | | | | | | | | | | make cppcheck takes a long time, because it checks a large number of different configurations. It's assembling this very large set of configurations not because of conditionals in the passt code itself, but from those in the system headers. By adding --config-exclude directives to stop considering those configs, make cppcheck becomes around 60x faster on my system. Similarly, any problems that are found in the system headers are not our problem, and so we can uniformly suppress them, rather than having specific suppressions for particular problems in particular files (which might not be correct for all different distro / version combinations either). Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* clang-tidy: Disable 'readability-identifier-length'David Gibson2022-09-291-1/+6
| | | | | | | | This check complains about any identifier of less than 3 characters. For locals and parameters this is often pointlessly verbose. Disable it. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Improve types and names for port forwarding configurationDavid Gibson2022-09-241-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Fix the name of the qemu-system-* executableVasiliy Ulyanov2022-09-241-4/+4
| | | | | | | | | | | | | | | 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>
* Makefile: Include seccomp.h in HEADERS and require it for static checkersStefano Brivio2022-09-221-3/+3
| | | | | | | | 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>
* Makefile: Allow define overrides by prepending, not appending, CFLAGSStefano Brivio2022-09-221-24/+25
| | | | | | | | | | | | | | | | | | | 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>
* Move self-isolation code into a separate fileDavid Gibson2022-09-131-4/+4
| | | | | | | | passt/pasta contains a number of routines designed to isolate passt from the rest of the system for security. These are spread through util.c and passt.c. Move them together into a new isolation.c file. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Honour LDFLAGS for binary targetsStefano Brivio2022-09-071-3/+3
| | | | | | | | | | | | | We don't set any, but we should use them if they are passed in the environment. On a Fedora Rawhide package build, annocheck (https://sourceware.org/annobin/) reports: Hardened: /usr/bin/passt: FAIL: bind-now test because not linked with -Wl,-z,now ...despite the build system exporting -Wl,-z,now in LDFLAGS. Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Use more GNU-style directory variables, explicit docdir for OpenSUSE2022_08_21.7b71094Stefano Brivio2022-08-211-11/+17
| | | | | | | | | | | | | It turns out that, while on most distributions "docdir" would be /usr/share/doc, it's /usr/share/doc/packages/ on OpenSUSE Tumbleweed. Use an explicit docdir as shown in: https://en.opensuse.org/openSUSE:Build_Service_cross_distribution_howto and don't unnecessarily hardcode directory variables in the Makefile. Otherwise, RPM builds for OpenSUSE will fail now that we have a README there. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Install demo.sh too, uninstall stuff under /usr/shareStefano Brivio2022-08-201-0/+4
| | | | | Suggested-by: Benson Muite <benson_muite@emailplus.org> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Ugly hack to get a "plain" Markdown version of READMEStefano Brivio2022-08-201-3/+27
| | | | | | | | | | | | | | | | | | Distribution packages reasonably expect to have a human-readable Markdown version of the README under /usr/share/doc/, but all we have right now is a heavily web-oriented version. Introduce a ugly hack to strip web-oriented parts from the current README and install it. It should probably work the other way around: a human-readable README could be used as a source for the web page. But cgit needs a file that's in the tree, not something that can be built, and https://passt.top/ is based on cgit. It should eventually be doable to work around this in cgit, instead. Reported-by: Benson Muite <benson_muite@emailplus.org> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* valgrind needs futexDavid Gibson2022-07-221-1/+1
| | | | | | | | | Some versions of valgrind (such as the version on my Fedora laptop - valgrind-3.19.0-3.fc36.x86_64) use futexes. But futex is currently not allowed in the seccomp filter, even with the extra calls added for valgrind builds. Add it, to avoid spurious valgrind failures. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* passt: Allow exit_group() system call in seccomp profilesStefano Brivio2022-07-141-1/+1
| | | | | | | | | | | | We handle SIGQUIT and SIGTERM calling exit(), which is usually implemented with the exit_group() system call. If we don't allow exit_group(), we'll get a SIGSYS while handling SIGQUIT and SIGTERM, which means a misleading non-zero exit code. Reported-by: Wenli Quan <wquan@redhat.com> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2101990 Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Clean up passt.pid fileDavid Gibson2022-07-141-1/+2
| | | | | | | | If the tests are interrupted at the right point a passt.pid file can be left over. Clean it up with "make clean" and add it to .gitignore so it doesn't get accidentally committed. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Add cleaner line-by-line reading primitivesDavid Gibson2022-07-061-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Two places in passt need to read files line by line (one parsing resolv.conf, the other parsing /proc/net/*. They can't use fgets() because in glibc that can allocate memory. Instead they use an implementation line_read() in util.c. This has some problems: * It has two completely separate modes of operation, one buffering and one not, the relation between these and how they're activated is subtle and confusing * At least in non-buffered mode, it will mishandle an empty line, folding them onto the start of the next non-empty line * In non-buffered mode it will use lseek() which prevents using this on non-regular files (we don't need that at present, but it's a surprising limitation) * It has a lot of difficult to read pointer mangling Add a new cleaner implementation of allocation-free line-by-line reading in lineread.c. This one always buffers, using a state structure to keep track of what we need. This is larger than I'd like, but it turns out handling all the edge cases of line-by-line reading in C is surprisingly hard. This just adds the code, subsequent patches will change the existing users of line_read() to the new implementation. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Don't create extraneous -.s fileDavid Gibson2022-06-181-1/+1
| | | | | | | | | | In order to probe availability of certain features the Makefile test compiles a handful of tiny snippets, feeding those in from stdin. However in one case - the one for -fstack-protector - it forgets to redirect the output to stdout, meaning it creates a stray '-.s' file when make is invoked (even make clean). Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Tweak $(RM) usageDavid Gibson2022-06-181-3/+3
| | | | | | | | | | | The use of rm commands in the clean and uninstall targets adds an explicit leading - to ignore errors. However the built-in RM variable in make is actually "rm -f" which already ignores errors, so the - isn't neccessary. Also replace ${RM} with $(RM) which is the more conventional form in Makefiles. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Simplify pasta* targets with a pattern ruleDavid Gibson2022-06-181-8/+2
| | | | | | | | pasta, pasta.avx2 and pasta.1 are all generated as a link to the corresponding passt file. We can consolidate the 3 rules for these targets into a single pattern rule. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Use $(BIN) and $(MANPAGES) variable to simplify several targetsDavid Gibson2022-06-181-14/+12
| | | | | | | | | | | | | | There are several places which explicitly list the various generated binaries, even though a $(BIN) variable already lists them. There are several more places that list all the manpage files, introduce a $(MANPAGES) variable to remove that repetition as well. Tweak the generation of pasta.1 as a link to passt.1 so it's not just made as a side effect of the pasta target. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> [sbrivio: add passt.1 and qrap.1 to guest files for distro tests] Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Avoid using wildcard sourcesDavid Gibson2022-06-181-15/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | The passt/pasta Makefile makes fairly heavy use of GNU make's $(wildcard) function to locate the sources and headers to build. Using wildcards for the things to compile is usually a bad idea though: if somehow you end up with a .c or .h file in your tree you didn't expect it can misbuild in an exceedingly confusing way. In particular this can sometimes happen if switching between releases / branches where files have been added or removed without 100% cleaning the tree. It also makes life a bit complicated if building multiple different binaries in the same tree: we already have some rather awkward $(filter-out) constructions to avoid including qrap.c in the passt build. Replace use of $(wildcard) with the more idiomatic approach of defining variables listing all the relevant source files then using that throughout. In the rule for seccomp.h there was also a bare "*.c" which caused make to always rebuild that target. Fix that as well. Similarly, seccomp.sh uses a wildcard to locate the sources, which is unwise for the same reasons. Make it take the sources to examine on the command line instead, and have the Makefile pass them in from the same variables. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Suppress unusedStructMember Cppcheck warning in dhcp.cStefano Brivio2022-06-181-0/+2
| | | | | | | | | | | | | | | New from Cppcheck 2.8: all the fields of struct msg that are not directly manipulated are now reported as unused, which is kind of correct as those fields are used as a blob "copied" from request to response and not as separate fields. However, keeping the message composition explicit is probably desirable, and adding inline suppressions makes the whole thing rather unreadable, so just suppress unusedStructMember warnings for dhcp.c, while also adding a suppression for unmatched suppressions to keep earlier versions of Cppcheck happy. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Allow implicit test for bugprone-suspicious-string-compare checkerStefano Brivio2022-03-291-4/+1
| | | | Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* treewide: Fix android-cloexec-* clang-tidy warnings, re-enable checksStefano Brivio2022-03-291-9/+0
| | | | Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* test, seccomp, Makefile: Switch to valgrind runs for passt functional testsStefano Brivio2022-03-291-1/+7
| | | | | | | | | | | | | | Pass to seccomp.sh a list of additional syscalls valgrind needs as EXTRA_SYSCALLS in a new 'valgrind' make target, and add corresponding support in seccomp.sh itself. In test setup functions, start passt with valgrind, but not for performance tests. Add tests checking that valgrind exits without errors after all the other tests in the group are done. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Enable a few hardening flagsStefano Brivio2022-03-281-2/+8
| | | | | | | They don't have a measurable performance impact and make things a bit safer. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile, hooks: Static target precondition for pkgs, copy .avx2 buildsStefano Brivio2022-03-011-1/+1
| | | | | | Convenience packages are anyway built from static builds. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* passt, pasta: Run-time selection of AVX2 buildStefano Brivio2022-02-281-10/+28
| | | | | | | | | | | | | Build-time selection of AVX2 flags and routines is not practical for distributions, but limiting AVX2 usage to checksum routines with specific run-time detection doesn't allow for easy performance gains from auto-vectorisation of batched packet handling routines. For x86_64, build non-AVX2 and AVX2 binaries, and implement a simple wrapper replacing the current executable with the AVX2 build if it's available, and if AVX2 is supported by the current CPU. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Fix up AUDIT_ARCH for armv6l, armv7lStefano Brivio2022-02-261-0/+1
| | | | | | | There's a single AUDIT_ARCH_ARM define available (and big-endian shouldn't be a concern with those). Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* pasta: By default, quit if filesystem-bound net namespace goes awayStefano Brivio2022-02-211-1/+2
| | | | | | | | | | | | This should be convenient for users managing filesystem-bound network namespaces: monitor the base directory of the namespace and exit if the namespace given as PATH or NAME target is deleted. We can't add an inotify watch directly on the namespace directory, that won't work with nsfs. Add an option to disable this behaviour, --no-netns-quit. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile, conf, passt: Drop passt4netns references, explicit argc checkStefano Brivio2022-02-211-5/+2
| | | | | | | | | | | Nobody currently calls this as passt4netns, that was the name I used before 'pasta', drop any reference before it's too late. While at it, explicitly check that argc is bigger than or equal to one, just as a defensive measure: argv[0] being NULL is not an issue anyway. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* passt: Address new clang-tidy warnings from LLVM 13.0.1Stefano Brivio2022-01-301-1/+23
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* tcp, netlink, HAS{BYTES_ACKED,MIN_RTT,GETRANDOM} and NETLINK_GET_STRICT_CHKStefano Brivio2022-01-261-0/+15
| | | | | | | | | | | | | | | | tcpi_bytes_acked and tcpi_min_rtt are only available on recent kernel versions: provide fall-back paths (incurring some grade of performance penalty). Support for getrandom() was introduced in Linux 3.17 and glibc 2.25: provide an alternate mechanism for that as well, reading from /dev/random. Also check if NETLINK_GET_STRICT_CHK is defined before using it: it's not strictly needed, we'll filter out irrelevant results from netlink anyway. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile, seccomp: Fix build for i386, ppc64, ppc64leStefano Brivio2022-01-261-2/+12
| | | | | | | | | | | | | | | | | On some distributions, on ppc64, ulimit -s returns 'unlimited': add a reasonable default, and also make sure ulimit is invoked using the default shell, which should ensure ulimit is actually implemented. Also note that AUDIT_ARCH doesn't follow closely the naming reported by 'uname -m': convert for i386 and ppc as needed. While at it, move inclusion of seccomp.h after util.h, the former is less generic (cosmetic/clang-tidy only). Older kernel headers might lack a definition for AUDIT_ARCH_PPC64LE: define that explicitly if it's not available. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: cppcheck target: Suppress unmatchedSuppression, pass CFLAGSStefano Brivio2021-10-211-3/+16
| | | | | | | | | | Some of those warnings don't trigger even on systems with very similar toolchains, suppress unmatchedSuppression warnings, they're basically useless. While at it, pass CFLAGS to cppcheck. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* passt: Add cppcheck target, test, and address resulting warningsStefano Brivio2021-10-211-1/+31
| | | | | | | ...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>
* passt: Fix build with gcc 7, use std=c99, enable some more Clang checkersStefano Brivio2021-10-211-5/+1
| | | | | | | | | | | | | | 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>
* Makefile, tcp: Don't try to use tcpi_snd_wnd from tcp_info on pre-5.3 kernelsStefano Brivio2021-10-211-0/+5
| | | | | | | Detect missing tcpi_snd_wnd in struct tcp_info at build time, otherwise build fails with a pre-5.3 linux/tcp.h header. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* passt: Add clang-tidy Makefile target and test, take care of warningsStefano Brivio2021-10-201-0/+75
| | | | | | | Most are just about style and form, but a few were actually serious mistakes (NDP-related). Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* passt: Address gcc 11 warningsStefano Brivio2021-10-201-0/+14
| | | | | | | | | A mix of unchecked return values, a missing permission mask for open(2) with O_CREAT, and some false positives from -Wstringop-overflow and -Wmaybe-uninitialized. Reported-by: Martin Hauke <mardnh@gmx.de> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* LICENSES: Add license text files, add missing notices, fix SPDX tagsStefano Brivio2021-10-201-0/+11
| | | | | | | | | | SPDX tags don't replace license files. Some notices were missing and some tags were not according to the SPDX specification, too. Now reuse --lint from the REUSE tool (https://reuse.software/) passes. Reported-by: Martin Hauke <mardnh@gmx.de> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Install man pages to /usr/share/man instead of /usr/manStefano Brivio2021-10-201-5/+5
| | | | | Reported-by: Martin Hauke <mardnh@gmx.de> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Prefix installation paths with $(DESTDIR)Stefano Brivio2021-10-191-9/+9
| | | | | | | | | Martin reports that DESTDIR is ignored in install/uninstall targets, see also: https://www.gnu.org/prep/standards/html_node/DESTDIR.html Reported-by: Martin Hauke <mardnh@gmx.de> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* passt: Static builds: don't redefine __vsyslog(), skip getpwnam() and ↵Stefano Brivio2021-10-161-1/+1
| | | | | | initgroups() Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* passt, pasta: Add seccomp supportStefano Brivio2021-10-141-9/+8
| | | | | | | | | | | | | | | | | | List of allowed syscalls comes from comments in the form: #syscalls <list> for syscalls needed both in passt and pasta mode, and: #syscalls:pasta <list> #syscalls:passt <list> for syscalls specifically needed in pasta or passt mode only. seccomp.sh builds a list of BPF statements from those comments, prefixed by a binary search tree to keep lookup fast. While at it, clean up a bit the Makefile using wildcards. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* conf, tap: Split netlink and pasta functions, allow interface configurationStefano Brivio2021-10-141-4/+5
| | | | | | | | | | Move netlink routines to their own file, and use netlink to configure or fetch all the information we need, except for the TUNSETIFF ioctl. Move pasta-specific functions to their own file as well, add parameters and calls to configure the tap interface in the namespace. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* pasta: Allow specifying paths and names of namespacesGiuseppe Scrivano2021-10-071-0/+1
| | | | | | | | | | | | | | | | | | Based on a patch from Giuseppe Scrivano, this adds the ability to: - specify paths and names of target namespaces to join, instead of a PID, also for user namespaces, with --userns - request to join or create a network namespace only, without entering or creating a user namespace, with --netns-only - specify the base directory for netns mountpoints, with --nsrun-dir Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> [sbrivio: reworked logic to actually join the given namespaces when they're not created, implemented --netns-only and --nsrun-dir, updated pasta demo script and man page] Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* passt: Align pkt_buf to PAGE_SIZE (start and size), try to fit in huge pagesStefano Brivio2021-09-271-0/+1
| | | | | | | | | 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>