Compare commits

..

13 Commits

Author SHA1 Message Date
Beniamino Galvani 8403c1a2a0 networkd: reduce the IPv4 DAD timeout to 200ms
The original timeout of 7 seconds is very long for today's networks. Reduce it
to 200ms. Note that this change also affects IPv4 link-local addressing.
2025-04-17 21:06:50 +02:00
Beniamino Galvani eee7aa41fc networkd: make the ACD timeout configurable
RFC 5227 specifies randomized intervals to avoid that a large number of hosts
powered up at the same time send their message simultaneously. Performing the
conflict detection takes a variable time between 4 and 7 seconds from the
beginning to the first announcement, as shown by the following diagram where P
indicates a probe and A an announcement:

 time(s)     0   1   2   3   4   5   6   7   8   9
             +---+---+---+---+---+---+---+---+---+
 SHORTEST    P   P   P       A       A
 LONGEST         P       P       P       A       A

The host can't use the address until the first announcement is sent. 7 seconds
is a very long time on modern computers especially considering the fact that
the round-trip time on current LAN technologies is at most few milliseconds.
Section 2.2 of the RFC addresses this matter and hints that a future standard
will adjust those timeouts; however that standard doesn't exist yet.

Make the timeout configurable via a new "IPv4DuplicateAddressDetectionTimeout"
option. The intervals defined in the RFC are then scaled proportionally so that
the duration of the conflict detection takes at most the given value. Interval
happening after the first announcement are not scaled, as recommended by the
RFC.
2025-04-17 21:06:50 +02:00
Beniamino Galvani c6c34be994 network/ipv4acd: check for IFF_NOARP before starting ACD
The IFF_NOARP flag indicates that ARP is disabled in kernel. It is
automatically set for those device that can't do ARP (and therefore can't do
ACD).

Technically, it's possible that an interface is ARP-capable but has IFF_NOARP
manually set to avoid using the protocol. In that case, it makes sense to
disable ACD as well because ACD would send ARP packets.
2025-04-17 20:39:23 +02:00
Daan De Meyer 710653d3bc test: Use meson add_test_setup() instead of environment variables
We add a default test setup that excludes the integration-tests suite
so that the integration tests don't run by default. This allows us to
get rid of $SYSTEMD_INTEGRATION_TESTS. Then, we add two extra setups:
'integration' and 'shell'. The 'integration' setup does not exclude the
integration-tests suite, and so can be used to run the integration tests.
The 'shell' setup does the same, but additionally sets $TEST_SHELL=1,
allowing to get rid of $TEST_SHELL in the docs.
2025-04-17 20:31:08 +02:00
Daan De Meyer d9826d303b mkosi: update mkosi commit reference to dbb4020beee2cdf250f93a425794f1cf8b0fe693
* dbb4020bee mkosi: Use tools tree by default in repository config
* a2407a305c dnf: Stop messing around with plugins
* eee382ebc6 Fix mkosi help
* 8d4f9969bb mkosi-obs: simplify generation of signed UEFI auth files
*   364dfc65eb Merge pull request #3661 from septatrix/ssh-runtime
|\
| * ab3b52841c Improve Ssh= documentation
| * 79878d7e6c Add new Ssh=auto and Ssh=runtime options
*   49036322c2 Merge pull request #3682 from DaanDeMeyer/history
|\
| * 96e512fe6e installer: Make sure package manager state is preserved in the image
| * b859a7cf0a Only copy repository metadata from specific subdirs from /var
| * c8bf8e4278 Rename cache_subdirs() to package_subdirs()
* |   54b59c4a2e Merge pull request #3696 from DaanDeMeyer/history-cli
|\ \
| * | 898d89e887 Rework version bumping
| * | cc45fe3bad Only write CLI arguments to history instead of full config
| * | 1def443097 Disallow using --rerun-build-scripts with --force again
| * | 87b03ee264 Rename get_configdir() to finalize_configdir()
| * | 9c1217a217 Get rid of to_json() methods on Args and Config
| |/
* | 124f551e77 mkosi-obs: do not publish roothash
* | fc86100e51 mkosi-obs: append certs from mkosi.uefi.db/ to 'db'
* | 8bee4cb8e2 Make sure sync scripts are executable
|/
* a7e90514fa Simplify tools tree out of date error
* f9956daba7 Fail if --rerun-build-scripts is used and tools is out of date
* d94bf56ae8 mkosi-initrd: add specific configuration for plymouth in Debian
* 8235ddbc5b Take shared lock in copy_ephemeral()
* 19c74d5ba5 Two follow ups for #3678
*   0d6f15e8c3 Merge pull request #3678 from DaanDeMeyer/history
|\
| * 5410c4c7af tests: Require genkey to be run once upfront
| * 86b8c611a1 tests: Drop unused tools field
| * c3d1bd0dde Rework history <=> sandbox integration
* fce4db970f zypper: display debugging output if ARG_DEBUG is set
* 2c052b9d45 Allow PCR signing settings to be overridden in sub-images
* 00c220225b zypper: do not fail if a package configured to be removed is not found
2025-04-17 18:30:17 +01:00
Luca Boccassi 10ed8cda58 Revert "mkosi: temporarily disable panic_on_warn"
The BRTFS issue that caused a spurious WARN has been fixed and
backported to Noble, so we can enable panic_on_warm again.

This reverts commit 930d65ccca.
2025-04-17 17:03:47 +01:00
Lennart Poettering a035eaa227 netlink-socket: extend comments a bit
Follow-up for 90755dac69.
2025-04-17 14:42:02 +02:00
Daan De Meyer e8881f09c5 mkosi: Rename mkosi.prepare scripts for systemd deps to systemd.prepare
These scripts are reused by multiple images, so let's give them a
non-standard name to indicate that. Otherwise it's all too easy to add
something to mkosi.prepare for the main image and accidentally have it
included in all the subimages as well even though that's not desired.
2025-04-17 13:33:25 +02:00
Zbigniew Jędrzejewski-Szmek 60bcd98228
sd-netlink: don't fail on netlink message truncation if we pass a zero sized buffer (#37165)
Alternative to #37163
2025-04-17 13:11:13 +02:00
Lennart Poettering 90755dac69 netlink-socket: ignore ECHRNG/EXFULL errors from recvmsg_safe() if we expect truncation
When we receive a netlink messages from userspace we need to drop it
from the queue. Hence we need call recvmsg() on the socket for it. We do
this with a zero-size socket read() buffer, so that the message would be
truncated when copied to userspace, and we do not have to allocate any
memory for it, but it's still dropped.

This was broken in ad501930d7, which
turned datagram truncation into an error (rightfully so I think – for
the common case). That broke this code here, because here we *expect*
truncation, and need to handle it gracefully.

Hence simply check for the two error codes for truncated payload or
cdata, and eat it up.
2025-04-17 08:26:06 +02:00
Lennart Poettering 6d88e4a4b4 Revert "sd-netlink: prepare buffer for dropping unexpected message"
This reverts commit bf478dcffb.

I think we should avoid allocating memory needlessly just to free it
again, in particular if this can be triggered by some rogue peer.
2025-04-17 08:25:40 +02:00
Yu Watanabe bf478dcffb sd-netlink: prepare buffer for dropping unexpected message
Follow-up for c7460cce79 (v219).

Fixes #35654.
2025-04-17 01:52:17 +01:00
Beniamino Galvani ec65c29e51 network: fix handling of routing policy rule fwmask
The firewall mask should be applied even if the mark is 0, to allow defining a
value of e.g. 0/255.

Fixes #36973
2025-04-17 09:18:54 +09:00
37 changed files with 121 additions and 87 deletions

View File

@ -25,7 +25,7 @@ jobs:
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: systemd/mkosi@7e4ec15aee6b98300b2ee14265bc647a716a9f8a - uses: systemd/mkosi@dbb4020beee2cdf250f93a425794f1cf8b0fe693
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
# immediately, we remove the files in the background. However, we first move them to a different location # immediately, we remove the files in the background. However, we first move them to a different location
@ -90,7 +90,6 @@ jobs:
sudo mkosi sandbox -- \ sudo mkosi sandbox -- \
meson setup \ meson setup \
--buildtype=debugoptimized \ --buildtype=debugoptimized \
-Dintegration-tests=true \
build build
- name: Build image - name: Build image
@ -120,7 +119,8 @@ jobs:
meson test \ meson test \
-C build \ -C build \
--no-rebuild \ --no-rebuild \
--suite integration-tests \ --setup=integration \
--suite=integration-tests \
--print-errorlogs \ --print-errorlogs \
--no-stdsplit \ --no-stdsplit \
--num-processes "$(($(nproc) - 1))" \ --num-processes "$(($(nproc) - 1))" \

View File

