The dispatcher previously serialized all "wait" scripts globally through a
single current_request slot and FIFO requests_waiting queue. Pre-up and
pre-down actions look only at pre-up.d/ resp. pre-down.d/, which never
share script files with the regular dispatcher.d/* lookups, so they cannot
truly conflict with non-pre-* requests.
Yet the global FIFO meant that a slow or hung script for any unrelated
action (for example a misbehaving down or dhcp4-change handler) could
queue up in front of a pre-up dispatcher call. Because pre-up
synchronously gates the device state machine in IP_CHECK
(ip_check_pre_up() in src/core/devices/nm-device.c waits for
_dispatcher_complete_proceed_state), the activation of an unrelated
connection would stall by the full duration of the in-flight regular
script, up to SCRIPT_TIMEOUT (600s). Even an async event like
dhcp4-change inherits gating semantics this way if it is queued ahead
of a pre-up.
Split the queue: REQ_QUEUE_NORMAL for everything routed through
dispatcher.d/, REQ_QUEUE_PRE for pre-up/pre-down/vpn-pre-up/vpn-pre-down.
The two queues advance independently, so a hung regular script no longer
delays connection activation.
Signed-off-by: Stefan Agner <stefan@agner.ch>
Given linux bridge/bond holds DHCP config with
`ipv4.dhcp-send-release: ture` or `ipv6.dhcp-send-release: true`,
when stopping NetworkManager daemon, then NM daemon might
remove/deactivate physical interface first causing DHCP release packet
cannot be delivered.
To fix the issue, we sort the device deletion to let software device
that holds DHCP config to remove first.
Merge Request: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2379
Co-authored-by: Rahul Rajesh <rajeshrah22@gmail.com>
Add _dev_ipdhcpx_cleanup in __set_state_full in DEACTIVATING STATE
before STATE_CHANGED signal is emitted to ensure DHCP RELEASE
packet is sent.
Assisted-by: Cursor with Claude Opus 4.5
The inner condition at line 4086 duplicated the outer check for
NM_CONNECTION_SERIALIZE_ALL, making the else-if branch for
NM_CONNECTION_SERIALIZE_WITH_NON_SECRET unreachable. This meant
the non-secret serialization path was never actually tested.
Restructure to make both branches reachable.
Found by Coverity (CID: DEADCODE).
Fixes: 395a78618b ('libnm/tests: add tests for creating wireguard connection profiles')
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The validation checks 'addr' (the extracted address portion before '/')
but the error message prints 'string' (the full input including the
prefix). For input like "192.168.1.999/24", the error would show the
full string instead of just the invalid address part.
Found by Coverity (CID: COPY_PASTE_ERROR).
Fixes: 539db43619 ('libnm: avoid heap allocation for checking valid routes in nm_ip_route_attribute_validate()')
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The error variable is declared outside the loop but freed with
g_error_free() which does not reset the pointer to NULL. On the
next iteration, g_set_error() sees a non-NULL *err (dangling pointer)
and error->message dereferences freed memory.
Use g_clear_error() instead which also resets the pointer.
Found by Coverity (CID: USE_AFTER_FREE).
Fixes: ecc074b2f8 ('initrd: add command line parser')
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nm_wireguard_peer_new() returns a new peer with refcount 1.
nmt_wireguard_peer_editor_new() takes its own copy via
g_value_dup_boxed(), so the original peer was never unreffed.
Unref the peer after passing it to the editor.
Found by Coverity (CID: RESOURCE_LEAK).
Fixes: b0f5b1d97a ('tui: add WireGuard support to nmtui')
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The loop condition checked the same pointer twice instead of checking
the array element: `ip_data->domains.search && ip_data->domains.search`
should be `ip_data->domains.search && ip_data->domains.search[i]`.
As written, the loop would never terminate when `search` is non-NULL
(only in debug builds with NM_MORE_ASSERTS > 5).
Found by Coverity (CID: CONSTANT_EXPRESSION_RESULT).
Fixes: b8dab47705 ('dns: fix handling default routing domains with systemd-resolved')
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
find_port_info() can return NULL if the port is not registered.
The code dereferenced `info->port_state` before the null check,
which would crash. Move the null check before the dereference.
Found by Coverity (CID: REVERSE_INULL).
Fixes: a8329587c8 ('device: fix bug when deactivating port connections asynchronously')
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The literal `1` is a 32-bit int. When prefix length is less than 33,
the shift `(64 - plen)` exceeds 31 bits, causing undefined behavior.
Cast to guint64 (same type as `num_subnets`) to perform the shift in
64-bit arithmetic.
Found by Coverity (CID: OVERFLOW_BEFORE_WIDEN).
Fixes: ec12fcf6bf ('policy: delegate IPv6 configuration to ipv6.method=shared connections')
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
while the default value of the same in NM is 0, which causes warnings to
arise, change this default value.
Allow the range in NM to stay 0-255 as 0 is used to indicate arp_missed_max
is unset (for modes that don't support the setting), however do not let it
be set beyond the kernel permissible range for the modes that support it, set
it to the kernel default of 2 instead.
Do not apply or reapply the arp_missed_max setting when it is not
supported.
Signed-off-by: Pradyumn Rahar <pradyumn.rahar@oracle.com>
When creating the first device in a veth pair, the peer ifindex is
valid, but the peer device does not exist yet. This should be set
when update_properties() is called for the second device, but fix
the conditional.
Bond connections can have options that are not exposed by any widget
in the bond editor. The presence of certain mode-specific options makes
it impossible to change the mode, e.g. from 802.3ad to active-backup
when `lacp_rate` is set.
Introduce an "Other options" list that shows all bond options not
already configurable by a specific widget, and allow the user to edit
them as key=value entries.
Resolves#1805
Resolves: https://redhat.atlassian.net/browse/NMT-1888
During the dbus-glib to GDBus port in 89228569f (2014), the last-resort
gateway in nm_ip_up() was accidentally changed from peer_opts.hisaddr to
peer_opts.ouraddr. peer_opts.ouraddr is typically 0 when IPCP does not
provide a peer address, causing gateway=0 and broken PPP connectivity
probing/routing behavior.
Restore the original behavior from 369299271 (2008).
Fixes: 89228569f8 ('ppp-manager: port nm-pppd-plugin from dbus-glib to gdbus')
Strip newline from GI_TYPELIB_PATH and LD_LIBRARY_PATH
run_command().stdout() returns the raw shell output including a trailing
newline. When the value is used to build a colon-separated path, the newline
gets embedded at the end of the last path component, making the directory
invalid and causing GObject Introspection to fail with:
ImportError: Typelib file for namespace 'Gio', version '2.0' not found
Use .strip() to remove leading/trailing whitespace from both env variable
reads.
Fix jansson SONAME detection for cross-compilation
When cross-compiling, jansson's pkg-config 'libdir' variable returns a
path relative to the sysroot (e.g., /usr/lib) without the actual sysroot
prefix. The host readelf binary cannot find the library at that path.
Fix this by using meson.get_external_property('sys_root', '') to obtain
the sysroot path set by the cross-compilation environment and prepend it
to the library path before calling readelf.
Signed-off-by: Andrej Kozemcak <andrej.kozemcak@siemens.com>
Replace GFile with GDir to avoid libgvfs and other DBus infra
initialization.
This was done mainly to avoid heavy initialization just for executing
NetworkManager --print-config command.
Resolves: https://redhat.atlassian.net/browse/RHEL-140113
If a DHCP plugin is unknown, the logs says "DHCP client 'x' not
available". This is the same message that is shown if, for example, it
is a valid DHCP plugin name, but the program is not installed in the
system.
For example, after 'dhclient' was deprecated, now NM is built without
support for it. Then, people with old configs `dhcp=dhclient` get the
message "DHCP client 'dhclient' not available". That seems to mean that
dhclient is not installed.
Show a message "unknown DHCP client" instead.
Fixes https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/work_items/1917
Fixes the following warning when building without CLAT:
../src/core/nm-l3cfg.c:4157:1: warning: ‘_clat_prefix_is_better’ defined but not used [-Wunused-function]
4157 | _clat_prefix_is_better(const NMPlatformIP6Address *best,
| ^~~~~~~~~~~~~~~~~~~~~~
Fixes: a03a245819 ('l3cfg: fix selection of the CLAT IPv6 prefix')
If the router advertises both ULA and GUA prefixes, the CLAT should
select the one that better matches the NAT64 prefix when generating
the additional IPv6 address, as recommended by Internet Draft
draft-ietf-v6ops-claton.
The current implementation just takes the first one, which can cause
problems. For example, if the network is using a public NAT64 server,
the NAT64 prefix is in the GUA range. Choosing a ULA as source address
would not work.
Fixes: f0e77a4354 ('Add support for CLAT to l3cfg')
Remove the redundant OK button from the main menu, as menu items are activated with Enter.
This simplifies the UI and avoids unnecessary actions.
Closes#1816
We are going to print the same warning message in different places
(the daemon, nmcli, nmtui). Add a function to return the message. Note
that the message needs to be translated in clients but not in the
daemon logs.
nm_connection_get_unreachable_gateways() is a non-public function,
available in the daemon and clients, which detects gateways in the
static configuration that are not directly reachable.
Unreachable gateways are often the consequence of user mistakes; we
want to catch them early. In the following commits, warnings will be
emitted when a connection is created/modified/activated and has
unreachable gateways.
The --print-config option should only read and print the configuration
without initializing any D-Bus infrastructure. However, g_type_ensure()
calls for D-Bus types were happening before the --print-config check,
causing GLib/GIO to set up D-Bus infrastructure and create cache
directories (~/.cache/bus or /root/.cache) unnecessarily.
Move the g_type_ensure() calls to after the --print-config (and
--version) early exits, so they only run when NetworkManager actually
needs to start normally and use D-Bus.
Resolves: https://issues.redhat.com/browse/RHEL-140113
Assisted-by: Claude Code claude-sonnet-4-5@20250929
Signed-off-by: Till Maas <opensource@till.name>
We need to wait for it to finish so we can show error messages, if any.
Also, if we don't do it, sometimes the `d set eth0 managed ...`
operation fails with the following message in the daemon's log: "Unable
to determine UID of the request". This is because the client's process
is terminated before the daemon can check the permissions, as it needs
to check the uid and gid from the client's process.
Allow to manage or unmanage a device persisting across reboots.
If --permanent is not specified, only the runtime managed state is
changed, preserving the previous behavior. The --permanent-only
option allows to edit only the persistent value, without touching
the runtime value.
Also add the values up/down. Up means managed=yes and set device's
administrative state UP. Down means managed=no and admin state DOWN.
Add the value 'reset' too. It reverts managed runtime status to default
behaviour. When used with `--permanent` flag, the persisted managed
settings is cleared.
Co-authored-by: Rahul Rajesh <rajeshrah22@gmail.com>
Devices like veth without a permanent MAC address cannot be matched by
MAC. If using the BY_MAC flag in SetManaged(), the changes are not
effective for such kind of devices.
Add a BY_NAME flag, in addition to the BY_MAC one. If the client sets
one of them, it means to force this mode of matching. If none is
selected, the daemon will choose how to match, preferring matching by
MAC when possible, and by ifname when not possible.
Control it with a new NM_DEVICE_MANAGED_SET_ADMIN_STATE flag.
This flag will make that, at the same time that the device is moved to
managed/unmanaged, it's admin state is set to up/down. Many users want
to have a way to have their devices in a DOWN admin state when they are
not using them. Because of the complex activation process, NM wants to
have its devices in UP state all the time. However, it is not a problem
to have it DOWN if we are not managing it.
Previous commits added the capability to persist to disk the value of
'managed' received via the D-Bus API. Users might need to clear the
previous content, thus reseting it to its default.
Although this is specially useful for the PERMANENT flag, we need to be
consistent and reset the runtime state too.
If the NM_DEVICE_MANAGED_FLAGS_PERMANENT flag is used, the value will be
stored to disk, to the NetworkManager-intern.conf file, in a [device-*]
section.
To modify the runtime value, the NM_DEVICE_MANAGED_FLAGS_RUNTIME must be
passed. This allows to control independently whether to modify only one
or both.
To support setting devices as managed or unmanaged via D-Bus API in a
permanent way, we need a way to store this configuration on disk. Before
this commit, only config files manually edited allowed it. Following
commits will make use of the new functions to store [device-*] sections
into NetworkManager-intern.conf depending on D-Bus method invocations.
The 'Managed' property only sets the managed state in runtime, but it is
not possible to persist it to disk. Add a SetManaged method that will be
able to persist it to disk. In this commit, it just modify the runtime
state, so it actually only does the same than setting the property.
Storing to disk will be added in next commits.
With `nmcli -f SLAVE` the PORT column will be shown. In this case we
don't duplicate the field because it's typically shown in columns and
having duplicated columns is more annoying than a duplicated row.
They show the same than the old BRIDGE/TEAM.SLAVES and GENERAL.MASTER-PATH.
We missed this when we did the changes in favour of conscious language.
Instead of replacing them, we add a new field that will show the same
value with the new name. This way we avoid breaking users doing
`nmcli -f BRIDGE.SLAVES` or `nmcli ... | grep SLAVES`.
RFC 3442 says:
If the DHCP server returns both a Classless Static Routes option and
a Router option, the DHCP client MUST ignore the Router option.
Currently the internal client is ignoring the Router option only if
the Classless Static Routes option doesn't include a default route,
which is different from what is recommended in the RFC. Fix the behavior.
Fixes: 6adade6f21 ('dhcp: add nettools dhcp4 client')
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/834