From 5d9e3721ad196595acd064e0d3ce66edc2613e51 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Wed, 11 Jan 2023 13:39:59 +0100 Subject: New upstream version 1.40.10 --- Makefile.examples | 1 + Makefile.in | 1 + NEWS | 12 + configure | 26 +-- configure.ac | 2 +- .../dbus-org.freedesktop.NetworkManager.Device.xml | 5 +- docs/api/html/NetworkManager.devhelp2 | 99 ++++---- ...dbus-org.freedesktop.NetworkManager.Device.html | 6 +- docs/api/html/index.html | 2 +- docs/api/html/ix01.html | 16 +- docs/api/html/nm-dbus-types.html | 67 +++++- docs/api/version.xml | 2 +- docs/libnm/html/NMDevice.html | 4 +- docs/libnm/html/NMVpnConnection.html | 8 +- docs/libnm/html/NMVpnPluginOld.html | 12 +- docs/libnm/html/NMVpnServicePlugin.html | 6 +- docs/libnm/html/api-index-full.html | 12 +- docs/libnm/html/index.html | 2 +- docs/libnm/html/libnm-nm-dbus-interface.html | 38 ++++ docs/libnm/html/libnm.devhelp2 | 3 + docs/libnm/html/object-tree.html | 8 +- docs/libnm/html/usage.html | 2 +- docs/libnm/libnm-sections.txt | 1 + docs/libnm/version.xml | 2 +- examples/python/gi/device-reapply.py | 147 ++++++++++++ .../org.freedesktop.NetworkManager.Device.xml | 5 +- man/NetworkManager-dispatcher.8 | 4 +- man/NetworkManager-wait-online.service.8 | 4 +- man/NetworkManager.8 | 6 +- man/NetworkManager.conf.5 | 6 +- man/nm-cloud-setup.8 | 6 +- man/nm-initrd-generator.8 | 6 +- man/nm-online.1 | 6 +- man/nm-openvswitch.7 | 6 +- man/nm-settings-dbus.5 | 6 +- man/nm-settings-dbus.xml | 2 +- man/nm-settings-ifcfg-rh.5 | 6 +- man/nm-settings-ifcfg-rh.xml | 2 +- man/nm-settings-keyfile.5 | 6 +- man/nm-settings-keyfile.xml | 2 +- man/nm-settings-nmcli.5 | 6 +- man/nm-settings-nmcli.xml | 2 +- man/nmcli-examples.7 | 6 +- man/nmcli.1 | 6 +- man/nmtui.1 | 6 +- meson.build | 2 +- po/NetworkManager.pot | 252 ++++++++++----------- src/core/devices/nm-device-veth.c | 32 ++- src/core/devices/nm-device.c | 128 ++++------- src/core/devices/nm-device.h | 5 - src/core/dhcp/nm-dhcp-client.c | 117 +++++++--- src/core/dhcp/nm-dhcp-client.h | 17 +- src/core/dhcp/nm-dhcp-dhclient-utils.c | 91 ++++++-- src/core/dhcp/nm-dhcp-dhclient-utils.h | 5 +- src/core/dhcp/nm-dhcp-dhclient.c | 39 ++-- src/core/dhcp/nm-dhcp-nettools.c | 17 +- src/core/dhcp/nm-dhcp-options.c | 8 +- src/core/dhcp/nm-dhcp-options.h | 9 +- src/core/dhcp/nm-dhcp-systemd.c | 6 +- src/core/dhcp/tests/test-dhcp-dhclient.c | 248 ++++++++++++-------- src/core/dns/nm-dns-dnsmasq.c | 11 +- src/core/dns/nm-dns-dnsmasq.h | 2 + src/core/dns/nm-dns-manager.c | 3 + src/core/ndisc/nm-fake-ndisc.c | 2 +- src/core/nm-policy.c | 112 +-------- src/libnm-client-impl/nm-device-modem.c | 10 +- src/libnm-client-impl/nm-device.c | 4 +- src/libnm-core-public/nm-dbus-interface.h | 18 ++ src/libnm-core-public/nm-dbus-types.xml | 30 +++ src/libnm-core-public/nm-version-macros.h | 2 +- src/libnm-glib-aux/nm-shared-utils.c | 47 ++-- src/libnm-glib-aux/nm-shared-utils.h | 21 +- src/nm-cloud-setup/main.c | 64 ++++-- src/nm-cloud-setup/nm-cloud-setup-utils.c | 16 +- src/nm-cloud-setup/nm-cloud-setup-utils.h | 1 + src/nmcli/devices.c | 5 +- src/nmtui/nmt-device-entry.c | 2 + 77 files changed, 1167 insertions(+), 742 deletions(-) create mode 100755 examples/python/gi/device-reapply.py diff --git a/Makefile.examples b/Makefile.examples index 076af724..3b262209 100644 --- a/Makefile.examples +++ b/Makefile.examples @@ -182,6 +182,7 @@ EXTRA_DIST += \ examples/python/gi/add_connection.py \ examples/python/gi/checkpoint.py \ examples/python/gi/deactivate-all.py \ + examples/python/gi/device-reapply.py \ examples/python/gi/device-state-ip4config.py \ examples/python/gi/dns.py \ examples/python/gi/firewall-zone.py \ diff --git a/Makefile.in b/Makefile.in index 51c5b09b..9128eb17 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4993,6 +4993,7 @@ EXTRA_DIST = src/c-stdaux/src/c-stdaux.h $(NULL) \ examples/python/gi/add_connection.py \ examples/python/gi/checkpoint.py \ examples/python/gi/deactivate-all.py \ + examples/python/gi/device-reapply.py \ examples/python/gi/device-state-ip4config.py \ examples/python/gi/dns.py examples/python/gi/firewall-zone.py \ examples/python/gi/get-active-connections.py \ diff --git a/NEWS b/NEWS index 6ec9b358..237ef590 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +=============================================== +NetworkManager-1.40.10 +Overview of changes since NetworkManager-1.40.8 +=============================================== + +* Fix the evaluation of the autoconnect retries. +* nm-cloud-setup now preserves addresses added externally. +* Ensure that dnsmasq is stopped after changing the dns backend and + restarting the service. +* Fix honoring an explicit DHCPv6 DUID with dhclient. +* Other various fixes. + =============================================== NetworkManager-1.40.8 Overview of changes since NetworkManager-1.40.6 diff --git a/configure b/configure index 5f7abe4e..d387a2f4 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for NetworkManager 1.40.8. +# Generated by GNU Autoconf 2.71 for NetworkManager 1.40.10. # # Report bugs to . # @@ -622,8 +622,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='NetworkManager' PACKAGE_TARNAME='NetworkManager' -PACKAGE_VERSION='1.40.8' -PACKAGE_STRING='NetworkManager 1.40.8' +PACKAGE_VERSION='1.40.10' +PACKAGE_STRING='NetworkManager 1.40.10' PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager' PACKAGE_URL='' @@ -1744,7 +1744,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures NetworkManager 1.40.8 to adapt to many kinds of systems. +\`configure' configures NetworkManager 1.40.10 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1816,7 +1816,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of NetworkManager 1.40.8:";; + short | recursive ) echo "Configuration of NetworkManager 1.40.10:";; esac cat <<\_ACEOF @@ -2171,7 +2171,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -NetworkManager configure 1.40.8 +NetworkManager configure 1.40.10 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2892,7 +2892,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by NetworkManager $as_me 1.40.8, which was +It was created by NetworkManager $as_me 1.40.10, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -4388,7 +4388,7 @@ fi # Define the identity of the package. PACKAGE='NetworkManager' - VERSION='1.40.8' + VERSION='1.40.10' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -19328,8 +19328,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu NM_MAJOR_VERSION=1 NM_MINOR_VERSION=40 -NM_MICRO_VERSION=8 -NM_VERSION=1.40.8 +NM_MICRO_VERSION=10 +NM_VERSION=1.40.10 @@ -19337,7 +19337,7 @@ NM_VERSION=1.40.8 -NM_GIT_SHA=56e29666629b4de98121acd50f0dc364f2066384 +NM_GIT_SHA=5a82c141562dc3a23c73514f7981d76c8b55ea19 if test """" != "no-config-h" ; then @@ -32786,7 +32786,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by NetworkManager $as_me 1.40.8, which was +This file was extended by NetworkManager $as_me 1.40.10, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -32854,7 +32854,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -NetworkManager config.status 1.40.8 +NetworkManager config.status 1.40.10 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 27da3dcc..d5353e6e 100644 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ dnl "shared/nm-version-macros.h.in" dnl - update number in meson.build m4_define([nm_major_version], [1]) m4_define([nm_minor_version], [40]) -m4_define([nm_micro_version], [8]) +m4_define([nm_micro_version], [10]) m4_define([nm_version], [nm_major_version.nm_minor_version.nm_micro_version]) diff --git a/docs/api/dbus-org.freedesktop.NetworkManager.Device.xml b/docs/api/dbus-org.freedesktop.NetworkManager.Device.xml index 0d73ca72..c8ccbd52 100644 --- a/docs/api/dbus-org.freedesktop.NetworkManager.Device.xml +++ b/docs/api/dbus-org.freedesktop.NetworkManager.Device.xml @@ -100,6 +100,9 @@ that the user made these changes intentionally outside of NetworkManager). Reapply can make the applied-connection different from the settings-connection, just like updating the settings-connection can make them different. + +Since 1.42, 1.40.10, "preserve-external-ip" flag (0x1) is supported to not +remove externally added IP addresses and routes on the device during reapply. @@ -117,7 +120,7 @@ If non-zero, the current version id of the applied-connection must match. The cu IN u flags: -Flags which would modify the behavior of the Reapply call. There are no flags defined currently and the users should use the value of 0. +Flags which would modify the behavior of the Reapply call. Invalid flags are rejected. diff --git a/docs/api/html/NetworkManager.devhelp2 b/docs/api/html/NetworkManager.devhelp2 index 257f6bde..52186b6b 100644 --- a/docs/api/html/NetworkManager.devhelp2 +++ b/docs/api/html/NetworkManager.devhelp2 @@ -508,6 +508,7 @@ + @@ -811,54 +812,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.html b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.html index b1e492cb..f5026a1f 100644 --- a/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.html +++ b/docs/api/html/gdbus-org.freedesktop.NetworkManager.Device.html @@ -129,6 +129,10 @@ Reapply can make the applied-connection different from the settings-connection, just like updating the settings-connection can make them different.

+

+Since 1.42, 1.40.10, "preserve-external-ip" flag (0x1) is supported to not +remove externally added IP addresses and routes on the device during reapply. +

@@ -150,7 +154,7 @@ If non-zero, the current version id of the applied-connection must match. The cu diff --git a/docs/api/html/index.html b/docs/api/html/index.html index 6c1324c1..240e61e6 100644 --- a/docs/api/html/index.html +++ b/docs/api/html/index.html @@ -16,7 +16,7 @@

IN u flags:

-Flags which would modify the behavior of the Reapply call. There are no flags defined currently and the users should use the value of 0. +Flags which would modify the behavior of the Reapply call. Invalid flags are rejected.

- for NetworkManager 1.40.8 + for NetworkManager 1.40.10 The latest version of this documentation can be found on-line at https://networkmanager.dev/docs/api/latest/. diff --git a/docs/api/html/ix01.html b/docs/api/html/ix01.html index 15c9933b..d1897057 100644 --- a/docs/api/html/ix01.html +++ b/docs/api/html/ix01.html @@ -1123,9 +1123,9 @@

NMCheckpointCreateFlags, enum NMCheckpointCreateFlags
-
NMClientPermission, enum NMClientPermission +
NMClientPermission, enum NMClientPermission
-
NMClientPermissionResult, enum NMClientPermissionResult +
NMClientPermissionResult, enum NMClientPermissionResult
NMConnectionMultiConnect, enum NMConnectionMultiConnect
@@ -1133,10 +1133,12 @@
NMDeviceCapabilities, enum NMDeviceCapabilities
-
NMDeviceInterfaceFlags, enum NMDeviceInterfaceFlags +
NMDeviceInterfaceFlags, enum NMDeviceInterfaceFlags
NMDeviceModemCapabilities, enum NMDeviceModemCapabilities
+
NMDeviceReapplyFlags, enum NMDeviceReapplyFlags +
NMDeviceState, enum NMDeviceState
NMDeviceStateReason, enum NMDeviceStateReason @@ -1147,13 +1149,13 @@
NMIPTunnelMode, enum NMIPTunnelMode
-
NMManagerReloadFlags, enum NMManagerReloadFlags +
NMManagerReloadFlags, enum NMManagerReloadFlags
NMMetered, enum NMMetered
-
NMMptcpFlags, enum NMMptcpFlags +
NMMptcpFlags, enum NMMptcpFlags
-
NMRadioFlags, enum NMRadioFlags +
NMRadioFlags, enum NMRadioFlags
NMRollbackResult, enum NMRollbackResult
@@ -1169,7 +1171,7 @@
NMState, enum NMState
-
NMTernary, enum NMTernary +
NMTernary, enum NMTernary
NMVpnConnectionState, enum NMVpnConnectionState
diff --git a/docs/api/html/nm-dbus-types.html b/docs/api/html/nm-dbus-types.html index 0580b439..892a1924 100644 --- a/docs/api/html/nm-dbus-types.html +++ b/docs/api/html/nm-dbus-types.html @@ -3071,7 +3071,7 @@

enum NMMetered

-

The NMMetered enum has two different purposes: one is to configure "connection.metered" setting of a connection profile in NMSettingConnection, and the other is to express the actual metered state of the NMDevice at a given moment.

+

The NMMetered enum has two different purposes: one is to configure "connection.metered" setting of a connection profile in NMSettingConnection, and the other is to express the actual metered state of the NMDevice at a given moment.

For the connection profile only NM_METERED_UNKNOWN, NM_METERED_NO and NM_METERED_YES are allowed.

The device's metered state at runtime is determined by the profile which is currently active. If the profile explicitly specifies NM_METERED_NO or NM_METERED_YES, then the device's metered state is as such. If the connection profile leaves it undecided at NM_METERED_UNKNOWN (the default), then NetworkManager tries to guess the metered state, for example based on the device type or on DHCP options (like Android devices exposing a "ANDROID_METERED" DHCP vendor option). This then leads to either NM_METERED_GUESS_NO or NM_METERED_GUESS_YES.

Most applications probably should treat the runtime state NM_METERED_GUESS_YES like NM_METERED_YES, and all other states as not metered.

@@ -4619,12 +4619,63 @@

+

enum NMDeviceReapplyFlags

+

Flags for the Reapply() D-Bus call of a device and nm_device_reapply_async().

+

Since: 1.42, 1.40.10

+

On 1.40.10+, no GFlags type is created.

+

+
+

Values

+
++++++ + + + + + + + + + + + + + + +
+

NM_DEVICE_REAPPLY_FLAGS_NONE

+

+
+

= 0

+

+
+

no flag set.

+

+
 
+

NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP

+

+
+

= 0x1

+

+
+

during reapply, preserve external IP addresses and routes.

+

+
 
+
+
+
+

enum NMTernary

An boolean value that can be overridden by a default.

Since: 1.14

-

Values

+

Values

@@ -4689,7 +4740,7 @@

Since: 1.22

-

Values

+

Values

@@ -4784,7 +4835,7 @@

Since: 1.22

-

Values

+

Values

@@ -4893,7 +4944,7 @@

NMClientPermission values indicate various permissions that NetworkManager clients can obtain to perform certain tasks on behalf of the current user.

-

Values

+

Values

@@ -5182,7 +5233,7 @@

NMClientPermissionResult values indicate what authorizations and permissions the user requires to obtain a given NMClientPermission

-

Values

+

Values

@@ -5262,7 +5313,7 @@

Since: 1.38

-

Values

+

Values

@@ -5326,7 +5377,7 @@

Since: 1.40

-

Values

+

Values