@ -120,7 +120,7 @@ jobs:
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: systemd/mkosi@7e4ec15aee6b98300b2ee14265bc647a716a9f8a - uses: systemd/mkosi@dbb4020beee2cdf250f93a425794f1cf8b0fe693
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
# immediately, we remove the files in the background. However, we first move them to a different location # immediately, we remove the files in the background. However, we first move them to a different location
@ -197,7 +197,6 @@ jobs:
sudo mkosi sandbox -- \ sudo mkosi sandbox -- \
meson setup \ meson setup \
--buildtype=debugoptimized \ --buildtype=debugoptimized \
-Dintegration-tests=true \
-Dbpf-framework=disabled \ -Dbpf-framework=disabled \
build build
@ -233,7 +232,8 @@ jobs:
meson test \ meson test \
-C build \ -C build \
--no-rebuild \ --no-rebuild \
--suite integration-tests \ --setup=integration \
--suite=integration-tests \
--print-errorlogs \ --print-errorlogs \
--no-stdsplit \ --no-stdsplit \
--num-processes "$(($(nproc) - 1))" \ --num-processes "$(($(nproc) - 1))" \

8
NEWS
View File

@ -489,10 +489,10 @@ CHANGES WITH 257:
existing interfaces, and invoke 'networkctl reload' or restart existing interfaces, and invoke 'networkctl reload' or restart
systemd-networkd. systemd-networkd.
* The timeout for IPv4 Duplicate Address Detection can now be * systemd-networkd now supports configuring the timeout for IPv4
configured via a new IPv4DuplicateAddressDetectionTimeout= Duplicate Address Detection via a new setting
setting. The default timeout value has been changed from 7 seconds to IPv4DuplicateAddressDetectionTimeout=. The default timeout value has
200 milliseconds. been changed from 7 seconds to 200 milliseconds.
systemd-boot, systemd-stub, and related tools: systemd-boot, systemd-stub, and related tools:

View File

@ -1749,8 +1749,10 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
<term><varname>FirewallMark=</varname></term> <term><varname>FirewallMark=</varname></term>
<listitem> <listitem>
<para>Specifies the iptables firewall mark value to match (a number in the range <para>Specifies the iptables firewall mark value to match (a number in the range
1…4294967295). Optionally, the firewall mask (also a number between 1…4294967295) can be 0…4294967295). Optionally, the firewall mask (also a number between 0…4294967295) can be
suffixed with a slash (<literal>/</literal>), e.g., <literal>7/255</literal>.</para> suffixed with a slash (<literal>/</literal>), e.g., <literal>7/255</literal>. When the
mark value is non-zero and no mask is explicitly specified, all bits of the mark are
compared. </para>
<xi:include href="version-info.xml" xpointer="v235"/> <xi:include href="version-info.xml" xpointer="v235"/>
</listitem> </listitem>

View File

@ -13,6 +13,12 @@ project('systemd', 'c',
meson_version : '>= 0.62.0', meson_version : '>= 0.62.0',
) )
add_test_setup(
'default',
exclude_suites : ['integration-tests'],
is_default : true,
)
project_major_version = meson.project_version().split('.')[0].split('~')[0] project_major_version = meson.project_version().split('.')[0].split('~')[0]
if meson.project_version().contains('.') if meson.project_version().contains('.')
project_minor_version = meson.project_version().split('.')[-1].split('~')[0] project_minor_version = meson.project_version().split('.')[-1].split('~')[0]
@ -339,7 +345,6 @@ meson_build_sh = find_program('tools/meson-build.sh')
want_tests = get_option('tests') want_tests = get_option('tests')
want_slow_tests = want_tests != 'false' and get_option('slow-tests') want_slow_tests = want_tests != 'false' and get_option('slow-tests')
want_fuzz_tests = want_tests != 'false' and get_option('fuzz-tests') want_fuzz_tests = want_tests != 'false' and get_option('fuzz-tests')
want_integration_tests = want_tests != 'false' and get_option('integration-tests')
install_tests = want_tests != 'false' and get_option('install-tests') install_tests = want_tests != 'false' and get_option('install-tests')
if add_languages('cpp', native : false, required : fuzzer_build) if add_languages('cpp', native : false, required : fuzzer_build)
@ -2661,10 +2666,6 @@ endif
##################################################################### #####################################################################
mkosi = find_program('mkosi', required : false) mkosi = find_program('mkosi', required : false)
if want_integration_tests and not mkosi.found()
error('Could not find mkosi which is required to run the integration tests')
endif
mkosi_depends = public_programs mkosi_depends = public_programs
foreach executable : ['systemd-journal-remote', 'systemd-sbsign', 'systemd-keyutil'] foreach executable : ['systemd-journal-remote', 'systemd-sbsign', 'systemd-keyutil']

View File

@ -509,7 +509,7 @@ option('install-tests', type : 'boolean', value : false,
description : 'install test executables') description : 'install test executables')
option('log-message-verification', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' }, option('log-message-verification', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' },
description : 'do fake printf() calls to verify format strings') description : 'do fake printf() calls to verify format strings')
option('integration-tests', type : 'boolean', value : false, option('integration-tests', type : 'boolean', value : false, deprecated : true,
description : 'run the integration tests') description : 'run the integration tests')
option('ok-color', type : 'combo', option('ok-color', type : 'combo',

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
[Config] [Config]
MinimumVersion=commit:7e4ec15aee6b98300b2ee14265bc647a716a9f8a MinimumVersion=commit:dbb4020beee2cdf250f93a425794f1cf8b0fe693
Dependencies= Dependencies=
exitrd exitrd
initrd initrd
@ -78,8 +78,7 @@ KernelCommandLine=
oops=panic oops=panic
panic=-1 panic=-1
softlockup_panic=1 softlockup_panic=1
# Disabled due to BTRFS issue, waiting for the fix to become available panic_on_warn=1
panic_on_warn=0
psi=1 psi=1
mitigations=off mitigations=off

View File

@ -4,6 +4,7 @@
Distribution=arch Distribution=arch
[Content] [Content]
PrepareScripts=systemd.prepare
VolatilePackages= VolatilePackages=
systemd systemd
systemd-libs systemd-libs

View File

@ -5,6 +5,7 @@ Distribution=|centos
Distribution=|fedora Distribution=|fedora
[Content] [Content]
PrepareScripts=systemd.prepare
VolatilePackages= VolatilePackages=
systemd systemd
systemd-boot systemd-boot

View File

@ -5,6 +5,7 @@ Distribution=|debian
Distribution=|ubuntu Distribution=|ubuntu
[Content] [Content]
PrepareScripts=systemd.prepare
VolatilePackages= VolatilePackages=
libnss-myhostname libnss-myhostname
libnss-mymachines libnss-mymachines

View File

@ -11,6 +11,7 @@ Repositories=non-oss
SandboxTrees=macros.db_backend:/etc/rpm/macros.db_backend SandboxTrees=macros.db_backend:/etc/rpm/macros.db_backend
[Content] [Content]
PrepareScripts=systemd.prepare
VolatilePackages= VolatilePackages=
libsystemd0 libsystemd0
libudev1 libudev1

View File

@ -4,7 +4,7 @@
Distribution=arch Distribution=arch
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/arch/systemd.prepare
VolatilePackages= VolatilePackages=
systemd systemd
systemd-libs systemd-libs

View File

@ -5,6 +5,6 @@ Distribution=|centos
Distribution=|fedora Distribution=|fedora
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/systemd.prepare
VolatilePackages= VolatilePackages=
systemd-standalone-shutdown systemd-standalone-shutdown

View File

@ -4,6 +4,6 @@
Distribution=debian Distribution=debian
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/systemd.prepare
VolatilePackages= VolatilePackages=
systemd-standalone-shutdown systemd-standalone-shutdown

View File

@ -4,7 +4,7 @@
Distribution=opensuse Distribution=opensuse
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/systemd.prepare
Packages= Packages=
diffutils diffutils
grep grep

View File

@ -4,7 +4,7 @@
Distribution=ubuntu Distribution=ubuntu
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/systemd.prepare
VolatilePackages= VolatilePackages=
libsystemd-shared libsystemd-shared
libsystemd0 libsystemd0

View File

@ -4,7 +4,7 @@
Distribution=arch Distribution=arch
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/arch/systemd.prepare
Packages= Packages=
btrfs-progs btrfs-progs
tpm2-tools tpm2-tools

View File

@ -5,7 +5,7 @@ Distribution=|centos
Distribution=|fedora Distribution=|fedora
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/systemd.prepare
Packages= Packages=
tpm2-tools tpm2-tools

View File

@ -5,7 +5,7 @@ Distribution=|debian
Distribution=|ubuntu Distribution=|ubuntu
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/systemd.prepare
Packages= Packages=
btrfs-progs btrfs-progs
tpm2-tools tpm2-tools

View File

@ -4,7 +4,7 @@
Distribution=opensuse Distribution=opensuse
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/systemd.prepare
Packages= Packages=
btrfs-progs btrfs-progs
kmod kmod

View File

@ -4,7 +4,7 @@
Distribution=arch Distribution=arch
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/arch/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/arch/systemd.prepare
Packages= Packages=
inetutils inetutils
iproute iproute

View File

@ -5,7 +5,7 @@ Distribution=|centos
Distribution=|fedora Distribution=|fedora
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/systemd.prepare
Packages= Packages=
hostname hostname
iproute iproute

View File

@ -5,7 +5,7 @@ Distribution=|debian
Distribution=|ubuntu Distribution=|ubuntu
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/debian-ubuntu/systemd.prepare
Packages= Packages=
hostname hostname
iproute2 iproute2

View File

@ -4,7 +4,7 @@
Distribution=opensuse Distribution=opensuse
[Content] [Content]
PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/mkosi.prepare PrepareScripts=%D/mkosi/mkosi.conf.d/opensuse/systemd.prepare
Packages= Packages=
diffutils diffutils
grep grep

View File

@ -30,7 +30,7 @@
#define PROBE_MIN 1U #define PROBE_MIN 1U
#define PROBE_MAX 2U #define PROBE_MAX 2U
#define ANNOUNCE_WAIT 2U #define ANNOUNCE_WAIT 2U
#define TOTAL_TIMEOUT 7U #define TOTAL_TIME_UNITS 7U
/* Intervals from the RFC not adjusted to the time unit */ /* Intervals from the RFC not adjusted to the time unit */
#define ANNOUNCE_INTERVAL_USEC (2U * USEC_PER_SEC) #define ANNOUNCE_INTERVAL_USEC (2U * USEC_PER_SEC)
@ -162,7 +162,7 @@ int sd_ipv4acd_new(sd_ipv4acd **ret) {
*acd = (sd_ipv4acd) { *acd = (sd_ipv4acd) {
.n_ref = 1, .n_ref = 1,
.state = IPV4ACD_STATE_INIT, .state = IPV4ACD_STATE_INIT,
.time_unit = TIMEOUT_DEFAULT_USEC / TOTAL_TIMEOUT, .time_unit = TIMEOUT_DEFAULT_USEC / TOTAL_TIME_UNITS,
.ifindex = -1, .ifindex = -1,
.fd = -EBADF, .fd = -EBADF,
}; };
@ -232,9 +232,9 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
acd->defend_window = 0; acd->defend_window = 0;
log_ipv4acd(acd, log_ipv4acd(acd,
"Started on address " IPV4_ADDRESS_FMT_STR " with a max timeout of %" PRIu64 "msec", "Started on address " IPV4_ADDRESS_FMT_STR " with a max timeout of %s",
IPV4_ADDRESS_FMT_VAL(acd->address), IPV4_ADDRESS_FMT_VAL(acd->address),
(acd->time_unit * TOTAL_TIMEOUT + (USEC_PER_MSEC - 1)) / USEC_PER_MSEC); FORMAT_TIMESPAN(acd->time_unit * TOTAL_TIME_UNITS, USEC_PER_MSEC));
ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_PROBE, true); ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_PROBE, true);
@ -471,7 +471,8 @@ int sd_ipv4acd_set_timeout(sd_ipv4acd *acd, uint64_t timeout_usec) {
timeout_usec = TIMEOUT_DEFAULT_USEC; timeout_usec = TIMEOUT_DEFAULT_USEC;
/* Clamp the total duration to a value between 1ms and 1 minute */ /* Clamp the total duration to a value between 1ms and 1 minute */
acd->time_unit = CLAMP(timeout_usec, 1U * USEC_PER_MSEC, 60U * USEC_PER_SEC) / TOTAL_TIMEOUT; acd->time_unit = DIV_ROUND_UP(
CLAMP(timeout_usec, 1U * USEC_PER_MSEC, 1U * USEC_PER_MINUTE), TOTAL_TIME_UNITS);
return 0; return 0;
} }

