diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-10-06 15:21:29 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-10-08 22:01:48 +0200 |
commit | e6d7fee5a617632acae02e12b1ec6156842df788 (patch) | |
tree | 073aab3fdd4d4d6943271d1544d5f03671c51a47 | |
parent | e29ab54335c6a5ef1ce6bac525f1f18a8e81b96e (diff) | |
download | NetworkManager-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.c | 40 |
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, |