Implement requesting additional DHCP options in the internal DHCPv4
client and encode the returned values as hex string to be used by
external components like dispatcher scripts.
Add a setting to request additional dhcp options from a DHCP server.
This is intended to be used for external software like dispatcher
scripts, which want to query these additional option values.
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 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.
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')
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')
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>
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.
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
In kernel, the onlink flag (RTNH_F_ONLINK) is associated with each
nexthop (rtnh_flags) rather than the route as a whole. NM previously
stored it only per-route in NMPlatformIPRoute.r_rtm_flags, which meant
that two nexthops only differing with the onlink flag were combined
as one entry in the platform cache.
Fix this by tracking the onlink flag per-nexthop.
Resolves: https://issues.redhat.com/browse/NMT-1486
dns-search parameters set on VPN connections should be merged with
domains received through the VPN (which may be empty if the connection
sets ignore-auto-dns).
This is currently not the case because domains received by the VPN
connection are only added through nm_l3_config_data_add_domain.
If dns-search is unset, this behaves correctly because the structure
built in _mgr_configs_data_construct in src/core/dns/nm-dns-manager.c
correctly uses the domains from nm_l3_config_data_get_domains.
However if dns-search is set, nm_l3_config_data_get_searches is no
longer empty and it takes precedence because of the "n_searches > 0"
condition.
The previous check was based only on the presence of a non-NULL
"existing_secrets" GVariant. That GVariant is created via:
nm_connection_to_dbus(nm_settings_connection_get_connection(self),
NM_CONNECTION_SERIALIZE_WITH_SECRETS_SYSTEM_OWNED)
The function returns a GVariant containing a first-level dictionary
for each setting, even for those that doesn't contain any secrets. As
a result, the check was requiring the system.modify permission even if
there weren't any cached secrets to send to the agent.
Fix the check to actually check for the presence of any secrets in the
cached dictionary. Some connection types have a third-level
dictionary that can be empty, for example VPNs have vpn.secrets.
The "modify.system" polkit permission allows a user to modify settings
for connection profiles that belong to all users.
For this reason, when an agent returns system secrets (i.e. secrets
that are going to be stored to disk), NetworkManager checks that the
agent has the modify.system permission.
If a secret has the AGENT_OWNED flag, it's stored in the agent
itself. If the secret has the NOT_SAVED flag, it will be asked to
users at the beginning of every connection attempt.
In both those cases the profile is not modified and there is no need
for the modify.system permission. Fix the check to also consider the
NOT_SAVED flag.
GENEVE (Generic Network Virtualization Encapsulation) is a network
tunneling protocol that provides a flexible encapsulation format for
overlay networks. It uses UDP as the transport protocol and supports
variable-length metadata in the tunnel header.
This patch adds GENEVE tunnel to NM's platform layer:
- Add platform API functions (nm_platform_link_geneve_add,
nm_platform_link_get_lnk_geneve)
- Netlink message parsing for the following attributes:
* IFLA_GENEVE_ID - VNI (Virtual Network Identifier)
IPv4 and IPv6 remote
* IFLA_GENEVE_REMOTE
* IFLA_GENEVE_REMOTE6
TTL, TOS, and DF flags
* IFLA_GENEVE_TTL
* IFLA_GENEVE_TOS
* IFLA_GENEVE_DF
UDP destination port
* IFLA_GENEVE_PORT
- Add test cases for GENEVE tunnel creation and detection with two test
modes covering IPv4 and IPv6.
The implementation tries to follow the same patterns as other tunnel
types (GRE, VXLAN, etc.) and integrates with the existing platform
abstraction layer.
Print some statistics about the translation when the connection goes
down:
clat: stats: egress (v4 to v6): tcp 1275, udp 191, icmp 9, other 0, dropped 2; ingress (v6 to v4): tcp 1669, udp 272, icmp 0, other 0, fragment 136, dropped 0
Those counters can be used to better understand what's going wrong in
case of problems; for example, if the packets are being dropped in the
ingress path or in the egress one.
When running the CLAT over an interface that doesn't use the Ethernet
header, like an IP tunnel, there are some changes needed. The BPF
program must compute offsets differently. Also, the DAD packet should
not include an Ethernet header.
libndp >= 1.9 is only required to parse the PREF64 option needed for
CLAT. When building NM in an enviroment with an older libndp, still
allow building without CLAT support.
In the l3cd we already stored the CLAT administrative state (whether
we want to enable it or not) and the selected PREF64. Also store the
other current CLAT parameters, so that we can export them to clients
via D-Bus.
As per draft-ietf-v6ops-claton-14, hosts must perform duplicate
addresses detection (DAD) on the generated CLAT IPv6 address. This is
necessary not only to avoid address collisions but also because some
networks drop traffic from addresses that have not done DAD.
Since doing true DAD adds complexity, adopt the same approach as
Android: start DAD by sending a neighbor solicitation and don't wait
for any reply. This avoids the problem with dropped traffic; it
doesn't help with collisions, but collisions are anyway very unlikely
because the interface identifier is a random 64-bit value.
5ae193ae36/clatd/main.c (363)
Previously the NMNDisc instance always used the last received NAT64
prefix. If a network advertises multiple NAT64 prefixes,
NetworkManager would constantly flip between them. Change this and
keep a list of valid PREF64. Most importantly, stick with the same
PREF64 unless a new one appears from a router with higher priority, or
the current PREF64 expires.