mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 05:18:23 +02:00
cloud-setup,core: merge branch 'th/cloud-setup-preserve-external-ip'
This is a partial backport of "th/cloud-setup-preserve-external-ip"
branch from 1.41.6.
https://bugzilla.redhat.com/show_bug.cgi?id=2132754
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1476
(cherry picked from commit f0e8b6f0e2)
This commit is contained in:
commit
caff311fd6
9 changed files with 276 additions and 55 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
147
examples/python/gi/device-reapply.py
Executable file
147
examples/python/gi/device-reapply.py
Executable file
|
|
@ -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()
|
||||
|
|
@ -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.
|
||||
-->
|
||||
<method name="Reapply">
|
||||
<arg name="connection" type="a{sa{sv}}" direction="in"/>
|
||||
|
|
|
|||
|
|
@ -12791,6 +12791,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 +12801,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 +12974,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 +12996,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 +13018,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 +13047,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 +13081,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 +13099,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 +13139,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 +13180,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue