Add upstream patches that went into RHEL

- bond: fix crash comparing mode while generating bond connection (rh #1459580)
- connectivity: fix route penalty if WWAN and BT device using ip-ifindex (rh #1459932)
- device: persist nm-owned in run state (rh #1376199)
- device: fix assuming master device on restart (rh #1452062)
- device: apply route metric penality only when the default route exists (rh #1459604)
- connectivity: fix periodic connectivity check (rh #1458399)
- bond: improve option matching on daemon restart (rh #1457909)
- device: fix touching device after external activation (rh #1457242)
This commit is contained in:
Lubomir Rintel 2017-06-09 17:27:09 +02:00
parent a53c203b20
commit ebf02b63fe
10 changed files with 2800 additions and 1 deletions

View File

@ -0,0 +1,147 @@
From 2d4555ec97d2cb0829106cbff82753bd168e5a20 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Fri, 12 May 2017 09:37:42 +0200
Subject: [PATCH 1/3] connectivity: avoid compiler warning for argument of
curl_easy_getinfo()
libcurl employs some typechecking via "curl/typecheck-gcc.h". When
compling with --enable-lto, compilation fails otherwise with:
make[2]: Entering directory '/data/src/NetworkManager'
CC src/src_libNetworkManager_la-nm-connectivity.lo
CCLD src/libNetworkManager.la
CCLD src/libNetworkManagerTest.la
CCLD src/dhcp/tests/test-dhcp-dhclient
src/nm-connectivity.c: In function 'curl_check_connectivity':
src/nm-connectivity.c:147:10: error: call to '_curl_easy_getinfo_err_string' declared with attribute warning: curl_easy_getinfo expects a pointer to char * for this info [-Werror]
eret = curl_easy_getinfo (msg->easy_handle, CURLINFO_PRIVATE, &cb_data);
^
lto1: all warnings being treated as errors
lto-wrapper: fatal error: /usr/bin/gcc returned 1 exit status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
(cherry picked from commit 7f8815a9c35c3b588b174c5e0c2568d3068726f6)
(cherry picked from commit 7f139c8ea87d0ceaa1f1d3601c846ace9054ffe5)
---
src/nm-connectivity.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c
index 75bb7b6..0708d96 100644
--- a/src/nm-connectivity.c
+++ b/src/nm-connectivity.c
@@ -144,7 +144,7 @@ curl_check_connectivity (CURLM *mhandle, CURLMcode ret)
continue;
/* Here we have completed a session. Check easy session result. */
- eret = curl_easy_getinfo (msg->easy_handle, CURLINFO_PRIVATE, &cb_data);
+ eret = curl_easy_getinfo (msg->easy_handle, CURLINFO_PRIVATE, (char **) &cb_data);
if (eret != CURLE_OK) {
_LOG2E ("curl cannot extract cb_data for easy handle %p, skipping msg", msg->easy_handle);
continue;
--
2.9.4
From e94a36ce1c880c5a4f52ae59d18bb2b6d2bee704 Mon Sep 17 00:00:00 2001
From: Francesco Giudici <fgiudici@redhat.com>
Date: Wed, 3 May 2017 17:01:41 +0200
Subject: [PATCH 2/3] connectivity: fix typo in error message
(cherry picked from commit 7a2c31a54a7ee82b930b0d9ef21ea11f565c2859)
(cherry picked from commit 16187171709347611caf9b8e8c75988c15b66b12)
---
src/nm-connectivity.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c
index 0708d96..b96737c 100644
--- a/src/nm-connectivity.c
+++ b/src/nm-connectivity.c
@@ -498,7 +498,7 @@ nm_connectivity_init (NMConnectivity *self)
priv->curl_mhandle = curl_multi_init ();
if (priv->curl_mhandle == NULL) {
- _LOGE ("cnable to init cURL, connectivity check will not work");
+ _LOGE ("unable to init cURL, connectivity check will not work");
return;
}
--
2.9.4
From fe45631585e93e15c552194cf4ffd82cbe513ee1 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Fri, 2 Jun 2017 19:11:11 +0200
Subject: [PATCH 3/3] connectivity: fix scheduling periodic connectivity checks
commit a955639 (connectivity: don't do periodic checks on interval=0)
broke scheduling connectivity checks.
That is because the timer is on only scheduled if
nm_connectivity_check_enabled(), which in turn only returns TRUE
if curl_mhandle is set. However, nm_connectivity_init() would only
initialize curl_mhandle after update_config(), missing to schedule
the periodic task.
https://mail.gnome.org/archives/networkmanager-list/2017-May/msg00076.html
Fixes: a95563996f07641e9877eb1760cac24415b65070
(cherry picked from commit f1eb1619f173a092c49dfcd1d53ec356827b6e0a)
(cherry picked from commit e984d9eb36f7838df58c0606bd00efc10730d329)
---
src/nm-connectivity.c | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c
index b96737c..6f16b28 100644
--- a/src/nm-connectivity.c
+++ b/src/nm-connectivity.c
@@ -486,27 +486,28 @@ nm_connectivity_init (NMConnectivity *self)
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
CURLcode retv;
- priv->config = g_object_ref (nm_config_get ());
- update_config (self, nm_config_get_data (priv->config));
- g_signal_connect (G_OBJECT (priv->config),
- NM_CONFIG_SIGNAL_CONFIG_CHANGED,
- G_CALLBACK (config_changed_cb),
- self);
-
retv = curl_global_init (CURL_GLOBAL_ALL);
if (retv == CURLE_OK)
priv->curl_mhandle = curl_multi_init ();
- if (priv->curl_mhandle == NULL) {
+ if (!priv->curl_mhandle)
_LOGE ("unable to init cURL, connectivity check will not work");
- return;
+ else {
+ curl_multi_setopt (priv->curl_mhandle, CURLMOPT_SOCKETFUNCTION, multi_socket_cb);
+ curl_multi_setopt (priv->curl_mhandle, CURLMOPT_SOCKETDATA, self);
+ curl_multi_setopt (priv->curl_mhandle, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
+ curl_multi_setopt (priv->curl_mhandle, CURLMOPT_TIMERDATA, self);
+ curl_multi_setopt (priv->curl_mhandle, CURLOPT_VERBOSE, 1);
}
- curl_multi_setopt (priv->curl_mhandle, CURLMOPT_SOCKETFUNCTION, multi_socket_cb);
- curl_multi_setopt (priv->curl_mhandle, CURLMOPT_SOCKETDATA, self);
- curl_multi_setopt (priv->curl_mhandle, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
- curl_multi_setopt (priv->curl_mhandle, CURLMOPT_TIMERDATA, self);
- curl_multi_setopt (priv->curl_mhandle, CURLOPT_VERBOSE, 1);
+ priv->config = g_object_ref (nm_config_get ());
+
+ update_config (self, nm_config_get_data (priv->config));
+ g_signal_connect (G_OBJECT (priv->config),
+ NM_CONFIG_SIGNAL_CONFIG_CHANGED,
+ G_CALLBACK (config_changed_cb),
+ self);
+
}
static void
--
2.9.4

View File

@ -0,0 +1,252 @@
From 8c6f8c65955d18ca9b43ad2bcd1bccf2cd85e7ed Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Mon, 5 Jun 2017 13:51:18 +0200
Subject: [PATCH 1/2] libnm-core: remove unsupported bond options during
normalization
In an ideal world, we should not validate connections containing
options not valid for the current bond mode. However adding such
restriction now means that during an upgrade to the new NM version
some connections that were valid before become invalid, possibly
disrupting connectivity.
Instead, consider invalid options as a normalizable error and remove
them during normalization.
Converting the setting to a "canonical" form without invalid options
is important for the connection matching logic, where such invalid
options can cause false mismatches.
(cherry picked from commit f25e008e2fe655bbddbb8a66612a9d141e982049)
(cherry picked from commit ac7a5c074c72310d8328fb448824d29bbec932f3)
---
libnm-core/nm-connection.c | 31 +++++++++++++++++++++++
libnm-core/nm-setting-bond.c | 18 +++++++++++++
libnm-core/tests/test-setting-bond.c | 49 ++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+)
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index ecfb978..c1b7506 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -913,6 +913,36 @@ _normalize_bond_mode (NMConnection *self, GHashTable *parameters)
}
static gboolean
+_normalize_bond_options (NMConnection *self, GHashTable *parameters)
+{
+ NMSettingBond *s_bond = nm_connection_get_setting_bond (self);
+ gboolean changed = FALSE;
+ const char *name, *mode_str;
+ NMBondMode mode;
+ guint32 num, i;
+
+ /* Strip away unsupported options for current mode */
+ if (s_bond) {
+ mode_str = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE);
+ mode = _nm_setting_bond_mode_from_string (mode_str);
+ if (mode == NM_BOND_MODE_UNKNOWN)
+ return FALSE;
+again:
+ num = nm_setting_bond_get_num_options (s_bond);
+ for (i = 0; i < num; i++) {
+ if ( nm_setting_bond_get_option (s_bond, i, &name, NULL)
+ && !_nm_setting_bond_option_supported (name, mode)) {
+ nm_setting_bond_remove_option (s_bond, name);
+ changed = TRUE;
+ goto again;
+ }
+ }
+ }
+
+ return changed;
+}
+
+static gboolean
_normalize_wireless_mac_address_randomization (NMConnection *self, GHashTable *parameters)
{
NMSettingWireless *s_wifi = nm_connection_get_setting_wireless (self);
@@ -1275,6 +1305,7 @@ nm_connection_normalize (NMConnection *connection,
was_modified |= _normalize_ethernet_link_neg (connection);
was_modified |= _normalize_infiniband_mtu (connection, parameters);
was_modified |= _normalize_bond_mode (connection, parameters);
+ was_modified |= _normalize_bond_options (connection, parameters);
was_modified |= _normalize_wireless_mac_address_randomization (connection, parameters);
was_modified |= _normalize_team_config (connection, parameters);
was_modified |= _normalize_team_port_config (connection, parameters);
diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c
index 9a8bdc3..b62964c 100644
--- a/libnm-core/nm-setting-bond.c
+++ b/libnm-core/nm-setting-bond.c
@@ -542,6 +542,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
const char *arp_ip_target = NULL;
const char *lacp_rate;
const char *primary;
+ NMBondMode bond_mode;
g_hash_table_iter_init (&iter, priv->options);
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
@@ -776,6 +777,23 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return NM_SETTING_VERIFY_NORMALIZABLE;
}
+ /* normalize unsupported options for the current mode */
+ bond_mode = _nm_setting_bond_mode_from_string (mode_new);
+ g_hash_table_iter_init (&iter, priv->options);
+ while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) {
+ if (nm_streq (key, "mode"))
+ continue;
+ if (!_nm_setting_bond_option_supported (key, bond_mode)) {
+ g_set_error (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("'%s' option is not valid with mode '%s'"),
+ key, mode_new);
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+ return NM_SETTING_VERIFY_NORMALIZABLE;
+ }
+ }
+
return TRUE;
}
diff --git a/libnm-core/tests/test-setting-bond.c b/libnm-core/tests/test-setting-bond.c
index 91a8199..e6a65bb 100644
--- a/libnm-core/tests/test-setting-bond.c
+++ b/libnm-core/tests/test-setting-bond.c
@@ -182,6 +182,54 @@ test_compare (void)
((const char *[]){ "num_unsol_na", "4", "num_grat_arp", "4", NULL }));
}
+static void
+test_normalize_options (const char **opts1, const char **opts2)
+{
+ gs_unref_object NMConnection *con = NULL;
+ NMSettingBond *s_bond;
+ GError *error = NULL;
+ gboolean success;
+ const char **p;
+ int num = 0;
+
+ create_bond_connection (&con, &s_bond);
+
+ for (p = opts1; p[0] && p[1]; p += 2)
+ g_assert (nm_setting_bond_add_option (s_bond, p[0], p[1]));
+
+ nmtst_assert_connection_verifies_and_normalizable (con);
+ nmtst_connection_normalize (con);
+ success = nm_setting_verify ((NMSetting *) s_bond, con, &error);
+ nmtst_assert_success (success, error);
+
+ for (p = opts2; p[0] && p[1]; p += 2) {
+ g_assert_cmpstr (nm_setting_bond_get_option_by_name (s_bond, p[0]), ==, p[1]);
+ num++;
+ }
+
+ g_assert_cmpint (num, ==, nm_setting_bond_get_num_options (s_bond));
+}
+
+static void
+test_normalize (void)
+{
+ test_normalize_options (
+ ((const char *[]){ "mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL }),
+ ((const char *[]){ "mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL }));
+ test_normalize_options (
+ ((const char *[]){ "mode", "1", "miimon", "1", NULL }),
+ ((const char *[]){ "mode", "active-backup", "miimon", "1", NULL }));
+ test_normalize_options (
+ ((const char *[]){ "mode", "balance-alb", "tlb_dynamic_lb", "1", NULL }),
+ ((const char *[]){ "mode", "balance-alb", NULL }));
+ test_normalize_options (
+ ((const char *[]){ "mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL }),
+ ((const char *[]){ "mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL }));
+ test_normalize_options (
+ ((const char *[]){ "mode", "balance-rr", "ad_actor_sys_prio", "4", "packets_per_slave", "3", NULL }),
+ ((const char *[]){ "mode", "balance-rr", "packets_per_slave", "3", NULL }));
+}
+
#define TPATH "/libnm/settings/bond/"
NMTST_DEFINE ();
@@ -193,6 +241,7 @@ main (int argc, char **argv)
g_test_add_func (TPATH "verify", test_verify);
g_test_add_func (TPATH "compare", test_compare);
+ g_test_add_func (TPATH "normalize", test_normalize);
return g_test_run ();
}
--
2.9.3
From 0d96d249ffe95e0232b8247e6bb9c1385a2b4940 Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Mon, 5 Jun 2017 14:48:08 +0200
Subject: [PATCH 2/2] bond: add only supported options to the generated
connection
Upstream commit [1] changed in the kernel the default value of
tlb_dynamic_lb bond from 1 to 0 when the mode is not tlb. This is not
wrong, as the option value doesn't really matter for other modes, but
it breaks the connection matching because we read back a 0 value when
we expect a default of 1.
Fix this in a generic way by ignoring altogether options that are not
relevant for the current bond mode, because they are removed from the
connection during normalization.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8b426dc54cf4056984bab7dfa48c92ee79a46434
https://bugzilla.redhat.com/show_bug.cgi?id=1457909
(cherry picked from commit 056a973a4fdb68abe8bc7bfc5f31250345d71f21)
(cherry picked from commit 61817661c899844ddb364ebd529716f574146588)
---
src/devices/nm-device-bond.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c
index 3325c94..c8748fe 100644
--- a/src/devices/nm-device-bond.c
+++ b/src/devices/nm-device-bond.c
@@ -155,6 +155,7 @@ update_connection (NMDevice *device, NMConnection *connection)
{
NMSettingBond *s_bond = nm_connection_get_setting_bond (connection);
int ifindex = nm_device_get_ifindex (device);
+ NMBondMode mode = NM_BOND_MODE_UNKNOWN;
const char **options;
if (!s_bond) {
@@ -164,7 +165,7 @@ update_connection (NMDevice *device, NMConnection *connection)
/* Read bond options from sysfs and update the Bond setting to match */
options = nm_setting_bond_get_valid_options (s_bond);
- while (options && *options) {
+ for (; *options; options++) {
gs_free char *value = nm_platform_sysctl_master_get_option (nm_device_get_platform (device), ifindex, *options);
const char *defvalue = nm_setting_bond_get_option_default (s_bond, *options);
char *p;
@@ -176,6 +177,12 @@ update_connection (NMDevice *device, NMConnection *connection)
*p = '\0';
}
+ if (nm_streq (*options, NM_SETTING_BOND_OPTION_MODE))
+ mode = _nm_setting_bond_mode_from_string (value);
+
+ if (!_nm_setting_bond_option_supported (*options, mode))
+ continue;
+
if ( value
&& value[0]
&& !ignore_if_zero (*options, value)
@@ -190,7 +197,6 @@ update_connection (NMDevice *device, NMConnection *connection)
nm_setting_bond_add_option (s_bond, *options, value);
}
- options++;
}
}
--
2.9.3

View File

@ -0,0 +1,43 @@
From b905393348574d8a363fe3fac4afb2fe6b03cfc0 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Thu, 1 Jun 2017 22:04:26 +0200
Subject: [PATCH 1/1] device: mark device as sys-iface-state=external when
assuming connection
Since commit 74dac5f (nm-manager: try assuming connections on managed devices),
and commit f4226e7 (manager: avoid generating in memory connections
during startup for managed devices), recheck_assume_connection() also
assumes connections on devices that are currently not in sys-iface-state
"external".
That is correct, as also for fully managed devices (which are currently
in disconnected state), we want to assume external connections. However,
when doing that, we must reset the sys-iface-state to external.
https://bugzilla.redhat.com/show_bug.cgi?id=1457242
(cherry picked from commit 02e7476e9fd0f4248009ce8eaa7870ba05e2504e)
(cherry picked from commit fcbcd1aa870ec5aa74c5c570ea08ffc52cffa63e)
---
src/nm-manager.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 3d94ce9..283ceda 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1884,8 +1884,10 @@ recheck_assume_connection (NMManager *self,
_LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
nm_device_get_iface (device));
- if (!generated)
- nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_ASSUME);
+ nm_device_sys_iface_state_set (device,
+ generated
+ ? NM_DEVICE_SYS_IFACE_STATE_EXTERNAL
+ : NM_DEVICE_SYS_IFACE_STATE_ASSUME);
/* Move device to DISCONNECTED to activate the connection */
if (state == NM_DEVICE_STATE_UNMANAGED) {
--
2.9.4

View File

@ -0,0 +1,36 @@
From 27b3757b5beecc9fcd98ce3a1acbc50431c204cb Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Wed, 7 Jun 2017 18:51:41 +0200
Subject: [PATCH 1/1] bond: check for NULL bond mode value in
update_connection()
Don't crash if the bond mode can't be read from sysfs - for example
when the interface disappears. The generated connection will be bogus,
but at that point it doesn't matter because the in-memory connection
will be destroyed.
Fixes: 056a973a4fdb68abe8bc7bfc5f31250345d71f21
https://bugzilla.redhat.com/show_bug.cgi?id=1459580
(cherry picked from commit 5600a27c2aa1a69c1c72422937bfd4401217046e)
(cherry picked from commit a3a792dd2253085933ca03e3cb61c37a44a6d304)
---
src/devices/nm-device-bond.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c
index c8748fe..451a4f0 100644
--- a/src/devices/nm-device-bond.c
+++ b/src/devices/nm-device-bond.c
@@ -177,7 +177,7 @@ update_connection (NMDevice *device, NMConnection *connection)
*p = '\0';
}
- if (nm_streq (*options, NM_SETTING_BOND_OPTION_MODE))
+ if (value && nm_streq (*options, NM_SETTING_BOND_OPTION_MODE))
mode = _nm_setting_bond_mode_from_string (value);
if (!_nm_setting_bond_option_supported (*options, mode))
--
2.9.4

View File

@ -0,0 +1,32 @@
From 1e8d7050a7d115faf78c1a7531195358c9919bf0 Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Thu, 8 Jun 2017 00:23:05 +0200
Subject: [PATCH 1/1] device: check connectivity on the IP interface
curl must bind to the interface that has IP configuration, not the
underlying device. Without this commit, connectivity check fails on
certain connection types (PPPoE, WWAN).
Fixes: 9d43869e473b47542520c807dace93a6f9520964
(cherry picked from commit c66995ad4ddbe44cbbb4d4d56a48420be6d483cf)
(cherry picked from commit dc1c8c22cc8034fe4c257d43b3c31196e9899326)
---
src/devices/nm-device.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index f5eb71d..a804771 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1858,7 +1858,7 @@ nm_device_check_connectivity (NMDevice *self,
/* Kick off a real connectivity check. */
nm_connectivity_check_async (nm_connectivity_get (),
- nm_device_get_iface (self),
+ nm_device_get_ip_iface (self),
concheck_cb,
data);
return;
--
2.9.4

View File

@ -0,0 +1,510 @@
From ffa247f2a2a70e9484ddb46c8dc66a1a7183ef55 Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Wed, 31 May 2017 16:42:05 +0200
Subject: [PATCH 1/5] device: rename priv->is_nm_owned to priv->nm_owned
Only a matter of taste, but nm_device_get_is_nm_owned() sounds
strange.
(cherry picked from commit 8cce037bf8078b7dbb8e3abc45f84ae6f7e9299c)
(cherry picked from commit 84273a35162aaef50c9b9a4f1b565326989d370a)
---
src/devices/nm-device.c | 14 +++++++-------
src/devices/nm-device.h | 2 +-
src/nm-manager.c | 2 +-
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index f5eb71d..746117d 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -262,7 +262,7 @@ typedef struct _NMDevicePrivate {
NMUtilsStableType current_stable_id_type:3;
- bool is_nm_owned:1; /* whether the device is a device owned and created by NM */
+ bool nm_owned:1; /* whether the device is a device owned and created by NM */
GHashTable * available_connections;
char * hw_addr;
@@ -2069,7 +2069,7 @@ nm_device_master_release_one_slave (NMDevice *self, NMDevice *slave, gboolean co
static gboolean
can_unmanaged_external_down (NMDevice *self)
{
- return !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned
+ return !NM_DEVICE_GET_PRIVATE (self)->nm_owned
&& nm_device_is_software (self);
}
@@ -2809,9 +2809,9 @@ nm_device_create_and_realize (NMDevice *self,
const NMPlatformLink *plink = NULL;
/* Must be set before device is realized */
- priv->is_nm_owned = !nm_platform_link_get_by_ifname (nm_device_get_platform (self), priv->iface);
+ priv->nm_owned = !nm_platform_link_get_by_ifname (nm_device_get_platform (self), priv->iface);
- _LOGD (LOGD_DEVICE, "create (is %snm-owned)", priv->is_nm_owned ? "" : "not ");
+ _LOGD (LOGD_DEVICE, "create (is %snm-owned)", priv->nm_owned ? "" : "not ");
/* Create any resources the device needs */
if (NM_DEVICE_GET_CLASS (self)->create_and_realize) {
@@ -8682,9 +8682,9 @@ _update_ip4_address (NMDevice *self)
}
gboolean
-nm_device_get_is_nm_owned (NMDevice *self)
+nm_device_is_nm_owned (NMDevice *self)
{
- return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
+ return NM_DEVICE_GET_PRIVATE (self)->nm_owned;
}
/*
@@ -8745,7 +8745,7 @@ delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex)
if (ifindex <= 0)
return;
- if (!priv->is_nm_owned)
+ if (!priv->nm_owned)
return;
if (priv->queued_act_request)
return;
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 5e6abb4..27f5018 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -605,7 +605,7 @@ void nm_device_set_unmanaged_by_user_settings (NMDevice *self);
void nm_device_set_unmanaged_by_user_udev (NMDevice *self);
void nm_device_set_unmanaged_by_quitting (NMDevice *device);
-gboolean nm_device_get_is_nm_owned (NMDevice *device);
+gboolean nm_device_is_nm_owned (NMDevice *device);
gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 283ceda..56852f6 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1858,7 +1858,7 @@ recheck_assume_connection (NMManager *self,
g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
- if (nm_device_get_is_nm_owned (device))
+ if (nm_device_is_nm_owned (device))
return FALSE;
if (!nm_device_get_managed (device, FALSE))
--
2.9.4
From 1ee731fc9890001fe5f6ac4884c9f5b8bf047024 Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Tue, 30 May 2017 13:36:56 +0200
Subject: [PATCH 2/5] config: allow persisting the device nm-owned state
(cherry picked from commit 3fbbbb62f0b18a1efdc25ee0c01625ae8da65826)
(cherry picked from commit a42f3b92b7ef922c491c07a8ab0f24b1cf12b223)
---
src/nm-config.c | 28 +++++++++++++++++++++++++---
src/nm-config.h | 7 ++++++-
src/nm-manager.c | 3 ++-
3 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/src/nm-config.c b/src/nm-config.c
index 54ccf9a..91c21de 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -1872,6 +1872,7 @@ _nm_config_state_set (NMConfig *self,
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_MANAGED "managed"
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_PERM_HW_ADDR_FAKE "perm-hw-addr-fake"
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_CONNECTION_UUID "connection-uuid"
+#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NM_OWNED "nm-owned"
NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_device_state_managed_type_to_str, NMConfigDeviceStateManagedType,
NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"),
@@ -1889,6 +1890,7 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf)
gs_free char *perm_hw_addr_fake = NULL;
gsize connection_uuid_len;
gsize perm_hw_addr_fake_len;
+ gint nm_owned = -1;
char *p;
nm_assert (ifindex > 0);
@@ -1924,6 +1926,11 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf)
g_free (perm_hw_addr_fake);
perm_hw_addr_fake = normalized;
}
+
+ nm_owned = nm_config_keyfile_get_boolean (kf,
+ DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
+ DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NM_OWNED,
+ -1);
}
connection_uuid_len = connection_uuid ? strlen (connection_uuid) + 1 : 0;
@@ -1937,6 +1944,7 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf)
device_state->managed = managed_type;
device_state->connection_uuid = NULL;
device_state->perm_hw_addr_fake = NULL;
+ device_state->nm_owned = nm_owned;
p = (char *) (&device_state[1]);
if (connection_uuid) {
@@ -1966,6 +1974,7 @@ nm_config_device_state_load (int ifindex)
NMConfigDeviceStateData *device_state;
char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR) + 60];
gs_unref_keyfile GKeyFile *kf = NULL;
+ const char *nm_owned_str;
g_return_val_if_fail (ifindex > 0, NULL);
@@ -1976,13 +1985,18 @@ nm_config_device_state_load (int ifindex)
g_clear_pointer (&kf, g_key_file_unref);
device_state = _config_device_state_data_new (ifindex, kf);
+ nm_owned_str = device_state->nm_owned == TRUE ?
+ ", nm-owned=1" :
+ (device_state->nm_owned == FALSE ? ", nm-owned=0" : "");
+
- _LOGT ("device-state: %s #%d (%s); managed=%s%s%s%s%s%s%s",
+ _LOGT ("device-state: %s #%d (%s); managed=%s%s%s%s%s%s%s%s",
kf ? "read" : "miss",
ifindex, path,
_device_state_managed_type_to_str (device_state->managed),
NM_PRINT_FMT_QUOTED (device_state->connection_uuid, ", connection-uuid=", device_state->connection_uuid, "", ""),
- NM_PRINT_FMT_QUOTED (device_state->perm_hw_addr_fake, ", perm-hw-addr-fake=", device_state->perm_hw_addr_fake, "", ""));
+ NM_PRINT_FMT_QUOTED (device_state->perm_hw_addr_fake, ", perm-hw-addr-fake=", device_state->perm_hw_addr_fake, "", ""),
+ nm_owned_str);
return device_state;
}
@@ -1991,7 +2005,8 @@ gboolean
nm_config_device_state_write (int ifindex,
NMConfigDeviceStateManagedType managed,
const char *perm_hw_addr_fake,
- const char *connection_uuid)
+ const char *connection_uuid,
+ gint nm_owned)
{
char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR) + 60];
GError *local = NULL;
@@ -2026,6 +2041,13 @@ nm_config_device_state_write (int ifindex,
DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_CONNECTION_UUID,
connection_uuid);
}
+ if (nm_owned >= 0) {
+ g_key_file_set_boolean (kf,
+ DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
+ DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NM_OWNED,
+ nm_owned);
+ }
+
if (!g_key_file_save_to_file (kf, path, &local)) {
_LOGW ("device-state: write #%d (%s) failed: %s", ifindex, path, local->message);
diff --git a/src/nm-config.h b/src/nm-config.h
index ae695fc..c5ff7c6 100644
--- a/src/nm-config.h
+++ b/src/nm-config.h
@@ -205,13 +205,18 @@ struct _NMConfigDeviceStateData {
const char *connection_uuid;
const char *perm_hw_addr_fake;
+
+ /* whether the device was nm-owned (0/1) or -1 for
+ * non-software devices. */
+ gint nm_owned;
};
NMConfigDeviceStateData *nm_config_device_state_load (int ifindex);
gboolean nm_config_device_state_write (int ifindex,
NMConfigDeviceStateManagedType managed,
const char *perm_hw_addr_fake,
- const char *connection_uuid);
+ const char *connection_uuid,
+ gint nm_owned);
void nm_config_device_state_prune_unseen (GHashTable *seen_ifindexes);
/*****************************************************************************/
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 56852f6..dc52115 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -5048,7 +5048,8 @@ nm_manager_write_device_state (NMManager *self)
if (nm_config_device_state_write (ifindex,
managed_type,
perm_hw_addr_fake,
- uuid))
+ uuid,
+ -1))
g_hash_table_add (seen_ifindexes, GINT_TO_POINTER (ifindex));
}
--
2.9.4
From cf3d67882676ccba5089fd523ccf6337f66e6c3f Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Wed, 31 May 2017 16:58:21 +0200
Subject: [PATCH 3/5] manager: restore the previous persistent nm-owned state
of devices
After a daemon restart, any software device is considered !nm-owned,
even if it was created by NM. Therefore, a device stays around even if
the connection which created it gets deactivated or deleted.
Fix this by remembering the previous nm-owned state in the device
state file.
https://bugzilla.redhat.com/show_bug.cgi?id=1376199
(cherry picked from commit cf9ba271e664ffd93f6ba6294ebc5f7e341a9a78)
(cherry picked from commit 333ed6ee2a30b0d40a2ac0d59e3fd2e9aaf3bf00)
---
src/devices/nm-device.c | 13 +++++++++++++
src/nm-manager.c | 5 ++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 746117d..fe6e955 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -3011,6 +3011,19 @@ realize_start_setup (NMDevice *self,
_add_capabilities (self, capabilities);
+ /* Update nm-owned flag according to state file */
+ if ( !priv->nm_owned
+ && priv->ifindex > 0
+ && nm_device_is_software (self)) {
+ gs_free NMConfigDeviceStateData *dev_state = NULL;
+
+ dev_state = nm_config_device_state_load (priv->ifindex);
+ if (dev_state && dev_state->nm_owned == TRUE) {
+ priv->nm_owned = TRUE;
+ _LOGD (LOGD_DEVICE, "set nm-owned from state file");
+ }
+ }
+
if (!priv->udi) {
/* Use a placeholder UDI until we get a real one */
priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index dc52115..97752c4 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -5006,6 +5006,7 @@ nm_manager_write_device_state (NMManager *self)
const GSList *devices;
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
gs_unref_hashtable GHashTable *seen_ifindexes = NULL;
+ gint nm_owned;
seen_ifindexes = g_hash_table_new (NULL, NULL);
@@ -5045,11 +5046,13 @@ nm_manager_write_device_state (NMManager *self)
if (perm_hw_addr_fake && !perm_hw_addr_is_fake)
perm_hw_addr_fake = NULL;
+ nm_owned = nm_device_is_software (device) ? nm_device_is_nm_owned (device) : -1;
+
if (nm_config_device_state_write (ifindex,
managed_type,
perm_hw_addr_fake,
uuid,
- -1))
+ nm_owned))
g_hash_table_add (seen_ifindexes, GINT_TO_POINTER (ifindex));
}
--
2.9.4
From 02b5487b3d3827b3ba6fcda7234f3f7a1976b2d4 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 7 Jun 2017 22:11:50 +0200
Subject: [PATCH 4/5] device: only set nm-owned from statefile during initial
setup
The state file should only be read initially when NM starts, that is:
during NMManager's platform_query_devices().
At all later points, for example when a software device gets destroyed
and re-realized, the state file is clearly no longer relevant.
Hence, pass the set-nm-owned flag from NMManager to realize_start_setup().
This is very much the same as with the NM_UNMANAGED_FLAG_USER_EXPLICT flag,
which we also read from the state-file.
(cherry picked from commit d83848be9dfd0edb5f318b81854b371133d84f6e)
(cherry picked from commit 8e25de8ab360fc973d7222685f107b81dd872dc1)
---
src/devices/nm-device.c | 22 +++++++++++-----------
src/devices/nm-device.h | 1 +
src/nm-manager.c | 3 +++
3 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index fe6e955..1aea8cb 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -527,6 +527,7 @@ static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll);
static void nm_device_start_ip_check (NMDevice *self);
static void realize_start_setup (NMDevice *self,
const NMPlatformLink *plink,
+ gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit);
static void _commit_mtu (NMDevice *self, const NMIP4Config *config);
static void dhcp_schedule_restart (NMDevice *self, int family, const char *reason);
@@ -2740,6 +2741,7 @@ link_type_compatible (NMDevice *self,
* nm_device_realize_start():
* @self: the #NMDevice
* @plink: an existing platform link or %NULL
+ * @set_nm_owned: for software device, if TRUE set nm-owned.
* @unmanaged_user_explicit: the user-explicit unmanaged flag to apply
* on the device initially.
* @out_compatible: %TRUE on return if @self is compatible with @plink
@@ -2757,6 +2759,7 @@ link_type_compatible (NMDevice *self,
gboolean
nm_device_realize_start (NMDevice *self,
const NMPlatformLink *plink,
+ gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible,
GError **error)
@@ -2781,7 +2784,7 @@ nm_device_realize_start (NMDevice *self,
plink_copy = *plink;
plink = &plink_copy;
}
- realize_start_setup (self, plink, unmanaged_user_explicit);
+ realize_start_setup (self, plink, set_nm_owned, unmanaged_user_explicit);
return TRUE;
}
@@ -2821,7 +2824,7 @@ nm_device_create_and_realize (NMDevice *self,
plink = &plink_copy;
}
- realize_start_setup (self, plink, NM_UNMAN_FLAG_OP_FORGET);
+ realize_start_setup (self, plink, FALSE, NM_UNMAN_FLAG_OP_FORGET);
nm_device_realize_finish (self, plink);
if (nm_device_get_managed (self, FALSE)) {
@@ -2917,6 +2920,8 @@ realize_start_notify (NMDevice *self,
* realize_start_setup():
* @self: the #NMDevice
* @plink: the #NMPlatformLink if backed by a kernel netdevice
+ * @set_nm_owned: if TRUE and device is a software-device, set nm-owned.
+ * TRUE.
* @unmanaged_user_explicit: the user-explict unmanaged flag to set.
*
* Update the device from backing resource properties (like hardware
@@ -2928,6 +2933,7 @@ realize_start_notify (NMDevice *self,
static void
realize_start_setup (NMDevice *self,
const NMPlatformLink *plink,
+ gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit)
{
NMDevicePrivate *priv;
@@ -3011,17 +3017,11 @@ realize_start_setup (NMDevice *self,
_add_capabilities (self, capabilities);
- /* Update nm-owned flag according to state file */
if ( !priv->nm_owned
- && priv->ifindex > 0
+ && set_nm_owned
&& nm_device_is_software (self)) {
- gs_free NMConfigDeviceStateData *dev_state = NULL;
-
- dev_state = nm_config_device_state_load (priv->ifindex);
- if (dev_state && dev_state->nm_owned == TRUE) {
- priv->nm_owned = TRUE;
- _LOGD (LOGD_DEVICE, "set nm-owned from state file");
- }
+ priv->nm_owned = TRUE;
+ _LOGD (LOGD_DEVICE, "set nm-owned from state file");
}
if (!priv->udi) {
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 27f5018..74cc230 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -611,6 +611,7 @@ gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
gboolean nm_device_realize_start (NMDevice *device,
const NMPlatformLink *plink,
+ gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible,
GError **error);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 97752c4..b603b09 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -2215,6 +2215,7 @@ factory_device_added_cb (NMDeviceFactory *factory,
if (nm_device_realize_start (device,
NULL,
+ FALSE,
NM_UNMAN_FLAG_OP_FORGET,
NULL,
&error)) {
@@ -2293,6 +2294,7 @@ platform_link_added (NMManager *self,
return;
} else if (nm_device_realize_start (candidate,
plink,
+ FALSE,
NM_UNMAN_FLAG_OP_FORGET,
&compatible,
&error)) {
@@ -2364,6 +2366,7 @@ platform_link_added (NMManager *self,
if (nm_device_realize_start (device,
plink,
+ dev_state ? (dev_state->nm_owned == 1) : FALSE,
unmanaged_user_explicit,
NULL,
&error)) {
--
2.9.4
From ba9657314afa3a0eab63281db83fbf38ba3fac2c Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 7 Jun 2017 22:22:14 +0200
Subject: [PATCH 5/5] core: allow assuming connections on "nm-owned" software
devices
Especially now we load the nm-owned flag from run-state. We very much want to
assume connections on such devices.
(cherry picked from commit 6a7b51f79bf93889665f9f6eb1ebbd4920535e24)
(cherry picked from commit 122be86c58b39b661b1cf466d5616d6f0006744e)
---
src/nm-manager.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/nm-manager.c b/src/nm-manager.c
index b603b09..1daf633 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1858,9 +1858,6 @@ recheck_assume_connection (NMManager *self,
g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
- if (nm_device_is_nm_owned (device))
- return FALSE;
-
if (!nm_device_get_managed (device, FALSE))
return FALSE;
--
2.9.4

View File

@ -0,0 +1,536 @@
From 72e544c7eca495d0857d0710cc77161cd3b145d0 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Wed, 7 Jun 2017 17:34:47 +0200
Subject: [PATCH 1/1] manager: fix preserving assume state during activation
Originally 850c977 "device: track system interface state in NMDevice",
intended that a connection can only be assumed initially when seeing
a device for the first time. Assuming a connection later was to be
prevented by setting device's sys-iface-state to MANAGED.
That changed too much in behavior, because we used to assume external
connections also when they are activated later on. So this was attempted
to get fixed by
- acf1067 nm-manager: try assuming connections on managed devices
- b6b7d90 manager: avoid generating in memory connections during startup for managed devices
It's probably just wrong to prevent assuming connections based on the
sys-iface-state. So drop the check for sys-iface-state from
recheck_assume_connection(). Now, we can assume anytime on managed,
disconnected interfaces, like previously.
Btw, note that priv->startup is totally wrong to check there, because
priv->startup has the sole purpose of tracking startup-complete property.
Startup, as far as NMManager is concerned, is platform_query_devices().
However, the problem is that we only assume connections (contrary to
doing external activation) when we have a connection-uuid from the state
file or with guess-assume during startup.
When assuming a master device, it can fail with
(nm-bond): ignoring generated connection (IPv6LL-only and not in master-slave relationship)
thus, for internal reason the device cannot be assumed yet.
Fix that by attatching the assume-state to the device, so that on multiple
recheck_assume_connection() calls we still try to assume. Whenever we try
to assume the connection and it fails due to external reasons (like, the connection
no longer matching), we clear the assume state, so that we only try as
long as there are internal reasons why assuming fails.
https://bugzilla.redhat.com/show_bug.cgi?id=1452062
(cherry picked from commit 729de7d7f09c3ad813477b7a822155b4b95dc682)
(cherry picked from commit 06db38b91d627f897b5bdd0de4a06f7b8a220902)
---
src/devices/nm-device.c | 86 ++++++++++++++++++++++++++++++++++++++++++---
src/devices/nm-device.h | 15 +++++++-
src/nm-manager.c | 93 +++++++++++++++++++++++++------------------------
3 files changed, 144 insertions(+), 50 deletions(-)
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 1aea8cb..404dcf7 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -264,6 +264,9 @@ typedef struct _NMDevicePrivate {
bool nm_owned:1; /* whether the device is a device owned and created by NM */
+ bool assume_state_guess_assume:1;
+ char * assume_state_connection_uuid;
+
GHashTable * available_connections;
char * hw_addr;
char * hw_addr_perm;
@@ -527,6 +530,8 @@ static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll);
static void nm_device_start_ip_check (NMDevice *self);
static void realize_start_setup (NMDevice *self,
const NMPlatformLink *plink,
+ gboolean assume_state_guess_assume,
+ const char *assume_state_connection_uuid,
gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit);
static void _commit_mtu (NMDevice *self, const NMIP4Config *config);
@@ -711,6 +716,52 @@ nm_device_sys_iface_state_set (NMDevice *self,
/*****************************************************************************/
+void
+nm_device_assume_state_get (NMDevice *self,
+ gboolean *out_assume_state_guess_assume,
+ const char **out_assume_state_connection_uuid)
+{
+ NMDevicePrivate *priv;
+
+ g_return_if_fail (NM_IS_DEVICE (self));
+
+ priv = NM_DEVICE_GET_PRIVATE (self);
+ NM_SET_OUT (out_assume_state_guess_assume, priv->assume_state_guess_assume);
+ NM_SET_OUT (out_assume_state_connection_uuid, priv->assume_state_connection_uuid);
+}
+
+static void
+_assume_state_set (NMDevice *self,
+ gboolean assume_state_guess_assume,
+ const char *assume_state_connection_uuid)
+{
+ NMDevicePrivate *priv;
+
+ nm_assert (NM_IS_DEVICE (self));
+
+ priv = NM_DEVICE_GET_PRIVATE (self);
+ if ( priv->assume_state_guess_assume == !!assume_state_guess_assume
+ && nm_streq0 (priv->assume_state_connection_uuid, assume_state_connection_uuid))
+ return;
+
+ _LOGD (LOGD_DEVICE, "assume-state: set guess-assume=%c, connection=%s%s%s",
+ assume_state_guess_assume ? '1' : '0',
+ NM_PRINT_FMT_QUOTE_STRING (assume_state_connection_uuid));
+ priv->assume_state_guess_assume = assume_state_guess_assume;
+ g_free (priv->assume_state_connection_uuid);
+ priv->assume_state_connection_uuid = g_strdup (assume_state_connection_uuid);
+}
+
+void
+nm_device_assume_state_reset (NMDevice *self)
+{
+ g_return_if_fail (NM_IS_DEVICE (self));
+
+ _assume_state_set (self, FALSE, NULL);
+}
+
+/*****************************************************************************/
+
static void
init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config)
{
@@ -2741,6 +2792,8 @@ link_type_compatible (NMDevice *self,
* nm_device_realize_start():
* @self: the #NMDevice
* @plink: an existing platform link or %NULL
+ * @assume_state_guess_assume: set the guess_assume state.
+ * @assume_state_connection_uuid: set the connection uuid to assume.
* @set_nm_owned: for software device, if TRUE set nm-owned.
* @unmanaged_user_explicit: the user-explicit unmanaged flag to apply
* on the device initially.
@@ -2759,6 +2812,8 @@ link_type_compatible (NMDevice *self,
gboolean
nm_device_realize_start (NMDevice *self,
const NMPlatformLink *plink,
+ gboolean assume_state_guess_assume,
+ const char *assume_state_connection_uuid,
gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible,
@@ -2784,8 +2839,11 @@ nm_device_realize_start (NMDevice *self,
plink_copy = *plink;
plink = &plink_copy;
}
- realize_start_setup (self, plink, set_nm_owned, unmanaged_user_explicit);
-
+ realize_start_setup (self, plink,
+ assume_state_guess_assume,
+ assume_state_connection_uuid,
+ set_nm_owned,
+ unmanaged_user_explicit);
return TRUE;
}
@@ -2824,7 +2882,10 @@ nm_device_create_and_realize (NMDevice *self,
plink = &plink_copy;
}
- realize_start_setup (self, plink, FALSE, NM_UNMAN_FLAG_OP_FORGET);
+ realize_start_setup (self, plink,
+ FALSE, /* assume_state_guess_assume */
+ NULL, /* assume_state_connection_uuid */
+ FALSE, NM_UNMAN_FLAG_OP_FORGET);
nm_device_realize_finish (self, plink);
if (nm_device_get_managed (self, FALSE)) {
@@ -2920,6 +2981,8 @@ realize_start_notify (NMDevice *self,
* realize_start_setup():
* @self: the #NMDevice
* @plink: the #NMPlatformLink if backed by a kernel netdevice
+ * @assume_state_guess_assume: set the guess_assume state.
+ * @assume_state_connection_uuid: set the connection uuid to assume.
* @set_nm_owned: if TRUE and device is a software-device, set nm-owned.
* TRUE.
* @unmanaged_user_explicit: the user-explict unmanaged flag to set.
@@ -2933,6 +2996,8 @@ realize_start_notify (NMDevice *self,
static void
realize_start_setup (NMDevice *self,
const NMPlatformLink *plink,
+ gboolean assume_state_guess_assume,
+ const char *assume_state_connection_uuid,
gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit)
{
@@ -2972,6 +3037,8 @@ realize_start_setup (NMDevice *self,
_notify (self, PROP_MTU);
}
+ _assume_state_set (self, assume_state_guess_assume, assume_state_connection_uuid);
+
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
if (plink) {
@@ -3193,6 +3260,8 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
_LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0);
+ nm_device_assume_state_reset (self);
+
if (remove_resources) {
if (NM_DEVICE_GET_CLASS (self)->unrealize) {
if (!NM_DEVICE_GET_CLASS (self)->unrealize (self, error))
@@ -4042,7 +4111,7 @@ nm_device_master_update_slave_connection (NMDevice *self,
}
NMConnection *
-nm_device_generate_connection (NMDevice *self, NMDevice *master)
+nm_device_generate_connection (NMDevice *self, NMDevice *master, gboolean *out_maybe_later)
{
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
@@ -4056,6 +4125,8 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master)
GError *error = NULL;
const NMPlatformLink *pllink;
+ NM_SET_OUT (out_maybe_later, FALSE);
+
/* If update_connection() is not implemented, just fail. */
if (!klass->update_connection)
return NULL;
@@ -4131,6 +4202,7 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master)
&& !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))
&& !priv->slaves) {
_LOGD (LOGD_DEVICE, "ignoring generated connection (no IP and not in master-slave relationship)");
+ NM_SET_OUT (out_maybe_later, TRUE);
g_object_unref (connection);
connection = NULL;
}
@@ -4145,6 +4217,7 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master)
&& !priv->slaves
&& !nm_config_data_get_assume_ipv6ll_only (NM_CONFIG_GET_DATA, self)) {
_LOGD (LOGD_DEVICE, "ignoring generated connection (IPv6LL-only and not in master-slave relationship)");
+ NM_SET_OUT (out_maybe_later, TRUE);
g_object_unref (connection);
connection = NULL;
}
@@ -12504,6 +12577,9 @@ _set_state_full (NMDevice *self,
NM_DEVICE_SYS_IFACE_STATE_ASSUME))
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+ if (state > NM_DEVICE_STATE_DISCONNECTED)
+ nm_device_assume_state_reset (self);
+
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
if (available_connections_del_all (self))
_notify (self, PROP_AVAILABLE_CONNECTIONS);
@@ -13778,6 +13854,8 @@ dispose (GObject *object)
nm_clear_g_cancellable (&priv->deactivating_cancellable);
+ nm_device_assume_state_reset (self);
+
_parent_set_ifindex (self, 0, FALSE);
platform = nm_device_get_platform (self);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 74cc230..01e3938 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -487,7 +487,9 @@ void nm_device_removed (NMDevice *self, gboolean unconf
gboolean nm_device_is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags);
gboolean nm_device_has_carrier (NMDevice *dev);
-NMConnection * nm_device_generate_connection (NMDevice *self, NMDevice *master);
+NMConnection * nm_device_generate_connection (NMDevice *self,
+ NMDevice *master,
+ gboolean *out_maybe_later);
gboolean nm_device_master_update_slave_connection (NMDevice *master,
NMDevice *slave,
@@ -609,8 +611,19 @@ gboolean nm_device_is_nm_owned (NMDevice *device);
gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
+/*****************************************************************************/
+
+void nm_device_assume_state_get (NMDevice *self,
+ gboolean *out_assume_state_guess_assume,
+ const char **out_assume_state_connection_uuid);
+void nm_device_assume_state_reset (NMDevice *self);
+
+/*****************************************************************************/
+
gboolean nm_device_realize_start (NMDevice *device,
const NMPlatformLink *plink,
+ gboolean assume_state_guess_assume,
+ const char *assume_state_connection_uuid,
gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible,
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 1daf633..9a7b123 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1691,11 +1691,6 @@ done:
* get_existing_connection:
* @manager: #NMManager instance
* @device: #NMDevice instance
- * @guess_assume: whether to employ a heuristic to search for a matching
- * connection to assume.
- * @assume_connection_uuid: if present, try to assume a connection with this
- * UUID. If no uuid is given or no matching connection is found, we
- * only do external activation.
* @out_generated: (allow-none): return TRUE, if the connection was generated.
*
* Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
@@ -1704,8 +1699,6 @@ done:
static NMSettingsConnection *
get_existing_connection (NMManager *self,
NMDevice *device,
- gboolean guess_assume,
- const char *assume_connection_uuid,
gboolean *out_generated)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
@@ -1716,6 +1709,9 @@ get_existing_connection (NMManager *self,
int ifindex = nm_device_get_ifindex (device);
NMSettingsConnection *matched;
NMSettingsConnection *connection_checked = NULL;
+ gboolean assume_state_guess_assume = FALSE;
+ const char *assume_state_connection_uuid = NULL;
+ gboolean maybe_later;
if (out_generated)
*out_generated = FALSE;
@@ -1746,9 +1742,16 @@ get_existing_connection (NMManager *self,
* update_connection() implemented, otherwise nm_device_generate_connection()
* returns NULL.
*/
- connection = nm_device_generate_connection (device, master);
- if (!connection)
+ connection = nm_device_generate_connection (device, master, &maybe_later);
+ if (!connection) {
+ if (!maybe_later)
+ nm_device_assume_state_reset (device);
return NULL;
+ }
+
+ nm_device_assume_state_get (device,
+ &assume_state_guess_assume,
+ &assume_state_connection_uuid);
/* Now we need to compare the generated connection to each configured
* connection. The comparison function is the heart of the connection
@@ -1759,8 +1762,8 @@ get_existing_connection (NMManager *self,
* When no configured connection matches the generated connection, we keep
* the generated connection instead.
*/
- if ( assume_connection_uuid
- && (connection_checked = nm_settings_get_connection_by_uuid (priv->settings, assume_connection_uuid))
+ if ( assume_state_connection_uuid
+ && (connection_checked = nm_settings_get_connection_by_uuid (priv->settings, assume_state_connection_uuid))
&& !active_connection_find_first (self, connection_checked, NULL,
NM_ACTIVE_CONNECTION_STATE_DEACTIVATING)
&& nm_device_check_connection_compatible (device, NM_CONNECTION (connection_checked))) {
@@ -1778,7 +1781,7 @@ get_existing_connection (NMManager *self,
} else
matched = NULL;
- if (!matched && guess_assume) {
+ if (!matched && assume_state_guess_assume) {
gs_free NMSettingsConnection **connections = NULL;
guint len, i, j;
@@ -1812,9 +1815,10 @@ get_existing_connection (NMManager *self,
nm_device_get_iface (device),
nm_settings_connection_get_id (matched),
nm_settings_connection_get_uuid (matched),
- assume_connection_uuid && nm_streq (assume_connection_uuid, nm_settings_connection_get_uuid (matched))
+ assume_state_connection_uuid && nm_streq (assume_state_connection_uuid, nm_settings_connection_get_uuid (matched))
? " (indicated)" : " (guessed)");
g_object_unref (connection);
+ nm_device_assume_state_reset (device);
return matched;
}
@@ -1822,6 +1826,8 @@ get_existing_connection (NMManager *self,
nm_device_get_iface (device),
nm_connection_get_id (connection));
+ nm_device_assume_state_reset (device);
+
added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
if (added) {
nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added),
@@ -1844,34 +1850,28 @@ get_existing_connection (NMManager *self,
static gboolean
recheck_assume_connection (NMManager *self,
- NMDevice *device,
- gboolean guess_assume,
- const char *assume_connection_uuid)
+ NMDevice *device)
{
NMSettingsConnection *connection;
gboolean was_unmanaged = FALSE;
gboolean generated = FALSE;
NMDeviceState state;
- NMDeviceSysIfaceState if_state;
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
- if (!nm_device_get_managed (device, FALSE))
+ if (!nm_device_get_managed (device, FALSE)) {
+ nm_device_assume_state_reset (device);
return FALSE;
+ }
state = nm_device_get_state (device);
- if (state > NM_DEVICE_STATE_DISCONNECTED)
- return FALSE;
-
- if_state = nm_device_sys_iface_state_get (device);
- if (!priv->startup && (if_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED))
- nm_assert (!guess_assume && (assume_connection_uuid == NULL));
- else if (if_state != NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)
+ if (state > NM_DEVICE_STATE_DISCONNECTED) {
+ nm_device_assume_state_reset (device);
return FALSE;
+ }
- connection = get_existing_connection (self, device, guess_assume, assume_connection_uuid, &generated);
+ connection = get_existing_connection (self, device, &generated);
if (!connection) {
_LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
nm_device_get_iface (device));
@@ -1951,9 +1951,9 @@ recheck_assume_connection (NMManager *self,
}
static void
-recheck_assume_connection_cb (NMDevice *device, gpointer user_data)
+recheck_assume_connection_cb (NMManager *self, NMDevice *device)
{
- recheck_assume_connection (user_data, device, FALSE, NULL);
+ recheck_assume_connection (self, device);
}
static void
@@ -2046,19 +2046,19 @@ device_connectivity_changed (NMDevice *device,
static void
_device_realize_finish (NMManager *self,
NMDevice *device,
- const NMPlatformLink *plink,
- gboolean guess_assume,
- const char *connection_uuid_to_assume)
+ const NMPlatformLink *plink)
{
g_return_if_fail (NM_IS_MANAGER (self));
g_return_if_fail (NM_IS_DEVICE (device));
nm_device_realize_finish (device, plink);
- if (!nm_device_get_managed (device, FALSE))
+ if (!nm_device_get_managed (device, FALSE)) {
+ nm_device_assume_state_reset (device);
return;
+ }
- if (recheck_assume_connection (self, device, guess_assume, connection_uuid_to_assume))
+ if (recheck_assume_connection (self, device))
return;
/* if we failed to assume a connection for the managed device, but the device
@@ -2128,9 +2128,9 @@ add_device (NMManager *self, NMDevice *device, GError **error)
G_CALLBACK (device_removed_cb),
self);
- g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
- G_CALLBACK (recheck_assume_connection_cb),
- self);
+ g_signal_connect_data (device, NM_DEVICE_RECHECK_ASSUME,
+ G_CALLBACK (recheck_assume_connection_cb),
+ self, NULL, G_CONNECT_SWAPPED);
g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
G_CALLBACK (device_ip_iface_changed),
@@ -2212,12 +2212,14 @@ factory_device_added_cb (NMDeviceFactory *factory,
if (nm_device_realize_start (device,
NULL,
- FALSE,
+ FALSE, /* assume_state_guess_assume */
+ NULL, /* assume_state_connection_uuid */
+ FALSE, /* set_nm_owned */
NM_UNMAN_FLAG_OP_FORGET,
NULL,
&error)) {
add_device (self, device, NULL);
- _device_realize_finish (self, device, NULL, FALSE, NULL);
+ _device_realize_finish (self, device, NULL);
} else {
_LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s",
nm_device_get_iface (device), error->message);
@@ -2291,12 +2293,13 @@ platform_link_added (NMManager *self,
return;
} else if (nm_device_realize_start (candidate,
plink,
- FALSE,
+ FALSE, /* assume_state_guess_assume */
+ NULL, /* assume_state_connection_uuid */
+ FALSE, /* set_nm_owned */
NM_UNMAN_FLAG_OP_FORGET,
&compatible,
&error)) {
- /* Success */
- _device_realize_finish (self, candidate, plink, FALSE, NULL);
+ _device_realize_finish (self, candidate, plink);
return;
}
@@ -2363,14 +2366,14 @@ platform_link_added (NMManager *self,
if (nm_device_realize_start (device,
plink,
+ guess_assume,
+ dev_state ? dev_state->connection_uuid : NULL,
dev_state ? (dev_state->nm_owned == 1) : FALSE,
unmanaged_user_explicit,
NULL,
&error)) {
add_device (self, device, NULL);
- _device_realize_finish (self, device, plink,
- guess_assume,
- dev_state ? dev_state->connection_uuid : NULL);
+ _device_realize_finish (self, device, plink);
} else {
_LOGW (LOGD_DEVICE, "%s: failed to realize device: %s",
plink->name, error->message);
--
2.9.4

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
From 5b1e11d056015e70431f4add8a5efd203d14775f Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Thu, 8 Jun 2017 00:26:00 +0200
Subject: [PATCH] device: apply route metric penality only when the default
route exists
It's useless (and in some cases also harmful) to commit the
configuration to update the default route metric when the device has
no default route. Also, don't commit configuration for externally
activated devices.
https://bugzilla.redhat.com/show_bug.cgi?id=1459604
(cherry picked from commit aa099906f93264bda3ae34fca4dfbdde5455b2bb)
(cherry picked from commit 6a4774b1a8fdc346e0a2d2a3d2ec43054190fdc5)
---
src/devices/nm-device.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 6c93a95..e60995d 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1827,10 +1827,13 @@ update_connectivity_state (NMDevice *self, NMConnectivityState state)
priv->connectivity_state = state;
_notify (self, PROP_CONNECTIVITY);
- if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED) {
- if (!ip4_config_merge_and_apply (self, NULL, TRUE))
+ if ( priv->state == NM_DEVICE_STATE_ACTIVATED
+ && !nm_device_sys_iface_state_is_external (self)) {
+ if ( priv->default_route.v4_has
+ && !ip4_config_merge_and_apply (self, NULL, TRUE))
_LOGW (LOGD_IP4, "Failed to update IPv4 default route metric");
- if (!ip6_config_merge_and_apply (self, TRUE))
+ if ( priv->default_route.v6_has
+ && !ip6_config_merge_and_apply (self, TRUE))
_LOGW (LOGD_IP6, "Failed to update IPv6 default route metric");
}
}
--
2.9.3

View File

@ -9,7 +9,7 @@
%global epoch_version 1
%global rpm_version 1.8.0
%global real_version 1.8.0
%global release_version 4
%global release_version 5
%global snapshot %{nil}
%global git_sha %{nil}
@ -96,6 +96,15 @@ Patch13: 0013-nmcli-fix-8021x-password-raw-rh1456362.patch
Patch15: 0015-ifcfg-rh-legacy-netmask-rh1445414.patch
Patch16: 0016-tui-connect-crash-rh1456826.patch
Patch17: 0017-libnm-fix-reject-vlan-id-4095-rh1456911.patch
Patch18: 0018-periodic-connectivity-check-rh1458399.patch
Patch19: 0019-bond-improve-option-matching-rh1457909.patch
Patch20: 0020-device-fix-external-assume-rh1457242.patch
Patch21: 0021-bond-crash-mode-rh1459580.patch
Patch22: 0022-connectivity-ip-iface-check-rh1459932.patch
Patch23: 0023-persist-nm-owned-in-device-state-rh1376199.patch
Patch24: 0024-fix-delayed-assume-master-rh1452062.patch
Patch25: 0025-improve-logging-assume-rh1452062.patch
Patch26: 0026-apply-route-penality-only-with-defroute-rh1459604.patch
Requires(post): systemd
Requires(preun): systemd
@ -364,6 +373,15 @@ by nm-connection-editor and nm-applet in a non-graphical environment.
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%build
%if %{with regen_docs}
@ -676,6 +694,16 @@ fi
%endif
%changelog
* Fri Jun 9 2017 Lubomir Rintel <lkundrak@v3.sk> - 1:1.8.0-5
- bond: fix crash comparing mode while generating bond connection (rh #1459580)
- connectivity: fix route penalty if WWAN and BT device using ip-ifindex (rh #1459932)
- device: persist nm-owned in run state (rh #1376199)
- device: fix assuming master device on restart (rh #1452062)
- device: apply route metric penality only when the default route exists (rh #1459604)
- connectivity: fix periodic connectivity check (rh #1458399)
- bond: improve option matching on daemon restart (rh #1457909)
- device: fix touching device after external activation (rh #1457242)
* Sun Jun 4 2017 Thomas Haller <thaller@redhat.com> - 1:1.8.0-4
- ifcfg-rh: fix writing legacy NETMASK value (rh #1445414)
- tui: fix crash during connect (rh #1456826)