Commit e6d7fee5 authored by Beniamino Galvani's avatar Beniamino Galvani

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
parent e29ab543
......@@ -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;
......@@ -78,6 +79,36 @@ parent_state_changed (NMDevice *parent,
nm_device_set_unmanaged (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent), reason);
}
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)
{
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment