summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-12-31 01:22:36 +0100
committerThomas Haller <thaller@redhat.com>2020-01-02 16:19:54 +0100
commit0697c1adcccbba1588d1c6387ca753a22bd88b59 (patch)
tree436862372c14e3b9ef7570ea75cfe3cd66aaffbd
parent7d2676919f79bac6c47226126039c27bae038f05 (diff)
downloadNetworkManager-th/device-ip-tunnel-mac.tar.gz
core: set MAC address for IP tunnels when creating deviceth/device-ip-tunnel-mac
There is however a serious issue currently: when NetworkManager creates virtual devices, it starts from an unrealized NMDevice, creates the netdev device, realizes the device, and transitions through states UNMANAGED and DISCONNECTED. Thereby, the state of NMDevice gets cleared again. That means, if the profile has "connection.stable-id=${RANDOM}" and "ethernet.cloned-mac-address=stable", then we will first set a random MAC address when creating the device. Then, the NMDevice transitions through UNMANAGED state, forgets the MAC address it generated and creates a new MAC address in stage 1. This should be fixed by better handling unrealized devices. It also affects all software devices that set the MAC address upon creation of the interfaces (as they all should).
-rw-r--r--src/devices/nm-device-bridge.c9
-rw-r--r--src/devices/nm-device-ip-tunnel.c39
2 files changed, 41 insertions, 7 deletions
diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c
index 72a8ce2bb2..164fa0a1e8 100644
--- a/src/devices/nm-device-bridge.c
+++ b/src/devices/nm-device-bridge.c
@@ -736,10 +736,11 @@ create_and_realize (NMDevice *device,
if ( !hwaddr
&& nm_device_hw_addr_get_cloned (device, connection, FALSE,
&hwaddr_cloned, NULL, NULL)) {
- /* The cloned MAC address might by dynamic, for example with stable-id="${RANDOM}".
- * It's a bit odd that we first create the device with one dynamic address,
- * and later on may reset it to another. That is, because we don't cache
- * the dynamic address in @device, like we do during nm_device_hw_addr_set_cloned(). */
+ /* FIXME: we set the MAC address when creating the interface, while the
+ * NMDevice is still unrealized. As we afterwards realize the device, it
+ * forgets the parameters for the cloned MAC address, and in stage 1
+ * it might create a different MAC address. That should be fixed by
+ * better handling device realization. */
hwaddr = hwaddr_cloned;
}
diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c
index c84ff3a587..87c8c7ba5b 100644
--- a/src/devices/nm-device-ip-tunnel.c
+++ b/src/devices/nm-device-ip-tunnel.c
@@ -657,11 +657,44 @@ create_and_realize (NMDevice *device,
gint64 val;
NMIPTunnelMode mode;
int r;
+ gs_free char *hwaddr = NULL;
+ guint8 mac_address[ETH_ALEN];
+ gboolean mac_address_valid = FALSE;
s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
- g_assert (s_ip_tunnel);
+ nm_assert (NM_IS_SETTING_IP_TUNNEL (s_ip_tunnel));
mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel);
+
+ if ( nm_device_hw_addr_get_cloned (device,
+ connection,
+ FALSE,
+ &hwaddr,
+ NULL,
+ NULL)
+ && hwaddr) {
+ /* FIXME: we set the MAC address when creating the interface, while the
+ * NMDevice is still unrealized. As we afterwards realize the device, it
+ * forgets the parameters for the cloned MAC address, and in stage 1
+ * it might create a different MAC address. That should be fixed by
+ * better handling device realization. */
+ if (!nm_utils_hwaddr_aton (hwaddr, mac_address, ETH_ALEN)) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
+ "Invalid hardware address '%s'",
+ hwaddr);
+ g_return_val_if_reached (FALSE);
+ }
+
+ if (NM_IN_SET (mode, NM_IP_TUNNEL_MODE_GRE)) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
+ "Invalid hardware address '%s' for tunnel type",
+ hwaddr);
+ return FALSE;
+ }
+
+ mac_address_valid = TRUE;
+ }
+
switch (mode) {
case NM_IP_TUNNEL_MODE_GRETAP:
lnk_gre.is_tap = TRUE;
@@ -704,8 +737,8 @@ create_and_realize (NMDevice *device,
r = nm_platform_link_gre_add (nm_device_get_platform (device),
iface,
- NULL,
- 0,
+ mac_address_valid ? mac_address : NULL,
+ mac_address_valid ? ETH_ALEN : 0,
&lnk_gre,
out_plink);
if (r < 0) {