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>
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.
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.
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>
SUSE does not provide a vmlinux.h so the package is not built with
CO-RE support, hence the test fails. This was previously masked
by the fact that python3-packaging was never installed, so the
test always skipped everywhere as it could not detect the kernel
version.
Follow-up for c310106c15
Unfortunately, previously the path to test-ndisc-send has been wrong, so
some test cases have not been checked in our mkosi CIs. And two test
cases have been broken.
The test case `test_ndisc_redirect` was not updated when the logic in
networkd was changed by 9142bd5a8e. The
change itself should be OK. So, the test case is updated.
The test case `test_ndisc_mtu` was broken when the commit
32417c1723 is merged. The commit is not
correct, as we cannot set IPv6 MTU larger than interface MTU. So, the
offending commit is reverted.
Then, this deprecates
- BindToInterface=
- RelayTarget=
- RelayAgentCircuitId=
- RelayAgentRemoteId=
settings in [DHCPServer] section.
These are gracefully translated as new settings.
After 9142bd5a8e, when NA without router
flag is received, the corresponding redirect route and the default route
is removed, but the other routes are kept.
The corresponding test case was not updated by the commit, and the test
case has been unfortunately skipped...
This fixes the test case, and added more checks.
Otherwise, all test cases that does not create/start the service emits
the following error:
```
Failed to stop test-modem-manager-mock.service: Unit test-modem-manager-mock.service not loaded.
```
Moreover, without this change, extra 'systemctl daemon-reload' is triggered after
all test cases. That's super heavy, especially when the test is running on
sanitizers.
Follow-up for abe3d570f8.
networkctl status may transiently fail right after start_networkd() because networkd has not yet picked up the freshly-created link from the kernel. The retry loop in wait_operstate() did not catch the resulting subprocess.CalledProcessError, so the test aborted on the first attempt instead of retrying for the configured timeout.
Observed in TEST-85-NETWORK-NetworkdBridgeTests, subtest test_bridge_configure_without_carrier[no-slave]:
[ 19.600156] systemd-networkd-tests.py[526]: Failed to issue io.systemd.Network.Link.Describe() varlink call: Invalid argument
[ 53.124982] systemd[1]: systemd-networkd.service: Changed start -> running
[ 53.336167] systemd-networkd-tests.py[526]: ERROR: test_bridge_configure_without_carrier (__main__.NetworkdBridgeTests.test_bridge_configure_without_carrier) (test='no-slave')
[ 53.336167] systemd-networkd-tests.py[526]: self.wait_operstate('bridge99', operstate=r'(no-carrier|routable)', setup_state=None, setup_timeout=30)
[ 53.336167] systemd-networkd-tests.py[526]: subprocess.CalledProcessError: Command '['/usr/bin/networkctl', '-n', '0', 'status', 'bridge99']' returned non-zero exit status 1.
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
Document the new setting in systemd.network(5) man page
and add coverage in the networkd integration tests.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
> read_dnsmasq_log_file() will raise FileNotFoundError if dnsmasq hasn’t created the
> log file yet (or if the file was just removed by stop_dnsmasq() before the restart).
> This would error the test instead of retrying.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
MultiPathRoute= can now specify device-only nexthops without a gateway
address, e.g. MultiPathRoute=@wg0. This enables ECMP configurations over
interfaces that don't use gateway addresses, such as WireGuard tunnels.
The syntax is extended from "address[@device] [weight]" to
"[address]@device [weight]". The address is now optional, but at least
one of gateway or device must be specified. The @ symbol must still be
present for device-only routes, making the syntax unambiguous: @wg0
specifies a device, while a bare IP address specifies a gateway.
Device-only nexthops are only available for IPv4 routes. Device-only
multipath routes for IPv6 are not supported by the kernel's netlink
interface and will be rejected with a warning.
This change is fully backwards compatible. All existing configurations
continue to work unchanged, as they always included a gateway address.
Closes#39699.
dnsmasq 2.92 started converting binary content to ascii so the previous
invalid URL is no longer invalid as it's escaped.
So the test started failing: https://bugs.debian.org/1122015
Use a '|' character instead, which is not a valid URL character but it's
also not escaped by dnsmasq.
Follow-up for 1219391c9f
Add unit tests for config_parse_multipath_route() covering the new
device-only nexthop syntax (@device). Tests verify basic parsing of
device-only routes, gateway with device routes, gateway-only routes,
interface index handling, etc. Also some checks on new hash/duplicate
semantics.
Also add an integration test to verify device-only multipath routes are
correctly installed in the kernel routing table.