View File

@ -161,12 +161,13 @@ static int socket_recv_message(int fd, void *buf, size_t buf_size, uint32_t *ret
assert(fd >= 0); assert(fd >= 0);
assert(peek || (buf && buf_size > 0)); assert(peek || (buf && buf_size > 0));
/* Note: this might return successfully, but with a zero size under some transient conditions, such
* as the reception of a non-kernel message. In such a case the passed buffer might or might not be
* modified. Caller must treat a zero return as "no message, but also not an error". */
n = recvmsg_safe(fd, &msg, peek ? (MSG_PEEK|MSG_TRUNC) : 0); n = recvmsg_safe(fd, &msg, peek ? (MSG_PEEK|MSG_TRUNC) : 0);
if (ERRNO_IS_NEG_TRANSIENT(n)) { if (ERRNO_IS_NEG_TRANSIENT(n))
if (ret_mcast_group) goto transient;
*ret_mcast_group = 0;
return 0;
}
if (n == -ENOBUFS) if (n == -ENOBUFS)
return log_debug_errno(n, "sd-netlink: kernel receive buffer overrun"); return log_debug_errno(n, "sd-netlink: kernel receive buffer overrun");
if (n == -ECHRNG) if (n == -ECHRNG)
@ -181,15 +182,16 @@ static int socket_recv_message(int fd, void *buf, size_t buf_size, uint32_t *ret
log_debug("sd-netlink: ignoring message from PID %"PRIu32, sender.nl.nl_pid); log_debug("sd-netlink: ignoring message from PID %"PRIu32, sender.nl.nl_pid);
if (peek) { if (peek) {
/* drop the message */ /* Drop the message. Note that we ignore ECHRNG/EXFULL errors here, which
* recvmsg_safe() returns in case the payload or cdata is truncated. Given we just
* want to drop the message we also don't care if its payload or cdata was
* truncated. */
n = recvmsg_safe(fd, &msg, 0); n = recvmsg_safe(fd, &msg, 0);
if (n < 0) if (n < 0 && !IN_SET(n, -ECHRNG, -EXFULL))
return (int) n; return (int) n;
} }
if (ret_mcast_group) goto transient;
*ret_mcast_group = 0;
return 0;
} }
if (ret_mcast_group) { if (ret_mcast_group) {
@ -203,6 +205,12 @@ static int socket_recv_message(int fd, void *buf, size_t buf_size, uint32_t *ret
} }
return (int) n; return (int) n;
transient:
if (ret_mcast_group)
*ret_mcast_group = 0;
return 0;
} }
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR( DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(

View File

@ -615,7 +615,7 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
if (r < 0) if (r < 0)
return r; return r;
if (rule->fwmark > 0) { if (rule->fwmark > 0 || rule->fwmask > 0) {
r = sd_netlink_message_append_u32(m, FRA_FWMARK, rule->fwmark); r = sd_netlink_message_append_u32(m, FRA_FWMARK, rule->fwmark);
if (r < 0) if (r < 0)
return r; return r;
@ -1315,14 +1315,12 @@ static int parse_fwmark_fwmask(const char *s, uint32_t *ret_fwmark, uint32_t *re
if (r < 0) if (r < 0)
return r; return r;
if (fwmark > 0) { if (slash) {
if (slash) { r = safe_atou32(slash + 1, &fwmask);
r = safe_atou32(slash + 1, &fwmask); if (r < 0)
if (r < 0) return r;
return r; } else if (fwmark > 0)
} else fwmask = UINT32_MAX;
fwmask = UINT32_MAX;
}
*ret_fwmark = fwmark; *ret_fwmark = fwmark;
*ret_fwmask = fwmask; *ret_fwmask = fwmask;

View File

@ -38,14 +38,14 @@ directory (`OutputDirectory=`) to point to the other directory using `mkosi/mkos
After the image has been built, the integration tests can be run with: After the image has been built, the integration tests can be run with:
```shell ```shell
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build --suite integration-tests --num-processes "$(($(nproc) / 4))" $ mkosi -f sandbox -- meson test -C build --setup=integration --suite integration-tests --num-processes "$(($(nproc) / 4))"
``` ```
As usual, specific tests can be run in meson by appending the name of the test As usual, specific tests can be run in meson by appending the name of the test
which is usually the name of the directory e.g. which is usually the name of the directory e.g.
```shell ```shell
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -v TEST-01-BASIC $ mkosi -f sandbox -- meson test -C build --setup=integration -v TEST-01-BASIC
``` ```
See `mkosi -f sandbox -- meson introspect build --tests` for a list of tests. See `mkosi -f sandbox -- meson introspect build --tests` for a list of tests.
@ -55,7 +55,7 @@ To interactively debug a failing integration test, the `--interactive` option
newer: newer:
```shell ```shell
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -i TEST-01-BASIC $ mkosi -f sandbox -- meson test -C build --setup=integration -i TEST-01-BASIC
``` ```
Due to limitations in meson, the integration tests do not yet depend on the Due to limitations in meson, the integration tests do not yet depend on the
@ -64,7 +64,7 @@ running the integration tests. To rebuild the image and rerun a test, the
following command can be used: following command can be used:
```shell ```shell
$ mkosi -f sandbox -- meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -v TEST-01-BASIC $ mkosi -f sandbox -- meson compile -C build mkosi && mkosi -f sandbox -- meson test -C build --setup=integration -v TEST-01-BASIC
``` ```
The integration tests use the same mkosi configuration that's used when you run The integration tests use the same mkosi configuration that's used when you run
@ -78,7 +78,7 @@ To iterate on an integration test, let's first get a shell in the integration te
the following: the following:
```shell ```shell
$ mkosi -f sandbox -- meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 TEST_SHELL=1 mkosi -f sandbox -- meson test -C build -i TEST-01-BASIC $ mkosi -f sandbox -- meson compile -C build mkosi && mkosi -f sandbox -- meson test -C build --setup=shell -i TEST-01-BASIC
``` ```
This will get us a shell in the integration test environment after booting the machine without running the This will get us a shell in the integration test environment after booting the machine without running the
@ -107,7 +107,7 @@ re-running the test will first install the new packages we just built, make a ne
the test again. You can keep running the loop of `mkosi -R`, `systemctl soft-reboot` and the test again. You can keep running the loop of `mkosi -R`, `systemctl soft-reboot` and
`systemctl start ...` until the changes to the integration test are working. `systemctl start ...` until the changes to the integration test are working.
If you're debugging a failing integration test (running `meson test --interactive` without `TEST_SHELL`), If you're debugging a failing integration test (running `meson test --interactive`),
there's no need to run `systemctl start ...`, running `systemctl soft-reboot` on its own is sufficient to there's no need to run `systemctl start ...`, running `systemctl soft-reboot` on its own is sufficient to
rerun the test. rerun the test.
@ -120,10 +120,6 @@ rerun the test.
`TEST_NO_KVM=1`: Disable qemu KVM auto-detection (may be necessary when you're `TEST_NO_KVM=1`: Disable qemu KVM auto-detection (may be necessary when you're
trying to run the *vanilla* qemu and have both qemu and qemu-kvm installed) trying to run the *vanilla* qemu and have both qemu and qemu-kvm installed)
`TEST_SHELL=1`: Configure the machine to be more *user-friendly* for
interactive debugging (e.g. by setting a usable default terminal, suppressing
the shutdown after the test, etc.).
`TEST_MATCH_SUBTEST=subtest`: If the test makes use of `run_subtests` use this `TEST_MATCH_SUBTEST=subtest`: If the test makes use of `run_subtests` use this
variable to provide a POSIX extended regex to run only subtests matching the variable to provide a POSIX extended regex to run only subtests matching the
expression. expression.

View File

@ -361,7 +361,7 @@ def statfs(path: Path) -> str:
def main() -> None: def main() -> None:
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--mkosi', required=True) parser.add_argument('--mkosi', default=None)
parser.add_argument('--meson-source-dir', required=True, type=Path) parser.add_argument('--meson-source-dir', required=True, type=Path)
parser.add_argument('--meson-build-dir', required=True, type=Path) parser.add_argument('--meson-build-dir', required=True, type=Path)
parser.add_argument('--name', required=True) parser.add_argument('--name', required=True)
@ -379,6 +379,12 @@ def main() -> None:
parser.add_argument('mkosi_args', nargs='*') parser.add_argument('mkosi_args', nargs='*')
args = parser.parse_args() args = parser.parse_args()
if not args.mkosi:
args.mkosi = shutil.which('mkosi')
if not args.mkosi:
print('Could not find mkosi which is required to run the integration tests', file=sys.stderr)
sys.exit(1)
# The meson source directory can either be the top-level repository directory or the # The meson source directory can either be the top-level repository directory or the
# test/integration-tests/standalone subdirectory in the repository directory. The mkosi configuration # test/integration-tests/standalone subdirectory in the repository directory. The mkosi configuration
# will always be a parent directory of one of these directories and at most 4 levels upwards, so don't # will always be a parent directory of one of these directories and at most 4 levels upwards, so don't
@ -395,13 +401,6 @@ def main() -> None:
) )
exit(1) exit(1)
if not bool(int(os.getenv('SYSTEMD_INTEGRATION_TESTS', '0'))):
print(
f'SYSTEMD_INTEGRATION_TESTS=1 not found in environment, skipping {args.name}',
file=sys.stderr,
)
exit(77)
if args.slow and not bool(int(os.getenv('SYSTEMD_SLOW_TESTS', '0'))): if args.slow and not bool(int(os.getenv('SYSTEMD_SLOW_TESTS', '0'))):
print( print(
f'SYSTEMD_SLOW_TESTS=1 not found in environment, skipping {args.name}', f'SYSTEMD_SLOW_TESTS=1 not found in environment, skipping {args.name}',

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
# We'd give these more descriptive names but only alphanumeric characters are allowed.
add_test_setup('integration')
add_test_setup('shell', env : {'TEST_SHELL' : '1'})
integration_test_wrapper = find_program('integration-test-wrapper.py') integration_test_wrapper = find_program('integration-test-wrapper.py')
integration_tests = [] integration_tests = []
integration_test_template = { integration_test_template = {
@ -129,11 +133,11 @@ foreach integration_test : integration_tests
integration_test_args += ['--skip'] integration_test_args += ['--skip']
endif endif
if not mkosi.found() if mkosi.found()
continue integration_test_args += ['--mkosi', mkosi.full_path()]
endif endif
integration_test_args += ['--mkosi', mkosi.full_path(), '--'] integration_test_args += ['--']
if integration_test['cmdline'].length() > 0 if integration_test['cmdline'].length() > 0
integration_test_args += [ integration_test_args += [
@ -151,19 +155,12 @@ foreach integration_test : integration_tests
integration_test_args += integration_test['mkosi-args'] integration_test_args += integration_test['mkosi-args']
integration_test_env = {}
if want_integration_tests
integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'}
endif
# We don't explicitly depend on the "mkosi" target because that means the image is rebuilt on every # We don't explicitly depend on the "mkosi" target because that means the image is rebuilt on every
# "ninja -C build". Instead, the mkosi target has to be rebuilt manually before running the # "ninja -C build". Instead, the mkosi target has to be rebuilt manually before running the
# integration tests with mkosi. # integration tests with mkosi.
test( test(
integration_test['name'], integration_test['name'],
integration_test_wrapper, integration_test_wrapper,
env : integration_test_env,
args : integration_test_args, args : integration_test_args,
timeout : integration_test['timeout'], timeout : integration_test['timeout'],
priority : integration_test['priority'], priority : integration_test['priority'],

View File

@ -16,7 +16,6 @@ project('systemd-testsuite',
fs = import('fs') fs = import('fs')
mkosi = find_program('mkosi', required : true) mkosi = find_program('mkosi', required : true)
want_integration_tests = true
# meson refuses .. in subdir() so we use a symlink to trick it into accepting it anyway. # meson refuses .. in subdir() so we use a symlink to trick it into accepting it anyway.
subdir('integration-tests') subdir('integration-tests')

View File

@ -48,6 +48,24 @@ From=10.1.0.0/16
Priority=104 Priority=104
Table=12 Table=12
[RoutingPolicyRule]
IncomingInterface=test1
FirewallMark=0/1
Priority=200
Table=20
[RoutingPolicyRule]
IncomingInterface=test1
FirewallMark=7/255
Priority=201
Table=21
[RoutingPolicyRule]
IncomingInterface=test1
FirewallMark=9999
Priority=202
Table=22
# The four routing policy rules below intentionally have the same config # The four routing policy rules below intentionally have the same config
# excepts for their To= addresses. See issue #35874. # excepts for their To= addresses. See issue #35874.
[RoutingPolicyRule] [RoutingPolicyRule]

View File

@ -3890,6 +3890,18 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output) print(output)
self.assertIn('104: from 10.1.0.0/16 iif test1 lookup 12 nop', output) self.assertIn('104: from 10.1.0.0/16 iif test1 lookup 12 nop', output)
output = check_output('ip rule list iif test1 priority 200')
print(output)
self.assertIn('200: from all fwmark 0/0x1 iif test1 lookup 20', output)
output = check_output('ip rule list iif test1 priority 201')
print(output)
self.assertIn('201: from all fwmark 0x7/0xff iif test1 lookup 21', output)
output = check_output('ip rule list iif test1 priority 202')
print(output)
self.assertIn('202: from all fwmark 0x270f iif test1 lookup 22', output)
output = check_output('ip rule list to 192.0.2.0/26') output = check_output('ip rule list to 192.0.2.0/26')
print(output) print(output)
self.assertIn('to 192.0.2.0/26 lookup 1001', output) self.assertIn('to 192.0.2.0/26 lookup 1001', output)