summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-10-06 15:21:29 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-10-08 22:01:48 +0200
commite6d7fee5a617632acae02e12b1ec6156842df788 (patch)
tree073aab3fdd4d4d6943271d1544d5f03671c51a47
parente29ab54335c6a5ef1ce6bac525f1f18a8e81b96e (diff)
downloadNetworkManager-e6d7fee5a617632acae02e12b1ec6156842df788.tar.gz
device/vlan: update VLAN MAC address when parent's one changes
When a VLAN has a bond as parent device the MAC address of the bond may change when other devices are enslaved and then the VLAN would have a MAC which is different from parent's one. Let the VLAN device listen for changes in hw-address property of parent and update its MAC address accordingly. https://bugzilla.redhat.com/show_bug.cgi?id=1264322
-rw-r--r--src/devices/nm-device-vlan.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index 2d0a2ff794..d30ce5f4ea 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -49,6 +49,7 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE)
typedef struct {
NMDevice *parent;
guint parent_state_id;
+ guint parent_hwaddr_id;
int vlan_id;
} NMDeviceVlanPrivate;
@@ -79,6 +80,36 @@ parent_state_changed (NMDevice *parent,
}
static void
+parent_hwaddr_changed (NMDevice *parent,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ NMDeviceVlan *self = NM_DEVICE_VLAN (user_data);
+ NMConnection *connection;
+ NMSettingWired *s_wired;
+ const char *cloned_mac = NULL;
+
+ /* Never touch assumed devices */
+ if (nm_device_uses_assumed_connection (self))
+ return;
+
+ connection = nm_device_get_applied_connection (self);
+ if (!connection)
+ return;
+
+ /* Update the VLAN MAC only if configuration does not specify one */
+ s_wired = nm_connection_get_setting_wired (connection);
+ if (s_wired)
+ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
+
+ if (!cloned_mac) {
+ _LOGD (LOGD_VLAN, "parent hardware address changed");
+ nm_device_set_hw_addr (self, nm_device_get_hw_address (parent),
+ "set", LOGD_VLAN);
+ }
+}
+
+static void
nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
@@ -87,10 +118,8 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent)
if (parent == priv->parent)
return;
- if (priv->parent_state_id) {
- g_signal_handler_disconnect (priv->parent, priv->parent_state_id);
- priv->parent_state_id = 0;
- }
+ nm_clear_g_signal_handler (priv->parent, &priv->parent_state_id);
+ nm_clear_g_signal_handler (priv->parent, &priv->parent_hwaddr_id);
g_clear_object (&priv->parent);
if (parent) {
@@ -100,6 +129,9 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent)
G_CALLBACK (parent_state_changed),
device);
+ priv->parent_hwaddr_id = g_signal_connect (priv->parent, "notify::" NM_DEVICE_HW_ADDRESS,
+ G_CALLBACK (parent_hwaddr_changed), device);
+
/* Set parent-dependent unmanaged flag */
nm_device_set_unmanaged (device,
NM_UNMANAGED_PARENT,