summaryrefslogtreecommitdiff
blob: 9c1e774c448d554d4a2d49b03410120801be61f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
From c52f385566e558ee3edc98d20225155b362d212f Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Sun, 28 Aug 2016 13:52:32 +0200
Subject: [PATCH 1/4] platform: split processing result from do_change_link()

(cherry picked from commit 3dc09446771a3434ed948bdd5e6ca9f6ef9a9e76)
(cherry picked from commit 471521ca84187cd32afcd20aebe5a369fe7368dc)
---
 src/platform/nm-linux-platform.c | 35 +++++++++++++++++++++++++++--------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 98c4e46..eeb24ca 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -4060,18 +4060,14 @@ out:
 	return !!nmp_cache_lookup_obj (priv->cache, obj_id);
 }
 
-static NMPlatformError
-do_change_link (NMPlatform *platform,
-                int ifindex,
-                struct nl_msg *nlmsg)
+static WaitForNlResponseResult
+do_change_link_request (NMPlatform *platform,
+                        int ifindex,
+                        struct nl_msg *nlmsg)
 {
 	nm_auto_pop_netns NMPNetns *netns = NULL;
 	WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN;
 	int nle;
-	char s_buf[256];
-	NMPlatformError result = NM_PLATFORM_ERROR_SUCCESS;
-	NMLogLevel log_level = LOGL_DEBUG;
-	const char *log_result = "failure", *log_detail = "";
 
 	if (!nm_platform_netns_push (platform, &netns))
 		return NM_PLATFORM_ERROR_UNSPECIFIED;
@@ -4098,6 +4094,18 @@ retry:
 		nlmsg_hdr (nlmsg)->nlmsg_type = RTM_SETLINK;
 		goto retry;
 	}
+	return seq_result;
+}
+
+static NMPlatformError
+do_change_link_result (NMPlatform *platform,
+                       int ifindex,
+                       WaitForNlResponseResult seq_result)
+{
+	char s_buf[256];
+	NMPlatformError result = NM_PLATFORM_ERROR_SUCCESS;
+	NMLogLevel log_level = LOGL_DEBUG;
+	const char *log_result = "failure", *log_detail = "";
 
 	if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) {
 		log_result = "success";
@@ -4123,6 +4131,17 @@ retry:
 	return result;
 }
 
+static NMPlatformError
+do_change_link (NMPlatform *platform,
+                int ifindex,
+                struct nl_msg *nlmsg)
+{
+	WaitForNlResponseResult seq_result;
+
+	seq_result = do_change_link_request (platform, ifindex, nlmsg);
+	return do_change_link_result (platform, ifindex, seq_result);
+}
+
 static gboolean
 link_add (NMPlatform *platform,
           const char *name,
-- 
2.7.4


From 559ed361a30650f263668aadb86233fb405f0b29 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Sun, 28 Aug 2016 14:08:42 +0200
Subject: [PATCH 2/4] platform: workaround kernel wrongly returning ENFILE when
 changing MAC address

https://bugzilla.gnome.org/show_bug.cgi?id=770456
(cherry picked from commit 2bef71611bd9fd2e333a7522205f0262ac25680f)
(cherry picked from commit 06d1679aa9867682297316e7b2cfac6fc8f67c2a)
---
 src/platform/nm-linux-platform.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index eeb24ca..c36e967 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -4449,6 +4449,8 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size
 {
 	nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
 	gs_free char *mac = NULL;
+	WaitForNlResponseResult seq_result;
+	char s_buf[256];
 
 	if (!address || !length)
 		g_return_val_if_reached (NM_PLATFORM_ERROR_BUG);
@@ -4468,7 +4470,30 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size
 
 	NLA_PUT (nlmsg, IFLA_ADDRESS, length, address);
 
-	return do_change_link (platform, ifindex, nlmsg);
+	seq_result = do_change_link_request (platform, ifindex, nlmsg);
+
+	if (NM_IN_SET (-((int) seq_result), ENFILE)) {
+		const NMPObject *obj_cache;
+
+		/* workaround ENFILE which may be wrongly returned (bgo #770456).
+		 * If the MAC address is as expected, assume success? */
+
+		obj_cache = nmp_cache_lookup_link (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, ifindex);
+		if (   obj_cache
+		    && obj_cache->link.addr.len == length
+		    && memcmp (obj_cache->link.addr.data, address, length) == 0) {
+			_NMLOG (LOGL_DEBUG,
+			        "do-change-link[%d]: %s changing link: %s%s",
+			        ifindex,
+			        "success",
+			        wait_for_nl_response_to_string (seq_result, s_buf, sizeof (s_buf)),
+			        " (assume success changing address)");
+			return NM_PLATFORM_ERROR_SUCCESS;
+		}
+	}
+
+	return do_change_link_result (platform, ifindex, seq_result);
+
 nla_put_failure:
 	g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED);
 }
