When IPv4 ACD is enabled for a DHCPv4 address, the address remains in
the request queue until ACD succeeds. Hence, when ACD detects a
conflict, the address may not be present in link->addresses yet.
on_acd() currently looks up the address with address_get(), which only
searches link->addresses. This makes the callback return early and
prevents dhcp4_address_on_conflict() from sending DHCPDECLINE.
Use address_get_harder(), which also looks up pending address requests.
Fixes#39460
(cherry picked from commit 2aed6d9ad7)
When a DHCP lease is lost or a client is stopped, there may exist
requests not processed yet. We need to cancel them, otherwise an
address or route requested by the lost lease may be configured later.
(cherry picked from commit 830b60ae1f)
If an address with IPv4ACD is requested, then sd_ipv4acd instance for
the address is configured. If the request is cancelled, we should
also disable the IPv4ACD instance.
Note, if the address is already configured, the IPv4ACD instance for the
address will be removed when the address is removed. See address_drop().
(cherry picked from commit c5bf6bac23)
network-generator writes generated command line configuration below
the alternate root passed with --root=, but network.* credentials
were copied to fixed host /run paths.
Build the credential target directories with arg_root before passing
them to pick_up_credentials(). This keeps normal boot behavior
unchanged while making credential output land in the requested root.
systemd-networkd needs authorization for
`org.freedesktop.ModemManager1.Device.Control` to allow establishing a
connection:
systemd-networkd[1457]: ModemManager: starting simple connect on huawei E3276 interface wwp106s0u4i2
systemd-networkd[1457]: Could not connect modem huawei E3276: Unauthorized: PolicyKit authorization failed: not authorized for 'org.freedesktop.ModemManager1.Device.Control'
When networkd starts or restarts, links are enumerated in ifindex
order. A slave enumerated before its master cannot register itself in
link_append_to_master(), as the master Link object does not exist yet.
The master then wrongly believes it has no slaves until the next
RTM_NEWLINK message for the slave arrives.
The stale slaves set affects operational state propagation
(degraded-carrier detection) and any code that inspects the slaves of
a master.
For instance, on restart, when networkd thinks that the master has no
slaves yet, we try to set the bond fail-over policy, which the kernel
then refuses because in reality the bond does have slaves.
To fix the issue, this updates the list of slaves after enumeration.
Co-authored-by: Yu Watanabe <watanabe.yu+github@gmail.com>
The last five hand-written help() functions are replaced by COMMAND()
descriptions: test-homectl-prompts, test-libudev,
test-modem-manager-mock, test-chase-manual, and test-journal-append
(which open-coded the help inside the option parsing loop). None of the
binaries are installed, so no man pages are referenced and they are not
added to the introspection smoke test.
Like the command-level CommandDescription.argspec, a verb's argspec is now
a nulstr, so that a verb may declare multiple alternative usage lines. The
verbs help table renders one synopsis line per nulstr entry in the
synopsis cell.
All verb argument specifications must gain an explicit NUL suffix. This
is a lot of churn, but I think this needs to be done. For now, there'll
be only one user of the new functionality (i.e. a verb with more than
one argspec), but I think we'll eventually want to use this in other
places too.
This converts systemd-homed, -hostnamed, -importd, -localed, -logind,
-machined, -networkd, -portebled, -resolved, -sysupdated, -timedated,
and -timesyncd.
The service name and description move from service_parse_argv() arguments
into a COMMAND() description that each daemon now defines. The
service_parse_argv() macro captures the calling binary's verb section,
where that COMMAND is found, while the options are still defined and
parsed in libshared, in the new "service" option namespace that each
COMMAND references. (The named namespace makes sure that options defined
by other translation units in libshared can never leak into the
services' parsers.)
The supported features are declared via option group filtering: each
COMMAND lists "Options" plus "Bus introspection" and/or "Runtime scope".
Unsupported options are now rejected by the parser as unknown options
(and are not shown in --help), replacing the runtime "This service does
not support …" errors.
The help output changes slightly: the "Bus introspection" and "Runtime
scope" option groups now get their own headings, and some descriptions
were reworded to the imperative form used elsewhere.
This time, various commands with non-trivial requirements are handled.
So the series is shorter, but has a pattern of feature additions and
then those new features being used. The way that --help output is
formatted is changed a bit in various places. Those changes are
described in individual commits.
22 'static int help()' functions left after this.
We already have io.systemd.service.SetLogLevel. Add a getter so that
CLI tools with `log-level` subcommands can be more easily implemented
with varlink.
Bind this method to all services that already bind io.systemd.service.SetLogLevel.
Otherwise, if reloading is requested after SIGTERM/SIGINT is received,
a new operation may be started, e.g. creating a new netdev or so,
and that will easily fail and may cause spurious network state.
Also, send STOPPING notification to the service manager when
received SIGTERM/SIGINT.
Almost all programs are simple and have only a single command. When
printing options, let's just use the first COMMAND block found by default.
This means we can drop the explicit program-name argument and reduce
copy&paste boilerplate.
A MAC change can mean the link joined another network, e.g. on an
active-backup bond failover with FailOverMACPolicy=active. NDisc only
solicits when it starts, so IPv6 sat stale until the next unsolicited
RA. Restart NDisc to solicit immediately.
The custom help() is replaced by a COMMAND() description, and
--introspect-cli is added. --help now goes through the pager, like other
commands with --no-pager.
The custom help() is replaced by a COMMAND() description, and
--introspect-cli is added. The old help had neither an abstract nor a
man page reference; both are added, with the abstract taken from the
man page.
This also makes IPv4 proxy neighbor entries independent of proxy_arp
sysctl. We can configure IPv4 proxy neighbor entries even if proxy_arp
is disabled.
Even though the document says "When unset, the kernel's default will
be used." for IPv6ProxyNDP=, previously, when both IPv6ProxyNDP= and
IPv6ProxyNDPAddress= are unspecified, proxy_ndp sysctl was disabled.
This was also inconsistent to other sysctl settings.
It is not necessary to provide dedicated settings for IPv4 and IPv6
proxy neighbor entries. Let's unify them.
The IPv4ProxyARPAddress= setting was introduced after v261. Hence, we
can freely rename it.
Previously, specifying multiple stacked netdevs of the same type required
repeating the corresponding setting, e.g.:
```
[Network]
VLAN=vlan_10
VLAN=vlan_20
VLAN=vlan_30
```
With this change, the same configuration can be written as:
```
[Network]
VLAN=vlan_10 vlan_20 vlan_30
```
Specifying an empty string now also clears all previously assigned stacked
netdevs.
Closes#43103.
During early boot, interfaces may be renamed frequently, which can lead to
caching the driver name of a different interface. Invalidate the cached
driver whenever an interface rename is detected so it can be re-read using
the new name.
Follow-up for #42545.
Fixes#43099.
Add a new --no-reconfigure flag to 'networkctl reload' that reloads
.network and .netdev files from disk without reconfiguring any network
interfaces. This may be useful to avoid reconfiguring multiple interfaces
simultaneously when multiple .network files are updated, or when an updated
.network file is applied to multiple interfaces.
On the networkd side, manager_reload() gains a reconfigure_links parameter
that gates the per-link reconfiguration loop. A new io.systemd.Network.Reload
varlink method is added that exposes this as an optional reconfigureLinks
boolean (defaults to true). Both plain 'networkctl reload' and
'--no-reconfigure' now unconditionally call this method first. If an older
networkd returns MethodNotFound, plain reload falls back to
io.systemd.service.Reload for backward compatibility; '--no-reconfigure'
fails with a clear error in that case.
Since 4c0d8d9673, most dlopen notes are
set at the beginning of the executables. Let's manage all dlopen notes
there, rather than setting them where dlopen is called.
Note that the only exceptions are the LIBBPF_NOTE for networkd and
nsresource. Since dlopen_bpf() is wrapped in an `#if` guard, the notes
are instead set within the corresponding functionality.
As a result, the DLOPEN_FOO() wrapper macros are no longer needed and
can be dropped completely.
[1177/3647] Compiling C object systemd-networkd.p/src_network_networkd-bridge-vlan.c.o
In function ‘bridge_vlan_append_set_info’,
inlined from ‘bridge_vlan_set_message’ at ../src/network/networkd-bridge-vlan.c:257:21:
../src/network/networkd-bridge-vlan.c:162:28: warning: ‘untagged’ may be used uninitialized [-Wmaybe-uninitialized]
162 | if (untagged == u)
| ^
../src/network/networkd-bridge-vlan.c: In function ‘bridge_vlan_set_message’:
../src/network/networkd-bridge-vlan.c:111:14: note: ‘untagged’ was declared here
111 | bool untagged, pvid_is_untagged;
| ^~~~~~~~
Store the asynchronous netlink slot in the Request object and release it
when the request is detached. This cancels the pending callback instead of
keeping the request alive until its reply arrives.
Follow-up for 80d62d4f1a
The multipath route comparator looks up every nexthop in the first
route and hence compares each entry with itself. Compare both ordered
nexthop sets instead, including weights, as the hash function does.
Follow-up for 47420573a7
This adds an IPv4 counterpart to `IPv6ProxyNDPAddress=` for adding
manual entries to the kernel's IPv4 neighbour proxy table (check via
`ip -4 neighbour show proxy dev <dev>`). systemd-networkd only exposed
`IPv4ProxyARP=` for per-interface `proxy_arp` sysctl (automatic proxy
ARP) with no way to manage manual entries from a .network file.
To avoid duplicating the IPv6 proxy NDP code path, both families are
now combined into a single new `networkd-neighbor-proxy` module. The
IPv6 behaviour is preserved: `IPv6ProxyNDPAddress=` still implies
`IPv6ProxyNDP=yes` unless `IPv6ProxyNDP=` is explicitly disabled and
entries are still dropped if the kernel has no IPv6 support.
The same rule is applied to `IPv4ProxyARPAddress=`. It implies
`IPv4ProxyARP=yes` when the sysctl is not explicitly set and has no
effect if `IPv4ProxyARP=` has been set to false.
This keeps the user model symmetric and predictable across both
families: a single per-address setting that turns on the matching
per-interface sysctl automatically, while still letting system
administrators opt out by setting the boolean explicitly to false.
Note that the IPv4 manual NTF_PROXY entries installed here would
actually function without `proxy_arp` (unlike IPv6, where `proxy_ndp`
gates the manual entries); the implication is kept for symmetry with
`IPv6ProxyNDPAddress=` and is now called out explicitly in the man
page, together with the fact that enabling `proxy_arp` also activates
interface-wide automatic proxy ARP for routed-toward addresses on
connected subnets.
Parser-time validation rejects addresses the kernel would refuse:
the ANY/null address for both families, IPv4 and IPv6 multicast
and the IPv4 limited broadcast 255.255.255.255.
Signed-off-by: Aritra Basu <aritrbas+gh@cisco.com>
When MACAddress= is unspecified, a stable MAC is generated to seed a newly
created netdev. Since existing netdevs are reconfigured on reload/restart,
this seed got re-applied to an already existing interface, conflicting with
an explicit MACAddress= from the matching .network file and flipping MAC.
Now, when MACAddress= is unspecified, only generate a new address if
addr_assign_type is not NET_ADDR_SET (i.e. not already set by userspace). On
first creation the interface does not exist yet, so this is a no-op and the
address is generated as before. Mirrors src/udev/net/link-config.c.
Fixes: #42457
Even though systemd-networkd and systemd-udevd do not support
ConditionSecurity= in .network, .netdev, and .link files, the unified
condition_test() function maintained a function pointer table that
unconditionally referenced condition_test_security(). Consequently,
linker garbage collection (--gc-sections) could not drop the security
test code, inadvertently pulling in dlopen dependencies and ELF notes
for apparmor, audit, and tpm2 libraries into these binaries.
To resolve this, introduce condition_test_net() and condition_test_list_net(),
which utilize a trimmed-down function pointer table that excludes
security-related condition evaluators.
By migrating networkd and udevd to these new network-specific variants,
the reference to condition_test_security() is completely severed in
their dependency chains. This allows the compiler and linker to
successfully garbage-collect the unused security logic and safely drops
the unnecessary dlopen notes from those binaries.
Previously, even though sd-journal does not support bzip2 and gzip
compression, the dlopen ELF notes for those libraries were still being
attached to libsystemd.so and various journal-handling executables.
This occurred because the unified compression/decompression interfaces
handled all formats unconditionally, causing the compiler and linker to
pull in all associated dlopen notes across the board.
To resolve this, split these functions into generic and journal-specific
variants (e.g., introducing compress_blob_journal() and decompress_blob_journal()).
The journal-specific variants only handle formats actually supported by
the journal (LZ4, XZ, and ZSTD).
By updating sd-journal, journald, journalctl, and related utilities to
use these new `_journal` interfaces and switching them to the narrower
COMPRESS_JOURNAL_NOTE macro, we ensure that unnecessary dlopen notes
(for bzip2 and gzip) are no longer embedded into these binaries.
Previously, when a library was dynamically loaded via a helper function
inside libsystemd-shared.so, the resulting dlopen ELF note was not
propagated to the invoking executable's ELF metadata.
This commit explicitly annotates each executable with the relevant
dlopen ELF notes for any optional dependencies it might potentially
load. This ensures that package managers and build systems can properly
discover runtime dependencies that are triggered indirectly.