diff --git a/docs/api/version.xml b/docs/api/version.xml index 19d25d0a..5faa4fff 100644 --- a/docs/api/version.xml +++ b/docs/api/version.xml @@ -1 +1 @@ -1.40.8 +1.40.10 diff --git a/docs/libnm/html/NMDevice.html b/docs/libnm/html/NMDevice.html index ac125f88..6542dc63 100644 --- a/docs/libnm/html/NMDevice.html +++ b/docs/libnm/html/NMDevice.html @@ -2242,7 +2242,7 @@ nm_device_get_applied_connection ( - + @@ -2301,7 +2301,7 @@ nm_device_get_applied_connection_async - + diff --git a/docs/libnm/html/NMVpnConnection.html b/docs/libnm/html/NMVpnConnection.html index 6dfe6f8b..1aeca777 100644 --- a/docs/libnm/html/NMVpnConnection.html +++ b/docs/libnm/html/NMVpnConnection.html @@ -44,7 +44,7 @@ - + @@ -136,7 +136,7 @@

Functions

nm_vpn_connection_get_vpn_state ()

-
NMVpnConnectionState
+
NMVpnConnectionState
 nm_vpn_connection_get_vpn_state (NMVpnConnection *vpn);

Gets the current NMVpnConnection state.

@@ -219,7 +219,7 @@ string used by the connection, and must not be modified.


The “vpn-state” property

-
  “vpn-state”                NMVpnConnectionState
+
  “vpn-state”                NMVpnConnectionState

The VPN state of the active VPN connection.

Owner: NMVpnConnection

Flags: Read

diff --git a/docs/libnm/html/NMVpnPluginOld.html b/docs/libnm/html/NMVpnPluginOld.html index ed72c07f..276d337b 100644 --- a/docs/libnm/html/NMVpnPluginOld.html +++ b/docs/libnm/html/NMVpnPluginOld.html @@ -53,7 +53,7 @@
- + @@ -258,7 +258,7 @@ nm_vpn_plugin_old_get_connection (

nm_vpn_plugin_old_get_state ()

-
NMVpnServiceState
+
NMVpnServiceState
 nm_vpn_plugin_old_get_state (NMVpnPluginOld *plugin);

nm_vpn_plugin_old_get_state has been deprecated since version 1.2 and should not be used in newly-written code.

@@ -270,7 +270,7 @@ nm_vpn_plugin_old_get_state (

nm_vpn_plugin_old_set_state ()

void
 nm_vpn_plugin_old_set_state (NMVpnPluginOld *plugin,
-                             NMVpnServiceState state);
+ NMVpnServiceState state);

nm_vpn_plugin_old_set_state has been deprecated since version 1.2 and should not be used in newly-written code.

Replaced by NMVpnServicePlugin.

@@ -336,7 +336,7 @@ nm_vpn_plugin_old_set_login_banner (

nm_vpn_plugin_old_failure ()

void
 nm_vpn_plugin_old_failure (NMVpnPluginOld *plugin,
-                           NMVpnPluginFailure reason);
+ NMVpnPluginFailure reason);

nm_vpn_plugin_old_failure has been deprecated since version 1.2 and should not be used in newly-written code.

Replaced by NMVpnServicePlugin.

@@ -497,7 +497,7 @@ to flags,

The “state” property

-
  “state”                    NMVpnServiceState
+
  “state”                    NMVpnServiceState

The state of the plugin.

NMVpnPluginOld:state has been deprecated since version 1.2 and should not be used in newly-written code.

diff --git a/docs/libnm/html/NMVpnServicePlugin.html b/docs/libnm/html/NMVpnServicePlugin.html index e53bfaa2..6349d207 100644 --- a/docs/libnm/html/NMVpnServicePlugin.html +++ b/docs/libnm/html/NMVpnServicePlugin.html @@ -150,7 +150,7 @@
- + @@ -325,7 +325,7 @@ nm_vpn_service_plugin_set_login_banner

nm_vpn_service_plugin_failure ()

void
 nm_vpn_service_plugin_failure (NMVpnServicePlugin *plugin,
-                               NMVpnPluginFailure reason);
+ NMVpnPluginFailure reason);

Since: 1.2


@@ -522,7 +522,7 @@ to flags,

The “state” property

-
  “state”                    NMVpnServiceState
+
  “state”                    NMVpnServiceState

The state of the plugin.

Owner: NMVpnServicePlugin

Flags: Read / Write

diff --git a/docs/libnm/html/api-index-full.html b/docs/libnm/html/api-index-full.html index a07306d0..a56e05db 100644 --- a/docs/libnm/html/api-index-full.html +++ b/docs/libnm/html/api-index-full.html @@ -913,6 +913,10 @@ NMDeviceEthernetClass, struct in NMDeviceReapplyFlags, enum in nm-dbus-interface + +
+
NMDeviceState, enum in nm-dbus-interface
@@ -3765,11 +3769,11 @@ NMUtilsPredicateStr, user_function in NMSettingOvs
-NMVpnConnectionState, enum in nm-vpn-dbus-interface +NMVpnConnectionState, enum in nm-vpn-dbus-interface
-NMVpnConnectionStateReason, enum in nm-vpn-dbus-interface +NMVpnConnectionStateReason, enum in nm-vpn-dbus-interface
@@ -3821,7 +3825,7 @@ NMVpnConnectionStateReason, enum in nm-vpn-dbus-interface
-NMVpnPluginFailure, enum in nm-vpn-dbus-interface +NMVpnPluginFailure, enum in nm-vpn-dbus-interface
@@ -3933,7 +3937,7 @@ NMVpnPluginFailure, enum in nm-vpn-dbus-interface
-NMVpnServiceState, enum in nm-vpn-dbus-interface +NMVpnServiceState, enum in nm-vpn-dbus-interface
diff --git a/docs/libnm/html/index.html b/docs/libnm/html/index.html index 9b382b70..6ed937a6 100644 --- a/docs/libnm/html/index.html +++ b/docs/libnm/html/index.html @@ -15,7 +15,7 @@

flags

the flags argument. Currently, this value must always be zero.

the flags argument. See NMDeviceReapplyFlags.

 

flags

the flags argument. Currently, this value must always be zero.

the flags argument. See NMDeviceReapplyFlags.

 
-NMVpnConnectionState +NMVpnConnectionState nm_vpn_connection_get_vpn_state () @@ -76,7 +76,7 @@ Read
NMVpnConnectionStateNMVpnConnectionState vpn-state Read
-NMVpnServiceState +NMVpnServiceState nm_vpn_plugin_old_get_state () @@ -142,7 +142,7 @@ Read / Write / Construct Only
NMVpnServiceStateNMVpnServiceState state Read / Write
Read / Write / Construct Only
NMVpnServiceStateNMVpnServiceState state Read / Write

- for libnm 1.40.8 + for libnm 1.40.10 The latest version of this documentation can be found on-line at https://networkmanager.dev/docs/libnm/latest/. diff --git a/docs/libnm/html/libnm-nm-dbus-interface.html b/docs/libnm/html/libnm-nm-dbus-interface.html index 4db42937..a91a828e 100644 --- a/docs/libnm/html/libnm-nm-dbus-interface.html +++ b/docs/libnm/html/libnm-nm-dbus-interface.html @@ -490,6 +490,10 @@ enum +NMDeviceReapplyFlags + + +enum NMTernary @@ -3671,6 +3675,40 @@ the profile. Since: 1.20.


+

enum NMDeviceReapplyFlags

+

Flags for the Reapply() D-Bus call of a device and +nm_device_reapply_async().

+
+

Members

+
+++++ + + + + + + + + + + + + +

NM_DEVICE_REAPPLY_FLAGS_NONE

+

no flag set.

+
 

NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP

+

during reapply, +preserve external IP addresses and routes.

+
 
+
+

Since: 1.42, 1.40.10

+
+
+

enum NMTernary

An boolean value that can be overridden by a default.

diff --git a/docs/libnm/html/libnm.devhelp2 b/docs/libnm/html/libnm.devhelp2 index c3b8145c..308e60cd 100644 --- a/docs/libnm/html/libnm.devhelp2 +++ b/docs/libnm/html/libnm.devhelp2 @@ -494,6 +494,7 @@ + @@ -3485,6 +3486,8 @@ + + diff --git a/docs/libnm/html/object-tree.html b/docs/libnm/html/object-tree.html index 04306fd0..ebc3205c 100644 --- a/docs/libnm/html/object-tree.html +++ b/docs/libnm/html/object-tree.html @@ -214,10 +214,10 @@ ├── NMTernary ├── NMUtilsSecurityType ├── NMVlanPriorityMap - ├── NMVpnConnectionState - ├── NMVpnConnectionStateReason - ├── NMVpnPluginFailure - ├── NMVpnServiceState + ├── NMVpnConnectionState + ├── NMVpnConnectionStateReason + ├── NMVpnPluginFailure + ├── NMVpnServiceState ├── NMWepKeyType ╰── NMWimaxNspNetworkType GBoxed diff --git a/docs/libnm/html/usage.html b/docs/libnm/html/usage.html index 3857f15a..e5334abc 100644 --- a/docs/libnm/html/usage.html +++ b/docs/libnm/html/usage.html @@ -96,7 +96,7 @@

$ cc $(pkg-config --libs --cflags libnm) -o hello-nm hello-nm.c
   $ ./hello-nm
-  NetworkManager version: 1.40.8
+  NetworkManager version: 1.40.10
 
   $ 

diff --git a/docs/libnm/libnm-sections.txt b/docs/libnm/libnm-sections.txt index e497c044..8bfa213b 100644 --- a/docs/libnm/libnm-sections.txt +++ b/docs/libnm/libnm-sections.txt @@ -722,6 +722,7 @@ NMSettingsConnectionFlags NMActivationStateFlags NMSettingsAddConnection2Flags NMSettingsUpdate2Flags +NMDeviceReapplyFlags NMTernary NMManagerReloadFlags NMDeviceInterfaceFlags diff --git a/docs/libnm/version.xml b/docs/libnm/version.xml index 19d25d0a..5faa4fff 100644 --- a/docs/libnm/version.xml +++ b/docs/libnm/version.xml @@ -1 +1 @@ -1.40.8 +1.40.10 diff --git a/examples/python/gi/device-reapply.py b/examples/python/gi/device-reapply.py new file mode 100755 index 00000000..9f5d3306 --- /dev/null +++ b/examples/python/gi/device-reapply.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: LGPL-2.1-or-later + +import os +import sys + +import gi + +gi.require_version("NM", "1.0") +from gi.repository import NM, GLib, Gio, GObject + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + +def kf_from_data(data): + kf = GLib.KeyFile.new() + kf.load_from_data(data, 18446744073709551615, GLib.KeyFileFlags.NONE) + return kf + + +def kf_to_data(kf): + data, l = kf.to_data() + return data + + +def connection_to_kf(connection): + return kf_to_data(NM.keyfile_write(connection, NM.KeyfileHandlerFlags.NONE)) + + +def connection_from_kf(data): + base_dir = os.getcwd() + return NM.keyfile_read(kf_from_data(data), base_dir, NM.KeyfileHandlerFlags.NONE) + + +def connection_from_stdin(): + return connection_from_kf(sys.stdin.read()) + + +def device_get_applied_connection(device): + mainloop = GLib.MainLoop() + r = [] + + def cb(device, result): + try: + connection, version_id = device.get_applied_connection_finish(result) + except Exception as e: + r.append(e) + else: + r.append(connection) + r.append(version_id) + mainloop.quit() + + device.get_applied_connection_async(0, None, cb) + mainloop.run() + if len(r) == 1: + raise r[0] + connection, version_id = r + return connection, version_id + + +def device_reapply(device, connection, version_id, reapply_flags): + mainloop = GLib.MainLoop() + r = [] + + def cb(device, result): + try: + device.reapply_finish(result) + except Exception as e: + r.append(e) + mainloop.quit() + + device.reapply_async(connection, version_id or 0, reapply_flags, None, cb) + mainloop.run() + if len(r) == 1: + raise r[0] + + +def parse_args(): + import argparse + + parser = argparse.ArgumentParser( + prog="device-reapply.py", + description="Example program to interact with the applied connection", + ) + + parser.add_argument("mode", choices=["get", "reapply", "modify"]) + parser.add_argument("device") + parser.add_argument("-V", "--version-id", type=int) + parser.add_argument("-s", "--stdin", action="store_true") + parser.add_argument("-p", "--preserve-external-ip", action="store_true") + + return parser.parse_args() + + +def main(): + args = parse_args() + + nmc = NM.Client.new() + + device = [d for d in nmc.get_devices() if d.get_iface() == args.device] + if not device: + raise Exception(f'Device "{args.device}" not found') + if len(device) != 1: + raise Exception(f'Not unique device "{args.device}" found') + device = device[0] + + assert not args.stdin or args.mode == "modify" + assert not args.preserve_external_ip or args.mode in ["modify", "reapply"] + + if args.mode == "get": + connection, version_id = device_get_applied_connection(device) + + version_id_matches = args.version_id is None or args.version_id == version_id + + print( + f'# Applied connection on "{device.get_iface()}": "{connection.get_id()}" ({connection.get_uuid()}, {connection.get_connection_type()})' + ) + s = "" if version_id_matches else f" (expected {args.version_id})" + print(f"# version-id={version_id}{s}") + print(f"#") + print(f"{connection_to_kf(connection)}") + + if not version_id_matches: + eprint( + f"Applied version-id does not match (expects {args.version_id} but got {version_id})" + ) + sys.exit(1) + sys.exit(0) + + if args.mode == "reapply": + new_connection = None + elif args.stdin: + new_connection = connection_from_stdin() + else: + new_connection, _ = device_get_applied_connection(device) + + reapply_flags = 0 + if args.preserve_external_ip: + reapply_flags = 1 # NM.DeviceReapplyFlags.PRESERVE_EXTERNAL_IP + + device_reapply(device, new_connection, args.version_id, reapply_flags) + + +if __name__ == "__main__": + main() diff --git a/introspection/org.freedesktop.NetworkManager.Device.xml b/introspection/org.freedesktop.NetworkManager.Device.xml index e694fcda..ae626a8e 100644 --- a/introspection/org.freedesktop.NetworkManager.Device.xml +++ b/introspection/org.freedesktop.NetworkManager.Device.xml @@ -322,7 +322,7 @@ Reapply: @connection: The optional connection settings that will be reapplied on the device. If empty, the currently active settings-connection will be used. The connection cannot arbitrarily differ from the current applied-connection otherwise the call will fail. Only certain changes are supported, like adding or removing IP addresses. @version_id: If non-zero, the current version id of the applied-connection must match. The current version id can be retrieved via GetAppliedConnection. This optional argument allows to catch concurrent modifications between the GetAppliedConnection call and Reapply. - @flags: Flags which would modify the behavior of the Reapply call. There are no flags defined currently and the users should use the value of 0. + @flags: Flags which would modify the behavior of the Reapply call. Invalid flags are rejected. Attempts to update the configuration of a device without deactivating it. NetworkManager has the concept of connections, which are profiles that @@ -344,6 +344,9 @@ Reapply can make the applied-connection different from the settings-connection, just like updating the settings-connection can make them different. + + Since 1.42, 1.40.10, "preserve-external-ip" flag (0x1) is supported to not + remove externally added IP addresses and routes on the device during reapply. --> diff --git a/man/NetworkManager-dispatcher.8 b/man/NetworkManager-dispatcher.8 index ba14b58a..8c6b44b4 100644 --- a/man/NetworkManager-dispatcher.8 +++ b/man/NetworkManager-dispatcher.8 @@ -2,9 +2,9 @@ .\" Title: NetworkManager-dispatcher .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Network management daemons -.\" Source: NetworkManager-dispatcher 1.40.8 +.\" Source: NetworkManager-dispatcher 1.40.10 .\" Language: English .\" .TH "NETWORKMANAGER\-DISPATCHER" "8" "" "NetworkManager\-dispatcher 1\&" "Network management daemons" diff --git a/man/NetworkManager-wait-online.service.8 b/man/NetworkManager-wait-online.service.8 index bfe4c230..7d5691b8 100644 --- a/man/NetworkManager-wait-online.service.8 +++ b/man/NetworkManager-wait-online.service.8 @@ -2,9 +2,9 @@ .\" Title: NetworkManager-wait-online.service .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Network management daemons -.\" Source: NetworkManager-wait-online.service 1.40.8 +.\" Source: NetworkManager-wait-online.service 1.40.10 .\" Language: English .\" .TH "NETWORKMANAGER\-WAIT\-ONLINE\&" "8" "" "NetworkManager\-wait\-online\&" "Network management daemons" diff --git a/man/NetworkManager.8 b/man/NetworkManager.8 index b102b9c4..558500f6 100644 --- a/man/NetworkManager.8 +++ b/man/NetworkManager.8 @@ -2,12 +2,12 @@ .\" Title: NetworkManager .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Network management daemons -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NETWORKMANAGER" "8" "" "NetworkManager 1\&.40\&.8" "Network management daemons" +.TH "NETWORKMANAGER" "8" "" "NetworkManager 1\&.40\&.10" "Network management daemons" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/NetworkManager.conf.5 b/man/NetworkManager.conf.5 index 8d092163..926d5ce6 100644 --- a/man/NetworkManager.conf.5 +++ b/man/NetworkManager.conf.5 @@ -2,12 +2,12 @@ .\" Title: NetworkManager.conf .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Configuration -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NETWORKMANAGER\&.CONF" "5" "" "NetworkManager 1\&.40\&.8" "Configuration" +.TH "NETWORKMANAGER\&.CONF" "5" "" "NetworkManager 1\&.40\&.10" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-cloud-setup.8 b/man/nm-cloud-setup.8 index 6e034264..2bab0ed6 100644 --- a/man/nm-cloud-setup.8 +++ b/man/nm-cloud-setup.8 @@ -2,12 +2,12 @@ .\" Title: nm-cloud-setup .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Automatic Network Configuration in Cloud with NetworkManager -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NM\-CLOUD\-SETUP" "8" "" "NetworkManager 1\&.40\&.8" "Automatic Network Configuratio" +.TH "NM\-CLOUD\-SETUP" "8" "" "NetworkManager 1\&.40\&.10" "Automatic Network Configuratio" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-initrd-generator.8 b/man/nm-initrd-generator.8 index f62e4732..902affd9 100644 --- a/man/nm-initrd-generator.8 +++ b/man/nm-initrd-generator.8 @@ -2,12 +2,12 @@ .\" Title: nm-initrd-generator .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: System Administration -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NM\-INITRD\-GENERATOR" "8" "" "NetworkManager 1\&.40\&.8" "System Administration" +.TH "NM\-INITRD\-GENERATOR" "8" "" "NetworkManager 1\&.40\&.10" "System Administration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-online.1 b/man/nm-online.1 index 6e554414..ea6b855d 100644 --- a/man/nm-online.1 +++ b/man/nm-online.1 @@ -2,12 +2,12 @@ .\" Title: nm-online .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: General Commands Manual -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NM\-ONLINE" "1" "" "NetworkManager 1\&.40\&.8" "General Commands Manual" +.TH "NM\-ONLINE" "1" "" "NetworkManager 1\&.40\&.10" "General Commands Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-openvswitch.7 b/man/nm-openvswitch.7 index b6f9fba8..ced68ccd 100644 --- a/man/nm-openvswitch.7 +++ b/man/nm-openvswitch.7 @@ -2,12 +2,12 @@ .\" Title: nm-openvswitch .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Open vSwitch support overview -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NM\-OPENVSWITCH" "7" "" "NetworkManager 1\&.40\&.8" "Open vSwitch support overview" +.TH "NM\-OPENVSWITCH" "7" "" "NetworkManager 1\&.40\&.10" "Open vSwitch support overview" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-settings-dbus.5 b/man/nm-settings-dbus.5 index 5f38dc88..5cff29d2 100644 --- a/man/nm-settings-dbus.5 +++ b/man/nm-settings-dbus.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings-dbus .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Configuration -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NM\-SETTINGS\-DBUS" "5" "" "NetworkManager 1\&.40\&.8" "Configuration" +.TH "NM\-SETTINGS\-DBUS" "5" "" "NetworkManager 1\&.40\&.10" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-settings-dbus.xml b/man/nm-settings-dbus.xml index bb56ea04..6111a8f1 100644 --- a/man/nm-settings-dbus.xml +++ b/man/nm-settings-dbus.xml @@ -1,6 +1,6 @@ -nm-settings-dbusNetworkManager developersnm-settings-dbus5NetworkManagerConfiguration1.40.8nm-settings-dbusDescription of settings and properties of NetworkManager connection profiles on the D-Bus APIDescription +nm-settings-dbusNetworkManager developersnm-settings-dbus5NetworkManagerConfiguration1.40.10nm-settings-dbusDescription of settings and properties of NetworkManager connection profiles on the D-Bus APIDescription NetworkManager is based on a concept of connection profiles, sometimes referred to as connections only. These connection profiles contain a network configuration. When NetworkManager activates a connection profile on a network device the configuration will diff --git a/man/nm-settings-ifcfg-rh.5 b/man/nm-settings-ifcfg-rh.5 index cd438540..55af04f4 100644 --- a/man/nm-settings-ifcfg-rh.5 +++ b/man/nm-settings-ifcfg-rh.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings-ifcfg-rh .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Configuration -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NM\-SETTINGS\-IFCFG\-RH" "5" "" "NetworkManager 1\&.40\&.8" "Configuration" +.TH "NM\-SETTINGS\-IFCFG\-RH" "5" "" "NetworkManager 1\&.40\&.10" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-settings-ifcfg-rh.xml b/man/nm-settings-ifcfg-rh.xml index 3834ec51..3e74ef76 100644 --- a/man/nm-settings-ifcfg-rh.xml +++ b/man/nm-settings-ifcfg-rh.xml @@ -1,6 +1,6 @@ -nm-settings-ifcfg-rhNetworkManager developersnm-settings-ifcfg-rh5NetworkManagerConfiguration1.40.8nm-settings-ifcfg-rhDescription of ifcfg-rh settings pluginDescription +nm-settings-ifcfg-rhNetworkManager developersnm-settings-ifcfg-rh5NetworkManagerConfiguration1.40.10nm-settings-ifcfg-rhDescription of ifcfg-rh settings pluginDescription NetworkManager is based on the concept of connection profiles that contain network configuration (see nm-settings5 for details). The profiles can be stored in various formats. NetworkManager uses plugins for reading and writing diff --git a/man/nm-settings-keyfile.5 b/man/nm-settings-keyfile.5 index c08e2c8f..7e7efd21 100644 --- a/man/nm-settings-keyfile.5 +++ b/man/nm-settings-keyfile.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings-keyfile .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Configuration -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NM\-SETTINGS\-KEYFILE" "5" "" "NetworkManager 1\&.40\&.8" "Configuration" +.TH "NM\-SETTINGS\-KEYFILE" "5" "" "NetworkManager 1\&.40\&.10" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-settings-keyfile.xml b/man/nm-settings-keyfile.xml index b3487914..8b85a440 100644 --- a/man/nm-settings-keyfile.xml +++ b/man/nm-settings-keyfile.xml @@ -1,6 +1,6 @@ -nm-settings-keyfileNetworkManager developersnm-settings-keyfile5NetworkManagerConfiguration1.40.8nm-settings-keyfileDescription of keyfile settings pluginDescription +nm-settings-keyfileNetworkManager developersnm-settings-keyfile5NetworkManagerConfiguration1.40.10nm-settings-keyfileDescription of keyfile settings pluginDescription NetworkManager is based on the concept of connection profiles that contain network configuration (see nm-settings5 for details). The profiles can be stored in various formats. NetworkManager uses plugins for reading and writing diff --git a/man/nm-settings-nmcli.5 b/man/nm-settings-nmcli.5 index d9c1bd4f..fc794c68 100644 --- a/man/nm-settings-nmcli.5 +++ b/man/nm-settings-nmcli.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings-nmcli .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Configuration -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NM\-SETTINGS\-NMCLI" "5" "" "NetworkManager 1\&.40\&.8" "Configuration" +.TH "NM\-SETTINGS\-NMCLI" "5" "" "NetworkManager 1\&.40\&.10" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nm-settings-nmcli.xml b/man/nm-settings-nmcli.xml index 2a77ffa8..a5ebbdd5 100644 --- a/man/nm-settings-nmcli.xml +++ b/man/nm-settings-nmcli.xml @@ -1,6 +1,6 @@ -nm-settings-nmcliNetworkManager developersnm-settings-nmcli5NetworkManagerConfiguration1.40.8nm-settings-nmcliDescription of settings and properties of NetworkManager connection profiles for nmcliDescription +nm-settings-nmcliNetworkManager developersnm-settings-nmcli5NetworkManagerConfiguration1.40.10nm-settings-nmcliDescription of settings and properties of NetworkManager connection profiles for nmcliDescription NetworkManager is based on a concept of connection profiles, sometimes referred to as connections only. These connection profiles contain a network configuration. When NetworkManager activates a connection profile on a network device the configuration will diff --git a/man/nmcli-examples.7 b/man/nmcli-examples.7 index d7c97a67..12d16a6b 100644 --- a/man/nmcli-examples.7 +++ b/man/nmcli-examples.7 @@ -2,12 +2,12 @@ .\" Title: nmcli-examples .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: Examples -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NMCLI\-EXAMPLES" "7" "" "NetworkManager 1\&.40\&.8" "Examples" +.TH "NMCLI\-EXAMPLES" "7" "" "NetworkManager 1\&.40\&.10" "Examples" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nmcli.1 b/man/nmcli.1 index 409a59ad..f547f431 100644 --- a/man/nmcli.1 +++ b/man/nmcli.1 @@ -2,12 +2,12 @@ .\" Title: nmcli .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: General Commands Manual -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NMCLI" "1" "" "NetworkManager 1\&.40\&.8" "General Commands Manual" +.TH "NMCLI" "1" "" "NetworkManager 1\&.40\&.10" "General Commands Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/nmtui.1 b/man/nmtui.1 index 5d74d326..ad188170 100644 --- a/man/nmtui.1 +++ b/man/nmtui.1 @@ -2,12 +2,12 @@ .\" Title: nmtui .\" Author: .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 12/16/2022 +.\" Date: 01/11/2023 .\" Manual: General Commands Manual -.\" Source: NetworkManager 1.40.8 +.\" Source: NetworkManager 1.40.10 .\" Language: English .\" -.TH "NMTUI" "1" "" "NetworkManager 1\&.40\&.8" "General Commands Manual" +.TH "NMTUI" "1" "" "NetworkManager 1\&.40\&.10" "General Commands Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/meson.build b/meson.build index 465558be..f30573f1 100644 --- a/meson.build +++ b/meson.build @@ -6,7 +6,7 @@ project( # - add corresponding NM_VERSION_x_y_z macros in # "src/libnm-core-public/nm-version-macros.h.in" # - update number in configure.ac - version: '1.40.8', + version: '1.40.10', license: 'GPL2+', default_options: [ 'buildtype=debugoptimized', diff --git a/po/NetworkManager.pot b/po/NetworkManager.pot index 29434902..17e471f4 100644 --- a/po/NetworkManager.pot +++ b/po/NetworkManager.pot @@ -6,10 +6,10 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: NetworkManager 1.40.8\n" +"Project-Id-Version: NetworkManager 1.40.10\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/NetworkManager/" "NetworkManager/issues\n" -"POT-Creation-Date: 2022-12-16 15:48+0100\n" +"POT-Creation-Date: 2023-01-11 12:01+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -301,7 +301,7 @@ msgstr "" msgid "Team connection" msgstr "" -#: src/core/devices/wifi/nm-device-olpc-mesh.c:112 src/nmcli/devices.c:1397 +#: src/core/devices/wifi/nm-device-olpc-mesh.c:112 src/nmcli/devices.c:1394 msgid "Mesh" msgstr "" @@ -770,15 +770,15 @@ msgstr "" msgid "The connection was not a MAC-VLAN connection." msgstr "" -#: src/libnm-client-impl/nm-device-modem.c:179 +#: src/libnm-client-impl/nm-device-modem.c:181 msgid "The connection was not a modem connection." msgstr "" -#: src/libnm-client-impl/nm-device-modem.c:189 +#: src/libnm-client-impl/nm-device-modem.c:191 msgid "The connection was not a valid modem connection." msgstr "" -#: src/libnm-client-impl/nm-device-modem.c:198 +#: src/libnm-client-impl/nm-device-modem.c:200 msgid "The device is lacking capabilities required by the connection." msgstr "" @@ -3653,46 +3653,46 @@ msgid "" "type '%s'" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5745 +#: src/libnm-glib-aux/nm-shared-utils.c:5756 msgid "interface name is missing" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5753 +#: src/libnm-glib-aux/nm-shared-utils.c:5764 msgid "interface name is too short" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5761 +#: src/libnm-glib-aux/nm-shared-utils.c:5772 msgid "interface name is reserved" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5774 +#: src/libnm-glib-aux/nm-shared-utils.c:5785 msgid "interface name contains an invalid character" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5782 +#: src/libnm-glib-aux/nm-shared-utils.c:5793 msgid "interface name is longer than 15 characters" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5807 +#: src/libnm-glib-aux/nm-shared-utils.c:5818 #, c-format msgid "'%%' is not allowed in interface names" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5819 +#: src/libnm-glib-aux/nm-shared-utils.c:5830 #, c-format msgid "'%s' is not allowed as interface name" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5841 +#: src/libnm-glib-aux/nm-shared-utils.c:5852 msgid "" "interface name must be alphanumerical with no forward or backward slashes" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5858 +#: src/libnm-glib-aux/nm-shared-utils.c:5869 msgid "interface name must not be empty" msgstr "" -#: src/libnm-glib-aux/nm-shared-utils.c:5866 +#: src/libnm-glib-aux/nm-shared-utils.c:5877 msgid "interface name must be UTF-8 encoded" msgstr "" @@ -3818,7 +3818,7 @@ msgstr "" #: src/libnmc-setting/nm-meta-setting-desc.c:885 #: src/libnmc-setting/nm-meta-setting-desc.c:2847 src/nmcli/connections.c:5533 #: src/nmcli/connections.c:7507 src/nmcli/connections.c:7508 -#: src/nmcli/devices.c:590 src/nmcli/devices.c:596 src/nmcli/devices.c:1408 +#: src/nmcli/devices.c:590 src/nmcli/devices.c:596 src/nmcli/devices.c:1405 #: src/nmcli/general.c:92 src/nmcli/utils.h:313 msgid "yes" msgstr "" @@ -3827,7 +3827,7 @@ msgstr "" #: src/libnmc-setting/nm-meta-setting-desc.c:885 #: src/libnmc-setting/nm-meta-setting-desc.c:2850 src/nmcli/connections.c:5532 #: src/nmcli/connections.c:7507 src/nmcli/connections.c:7508 -#: src/nmcli/devices.c:590 src/nmcli/devices.c:596 src/nmcli/devices.c:1408 +#: src/nmcli/devices.c:590 src/nmcli/devices.c:596 src/nmcli/devices.c:1405 #: src/nmcli/general.c:93 src/nmcli/utils.h:313 msgid "no" msgstr "" @@ -4234,7 +4234,7 @@ msgstr "" #: src/libnmc-base/nm-secret-agent-simple.c:979 #: src/libnmc-base/nm-vpn-helpers.c:143 src/libnmc-base/nm-vpn-helpers.c:147 #: src/libnmc-base/nm-vpn-helpers.c:153 src/libnmc-base/nm-vpn-helpers.c:158 -#: src/nmcli/devices.c:4691 src/nmtui/nmt-page-dsl.c:64 +#: src/nmcli/devices.c:4688 src/nmtui/nmt-page-dsl.c:64 #: src/nmtui/nmt-page-wifi.c:271 src/nmtui/nmt-page-wifi.c:305 #: src/nmtui/nmt-page-wifi.c:344 msgid "Password" @@ -9361,9 +9361,9 @@ msgstr "" msgid "Active connection details" msgstr "" -#: src/nmcli/connections.c:1795 src/nmcli/devices.c:1663 -#: src/nmcli/devices.c:1680 src/nmcli/devices.c:1698 src/nmcli/devices.c:1717 -#: src/nmcli/devices.c:1781 src/nmcli/devices.c:1910 +#: src/nmcli/connections.c:1795 src/nmcli/devices.c:1660 +#: src/nmcli/devices.c:1677 src/nmcli/devices.c:1695 src/nmcli/devices.c:1714 +#: src/nmcli/devices.c:1778 src/nmcli/devices.c:1907 msgid "NAME" msgstr "" @@ -9416,14 +9416,14 @@ msgstr "" #: src/nmcli/connections.c:2432 src/nmcli/connections.c:3153 #: src/nmcli/connections.c:3165 src/nmcli/connections.c:3177 #: src/nmcli/connections.c:3413 src/nmcli/connections.c:9640 -#: src/nmcli/connections.c:9662 src/nmcli/devices.c:3346 -#: src/nmcli/devices.c:3359 src/nmcli/devices.c:3371 src/nmcli/devices.c:3675 -#: src/nmcli/devices.c:3686 src/nmcli/devices.c:3705 src/nmcli/devices.c:3714 -#: src/nmcli/devices.c:3736 src/nmcli/devices.c:3747 src/nmcli/devices.c:3768 -#: src/nmcli/devices.c:4332 src/nmcli/devices.c:4343 src/nmcli/devices.c:4352 -#: src/nmcli/devices.c:4366 src/nmcli/devices.c:4384 src/nmcli/devices.c:4393 -#: src/nmcli/devices.c:4549 src/nmcli/devices.c:4560 src/nmcli/devices.c:4779 -#: src/nmcli/devices.c:4958 src/nmcli/devices.c:5179 +#: src/nmcli/connections.c:9662 src/nmcli/devices.c:3343 +#: src/nmcli/devices.c:3356 src/nmcli/devices.c:3368 src/nmcli/devices.c:3672 +#: src/nmcli/devices.c:3683 src/nmcli/devices.c:3702 src/nmcli/devices.c:3711 +#: src/nmcli/devices.c:3733 src/nmcli/devices.c:3744 src/nmcli/devices.c:3765 +#: src/nmcli/devices.c:4329 src/nmcli/devices.c:4340 src/nmcli/devices.c:4349 +#: src/nmcli/devices.c:4363 src/nmcli/devices.c:4381 src/nmcli/devices.c:4390 +#: src/nmcli/devices.c:4546 src/nmcli/devices.c:4557 src/nmcli/devices.c:4776 +#: src/nmcli/devices.c:4955 src/nmcli/devices.c:5176 #, c-format msgid "Error: %s argument is missing." msgstr "" @@ -9436,14 +9436,14 @@ msgstr "" #: src/nmcli/connections.c:2559 src/nmcli/connections.c:3139 #: src/nmcli/connections.c:3213 src/nmcli/connections.c:9146 #: src/nmcli/connections.c:9230 src/nmcli/connections.c:9769 -#: src/nmcli/devices.c:2010 src/nmcli/devices.c:2286 src/nmcli/devices.c:2453 -#: src/nmcli/devices.c:2579 src/nmcli/devices.c:2763 src/nmcli/devices.c:3546 -#: src/nmcli/devices.c:4513 src/nmcli/devices.c:4965 src/nmcli/general.c:1068 +#: src/nmcli/devices.c:2007 src/nmcli/devices.c:2283 src/nmcli/devices.c:2450 +#: src/nmcli/devices.c:2576 src/nmcli/devices.c:2760 src/nmcli/devices.c:3543 +#: src/nmcli/devices.c:4510 src/nmcli/devices.c:4962 src/nmcli/general.c:1068 #, c-format msgid "Error: %s." msgstr "" -#: src/nmcli/connections.c:2651 src/nmcli/devices.c:4732 +#: src/nmcli/connections.c:2651 src/nmcli/devices.c:4729 #, c-format msgid "no active connection on device '%s'" msgstr "" @@ -9518,10 +9518,10 @@ msgid "invalid passwd-file '%s': %s" msgstr "" #: src/nmcli/connections.c:3187 src/nmcli/connections.c:9673 -#: src/nmcli/devices.c:1967 src/nmcli/devices.c:2016 src/nmcli/devices.c:2459 -#: src/nmcli/devices.c:2651 src/nmcli/devices.c:2718 src/nmcli/devices.c:2918 -#: src/nmcli/devices.c:3406 src/nmcli/devices.c:3784 src/nmcli/devices.c:4403 -#: src/nmcli/devices.c:4566 src/nmcli/devices.c:4787 src/nmcli/devices.c:4970 +#: src/nmcli/devices.c:1964 src/nmcli/devices.c:2013 src/nmcli/devices.c:2456 +#: src/nmcli/devices.c:2648 src/nmcli/devices.c:2715 src/nmcli/devices.c:2915 +#: src/nmcli/devices.c:3403 src/nmcli/devices.c:3781 src/nmcli/devices.c:4400 +#: src/nmcli/devices.c:4563 src/nmcli/devices.c:4784 src/nmcli/devices.c:4967 #, c-format msgid "Error: invalid extra argument '%s'." msgstr "" @@ -9645,7 +9645,7 @@ msgstr "" msgid "Error: invalid . '%s'." msgstr "" -#: src/nmcli/connections.c:5429 src/nmcli/devices.c:2185 +#: src/nmcli/connections.c:5429 src/nmcli/devices.c:2182 #, c-format msgid "Warning: %s.\n" msgstr "" @@ -10479,7 +10479,7 @@ msgstr "" msgid "Interface(s): " msgstr "" -#: src/nmcli/devices.c:71 src/nmcli/devices.c:1442 +#: src/nmcli/devices.c:71 src/nmcli/devices.c:1439 msgid "(none)" msgstr "" @@ -10754,399 +10754,399 @@ msgstr "" msgid "Error: Device '%s' not found.\n" msgstr "" -#: src/nmcli/devices.c:1184 src/nmcli/devices.c:5203 +#: src/nmcli/devices.c:1184 src/nmcli/devices.c:5200 msgid "Error: not all devices found." msgstr "" -#: src/nmcli/devices.c:1216 +#: src/nmcli/devices.c:1213 msgid "No interface specified" msgstr "" -#: src/nmcli/devices.c:1237 +#: src/nmcli/devices.c:1234 #, c-format msgid "Device '%s' not found" msgstr "" -#: src/nmcli/devices.c:1349 +#: src/nmcli/devices.c:1346 #, c-format msgid "%u MHz" msgstr "" -#: src/nmcli/devices.c:1350 +#: src/nmcli/devices.c:1347 #, c-format msgid "%u Mbit/s" msgstr "" -#: src/nmcli/devices.c:1395 +#: src/nmcli/devices.c:1392 msgid "Ad-Hoc" msgstr "" -#: src/nmcli/devices.c:1396 +#: src/nmcli/devices.c:1393 msgid "Infra" msgstr "" -#: src/nmcli/devices.c:1398 +#: src/nmcli/devices.c:1395 msgid "N/A" msgstr "" -#: src/nmcli/devices.c:1590 +#: src/nmcli/devices.c:1587 msgid "Device details" msgstr "" -#: src/nmcli/devices.c:1607 +#: src/nmcli/devices.c:1604 #, c-format msgid "Error: 'device show': %s" msgstr "" -#: src/nmcli/devices.c:1984 +#: src/nmcli/devices.c:1981 msgid "Status of devices" msgstr "" -#: src/nmcli/devices.c:1988 +#: src/nmcli/devices.c:1985 #, c-format msgid "Error: 'device status': %s" msgstr "" -#: src/nmcli/devices.c:2051 src/nmcli/general.c:527 +#: src/nmcli/devices.c:2048 src/nmcli/general.c:527 #, c-format msgid "Error: Timeout %d sec expired." msgstr "" -#: src/nmcli/devices.c:2126 +#: src/nmcli/devices.c:2123 #, c-format msgid "Device '%s' successfully activated with '%s'.\n" msgstr "" -#: src/nmcli/devices.c:2132 +#: src/nmcli/devices.c:2129 msgid "" "Hint: \"nmcli dev wifi show-password\" shows the Wi-Fi name and password.\n" msgstr "" -#: src/nmcli/devices.c:2135 +#: src/nmcli/devices.c:2132 #, c-format msgid "Error: Connection activation failed: (%d) %s.\n" msgstr "" -#: src/nmcli/devices.c:2166 +#: src/nmcli/devices.c:2163 #, c-format msgid "Error: Failed to setup a Wi-Fi hotspot: %s" msgstr "" -#: src/nmcli/devices.c:2170 +#: src/nmcli/devices.c:2167 #, c-format msgid "Error: Failed to add/activate new connection: %s" msgstr "" -#: src/nmcli/devices.c:2174 +#: src/nmcli/devices.c:2171 #, c-format msgid "Error: Failed to activate connection: %s" msgstr "" -#: src/nmcli/devices.c:2242 +#: src/nmcli/devices.c:2239 #, c-format msgid "Error: Device activation failed: %s" msgstr "" -#: src/nmcli/devices.c:2292 +#: src/nmcli/devices.c:2289 #, c-format msgid "Error: extra argument not allowed: '%s'." msgstr "" -#: src/nmcli/devices.c:2361 src/nmcli/devices.c:2374 src/nmcli/devices.c:2629 +#: src/nmcli/devices.c:2358 src/nmcli/devices.c:2371 src/nmcli/devices.c:2626 #, c-format msgid "Device '%s' successfully disconnected.\n" msgstr "" -#: src/nmcli/devices.c:2363 src/nmcli/devices.c:2699 +#: src/nmcli/devices.c:2360 src/nmcli/devices.c:2696 #, c-format msgid "Device '%s' successfully removed.\n" msgstr "" -#: src/nmcli/devices.c:2423 src/nmcli/devices.c:2505 +#: src/nmcli/devices.c:2420 src/nmcli/devices.c:2502 #, c-format msgid "Error: Reapplying connection to device '%s' (%s) failed: %s" msgstr "" -#: src/nmcli/devices.c:2433 src/nmcli/devices.c:2514 +#: src/nmcli/devices.c:2430 src/nmcli/devices.c:2511 #, c-format msgid "Connection successfully reapplied to device '%s'.\n" msgstr "" -#: src/nmcli/devices.c:2536 +#: src/nmcli/devices.c:2533 #, c-format msgid "Error: Reading applied connection from device '%s' (%s) failed: %s" msgstr "" -#: src/nmcli/devices.c:2613 +#: src/nmcli/devices.c:2610 msgid "Error: not all devices disconnected." msgstr "" -#: src/nmcli/devices.c:2614 +#: src/nmcli/devices.c:2611 #, c-format msgid "Error: Device '%s' (%s) disconnecting failed: %s\n" msgstr "" -#: src/nmcli/devices.c:2690 +#: src/nmcli/devices.c:2687 msgid "Error: not all devices deleted." msgstr "" -#: src/nmcli/devices.c:2691 +#: src/nmcli/devices.c:2688 #, c-format msgid "Error: Device '%s' (%s) deletion failed: %s\n" msgstr "" -#: src/nmcli/devices.c:2769 +#: src/nmcli/devices.c:2766 msgid "Error: No property specified." msgstr "" -#: src/nmcli/devices.c:2786 src/nmcli/devices.c:2805 src/nmcli/general.c:797 +#: src/nmcli/devices.c:2783 src/nmcli/devices.c:2802 src/nmcli/general.c:797 #: src/nmcli/general.c:819 #, c-format msgid "Error: '%s' argument is missing." msgstr "" -#: src/nmcli/devices.c:2794 +#: src/nmcli/devices.c:2791 #, c-format msgid "Error: 'managed': %s." msgstr "" -#: src/nmcli/devices.c:2813 +#: src/nmcli/devices.c:2810 #, c-format msgid "Error: 'autoconnect': %s." msgstr "" -#: src/nmcli/devices.c:2820 src/nmcli/general.c:869 +#: src/nmcli/devices.c:2817 src/nmcli/general.c:869 #, c-format msgid "Error: property '%s' is not known." msgstr "" -#: src/nmcli/devices.c:2867 +#: src/nmcli/devices.c:2864 #, c-format msgid "%s: using connection '%s'\n" msgstr "" -#: src/nmcli/devices.c:2893 +#: src/nmcli/devices.c:2890 #, c-format msgid "%s: device created\n" msgstr "" -#: src/nmcli/devices.c:2900 +#: src/nmcli/devices.c:2897 #, c-format msgid "%s: device removed\n" msgstr "" -#: src/nmcli/devices.c:3080 +#: src/nmcli/devices.c:3077 msgid "Wi-Fi scan list" msgstr "" -#: src/nmcli/devices.c:3197 src/nmcli/devices.c:3478 +#: src/nmcli/devices.c:3194 src/nmcli/devices.c:3475 #, c-format msgid "Error: Access point with bssid '%s' not found." msgstr "" -#: src/nmcli/devices.c:3399 +#: src/nmcli/devices.c:3396 #, c-format msgid "Error: 'device wifi': %s" msgstr "" -#: src/nmcli/devices.c:3419 +#: src/nmcli/devices.c:3416 #, c-format msgid "Error: invalid rescan argument: '%s' not among [auto, no, yes]" msgstr "" -#: src/nmcli/devices.c:3458 +#: src/nmcli/devices.c:3455 #, c-format msgid "Error: Device '%s' not found." msgstr "" -#: src/nmcli/devices.c:3462 +#: src/nmcli/devices.c:3459 #, c-format msgid "" "Error: Device '%s' was not recognized as a Wi-Fi device, check " "NetworkManager Wi-Fi plugin." msgstr "" -#: src/nmcli/devices.c:3467 src/nmcli/devices.c:3819 src/nmcli/devices.c:4448 -#: src/nmcli/devices.c:4583 src/nmcli/devices.c:4718 +#: src/nmcli/devices.c:3464 src/nmcli/devices.c:3816 src/nmcli/devices.c:4445 +#: src/nmcli/devices.c:4580 src/nmcli/devices.c:4715 #, c-format msgid "Error: Device '%s' is not a Wi-Fi device." msgstr "" -#: src/nmcli/devices.c:3647 +#: src/nmcli/devices.c:3644 msgid "SSID or BSSID: " msgstr "" -#: src/nmcli/devices.c:3652 +#: src/nmcli/devices.c:3649 msgid "Error: SSID or BSSID are missing." msgstr "" -#: src/nmcli/devices.c:3696 +#: src/nmcli/devices.c:3693 #, c-format msgid "Error: bssid argument value '%s' is not a valid BSSID." msgstr "" -#: src/nmcli/devices.c:3727 +#: src/nmcli/devices.c:3724 #, c-format msgid "" "Error: wep-key-type argument value '%s' is invalid, use 'key' or 'phrase'." msgstr "" -#: src/nmcli/devices.c:3755 src/nmcli/devices.c:3776 +#: src/nmcli/devices.c:3752 src/nmcli/devices.c:3773 #, c-format msgid "Error: %s: %s." msgstr "" -#: src/nmcli/devices.c:3798 +#: src/nmcli/devices.c:3795 #, c-format msgid "Error: BSSID to connect to (%s) differs from bssid argument (%s)." msgstr "" -#: src/nmcli/devices.c:3806 +#: src/nmcli/devices.c:3803 #, c-format msgid "Error: Parameter '%s' is neither SSID nor BSSID." msgstr "" -#: src/nmcli/devices.c:3822 src/nmcli/devices.c:4451 src/nmcli/devices.c:4586 -#: src/nmcli/devices.c:4818 +#: src/nmcli/devices.c:3819 src/nmcli/devices.c:4448 src/nmcli/devices.c:4583 +#: src/nmcli/devices.c:4815 msgid "Error: No Wi-Fi device found." msgstr "" -#: src/nmcli/devices.c:3844 +#: src/nmcli/devices.c:3841 #, c-format msgid "Error: Failed to scan hidden SSID: %s." msgstr "" -#: src/nmcli/devices.c:3876 +#: src/nmcli/devices.c:3873 #, c-format msgid "Error: No network with SSID '%s' found." msgstr "" -#: src/nmcli/devices.c:3880 +#: src/nmcli/devices.c:3877 #, c-format msgid "Error: No access point with BSSID '%s' found." msgstr "" -#: src/nmcli/devices.c:3909 +#: src/nmcli/devices.c:3906 #, c-format msgid "Error: Connection '%s' exists but properties don't match." msgstr "" -#: src/nmcli/devices.c:3958 +#: src/nmcli/devices.c:3955 #, c-format msgid "" "Warning: '%s' should be SSID for hidden APs; but it looks like a BSSID.\n" msgstr "" -#: src/nmcli/devices.c:4000 +#: src/nmcli/devices.c:3997 msgid "Password: " msgstr "" -#: src/nmcli/devices.c:4138 +#: src/nmcli/devices.c:4135 #, c-format msgid "'%s' is not valid WPA PSK" msgstr "" -#: src/nmcli/devices.c:4159 +#: src/nmcli/devices.c:4156 #, c-format msgid "'%s' is not valid WEP key (it should be 5 or 13 ASCII chars)" msgstr "" -#: src/nmcli/devices.c:4178 +#: src/nmcli/devices.c:4175 #, c-format msgid "Hotspot password: %s\n" msgstr "" -#: src/nmcli/devices.c:4357 +#: src/nmcli/devices.c:4354 msgid "Error: ssid is too long." msgstr "" -#: src/nmcli/devices.c:4375 +#: src/nmcli/devices.c:4372 #, c-format msgid "Error: band argument value '%s' is invalid; use 'a' or 'bg'." msgstr "" -#: src/nmcli/devices.c:4426 +#: src/nmcli/devices.c:4423 msgid "Error: channel requires band too." msgstr "" -#: src/nmcli/devices.c:4433 +#: src/nmcli/devices.c:4430 #, c-format msgid "Error: channel '%s' not valid for band '%s'." msgstr "" -#: src/nmcli/devices.c:4464 +#: src/nmcli/devices.c:4461 #, c-format msgid "Error: Device '%s' supports neither AP nor Ad-Hoc mode." msgstr "" -#: src/nmcli/devices.c:4491 +#: src/nmcli/devices.c:4488 #, c-format msgid "Error: Invalid 'password': %s." msgstr "" -#: src/nmcli/devices.c:4542 src/nmcli/devices.c:4772 +#: src/nmcli/devices.c:4539 src/nmcli/devices.c:4769 #, c-format msgid "Error: '%s' cannot repeat." msgstr "" -#: src/nmcli/devices.c:4677 src/nmcli/devices.c:4680 src/nmcli/devices.c:4684 -#: src/nmcli/devices.c:4687 src/nmtui/nmt-page-wifi.c:253 +#: src/nmcli/devices.c:4674 src/nmcli/devices.c:4677 src/nmcli/devices.c:4681 +#: src/nmcli/devices.c:4684 src/nmtui/nmt-page-wifi.c:253 msgid "Security" msgstr "" -#: src/nmcli/devices.c:4677 +#: src/nmcli/devices.c:4674 msgid "None" msgstr "" -#: src/nmcli/devices.c:4806 +#: src/nmcli/devices.c:4803 #, c-format msgid "%s" msgstr "" #. Main header name -#: src/nmcli/devices.c:4859 +#: src/nmcli/devices.c:4856 msgid "Device LLDP neighbors" msgstr "" -#: src/nmcli/devices.c:4992 +#: src/nmcli/devices.c:4989 #, c-format msgid "Error: 'device lldp list': %s" msgstr "" -#: src/nmcli/devices.c:5060 +#: src/nmcli/devices.c:5057 msgid "Checkpoint was removed." msgstr "" #. The command is done, we're in the confirmation prompt. -#: src/nmcli/devices.c:5067 +#: src/nmcli/devices.c:5064 msgid "No" msgstr "" -#: src/nmcli/devices.c:5080 +#: src/nmcli/devices.c:5077 #, c-format msgid "Error: Destroying a checkpoint failed: %s" msgstr "" -#: src/nmcli/devices.c:5102 src/nmcli/devices.c:5103 +#: src/nmcli/devices.c:5099 src/nmcli/devices.c:5100 msgid "Yes" msgstr "" -#: src/nmcli/devices.c:5129 +#: src/nmcli/devices.c:5126 #, c-format msgid "Error: Creating a checkpoint failed: %s" msgstr "" -#: src/nmcli/devices.c:5145 +#: src/nmcli/devices.c:5142 #, c-format msgid "Error: %s" msgstr "" -#: src/nmcli/devices.c:5184 src/nmcli/nmcli.c:885 +#: src/nmcli/devices.c:5181 src/nmcli/nmcli.c:885 #, c-format msgid "Error: '%s' is not a valid timeout." msgstr "" -#: src/nmcli/devices.c:5211 +#: src/nmcli/devices.c:5208 msgid "Error: Expected a command to run after '--'" msgstr "" @@ -11938,7 +11938,7 @@ msgstr "" msgid "WireGuard connection %d" msgstr "" -#: src/nmtui/nmt-device-entry.c:348 +#: src/nmtui/nmt-device-entry.c:350 msgid "Select..." msgstr "" diff --git a/src/core/devices/nm-device-veth.c b/src/core/devices/nm-device-veth.c index c3482e78..17115d33 100644 --- a/src/core/devices/nm-device-veth.c +++ b/src/core/devices/nm-device-veth.c @@ -81,11 +81,13 @@ create_and_realize(NMDevice *device, const NMPlatformLink **out_plink, GError **error) { - const char *iface = nm_device_get_iface(device); - const char *peer; - NMDevice *peer_device; - NMSettingVeth *s_veth; - int r; + NMPlatform *platform = nm_device_get_platform(device); + const char *iface = nm_device_get_iface(device); + NMSettingVeth *s_veth; + const NMPlatformLink *plink; + const NMPlatformLink *peer_plink; + int peer_ifindex; + int r; s_veth = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VETH); if (!s_veth) { @@ -98,15 +100,23 @@ create_and_realize(NMDevice *device, return FALSE; } - peer = nm_setting_veth_get_peer(s_veth); - peer_device = nm_manager_get_device(NM_MANAGER_GET, peer, NM_DEVICE_TYPE_VETH); - if (peer_device) { - if (nm_device_parent_get_device(peer_device)) - /* The veth device and its peer already exist. No need to create it again. */ + /* For veths, users can define two connection profiles referencing each + * other as 'veth.peer'. Only the first to be activated will actually + * create the veth pair; the other must detect that interfaces already + * exist and proceed. */ + plink = nm_platform_link_get_by_ifname(platform, iface); + if (plink && nm_platform_link_veth_get_properties(platform, plink->ifindex, &peer_ifindex)) { + peer_plink = nm_platform_link_get(platform, peer_ifindex); + if (peer_plink && peer_plink->type == NM_LINK_TYPE_VETH + && nm_streq0(peer_plink->name, nm_setting_veth_get_peer(s_veth))) { return TRUE; + } } - r = nm_platform_link_veth_add(nm_device_get_platform(device), iface, peer, out_plink); + r = nm_platform_link_veth_add(nm_device_get_platform(device), + iface, + nm_setting_veth_get_peer(s_veth), + out_plink); if (r < 0) { g_set_error(error, NM_DEVICE_ERROR, diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 059e31f2..a723bf7f 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -96,8 +96,6 @@ #define NM_DEVICE_AUTH_RETRIES_INFINITY -2 #define NM_DEVICE_AUTH_RETRIES_DEFAULT 3 -#define AUTOCONNECT_RESET_RETRIES_TIMER 300 - /*****************************************************************************/ typedef void (*ActivationHandleFunc)(NMDevice *self); @@ -763,9 +761,6 @@ typedef struct _NMDevicePrivate { GVariant *ports_variant; /* Array of port devices D-Bus path */ char *prop_ip_iface; /* IP interface D-Bus property */ - - int autoconnect_retries; - gint32 autoconnect_retries_blocked_until; } NMDevicePrivate; G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) @@ -6397,7 +6392,8 @@ carrier_changed(NMDevice *self, gboolean carrier) if (carrier) { /* If needed, also resume IP configuration that is * waiting for carrier. */ - if (priv->state == NM_DEVICE_STATE_IP_CONFIG) + if (priv->state >= NM_DEVICE_STATE_IP_CONFIG + && priv->state <= NM_DEVICE_STATE_ACTIVATED) nm_device_activate_schedule_stage3_ip_config(self, FALSE); return; } @@ -12791,6 +12787,7 @@ reapply_connection(NMDevice *self, NMConnection *con_old, NMConnection *con_new) * the current settings connection * @version_id: either zero, or the current version id for the applied * connection. + * @reapply_flags: the #NMDeviceReapplyFlags. * @audit_args: on return, a string representing the changes * @error: the error if %FALSE is returned * @@ -12800,11 +12797,12 @@ reapply_connection(NMDevice *self, NMConnection *con_old, NMConnection *con_new) * Return: %FALSE if the new configuration can not be reapplied. */ static gboolean -check_and_reapply_connection(NMDevice *self, - NMConnection *connection, - guint64 version_id, - char **audit_args, - GError **error) +check_and_reapply_connection(NMDevice *self, + NMConnection *connection, + guint64 version_id, + NMDeviceReapplyFlags reapply_flags, + char **audit_args, + GError **error) { NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); @@ -12972,7 +12970,12 @@ check_and_reapply_connection(NMDevice *self, reactivate_proxy_config(self); - nm_device_l3cfg_commit(self, NM_L3_CFG_COMMIT_TYPE_REAPPLY, FALSE); + nm_device_l3cfg_commit( + self, + NM_FLAGS_HAS(reapply_flags, NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP) + ? NM_L3_CFG_COMMIT_TYPE_UPDATE + : NM_L3_CFG_COMMIT_TYPE_REAPPLY, + FALSE); } if (priv->state >= NM_DEVICE_STATE_IP_CHECK) @@ -12989,12 +12992,18 @@ nm_device_reapply(NMDevice *self, NMConnection *connection, GError **error) { g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - return check_and_reapply_connection(self, connection, 0, NULL, error); + return check_and_reapply_connection(self, + connection, + 0, + NM_DEVICE_REAPPLY_FLAGS_NONE, + NULL, + error); } typedef struct { - NMConnection *connection; - guint64 version_id; + NMConnection *connection; + guint64 version_id; + NMDeviceReapplyFlags reapply_flags; } ReapplyData; static void @@ -13005,16 +13014,16 @@ reapply_cb(NMDevice *self, gpointer user_data) { ReapplyData *reapply_data = user_data; - guint64 version_id = 0; - gs_unref_object NMConnection *connection = NULL; - GError *local = NULL; - gs_free char *audit_args = NULL; + guint64 version_id; + gs_unref_object NMConnection *connection = NULL; + NMDeviceReapplyFlags reapply_flags; + GError *local = NULL; + gs_free char *audit_args = NULL; - if (reapply_data) { - connection = reapply_data->connection; - version_id = reapply_data->version_id; - g_slice_free(ReapplyData, reapply_data); - } + connection = reapply_data->connection; + version_id = reapply_data->version_id; + reapply_flags = reapply_data->reapply_flags; + nm_g_slice_free(reapply_data); if (error) { nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, @@ -13034,6 +13043,7 @@ reapply_cb(NMDevice *self, connection ?: nm_device_get_settings_connection_get_connection(self), version_id, + reapply_flags, &audit_args, &local)) { nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, @@ -13067,12 +13077,12 @@ impl_device_reapply(NMDBusObject *obj, ReapplyData *reapply_data; gs_unref_variant GVariant *settings = NULL; guint64 version_id; - guint32 flags; + guint32 reapply_flags_u; + NMDeviceReapplyFlags reapply_flags; - g_variant_get(parameters, "(@a{sa{sv}}tu)", &settings, &version_id, &flags); + g_variant_get(parameters, "(@a{sa{sv}}tu)", &settings, &version_id, &reapply_flags_u); - /* No flags supported as of now. */ - if (flags != 0) { + if (NM_FLAGS_ANY(reapply_flags_u, ~((guint32) NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP))) { error = g_error_new_literal(NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "Invalid flags specified"); nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, @@ -13085,6 +13095,9 @@ impl_device_reapply(NMDBusObject *obj, return; } + reapply_flags = reapply_flags_u; + nm_assert(reapply_flags_u == reapply_flags); + if (priv->state < NM_DEVICE_STATE_PREPARE || priv->state > NM_DEVICE_STATE_ACTIVATED) { error = g_error_new_literal(NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ACTIVE, @@ -13122,12 +13135,12 @@ impl_device_reapply(NMDBusObject *obj, nm_connection_clear_secrets(connection); } - if (connection || version_id) { - reapply_data = g_slice_new(ReapplyData); - reapply_data->connection = connection; - reapply_data->version_id = version_id; - } else - reapply_data = NULL; + reapply_data = g_slice_new(ReapplyData); + *reapply_data = (ReapplyData){ + .connection = connection, + .version_id = version_id, + .reapply_flags = reapply_flags, + }; nm_device_auth_request(self, invocation, @@ -13163,7 +13176,7 @@ impl_device_get_applied_connection(NMDBusObject *obj, if (flags != 0) { g_dbus_method_invocation_return_error_literal(invocation, NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, + NM_DEVICE_ERROR_INVALID_ARGUMENT, "Invalid flags specified"); return; } @@ -16881,49 +16894,6 @@ nm_device_get_initial_hw_address(NMDevice *self) return NM_DEVICE_GET_PRIVATE(self)->hw_addr_initial; } -void -nm_device_set_autoconnect_retries(NMDevice *self, int tries) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - - if (priv->autoconnect_retries != tries) { - _LOGT(LOGD_DEVICE, "autoconnect: retries set %d", tries); - priv->autoconnect_retries = tries; - } - - if (tries) - priv->autoconnect_retries_blocked_until = 0; /* we are not blocked anymore */ - else - priv->autoconnect_retries_blocked_until = - nm_utils_get_monotonic_timestamp_sec() + AUTOCONNECT_RESET_RETRIES_TIMER; -} - -int -nm_device_get_autoconnect_retries(NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - - return priv->autoconnect_retries; -} - -gint32 -nm_device_autoconnect_retries_blocked_until(NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - - return priv->autoconnect_retries_blocked_until; -} - -void -nm_device_autoconnect_retries_reset(NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - - /* default value, we will sync. with connection value when needed */ - priv->autoconnect_retries = -2; - priv->autoconnect_retries_blocked_until = 0; -} - /** * nm_device_spec_match_list: * @self: an #NMDevice @@ -17675,8 +17645,6 @@ nm_device_init(NMDevice *self) priv->sys_iface_state_ = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL; priv->promisc_reset = NM_OPTION_BOOL_DEFAULT; - - priv->autoconnect_retries = -2; } static GObject * diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index fea46bb7..de850e68 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -464,11 +464,6 @@ const char *nm_device_get_permanent_hw_address_full(NMDevice *self, gboolean *out_is_fake); const char *nm_device_get_initial_hw_address(NMDevice *dev); -void nm_device_set_autoconnect_retries(NMDevice *self, int tries); -int nm_device_get_autoconnect_retries(NMDevice *self); -gint32 nm_device_autoconnect_retries_blocked_until(NMDevice *self); -void nm_device_autoconnect_retries_reset(NMDevice *self); - NMDhcpConfig *nm_device_get_dhcp_config(NMDevice *dev, int addr_family); NML3Cfg *nm_device_get_l3cfg(NMDevice *self); diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index 1329b953..805b42d2 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -237,30 +237,65 @@ nm_dhcp_client_create_l3cd(NMDhcpClient *self) NM_IP_CONFIG_SOURCE_DHCP); } +GHashTable * +nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys) +{ + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + GHashTable *options; + GBytes *effective_client_id; + + options = nm_dhcp_option_create_options_dict(static_keys); + + effective_client_id = nm_dhcp_client_get_effective_client_id(self); + if (effective_client_id) { + guint option = NM_IS_IPv4(priv->config.addr_family) ? NM_DHCP_OPTION_DHCP4_CLIENT_ID + : NM_DHCP_OPTION_DHCP6_CLIENT_ID; + gs_free char *str = nm_dhcp_utils_duid_to_string(effective_client_id); + + /* Note that for the nm-dhcp-helper based plugins (dhclient), the plugin + * may send the used client-id/DUID via the environment variables and + * overwrite them yet again. */ + + if (static_keys) { + nm_dhcp_option_add_option(options, priv->config.addr_family, option, str); + } else { + g_hash_table_insert( + options, + g_strdup(nm_dhcp_option_request_string(priv->config.addr_family, option)), + g_steal_pointer(&str)); + } + } + + return options; +} + /*****************************************************************************/ -void +gboolean nm_dhcp_client_set_effective_client_id(NMDhcpClient *self, GBytes *client_id) { - NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); - gs_free char *tmp_str = NULL; + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + gs_free char *tmp_str = NULL; + gs_unref_bytes GBytes *client_id_to_free = NULL; - g_return_if_fail(NM_IS_DHCP_CLIENT(self)); - g_return_if_fail(!client_id || g_bytes_get_size(client_id) >= 2); + g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), FALSE); + g_return_val_if_fail(!client_id || g_bytes_get_size(client_id) >= 2, FALSE); priv = NM_DHCP_CLIENT_GET_PRIVATE(self); if (nm_g_bytes_equal0(priv->effective_client_id, client_id)) - return; + return FALSE; - g_bytes_unref(priv->effective_client_id); + client_id_to_free = g_steal_pointer(&priv->effective_client_id); priv->effective_client_id = nm_g_bytes_ref(client_id); - _LOGT("%s: set %s", + _LOGT("%s: set effective %s", priv->config.addr_family == AF_INET6 ? "duid" : "client-id", priv->effective_client_id ? (tmp_str = nm_dhcp_utils_duid_to_string(priv->effective_client_id)) : "default"); + + return TRUE; } /*****************************************************************************/ @@ -967,12 +1002,6 @@ _dhcp_client_decline(NMDhcpClient *self, return klass->decline(self, l3cd, error_message, error); } -static GBytes * -get_duid(NMDhcpClient *self) -{ - return NULL; -} - static gboolean ipv6_lladdr_timeout(gpointer user_data) { @@ -1302,8 +1331,7 @@ gboolean nm_dhcp_client_start(NMDhcpClient *self, GError **error) { NMDhcpClientPrivate *priv; - gs_unref_bytes GBytes *own_client_id = NULL; - const NMPlatformIP6Address *addr = NULL; + const NMPlatformIP6Address *addr = NULL; int IS_IPv4; g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), FALSE); @@ -1317,11 +1345,6 @@ nm_dhcp_client_start(NMDhcpClient *self, GError **error) IS_IPv4 = NM_IS_IPv4(priv->config.addr_family); if (!IS_IPv4) { - if (!priv->config.v6.enforce_duid) - own_client_id = NM_DHCP_CLIENT_GET_CLASS(self)->get_duid(self); - - nm_dhcp_client_set_effective_client_id(self, own_client_id ?: priv->config.client_id); - addr = ipv6_lladdr_find(self); if (!addr) { _LOGD("waiting for IPv6LL address"); @@ -1449,7 +1472,7 @@ nm_dhcp_client_stop(NMDhcpClient *self, gboolean release) /*****************************************************************************/ static char * -bytearray_variant_to_string(NMDhcpClient *self, GVariant *value, const char *key) +bytearray_variant_to_string(GVariant *value) { const guint8 *array; char *str; @@ -1499,8 +1522,9 @@ label_is_unknown_xyz(const char *label) static void maybe_add_option(NMDhcpClient *self, GHashTable *hash, const char *key, GVariant *value) { - char *str_value; - int priv_opt_num; + const int IS_IPv4 = NM_IS_IPv4(NM_DHCP_CLIENT_GET_PRIVATE(self)->config.addr_family); + char *str_value; + int priv_opt_num; if (!g_variant_is_of_type(value, G_VARIANT_TYPE_BYTESTRING)) return; @@ -1517,27 +1541,49 @@ maybe_add_option(NMDhcpClient *self, GHashTable *hash, const char *key, GVariant if (NM_STR_HAS_PREFIX(key, "private_") || !key[0]) return; - str_value = bytearray_variant_to_string(self, value, key); + str_value = bytearray_variant_to_string(value); if (!str_value) return; + if ((IS_IPv4 && nm_streq(key, "dhcp_client_identifier")) + || (!IS_IPv4 && nm_streq(key, "dhcp6_client_id"))) { + gs_free char *str = g_steal_pointer(&str_value); + gs_unref_bytes GBytes *bytes = NULL; + + /* Validate and normalize the client-id/DUID. */ + + bytes = nm_utils_hexstr2bin(str); + if (!bytes || g_bytes_get_size(bytes) < 2) { + /* Seems invalid. Ignore */ + return; + } + + if (!nm_dhcp_client_set_effective_client_id(self, bytes)) { + /* the client-id is identical and we already set it. Nothing to do. */ + return; + } + + /* The effective-client-id was (re)set. Update "hash" with the new value... */ + str_value = nm_dhcp_utils_duid_to_string(bytes); + } + g_hash_table_insert(hash, g_strdup(key), str_value); /* dhclient has no special labels for private dhcp options: it uses "unknown_xyz" - * labels for that. We need to identify those to alias them to our "private_xyz" - * format unused in the internal dchp plugins. - */ + * labels for that. We need to identify those to alias them to our "private_xyz" + * format unused in the internal dchp plugins. + */ if ((priv_opt_num = label_is_unknown_xyz(key)) > 0) { gs_free guint8 *check_val = NULL; char *hex_str = NULL; gsize len; /* dhclient passes values from dhcp private options in its own "string" format: - * if the raw values are printable as ascii strings, it will pass the string - * representation; if the values are not printable as an ascii string, it will - * pass a string displaying the hex values (hex string). Try to enforce passing - * always an hex string, converting string representation if needed. - */ + * if the raw values are printable as ascii strings, it will pass the string + * representation; if the values are not printable as an ascii string, it will + * pass a string displaying the hex values (hex string). Try to enforce passing + * always an hex string, converting string representation if needed. + */ check_val = nm_utils_hexstr2bin_alloc(str_value, FALSE, TRUE, ":", 0, &len); hex_str = nm_utils_bin2hexstr_full(check_val ?: (guint8 *) str_value, check_val ? len : strlen(str_value), @@ -1623,7 +1669,7 @@ nm_dhcp_client_handle_event(gpointer unused, GVariant *value; /* Copy options */ - str_options = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + str_options = nm_dhcp_client_create_options_dict(self, FALSE); g_variant_iter_init(&iter, options); while (g_variant_iter_next(&iter, "{&sv}", &name, &value)) { maybe_add_option(self, str_options, name, value); @@ -1914,8 +1960,7 @@ nm_dhcp_client_class_init(NMDhcpClientClass *client_class) client_class->accept = _accept; client_class->decline = decline; - client_class->stop = stop; - client_class->get_duid = get_duid; + client_class->stop = stop; obj_properties[PROP_CONFIG] = g_param_spec_pointer(NM_DHCP_CLIENT_CONFIG, diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h index 51c6bc04..6f403b61 100644 --- a/src/core/dhcp/nm-dhcp-client.h +++ b/src/core/dhcp/nm-dhcp-client.h @@ -214,17 +214,6 @@ typedef struct { gboolean (*ip6_start)(NMDhcpClient *self, const struct in6_addr *ll_addr, GError **error); void (*stop)(NMDhcpClient *self, gboolean release); - - /** - * get_duid: - * @self: the #NMDhcpClient - * - * Attempts to find an existing DHCPv6 DUID for this client in the DHCP - * client's persistent configuration. Returned DUID should be the binary - * representation of the DUID. If no DUID is found, %NULL should be - * returned. - */ - GBytes *(*get_duid)(NMDhcpClient *self); } NMDhcpClientClass; GType nm_dhcp_client_get_type(void); @@ -285,11 +274,13 @@ const char *nm_dhcp_client_get_iface(NMDhcpClient *self); NMDedupMultiIndex *nm_dhcp_client_get_multi_idx(NMDhcpClient *self); int nm_dhcp_client_get_ifindex(NMDhcpClient *self); -void nm_dhcp_client_set_effective_client_id(NMDhcpClient *self, GBytes *client_id); -GBytes *nm_dhcp_client_get_effective_client_id(NMDhcpClient *self); +gboolean nm_dhcp_client_set_effective_client_id(NMDhcpClient *self, GBytes *client_id); +GBytes *nm_dhcp_client_get_effective_client_id(NMDhcpClient *self); NML3ConfigData *nm_dhcp_client_create_l3cd(NMDhcpClient *self); +GHashTable *nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys); + /***************************************************************************** * Client data *****************************************************************************/ diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c index 74e6b905..ea8943fa 100644 --- a/src/core/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/core/dhcp/nm-dhcp-dhclient-utils.c @@ -399,6 +399,7 @@ nm_dhcp_dhclient_create_config(const char *interface, if (out_new_client_id) nm_clear_pointer(out_new_client_id, g_bytes_unref); NM_SET_OUT(out_new_client_id, read_client_id(p)); + /* fall-through. We keep the line... */ } /* Override config file hostname and use one from the connection */ @@ -523,6 +524,20 @@ nm_dhcp_dhclient_create_config(const char *interface, return g_string_free(g_steal_pointer(&new_contents), FALSE); } +/* In the lease file, dhclient will write "option dhcp6.client-id $HEXSTR". This + * function does the same. */ +static char * +nm_dhcp_dhclient_escape_duid_as_hex(GBytes *duid) +{ + const guint8 *s; + gsize len; + + nm_assert(duid); + + s = g_bytes_get_data(duid, &len); + return nm_utils_bin2hexstr_fuller(s, len, ':', FALSE, FALSE, NULL); +} + /* Roughly follow what dhclient's quotify_buf() and pretty_escape() functions do */ char * nm_dhcp_dhclient_escape_duid(GBytes *duid) @@ -605,7 +620,7 @@ error: return NULL; } -#define DUID_PREFIX "default-duid \"" +#define DEFAULT_DUID_PREFIX "default-duid \"" /* Beware: @error may be unset even if the function returns %NULL. */ GBytes * @@ -626,10 +641,10 @@ nm_dhcp_dhclient_read_duid(const char *leasefile, GError **error) const char *p = nm_str_skip_leading_spaces(contents_v[i]); GBytes *duid; - if (!NM_STR_HAS_PREFIX(p, DUID_PREFIX)) + if (!NM_STR_HAS_PREFIX(p, DEFAULT_DUID_PREFIX)) continue; - p += NM_STRLEN(DUID_PREFIX); + p += NM_STRLEN(DEFAULT_DUID_PREFIX); g_strchomp((char *) p); @@ -647,15 +662,21 @@ nm_dhcp_dhclient_read_duid(const char *leasefile, GError **error) } gboolean -nm_dhcp_dhclient_save_duid(const char *leasefile, GBytes *duid, GError **error) +nm_dhcp_dhclient_save_duid(const char *leasefile, + GBytes *duid, + gboolean enforce_duid, + GError **error) { gs_free char *escaped_duid = NULL; gs_free const char **lines = NULL; nm_auto_free_gstring GString *s = NULL; const char *const *iter; - gsize len = 0; + gs_free char *conflicting_duid_line = NULL; + gs_free char *contents = NULL; + gsize contents_len = 0; g_return_val_if_fail(leasefile != NULL, FALSE); + if (!duid) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "missing duid"); g_return_val_if_reached(FALSE); @@ -665,48 +686,68 @@ nm_dhcp_dhclient_save_duid(const char *leasefile, GBytes *duid, GError **error) nm_assert(escaped_duid); if (g_file_test(leasefile, G_FILE_TEST_EXISTS)) { - gs_free char *contents = NULL; - - if (!g_file_get_contents(leasefile, &contents, &len, error)) { + if (!g_file_get_contents(leasefile, &contents, &contents_len, error)) { g_prefix_error(error, "failed to read lease file %s: ", leasefile); return FALSE; } - lines = nm_strsplit_set_with_empty(contents, "\n\r"); + lines = nm_strsplit_set_with_empty(contents, "\n"); } - s = g_string_sized_new(len + 50); - g_string_append_printf(s, DUID_PREFIX "%s\";\n", escaped_duid); + s = g_string_sized_new(contents_len + 50); + g_string_append_printf(s, DEFAULT_DUID_PREFIX "%s\";\n", escaped_duid); /* Preserve existing leasefile contents */ if (lines) { for (iter = lines; *iter; iter++) { const char *str = *iter; const char *l; + gboolean ends_with_r; + gsize l_len; + gsize prefix_len; - /* If we find an uncommented DUID in the file, check if - * equal to the one we are going to write: if so, no need - * to update the lease file, otherwise skip the old DUID. - */ - l = nm_str_skip_leading_spaces(str); - if (g_str_has_prefix(l, DUID_PREFIX)) { - gs_strfreev char **split = NULL; + l = nm_str_skip_leading_spaces(str); + l_len = strlen(l); + prefix_len = l - str; - split = g_strsplit(l, "\"", -1); - if (split[0] && nm_streq0(split[1], escaped_duid)) - return TRUE; + ends_with_r = l_len > 0 && l[l_len - 1u] == '\r'; + if (ends_with_r) { + ((char *) l)[--l_len] = '\0'; + } + if (NM_STR_HAS_PREFIX(l, DEFAULT_DUID_PREFIX)) { + /* We always add our line on top. This line can be skipped. */ continue; } - if (str) - g_string_append(s, str); - /* avoid to add an extra '\n' at the end of file */ - if ((iter[1]) != NULL) + if (enforce_duid & NM_STR_HAS_PREFIX(l, "option dhcp6.client-id ")) { + /* we want to use our duid. Skip the per-lease client-id. */ + if (!conflicting_duid_line) { + gs_free char *duid_hex = nm_dhcp_dhclient_escape_duid_as_hex(duid); + + conflicting_duid_line = g_strdup_printf("option dhcp6.client-id %s;", duid_hex); + } + /* We adjust the duid line and set what we want. */ + l = conflicting_duid_line; + } + + g_string_append_len(s, str, prefix_len); + g_string_append(s, l); + if (ends_with_r) { + g_string_append_c(s, '\r'); g_string_append_c(s, '\n'); + } else if ((iter[1]) != NULL) { + /* avoid to add an extra '\n' at the end of file */ + g_string_append_c(s, '\n'); + } } } + if (contents && strlen(contents) == contents_len && nm_streq(contents, s->str)) { + /* The file is already as we want it. We are done. */ + return TRUE; + } + if (!g_file_set_contents(leasefile, s->str, -1, error)) { g_prefix_error(error, "failed to set DUID in lease file %s: ", leasefile); return FALSE; diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.h b/src/core/dhcp/nm-dhcp-dhclient-utils.h index 0ce7dd90..6187cce0 100644 --- a/src/core/dhcp/nm-dhcp-dhclient-utils.h +++ b/src/core/dhcp/nm-dhcp-dhclient-utils.h @@ -29,6 +29,9 @@ GBytes *nm_dhcp_dhclient_unescape_duid(const char *duid); GBytes *nm_dhcp_dhclient_read_duid(const char *leasefile, GError **error); -gboolean nm_dhcp_dhclient_save_duid(const char *leasefile, GBytes *duid, GError **error); +gboolean nm_dhcp_dhclient_save_duid(const char *leasefile, + GBytes *duid, + gboolean enforce_duid, + GError **error); #endif /* __NETWORKMANAGER_DHCP_DHCLIENT_UTILS_H__ */ diff --git a/src/core/dhcp/nm-dhcp-dhclient.c b/src/core/dhcp/nm-dhcp-dhclient.c index d0cd5ebd..e4f40d7c 100644 --- a/src/core/dhcp/nm-dhcp-dhclient.c +++ b/src/core/dhcp/nm-dhcp-dhclient.c @@ -82,6 +82,10 @@ G_DEFINE_TYPE(NMDhcpDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT) /*****************************************************************************/ +static GBytes *read_duid_from_lease(NMDhcpDhclient *self); + +/*****************************************************************************/ + static const char * nm_dhcp_dhclient_get_path(void) { @@ -332,6 +336,7 @@ static gboolean dhclient_start(NMDhcpClient *client, gboolean set_mode, gboolean release, + gboolean set_duid, pid_t *out_pid, GError **error) { @@ -410,8 +415,11 @@ dhclient_start(NMDhcpClient *client, } /* Save the DUID to the leasefile dhclient will actually use */ - if (addr_family == AF_INET6) { - if (!nm_dhcp_dhclient_save_duid(priv->lease_file, client_config->client_id, &local)) { + if (set_duid && addr_family == AF_INET6) { + if (!nm_dhcp_dhclient_save_duid(priv->lease_file, + nm_dhcp_client_get_effective_client_id(client), + client_config->v6.enforce_duid, + &local)) { nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "failed to save DUID to '%s': %s", @@ -547,11 +555,11 @@ ip4_start(NMDhcpClient *client, GError **error) return FALSE; } - if (new_client_id) { - nm_assert(!client_config->client_id); - nm_dhcp_client_set_effective_client_id(client, new_client_id); - } - return dhclient_start(client, FALSE, FALSE, NULL, error); + /* Note that the effective-client-id for IPv4 here might be unknown/NULL. */ + nm_assert(!new_client_id || !client_config->client_id); + nm_dhcp_client_set_effective_client_id(client, client_config->client_id ?: new_client_id); + + return dhclient_start(client, FALSE, FALSE, FALSE, NULL, error); } static gboolean @@ -560,6 +568,7 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error) NMDhcpDhclient *self = NM_DHCP_DHCLIENT(client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE(self); const NMDhcpClientConfig *config; + gs_unref_bytes GBytes *effective_client_id = NULL; config = nm_dhcp_client_get_config(client); @@ -586,7 +595,12 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error) return FALSE; } - return dhclient_start(client, TRUE, FALSE, NULL, error); + nm_assert(config->client_id); + if (!config->v6.enforce_duid) + effective_client_id = read_duid_from_lease(self); + nm_dhcp_client_set_effective_client_id(client, effective_client_id ?: config->client_id); + + return dhclient_start(client, TRUE, FALSE, TRUE, NULL, error); } static void @@ -620,7 +634,7 @@ stop(NMDhcpClient *client, gboolean release) if (release) { pid_t rpid = -1; - if (dhclient_start(client, FALSE, TRUE, &rpid, NULL)) { + if (dhclient_start(client, FALSE, TRUE, FALSE, &rpid, NULL)) { /* Wait a few seconds for the release to happen */ nm_dhcp_client_stop_pid(rpid, nm_dhcp_client_get_iface(client)); } @@ -628,10 +642,10 @@ stop(NMDhcpClient *client, gboolean release) } static GBytes * -get_duid(NMDhcpClient *client) +read_duid_from_lease(NMDhcpDhclient *self) { - NMDhcpDhclient *self = NM_DHCP_DHCLIENT(client); - NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE(self); + NMDhcpClient *client = NM_DHCP_CLIENT(self); + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE(self); const NMDhcpClientConfig *client_config; GBytes *duid = NULL; gs_free char *leasefile = NULL; @@ -724,7 +738,6 @@ nm_dhcp_dhclient_class_init(NMDhcpDhclientClass *dhclient_class) client_class->ip4_start = ip4_start; client_class->ip6_start = ip6_start; client_class->stop = stop; - client_class->get_duid = get_duid; } const NMDhcpClientFactory _nm_dhcp_client_factory_dhclient = { diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index 05b7b52e..df88362e 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -624,7 +624,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err l3cd = nm_dhcp_client_create_l3cd(NM_DHCP_CLIENT(self)); - options = nm_dhcp_option_create_options_dict(); + options = nm_dhcp_client_create_options_dict(NM_DHCP_CLIENT(self), TRUE); if (!lease_parse_address(self, lease, l3cd, iface, options, &lease_address, error)) return NULL; @@ -1100,7 +1100,7 @@ dhcp4_event_cb(int fd, GIOCondition condition, gpointer user_data) } static gboolean -nettools_create(NMDhcpNettools *self, GError **error) +nettools_create(NMDhcpNettools *self, GBytes **out_effective_client_id, GError **error) { NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); nm_auto(n_dhcp4_client_config_freep) NDhcp4ClientConfig *config = NULL; @@ -1197,6 +1197,9 @@ nettools_create(NMDhcpNettools *self, GError **error) priv->event_source = nm_g_unix_fd_add_source(fd, G_IO_IN, dhcp4_event_cb, self); + *out_effective_client_id = + (client_id == client_id_new) ? g_steal_pointer(&client_id_new) : g_bytes_ref(client_id); + return TRUE; } @@ -1287,8 +1290,9 @@ static gboolean ip4_start(NMDhcpClient *client, GError **error) { nm_auto(n_dhcp4_client_probe_config_freep) NDhcp4ClientProbeConfig *config = NULL; - NMDhcpNettools *self = NM_DHCP_NETTOOLS(client); - NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); + NMDhcpNettools *self = NM_DHCP_NETTOOLS(client); + NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); + gs_unref_bytes GBytes *effective_client_id = NULL; const NMDhcpClientConfig *client_config; gs_free char *lease_file = NULL; struct in_addr last_addr = {0}; @@ -1299,7 +1303,7 @@ ip4_start(NMDhcpClient *client, GError **error) g_return_val_if_fail(!priv->probe, FALSE); g_return_val_if_fail(client_config, FALSE); - if (!nettools_create(self, error)) + if (!nettools_create(self, &effective_client_id, error)) return FALSE; r = n_dhcp4_client_probe_config_new(&config); @@ -1445,6 +1449,9 @@ ip4_start(NMDhcpClient *client, GError **error) } _LOGT("dhcp-client4: start " NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(priv->client)); + + nm_dhcp_client_set_effective_client_id(client, effective_client_id); + return TRUE; } diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c index 96fef81a..a5bb06d1 100644 --- a/src/core/dhcp/nm-dhcp-options.c +++ b/src/core/dhcp/nm-dhcp-options.c @@ -190,12 +190,12 @@ static const NMDhcpOption *const _sorted_options_4[G_N_ELEMENTS(_nm_dhcp_option_ }; const NMDhcpOption _nm_dhcp_option_dhcp6_options[] = { - REQ(NM_DHCP_OPTION_DHCP6_CLIENTID, "dhcp6_client_id", FALSE), + REQ(NM_DHCP_OPTION_DHCP6_CLIENT_ID, "dhcp6_client_id", FALSE), /* Don't request server ID by default; some servers don't reply to * Information Requests that request the Server ID. */ - REQ(NM_DHCP_OPTION_DHCP6_SERVERID, "dhcp6_server_id", FALSE), + REQ(NM_DHCP_OPTION_DHCP6_SERVER_ID, "dhcp6_server_id", FALSE), REQ(NM_DHCP_OPTION_DHCP6_DNS_SERVERS, "dhcp6_name_servers", TRUE), REQ(NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, "dhcp6_domain_search", TRUE), @@ -460,7 +460,7 @@ nm_dhcp_option_add_requests_to_options(GHashTable *options, int addr_family) } GHashTable * -nm_dhcp_option_create_options_dict(void) +nm_dhcp_option_create_options_dict(gboolean static_keys) { - return g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, g_free); + return g_hash_table_new_full(nm_str_hash, g_str_equal, static_keys ? NULL : g_free, g_free); } diff --git a/src/core/dhcp/nm-dhcp-options.h b/src/core/dhcp/nm-dhcp-options.h index 4c978c4f..fcc6f9cd 100644 --- a/src/core/dhcp/nm-dhcp-options.h +++ b/src/core/dhcp/nm-dhcp-options.h @@ -157,8 +157,8 @@ typedef enum { } NMDhcpOptionDhcp4Options; typedef enum { - NM_DHCP_OPTION_DHCP6_CLIENTID = 1, - NM_DHCP_OPTION_DHCP6_SERVERID = 2, + NM_DHCP_OPTION_DHCP6_CLIENT_ID = 1, + NM_DHCP_OPTION_DHCP6_SERVER_ID = 2, NM_DHCP_OPTION_DHCP6_DNS_SERVERS = 23, NM_DHCP_OPTION_DHCP6_DOMAIN_LIST = 24, NM_DHCP_OPTION_DHCP6_SNTP_SERVERS = 31, @@ -222,7 +222,8 @@ void nm_dhcp_option_add_option_in_addr(GHashTable *options, in_addr_t value); void nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value); -void nm_dhcp_option_add_requests_to_options(GHashTable *options, int addr_family); -GHashTable *nm_dhcp_option_create_options_dict(void); +void nm_dhcp_option_add_requests_to_options(GHashTable *options, int addr_family); + +GHashTable *nm_dhcp_option_create_options_dict(gboolean static_keys); #endif /* __NM_DHCP_OPTIONS_H__ */ diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index 49e21d97..7ce15d30 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -86,7 +86,7 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro l3cd = nm_dhcp_client_create_l3cd(NM_DHCP_CLIENT(self)); - options = nm_dhcp_option_create_options_dict(); + options = nm_dhcp_client_create_options_dict(NM_DHCP_CLIENT(self), TRUE); if (!nm_dhcp_client_get_config(NM_DHCP_CLIENT(self))->v6.info_only) { gboolean has_any_addresses = FALSE; @@ -271,7 +271,7 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error) /* TODO: honor nm_dhcp_client_get_anycast_address() */ - duid = nm_dhcp_client_get_effective_client_id(client); + duid = client_config->client_id; if (!duid || !(duid_arr = g_bytes_get_data(duid, &duid_len)) || duid_len < 2) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "missing DUID"); g_return_val_if_reached(FALSE); @@ -379,6 +379,8 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error) return FALSE; } + nm_dhcp_client_set_effective_client_id(client, duid); + return TRUE; } diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c index aaa0dbc3..e95f218e 100644 --- a/src/core/dhcp/tests/test-dhcp-dhclient.c +++ b/src/core/dhcp/tests/test-dhcp-dhclient.c @@ -895,122 +895,175 @@ test_read_commented_duid_from_leasefile(void) /*****************************************************************************/ static void -_save_duid(const char *path, const guint8 *duid_bin, gsize duid_len) +_check_duid_impl(const guint8 *duid_bin, + gsize duid_len, + gboolean enforce_duid, + const char *old_content, + const char *new_content) { - gs_unref_bytes GBytes *duid = NULL; - GError *error = NULL; + gs_free_error GError *error = NULL; + gs_free char *contents = NULL; gboolean success; + const char *path = NM_BUILD_BUILDDIR "/src/core/dhcp/tests/check-duid.lease"; + gs_unref_bytes GBytes *duid = NULL; + gsize contents_len; - g_assert(path); g_assert(duid_bin); g_assert(duid_len > 0); - duid = g_bytes_new(duid_bin, duid_len); - success = nm_dhcp_dhclient_save_duid(path, duid, &error); - nmtst_assert_success(success, error); -} - -static void -test_write_duid(void) -{ - const guint8 duid[] = {000, 001, 000, 001, 027, 'X', 0350, 'X', 0, '#', 025, 010, '~', 0254}; - const char *expected_contents = - "default-duid \"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n"; - GError *error = NULL; - gs_free char *contents = NULL; - gboolean success; - const char *path = "test-dhclient-write-duid.leases"; + if (!nm_str_is_empty(old_content) || nmtst_get_rand_bool()) { + success = g_file_set_contents(path, old_content ?: "", -1, &error); + nmtst_assert_success(success, error); + } else + nmtst_file_unlink_if_exists(path); - _save_duid(path, duid, G_N_ELEMENTS(duid)); + duid = g_bytes_new(duid_bin, duid_len); - success = g_file_get_contents(path, &contents, NULL, &error); + success = nm_dhcp_dhclient_save_duid(path, duid, enforce_duid, &error); nmtst_assert_success(success, error); - unlink(path); - - g_assert_cmpstr(expected_contents, ==, contents); -} - -static void -test_write_existing_duid(void) -{ - const guint8 duid[] = - {000, 001, 000, 001, 023, 'o', 023, 'n', 000, '"', 0372, 0214, 0326, 0302}; - const char *original_contents = - "default-duid \"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n"; - const char *expected_contents = - "default-duid \"\\000\\001\\000\\001\\023o\\023n\\000\\\"\\372\\214\\326\\302\";\n"; - GError *error = NULL; - gs_free char *contents = NULL; - gboolean success; - const char *path = "test-dhclient-write-existing-duid.leases"; - - success = g_file_set_contents(path, original_contents, -1, &error); + success = g_file_get_contents(path, &contents, &contents_len, &error); nmtst_assert_success(success, error); + g_assert(contents); - /* Save other DUID; should be overwritten */ - _save_duid(path, duid, G_N_ELEMENTS(duid)); + nmtst_file_unlink(path); - /* reread original contents */ - success = g_file_get_contents(path, &contents, NULL, &error); - nmtst_assert_success(success, error); + if (!nm_streq0(new_content, contents)) + g_error("FAILING:\n\nEXPECTED:\n%s\nACTUAL:\n%s\n\n", new_content, contents); - unlink(path); - g_assert_cmpstr(expected_contents, ==, contents); + g_assert_cmpstr(new_content, ==, contents); + g_assert_cmpint(contents_len, ==, strlen(contents)); } -static const guint8 DUID_BIN[] = - {000, 001, 000, 001, 023, 'o', 023, 'n', 000, '"', 0372, 0214, 0326, 0302}; -#define DUID "\\000\\001\\000\\001\\023o\\023n\\000\\\"\\372\\214\\326\\302" +#define _DUID(...) ((const guint8[]){__VA_ARGS__}) -static void -test_write_existing_commented_duid(void) -{ -#define ORIG_CONTENTS "#default-duid \"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n" - const char *expected_contents = "default-duid \"" DUID "\";\n" ORIG_CONTENTS; - GError *error = NULL; - gs_free char *contents = NULL; - gboolean success; - const char *path = "test-dhclient-write-existing-commented-duid.leases"; - - success = g_file_set_contents(path, ORIG_CONTENTS, -1, &error); - nmtst_assert_success(success, error); - - /* Save other DUID; should be saved on top */ - _save_duid(path, DUID_BIN, G_N_ELEMENTS(DUID_BIN)); - - /* reread original contents */ - success = g_file_get_contents(path, &contents, NULL, &error); - nmtst_assert_success(success, error); - - unlink(path); - g_assert_cmpstr(expected_contents, ==, contents); -#undef ORIG_CONTENTS -} +#define _check_duid(duid, enforce_duid, old_content, new_content) \ + _check_duid_impl((duid), sizeof(duid), (enforce_duid), (old_content), (new_content)) static void -test_write_existing_multiline_duid(void) +test_write_duid(void) { -#define ORIG_CONTENTS \ - "### Commented old DUID ###\n" \ - "#default-duid \"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n" - const char *expected_contents = "default-duid \"" DUID "\";\n" ORIG_CONTENTS; - GError *error = NULL; - gs_free char *contents = NULL; - gboolean success; - nmtst_auto_unlinkfile char *path = - g_strdup("test-dhclient-write-existing-multiline-duid.leases"); - - success = g_file_set_contents(path, ORIG_CONTENTS, -1, &error); - nmtst_assert_success(success, error); - - _save_duid(path, DUID_BIN, G_N_ELEMENTS(DUID_BIN)); + _check_duid(_DUID(000, 001, 000, 001, 027, 'X', 0350, 'X', 0, '#', 025, 010, '~', 0254), + FALSE, + NULL, + "default-duid \"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n"); - success = g_file_get_contents(path, &contents, NULL, &error); - nmtst_assert_success(success, error); + _check_duid( + _DUID(000, 001, 000, 001, 023, 'o', 023, 'n', 000, '"', 0372, 0214, 0326, 0302), + FALSE, + "default-duid \"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n", + "default-duid \"\\000\\001\\000\\001\\023o\\023n\\000\\\"\\372\\214\\326\\302\";\n"); - g_assert_cmpstr(expected_contents, ==, contents); -#undef ORIG_CONTENTS + _check_duid(_DUID(000, 001, 000, 001, 023, 'o', 023, 'n', 000, '"', 0372, 0214, 0326, 0302), + FALSE, + "#default-duid \"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n", + "default-duid " + "\"\\000\\001\\000\\001\\023o\\023n\\000\\\"\\372\\214\\326\\302\";\n#default-duid " + "\"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n"); + _check_duid( + _DUID(000, 001, 000, 001, 023, 'o', 023, 'n', 000, '"', 0372, 0214, 0326, 0302), + FALSE, + "### Commented old DUID ###\n#default-duid " + "\"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n", + "default-duid \"\\000\\001\\000\\001\\023o\\023n\\000\\\"\\372\\214\\326\\302\";\n### " + "Commented old DUID ###\n#default-duid " + "\"\\000\\001\\000\\001\\027X\\350X\\000#\\025\\010~\\254\";\n"); + + _check_duid( + _DUID(0xaa, 0xb, 0xcc, 0xd, 0xee, 0xf), + FALSE, + "default-duid \"\\252\\013\\314\\015\\356\\017\";\nlease6 {\n interface \"eth1\";\n " + " ia-na f1:ce:00:01 {\n starts 1671015678;\n renew 60;\n rebind 105;\n " + "iaaddr 192:168:121::1:112c {\n starts 1671015678;\n preferred-life 120;\n " + " max-life 120;\n }\n }\n option fqdn.encoded true;\n option " + "fqdn.server-update true;\n option fqdn.no-client-update false;\n option fqdn.fqdn " + "\"dff6de4fcb0f\";\n option fqdn.hostname \"dff6de4fcb0f\";\n option dhcp6.client-id " + "aa:b:cc:d:ee:f;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option " + "dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn " + "1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success " + "\"success\";\n}\n", + "default-duid \"\\252\\013\\314\\015\\356\\017\";\nlease6 {\n interface \"eth1\";\n " + " ia-na f1:ce:00:01 {\n starts 1671015678;\n renew 60;\n rebind 105;\n " + "iaaddr 192:168:121::1:112c {\n starts 1671015678;\n preferred-life 120;\n " + " max-life 120;\n }\n }\n option fqdn.encoded true;\n option " + "fqdn.server-update true;\n option fqdn.no-client-update false;\n option fqdn.fqdn " + "\"dff6de4fcb0f\";\n option fqdn.hostname \"dff6de4fcb0f\";\n option dhcp6.client-id " + "aa:b:cc:d:ee:f;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option " + "dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn " + "1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success " + "\"success\";\n}\n"); + + _check_duid( + _DUID(0xaa, 0xb, 0xcc, 0xd, 0xee, 0xf), + FALSE, + "default-duid \"\\252\\013\\314\\015\\356\\017\";\nlease6 {\n interface \"eth1\";\n " + " ia-na f1:ce:00:01 {\n starts 1671015678;\n renew 60;\n rebind 105;\n " + "iaaddr 192:168:121::1:112c {\n starts 1671015678;\n preferred-life 120;\n " + " max-life 120;\n }\n }\n option fqdn.encoded true;\n option " + "fqdn.server-update true;\n option fqdn.no-client-update false;\n option fqdn.fqdn " + "\"dff6de4fcb0f\";\n option fqdn.hostname \"dff6de4fcb0f\";\n option dhcp6.client-id " + "aa:b:cc:d:ee:f;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option " + "dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn " + "1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success " + "\"success\";\r\n}\n", + "default-duid \"\\252\\013\\314\\015\\356\\017\";\nlease6 {\n interface \"eth1\";\n " + " ia-na f1:ce:00:01 {\n starts 1671015678;\n renew 60;\n rebind 105;\n " + "iaaddr 192:168:121::1:112c {\n starts 1671015678;\n preferred-life 120;\n " + " max-life 120;\n }\n }\n option fqdn.encoded true;\n option " + "fqdn.server-update true;\n option fqdn.no-client-update false;\n option fqdn.fqdn " + "\"dff6de4fcb0f\";\n option fqdn.hostname \"dff6de4fcb0f\";\n option dhcp6.client-id " + "aa:b:cc:d:ee:f;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option " + "dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn " + "1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success " + "\"success\";\r\n}\n"); + + _check_duid( + _DUID(0xaa, 0xb, 0xcc, 0xd, 0xee, 0xe), + FALSE, + "default-duid \"\\252\\013\\314\\015\\356\\017\";\nlease6 {\n interface \"eth1\";\n " + " ia-na f1:ce:00:01 {\n starts 1671015678;\n renew 60;\n rebind 105;\n " + "iaaddr 192:168:121::1:112c {\n starts 1671015678;\n preferred-life 120;\n " + " max-life 120;\n }\n }\n option fqdn.encoded true;\n option " + "fqdn.server-update true;\n option fqdn.no-client-update false;\n option fqdn.fqdn " + "\"dff6de4fcb0f\";\n option fqdn.hostname \"dff6de4fcb0f\";\n option dhcp6.client-id " + "aa:b:cc:d:ee:f;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option " + "dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn " + "1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success " + "\"success\";\r\n}\n", + "default-duid \"\\252\\013\\314\\015\\356\\016\";\nlease6 {\n interface \"eth1\";\n " + " ia-na f1:ce:00:01 {\n starts 1671015678;\n renew 60;\n rebind 105;\n " + "iaaddr 192:168:121::1:112c {\n starts 1671015678;\n preferred-life 120;\n " + " max-life 120;\n }\n }\n option fqdn.encoded true;\n option " + "fqdn.server-update true;\n option fqdn.no-client-update false;\n option fqdn.fqdn " + "\"dff6de4fcb0f\";\n option fqdn.hostname \"dff6de4fcb0f\";\n option dhcp6.client-id " + "aa:b:cc:d:ee:f;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option " + "dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn " + "1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success " + "\"success\";\r\n}\n"); + + _check_duid( + _DUID(0xaa, 0xb, 0xcc, 0xd, 0xee, 0xe), + TRUE, + "default-duid \"\\252\\013\\314\\015\\356\\017\";\nlease6 {\n interface \"eth1\";\n " + " ia-na f1:ce:00:01 {\n starts 1671015678;\n renew 60;\n rebind 105;\n " + "iaaddr 192:168:121::1:112c {\n starts 1671015678;\n preferred-life 120;\n " + " max-life 120;\n }\n }\n option fqdn.encoded true;\n option " + "fqdn.server-update true;\n option fqdn.no-client-update false;\n option fqdn.fqdn " + "\"dff6de4fcb0f\";\n option fqdn.hostname \"dff6de4fcb0f\";\n option dhcp6.client-id " + "aa:b:cc:d:ee:f;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option " + "dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn " + "1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success " + "\"success\";\n}\n", + "default-duid \"\\252\\013\\314\\015\\356\\016\";\nlease6 {\n interface \"eth1\";\n " + " ia-na f1:ce:00:01 {\n starts 1671015678;\n renew 60;\n rebind 105;\n " + "iaaddr 192:168:121::1:112c {\n starts 1671015678;\n preferred-life 120;\n " + " max-life 120;\n }\n }\n option fqdn.encoded true;\n option " + "fqdn.server-update true;\n option fqdn.no-client-update false;\n option fqdn.fqdn " + "\"dff6de4fcb0f\";\n option fqdn.hostname \"dff6de4fcb0f\";\n option dhcp6.client-id " + "aa:b:cc:d:ee:e;\n option dhcp6.server-id 0:1:0:1:2b:2c:4d:1d:0:0:0:0:0:0;\n option " + "dhcp6.name-servers 192:168:121:0:ce0f:f1ff:fece:1;\n option dhcp6.fqdn " + "1:c:64:66:66:36:64:65:34:66:63:62:30:66;\n option dhcp6.status-code success " + "\"success\";\n}\n"); } /*****************************************************************************/ @@ -1329,12 +1382,7 @@ main(int argc, char **argv) g_test_add_func("/dhcp/dhclient/read_commented_duid_from_leasefile", test_read_commented_duid_from_leasefile); - g_test_add_func("/dhcp/dhclient/write_duid", test_write_duid); - g_test_add_func("/dhcp/dhclient/write_existing_duid", test_write_existing_duid); - g_test_add_func("/dhcp/dhclient/write_existing_commented_duid", - test_write_existing_commented_duid); - g_test_add_func("/dhcp/dhclient/write_existing_multiline_duid", - test_write_existing_multiline_duid); + g_test_add_func("/dhcp/dhclient/test_write_duid", test_write_duid); return g_test_run(); } diff --git a/src/core/dns/nm-dns-dnsmasq.c b/src/core/dns/nm-dns-dnsmasq.c index 7d0f0490..cc7c03a2 100644 --- a/src/core/dns/nm-dns-dnsmasq.c +++ b/src/core/dns/nm-dns-dnsmasq.c @@ -191,7 +191,8 @@ _gl_pid_kill_external(void) if (!g_file_get_contents(PIDFILE, &contents, NULL, &error)) { if (g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) do_unlink = FALSE; - _LOGD("spawn: failure to read pidfile %s: %s", PIDFILE, error->message); + else + _LOGD("spawn: failure to read pidfile %s: %s", PIDFILE, error->message); g_clear_error(&error); goto handle_kill; } @@ -667,6 +668,14 @@ _gl_pid_spawn(const char *dm_binary, /*****************************************************************************/ +void +nm_dnsmasq_kill_external(void) +{ + _gl_pid_kill_external(); +} + +/*****************************************************************************/ + typedef struct { GDBusConnection *dbus_connection; diff --git a/src/core/dns/nm-dns-dnsmasq.h b/src/core/dns/nm-dns-dnsmasq.h index 575b0b26..98761d3d 100644 --- a/src/core/dns/nm-dns-dnsmasq.h +++ b/src/core/dns/nm-dns-dnsmasq.h @@ -25,4 +25,6 @@ GType nm_dns_dnsmasq_get_type(void); NMDnsPlugin *nm_dns_dnsmasq_new(void); +void nm_dnsmasq_kill_external(void); + #endif /* __NETWORKMANAGER_DNS_DNSMASQ_H__ */ diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c index a2fead3f..edb8ce0f 100644 --- a/src/core/dns/nm-dns-manager.c +++ b/src/core/dns/nm-dns-manager.c @@ -2513,6 +2513,9 @@ again: self); } + if (!NM_IS_DNS_DNSMASQ(priv->plugin)) + nm_dnsmasq_kill_external(); + _update_pending_maybe_changed(self); g_object_thaw_notify(G_OBJECT(self)); diff --git a/src/core/ndisc/nm-fake-ndisc.c b/src/core/ndisc/nm-fake-ndisc.c index 5aea273e..59bf0c1b 100644 --- a/src/core/ndisc/nm-fake-ndisc.c +++ b/src/core/ndisc/nm-fake-ndisc.c @@ -358,7 +358,7 @@ NMNDisc * nm_fake_ndisc_new(NML3Cfg *l3cfg) { const NMNDiscConfig config = { - .l3cfg = g_object_ref(NM_L3CFG(l3cfg)), + .l3cfg = NM_L3CFG(l3cfg), .ifname = nm_l3cfg_get_ifname(l3cfg, TRUE), .node_type = NM_NDISC_NODE_TYPE_HOST, .stable_type = NM_UTILS_STABLE_TYPE_UUID, diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index 518fc596..0c07c29e 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -1579,7 +1579,6 @@ nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self) NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); NMSettingsConnection *const *connections = NULL; guint i; - gboolean multiconnect = FALSE; _LOGT(LOGD_DEVICE, "unblocking failed OVS interfaces"); @@ -1587,13 +1586,6 @@ nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self) for (i = 0; connections[i]; i++) { NMSettingsConnection *sett_conn = connections[i]; NMConnection *connection = nm_settings_connection_get_connection(sett_conn); - NMSettingConnection *s_con = nm_connection_get_setting_connection(connection); - - /* Check if any connection is connect multiple */ - if (s_con - && nm_setting_connection_get_multi_connect(s_con) - == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) - multiconnect = TRUE; if (nm_connection_get_setting_ovs_interface(connection)) { nm_settings_connection_autoconnect_retries_reset(sett_conn); @@ -1603,18 +1595,6 @@ nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self) FALSE); } } - - /* There is, at least, one multiconnect connection with an OVS setting. - * Let's check the OVS devices retries */ - if (multiconnect) { - NMDevice *device; - GHashTableIter h_iter; - g_hash_table_iter_init(&h_iter, priv->devices); - while (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) { - if (nm_device_get_device_type(device) == NM_DEVICE_TYPE_OVS_INTERFACE) - nm_device_autoconnect_retries_reset(device); - } - } } static gboolean @@ -1626,8 +1606,7 @@ reset_autoconnect_all( NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); NMSettingsConnection *const *connections = NULL; guint i; - gboolean changed = FALSE; - gboolean multiconnect = FALSE; + gboolean changed = FALSE; _LOGD(LOGD_DEVICE, "re-enabling autoconnect for all connections%s%s%s", @@ -1638,8 +1617,6 @@ reset_autoconnect_all( connections = nm_settings_get_connections(priv->settings, NULL); for (i = 0; connections[i]; i++) { NMSettingsConnection *sett_conn = connections[i]; - NMSettingConnection *s_con = - nm_connection_get_setting_connection(nm_settings_connection_get_connection(sett_conn)); if (device && !nm_device_check_connection_compatible( @@ -1648,11 +1625,6 @@ reset_autoconnect_all( NULL)) continue; - if (s_con - && nm_setting_connection_get_multi_connect(s_con) - == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) - multiconnect = TRUE; - if (only_no_secrets) { /* we only reset the no-secrets blocked flag. */ if (nm_settings_connection_autoconnect_blocked_reason_set( @@ -1681,20 +1653,6 @@ reset_autoconnect_all( } } } - - /* There is, at least, one multiconnect connection. Let's check the devices retries */ - if (multiconnect) { - NMDevice *device_iter; - GHashTableIter h_iter; - g_hash_table_iter_init(&h_iter, priv->devices); - while (g_hash_table_iter_next(&h_iter, (gpointer *) &device_iter, NULL)) { - if (nm_device_get_autoconnect_retries(device_iter) != -2) { - nm_device_autoconnect_retries_reset(device_iter); - changed = TRUE; - } - } - } - return changed; } @@ -1752,8 +1710,7 @@ reset_connections_retries(gpointer user_data) NMSettingsConnection *const *connections = NULL; guint i; gint32 con_stamp, min_stamp, now; - gboolean changed = FALSE; - gboolean multiconnect = FALSE; + gboolean changed = FALSE; priv->reset_retries_id = 0; @@ -1762,14 +1719,6 @@ reset_connections_retries(gpointer user_data) connections = nm_settings_get_connections(priv->settings, NULL); for (i = 0; connections[i]; i++) { NMSettingsConnection *connection = connections[i]; - NMSettingConnection *s_con = - nm_connection_get_setting_connection(nm_settings_connection_get_connection(connection)); - - /* Check if any connection is connect multiple */ - if (s_con - && nm_setting_connection_get_multi_connect(s_con) - == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) - multiconnect = TRUE; con_stamp = nm_settings_connection_autoconnect_retries_blocked_until(connection); if (con_stamp == 0) @@ -1782,25 +1731,6 @@ reset_connections_retries(gpointer user_data) min_stamp = con_stamp; } - /* There is, at least, one multiconnect connection. Let's check the devices retries */ - if (multiconnect) { - NMDevice *device; - GHashTableIter h_iter; - g_hash_table_iter_init(&h_iter, priv->devices); - while (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) { - con_stamp = nm_device_autoconnect_retries_blocked_until(device); - - /* default value in device is -2, which means, we do not care */ - if (con_stamp <= 0) - continue; - if (con_stamp <= now) { - nm_device_autoconnect_retries_reset(device); - changed = TRUE; - } else if (min_stamp == 0 || min_stamp > con_stamp) - min_stamp = con_stamp; - } - } - /* Schedule the handler again if there are some stamps left */ if (min_stamp != 0) priv->reset_retries_id = @@ -1814,31 +1744,21 @@ reset_connections_retries(gpointer user_data) } static void -_connection_autoconnect_retries_set(NMPolicy *self, - NMSettingsConnection *connection, - NMDevice *device, - int tries) +_connection_autoconnect_retries_set(NMPolicy *self, NMSettingsConnection *connection, int tries) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - NMSettingConnection *s_con; - gint32 retry_time; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); nm_assert(NM_IS_SETTINGS_CONNECTION(connection)); nm_assert(tries >= 0); - s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(connection)); - if (s_con - && nm_setting_connection_get_multi_connect(s_con) == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) { - nm_device_set_autoconnect_retries(device, tries); - retry_time = nm_device_autoconnect_retries_blocked_until(device); - } else { - nm_settings_connection_autoconnect_retries_set(connection, tries); - retry_time = nm_settings_connection_autoconnect_retries_blocked_until(connection); - } + nm_settings_connection_autoconnect_retries_set(connection, tries); if (tries == 0) { /* Schedule a handler to reset retries count */ if (!priv->reset_retries_id) { + gint32 retry_time = + nm_settings_connection_autoconnect_retries_blocked_until(connection); + g_warn_if_fail(retry_time != 0); priv->reset_retries_id = g_timeout_add_seconds(MAX(0, retry_time - nm_utils_get_monotonic_timestamp_sec()), @@ -2100,25 +2020,13 @@ device_state_changed(NMDevice *device, } if (!blocked) { - s_con = nm_connection_get_setting_connection( - nm_settings_connection_get_connection(sett_conn)); - if (s_con - && nm_setting_connection_get_multi_connect(s_con) - == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) { - if (nm_device_get_autoconnect_retries(device) == -2) - nm_device_set_autoconnect_retries( - device, - nm_settings_connection_autoconnect_retries_get(sett_conn)); - - tries = nm_device_get_autoconnect_retries(device); - } else - tries = nm_settings_connection_autoconnect_retries_get(sett_conn); + tries = nm_settings_connection_autoconnect_retries_get(sett_conn); if (tries > 0) { _LOGD(LOGD_DEVICE, "connection '%s' failed to autoconnect; %d tries left", nm_settings_connection_get_id(sett_conn), tries - 1); - _connection_autoconnect_retries_set(self, sett_conn, device, tries - 1); + _connection_autoconnect_retries_set(self, sett_conn, tries - 1); } else if (tries != 0) { _LOGD(LOGD_DEVICE, "connection '%s' failed to autoconnect; infinite tries left", diff --git a/src/libnm-client-impl/nm-device-modem.c b/src/libnm-client-impl/nm-device-modem.c index a1edfb04..4cf6a9bd 100644 --- a/src/libnm-client-impl/nm-device-modem.c +++ b/src/libnm-client-impl/nm-device-modem.c @@ -145,12 +145,14 @@ get_type_description(NMDevice *device) NMDeviceModemCapabilities caps; caps = nm_device_modem_get_current_capabilities(NM_DEVICE_MODEM(device)); - if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) + if (NM_FLAGS_ANY(caps, + NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | NM_DEVICE_MODEM_CAPABILITY_LTE + | NM_DEVICE_MODEM_CAPABILITY_5GNR)) return "gsm"; - else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) + if (NM_FLAGS_HAS(caps, NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) return "cdma"; - else - return NULL; + + return "modem"; } #define MODEM_CAPS_3GPP(caps) \ diff --git a/src/libnm-client-impl/nm-device.c b/src/libnm-client-impl/nm-device.c index 238e7c17..0e971d39 100644 --- a/src/libnm-client-impl/nm-device.c +++ b/src/libnm-client-impl/nm-device.c @@ -2496,7 +2496,7 @@ nm_device_reapply_finish(NMDevice *device, GAsyncResult *result, GError **error) /** * nm_device_get_applied_connection: * @device: a #NMDevice - * @flags: the flags argument. Currently, this value must always be zero. + * @flags: the flags argument. See #NMDeviceReapplyFlags. * @version_id: (out) (allow-none): returns the current version id of * the applied connection * @cancellable: a #GCancellable, or %NULL @@ -2559,7 +2559,7 @@ nm_device_get_applied_connection(NMDevice *device, /** * nm_device_get_applied_connection_async: * @device: a #NMDevice - * @flags: the flags argument. Currently, this value must always be zero. + * @flags: the flags argument. See #NMDeviceReapplyFlags. * @cancellable: a #GCancellable, or %NULL * @callback: callback to be called when the reapply operation completes * @user_data: caller-specific data passed to @callback diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h index 6e1a84a1..3e79d4c6 100644 --- a/src/libnm-core-public/nm-dbus-interface.h +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -1144,6 +1144,24 @@ typedef enum /*< flags >*/ { NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY = 0x40, } NMSettingsUpdate2Flags; +/** + * NMDeviceReapplyFlags: + * @NM_DEVICE_REAPPLY_FLAGS_NONE: no flag set. + * @NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP: during reapply, + * preserve external IP addresses and routes. + * + * Flags for the Reapply() D-Bus call of a device and + * nm_device_reapply_async(). + * + * Since: 1.42, 1.40.10 + * + * On 1.40.10+, no GFlags type is created. + */ +typedef enum /*< skip >*/ { + NM_DEVICE_REAPPLY_FLAGS_NONE = 0, + NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP = 0x1, +} NMDeviceReapplyFlags; + /** * NMTernary: * @NM_TERNARY_DEFAULT: use the globally-configured default value. diff --git a/src/libnm-core-public/nm-dbus-types.xml b/src/libnm-core-public/nm-dbus-types.xml index 52ac4981..d8de9002 100644 --- a/src/libnm-core-public/nm-dbus-types.xml +++ b/src/libnm-core-public/nm-dbus-types.xml @@ -1908,6 +1908,36 @@ + + enum NMDeviceReapplyFlags + + NMDeviceReapplyFlags + + Flags for the Reapply() D-Bus call of a device and nm_device_reapply_async().Since: 1.42, 1.40.10On 1.40.10+, no GFlags type is created. + + Values + + + + + + + + NM_DEVICE_REAPPLY_FLAGS_NONE + = 0 + no flag set. + + + NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP + = 0x1 + during reapply, preserve external IP addresses and routes. + + + + + + + enum NMTernary diff --git a/src/libnm-core-public/nm-version-macros.h b/src/libnm-core-public/nm-version-macros.h index 2b5bc67e..f95ca8ae 100644 --- a/src/libnm-core-public/nm-version-macros.h +++ b/src/libnm-core-public/nm-version-macros.h @@ -30,7 +30,7 @@ * Evaluates to the micro version number of NetworkManager which this source * compiled against. */ -#define NM_MICRO_VERSION (8) +#define NM_MICRO_VERSION (10) /** * NM_CHECK_VERSION: diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index d0885477..aca7d708 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -4846,7 +4846,7 @@ nm_utils_memeqzero(gconstpointer data, gsize length) } /** - * nm_utils_bin2hexstr_full: + * nm_utils_bin2hexstr_fuller: * @addr: pointer of @length bytes. If @length is zero, this may * also be %NULL. * @length: number of bytes in @addr. May also be zero, in which @@ -4854,12 +4854,17 @@ nm_utils_memeqzero(gconstpointer data, gsize length) * @delimiter: either '\0', otherwise the output string will have the * given delimiter character between each two hex numbers. * @upper_case: if TRUE, use upper case ASCII characters for hex. + * @with_leading_zero: if TRUE, then the hex values from 0 to 0xf + * are written as "00" to "0f", respectively. Otherwise, the leading + * zero is dropped. With @with_leading_zero set to FALSE, the resulting + * string may be shorter than expected. @delimiter must be set + * if @with_leading_zero is FALSE. * @out: if %NULL, the function will allocate a new buffer of - * either (@length*2+1) or (@length*3) bytes, depending on whether + * either (@length*2+1) or MAX(1, (@length*3)) bytes, depending on whether * a @delimiter is specified. In that case, the allocated buffer will * be returned and must be freed by the caller. * If not %NULL, the buffer must already be preallocated and contain - * at least (@length*2+1) or (@length*3) bytes, depending on the delimiter. + * at least (@length*2+1) or MAX(1, (@length*3)) bytes, depending on the delimiter. * If @length is zero, then of course at least one byte will be allocated * or @out (if given) must contain at least room for the trailing NUL byte. * @@ -4869,37 +4874,43 @@ nm_utils_memeqzero(gconstpointer data, gsize length) * an empty string is returned. */ char * -nm_utils_bin2hexstr_full(gconstpointer addr, - gsize length, - char delimiter, - gboolean upper_case, - char *out) +nm_utils_bin2hexstr_fuller(gconstpointer addr, + gsize length, + char delimiter, + gboolean upper_case, + gboolean with_leading_zero, + char *out) { const guint8 *in = addr; const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef"; char *out0; - if (out) - out0 = out; - else { - out0 = out = - g_new(char, length == 0 ? 1u : (delimiter == '\0' ? length * 2u + 1u : length * 3u)); - } + nm_assert(with_leading_zero || delimiter != '\0'); - /* @out must contain at least @length*3 bytes if @delimiter is set, + /* @out must contain at least (MAX(1, @length*3)) bytes if @delimiter is set, * otherwise, @length*2+1. */ + if (!out) + out = g_new(char, length == 0 ? 1u : (delimiter == '\0' ? length * 2u + 1u : length * 3u)); + + out0 = out; + if (length > 0) { nm_assert(in); for (;;) { const guint8 v = *in++; + guint8 v_hi; - *out++ = LOOKUP[v >> 4]; + v_hi = (v >> 4); + if (v_hi != 0 || with_leading_zero) { + nm_assert(v_hi < 16); + *out++ = LOOKUP[v_hi]; + } *out++ = LOOKUP[v & 0x0F]; length--; - if (!length) + if (length == 0) break; - if (delimiter) + if (delimiter != '\0') *out++ = delimiter; } } diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index fe7c59f3..53cf7f3e 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -2842,11 +2842,22 @@ nm_ascii_is_regular(char ch) return ch >= ' ' && ch < 127; } -char *nm_utils_bin2hexstr_full(gconstpointer addr, - gsize length, - char delimiter, - gboolean upper_case, - char *out); +char *nm_utils_bin2hexstr_fuller(gconstpointer addr, + gsize length, + char delimiter, + gboolean upper_case, + gboolean with_leading_zero, + char *out); + +static inline char * +nm_utils_bin2hexstr_full(gconstpointer addr, + gsize length, + char delimiter, + gboolean upper_case, + char *out) +{ + return nm_utils_bin2hexstr_fuller(addr, length, delimiter, upper_case, TRUE, out); +} char *_nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len); diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c index 0c452acf..e1cbd1d4 100644 --- a/src/nm-cloud-setup/main.c +++ b/src/nm-cloud-setup/main.c @@ -251,24 +251,38 @@ _get_config(GCancellable *sigterm_cancellable, NMCSProvider *provider, NMClient /*****************************************************************************/ static gboolean -_nmc_skip_connection(NMConnection *connection) +_nmc_skip_connection_by_user_data(NMConnection *connection) { NMSettingUser *s_user; const char *v; - s_user = NM_SETTING_USER(nm_connection_get_setting(connection, NM_TYPE_SETTING_USER)); - if (!s_user) - return FALSE; - #define USER_TAG_SKIP "org.freedesktop.nm-cloud-setup.skip" nm_assert(nm_setting_user_check_key(USER_TAG_SKIP, NULL)); - v = nm_setting_user_get_data(s_user, USER_TAG_SKIP); - return _nm_utils_ascii_str_to_bool(v, FALSE); + s_user = NM_SETTING_USER(nm_connection_get_setting(connection, NM_TYPE_SETTING_USER)); + if (s_user) { + v = nm_setting_user_get_data(s_user, USER_TAG_SKIP); + if (_nm_utils_ascii_str_to_bool(v, FALSE)) + return TRUE; + } + + return FALSE; } static gboolean +_nmc_skip_connection_by_type(NMConnection *connection) +{ + if (!nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_WIRED_SETTING_NAME)) + return TRUE; + + if (!nm_connection_get_setting_ip4_config(connection)) + return TRUE; + + return FALSE; +} + +static void _nmc_mangle_connection(NMDevice *device, NMConnection *connection, const NMCSProviderGetConfigResult *result, @@ -291,12 +305,8 @@ _nmc_mangle_connection(NMDevice *device, NM_SET_OUT(out_skipped_single_addr, FALSE); NM_SET_OUT(out_changed, FALSE); - if (!nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_WIRED_SETTING_NAME)) - return FALSE; - s_ip = nm_connection_get_setting_ip4_config(connection); - if (!s_ip) - return FALSE; + nm_assert(NM_IS_SETTING_IP4_CONFIG(s_ip)); if ((ac = nm_device_get_active_connection(device)) && (remote_connection = NM_CONNECTION(nm_active_connection_get_connection(ac)))) @@ -429,7 +439,6 @@ _nmc_mangle_connection(NMDevice *device, rules_new->len); NM_SET_OUT(out_changed, addrs_changed || routes_changed || rules_changed); - return TRUE; } /*****************************************************************************/ @@ -451,6 +460,7 @@ _config_one(GCancellable *sigterm_cancellable, gboolean version_id_changed; guint try_count; gboolean any_changes = FALSE; + gboolean maybe_no_preserved_external_ip; g_main_context_iteration(NULL, FALSE); @@ -484,6 +494,8 @@ _config_one(GCancellable *sigterm_cancellable, try_count = 0; try_again: + g_clear_object(&applied_connection); + g_clear_error(&error); applied_connection = nmcs_device_get_applied_connection(device, sigterm_cancellable, @@ -497,23 +509,25 @@ try_again: return any_changes; } - if (_nmc_skip_connection(applied_connection)) { + if (_nmc_skip_connection_by_user_data(applied_connection)) { _LOGD("config device %s: skip applied connection due to user data %s", hwaddr, USER_TAG_SKIP); return any_changes; } - if (!_nmc_mangle_connection(device, - applied_connection, - result, - config_data, - &skipped_single_addr, - &changed)) { + if (_nmc_skip_connection_by_type(applied_connection)) { _LOGD("config device %s: device has no suitable applied connection. Skip", hwaddr); return any_changes; } + _nmc_mangle_connection(device, + applied_connection, + result, + config_data, + &skipped_single_addr, + &changed); + if (!changed) { if (skipped_single_addr) { _LOGD("config device %s: device needs no update to applied connection \"%s\" (%s) " @@ -539,16 +553,22 @@ try_again: /* we are about to call Reapply(). Even if that fails, it counts as if we changed something. */ any_changes = TRUE; + /* "preserve-external-ip" flag was only introduced in 1.41.6 and 1.40.9. + * We have no convenient way to check the daemon version (short of parsing the "Version" + * string). Hence, we don't know it. Take into account, that the daemon that we + * talk to might not support the flag yet. This is to support backward compatibility + * during package upgrade. */ + maybe_no_preserved_external_ip = TRUE; + if (!nmcs_device_reapply(device, sigterm_cancellable, applied_connection, applied_version_id, + maybe_no_preserved_external_ip, &version_id_changed, &error)) { if (version_id_changed && try_count < 5) { _LOGD("config device %s: applied connection changed in the meantime. Retry...", hwaddr); - g_clear_object(&applied_connection); - g_clear_error(&error); try_count++; goto try_again; } diff --git a/src/nm-cloud-setup/nm-cloud-setup-utils.c b/src/nm-cloud-setup/nm-cloud-setup-utils.c index e505f8bd..7cf79592 100644 --- a/src/nm-cloud-setup/nm-cloud-setup-utils.c +++ b/src/nm-cloud-setup/nm-cloud-setup-utils.c @@ -822,6 +822,7 @@ nmcs_device_reapply(NMDevice *device, GCancellable *sigterm_cancellable, NMConnection *connection, guint64 version_id, + gboolean maybe_no_preserved_external_ip, gboolean *out_version_id_changed, GError **error) { @@ -829,11 +830,13 @@ nmcs_device_reapply(NMDevice *device, DeviceReapplyData data = { .main_loop = main_loop, }; + NMDeviceReapplyFlags reapply_flags = NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP; +again: nm_device_reapply_async(device, connection, version_id, - 0, + reapply_flags, sigterm_cancellable, _nmcs_device_reapply_cb, &data); @@ -841,6 +844,17 @@ nmcs_device_reapply(NMDevice *device, g_main_loop_run(main_loop); if (data.error) { + if (maybe_no_preserved_external_ip + && reapply_flags == NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP + && nm_g_error_matches(data.error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED)) { + /* Hm? Maybe we running against an older version of NetworkManager that + * doesn't support "preserve-external-ip" flags? Retry without the flag. + * + * Note that recent version would reject invalid flags with NM_DEVICE_ERROR_INVALID_ARGUMENT, + * but we want to detect old daemon versions here. */ + reapply_flags = NM_DEVICE_REAPPLY_FLAGS_NONE; + goto again; + } NM_SET_OUT( out_version_id_changed, g_error_matches(data.error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_VERSION_ID_MISMATCH)); diff --git a/src/nm-cloud-setup/nm-cloud-setup-utils.h b/src/nm-cloud-setup/nm-cloud-setup-utils.h index 4131abfe..fed0f4b6 100644 --- a/src/nm-cloud-setup/nm-cloud-setup-utils.h +++ b/src/nm-cloud-setup/nm-cloud-setup-utils.h @@ -136,6 +136,7 @@ gboolean nmcs_device_reapply(NMDevice *device, GCancellable *sigterm_cancellable, NMConnection *connection, guint64 version_id, + gboolean maybe_no_preserved_external_ip, gboolean *out_version_id_changed, GError **error); diff --git a/src/nmcli/devices.c b/src/nmcli/devices.c index 9b7ebce3..db14ec05 100644 --- a/src/nmcli/devices.c +++ b/src/nmcli/devices.c @@ -1149,7 +1149,7 @@ get_device_list(NmCli *nmc, int *argc, const char *const **argv) if (*argc == 0) { g_string_printf(nmc->return_text, _("Error: No interface specified.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; + return NULL; } devices = nmc_get_devices_sorted(nmc->client); @@ -1190,9 +1190,6 @@ get_device_list(NmCli *nmc, int *argc, const char *const **argv) } g_free(devices); -error: - g_strfreev(arg_arr); - return queue; } diff --git a/src/nmtui/nmt-device-entry.c b/src/nmtui/nmt-device-entry.c index 7f312bd1..99cc43ad 100644 --- a/src/nmtui/nmt-device-entry.c +++ b/src/nmtui/nmt-device-entry.c @@ -132,12 +132,14 @@ device_entry_parse(NmtDeviceEntry *deventry, && (!words[1] || nm_utils_ifname_valid_kernel(words[1], NULL))) { *mac_address = words[0]; *interface_name = NULL; + g_free(words[1]); g_free(words); return TRUE; } else if (nm_utils_ifname_valid_kernel(words[0], NULL) && (!words[1] || nm_utils_hwaddr_aton(words[1], buf, len))) { *interface_name = words[0]; *mac_address = NULL; + g_free(words[1]); g_free(words); return TRUE; } -- cgit 1.3.0-6-gf8a5 From ee09a059703503dd91ab30e374325d7413279a39 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Wed, 11 Jan 2023 13:41:26 +0100 Subject: New upstream version 1.40.10 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 5cbca208..460066b8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +network-manager (1.40.10-1) UNRELEASED; urgency=medium + + * New upstream version 1.40.10 + + -- Michael Biebl Wed, 11 Jan 2023 13:41:24 +0100 + network-manager (1.40.8-1) unstable; urgency=medium * Add lintian override for source-is-missing false positive -- cgit 1.3.0-6-gf8a5 From ac445e26cbdad011277f8822e0fc468ab1a6c61f Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Wed, 11 Jan 2023 16:24:55 +0100 Subject: Release version 1.40.10-1 to unstable --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 460066b8..9a17fd1e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -network-manager (1.40.10-1) UNRELEASED; urgency=medium +network-manager (1.40.10-1) unstable; urgency=medium * New upstream version 1.40.10 - -- Michael Biebl Wed, 11 Jan 2023 13:41:24 +0100 + -- Michael Biebl Wed, 11 Jan 2023 16:24:40 +0100 network-manager (1.40.8-1) unstable; urgency=medium -- cgit 1.3.0-6-gf8a5