-- 
2.7.4


From afe1a15516f0a5024f161e3ff1046afdfb7e58b8 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Mon, 29 Aug 2016 17:14:04 +0200
Subject: [PATCH 3/4] device: fix spelling in logging

(cherry picked from commit d51f2c2a4e99799739e2adbeaf578144b556c4b9)
(cherry picked from commit b1f5d3d798498c53fe65257490b2df3e3f71e364)
---
 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 199acc6..305a1bb 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -11820,7 +11820,7 @@ _hw_addr_set (NMDevice *self,
 			       operation, addr, detail);
 		} else {
 			_LOGW (LOGD_DEVICE,
-			       "set-hw-addr: new MAC address %s not successfully set to %s (%s)",
+			       "set-hw-addr: new MAC address %s not successfully %s (%s)",
 			       addr, operation, detail);
 			success = FALSE;
 		}
-- 
2.7.4


From ac81b54da92c569db110407a63142565d69963f4 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Mon, 29 Aug 2016 18:28:34 +0200
Subject: [PATCH 4/4] device: add hack to wait after changing MAC address

It seems some drivers return success for nm_platform_link_set_address(),
but at that point the address did not yet actually change *sigh*.
It changes a bit later, possibly after setting the device up.

Add a workaround to retry reading the MAC address when platform indicates
success but the address still differs at first.

https://bugzilla.gnome.org/show_bug.cgi?id=770456
(cherry picked from commit 67b685235847ac49712d77023e23ef5c38e82a9e)
(cherry picked from commit 3b51959f48f2b40a4d85e1d36fd69a46548369cb)
---
 src/devices/nm-device.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 305a1bb..6939332 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -11774,6 +11774,7 @@ _hw_addr_set (NMDevice *self,
 {
 	NMDevicePrivate *priv;
 	gboolean success = FALSE;
+	gboolean needs_refresh = FALSE;
 	NMPlatformError plerr;
 	const char *cur_addr;
 	guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
@@ -11819,10 +11820,10 @@ _hw_addr_set (NMDevice *self,
 			_LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)",
 			       operation, addr, detail);
 		} else {
-			_LOGW (LOGD_DEVICE,
-			       "set-hw-addr: new MAC address %s not successfully %s (%s)",
+			_LOGD (LOGD_DEVICE,
+			       "set-hw-addr: new MAC address %s not successfully %s (%s) (refresh link)",
 			       addr, operation, detail);
-			success = FALSE;
+			needs_refresh = TRUE;
 		}
 	} else {
 		_NMLOG (plerr == NM_PLATFORM_ERROR_NOT_FOUND ? LOGL_DEBUG : LOGL_WARN,
@@ -11836,6 +11837,27 @@ _hw_addr_set (NMDevice *self,
 			return FALSE;
 	}
 
+	if (needs_refresh) {
+		/* The platform call indicated success, however the address is not
+		 * as expected. May be a kernel issue and the MAC address takes
+		 * a moment to change (bgo#770456).
+		 *
+		 * Try to reload the link and check again. */
+		nm_platform_link_refresh (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self));
+
+		nm_device_update_hw_address (self);
+		cur_addr = nm_device_get_hw_address (self);
+		if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
+			_LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)",
+			       operation, addr, detail);
+		} else {
+			_LOGW (LOGD_DEVICE,
+			       "set-hw-addr: new MAC address %s not successfully %s (%s)",
+			       addr, operation, detail);
+			return FALSE;
+		}
+	}
+
 	return success;
 }
 
-- 
2.7.4