Blame SOURCES/0019-bond-improve-option-matching-rh1457909.patch

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