From ebdf1796f10954dd89cde1e95025f1b6d36166f3 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Sun, 8 Sep 2013 13:39:03 -0400 Subject: [PATCH] core: implement :mtu and :cloned-mac-address for VLAN --- src/devices/nm-device-ethernet.c | 52 ++-------------------------- src/devices/nm-device-private.h | 2 ++ src/devices/nm-device-vlan.c | 58 ++++++++++++++++++++++++++++++++ src/devices/nm-device-wifi.c | 46 ++----------------------- src/devices/nm-device.c | 49 +++++++++++++++++++++++++++ 5 files changed, 113 insertions(+), 94 deletions(-) diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index c619951b6..91a39ed18 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -301,54 +301,6 @@ nm_device_ethernet_new (NMPlatformLink *platform_device) NULL); } -static gboolean -_set_hw_addr (NMDeviceEthernet *self, const guint8 *addr, const char *detail) -{ - NMDevice *dev = NM_DEVICE (self); - const char *iface; - char *mac_str = NULL; - gboolean success = FALSE; - const guint8 *cur_addr = nm_device_get_hw_address (dev, NULL); - - g_return_val_if_fail (addr != NULL, FALSE); - - iface = nm_device_get_iface (dev); - - /* Do nothing if current MAC is same */ - if (cur_addr && !memcmp (cur_addr, addr, ETH_ALEN)) { - nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): no MAC address change needed", iface); - return TRUE; - } - - mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - - /* Can't change MAC address while device is up */ - nm_device_take_down (dev, FALSE); - - success = nm_platform_link_set_address (nm_device_get_ip_ifindex (dev), addr, ETH_ALEN); - if (success) { - /* MAC address succesfully changed; update the current MAC to match */ - nm_device_update_hw_address (dev); - cur_addr = nm_device_get_hw_address (dev, NULL); - if (memcmp (cur_addr, addr, ETH_ALEN) == 0) { - nm_log_info (LOGD_DEVICE | LOGD_ETHER, "(%s): %s MAC address to %s", - iface, detail, mac_str); - } else { - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "(%s): new MAC address %s " - "not successfully set", - iface, mac_str); - } - } else { - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "(%s): failed to %s MAC address to %s", - iface, detail, mac_str); - } - nm_device_bring_up (dev, FALSE, NULL); - g_free (mac_str); - - return success; -} - static void update_permanent_hw_address (NMDevice *dev) { @@ -953,7 +905,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) /* Set device MAC address if the connection wants to change it */ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - _set_hw_addr (self, (const guint8 *) cloned_mac->data, "set"); + nm_device_set_hw_addr (dev, cloned_mac->data, "set", LOGD_ETHER); } } @@ -1178,7 +1130,7 @@ deactivate (NMDevice *device) supplicant_interface_release (self); /* Reset MAC address back to initial address */ - _set_hw_addr (self, priv->initial_hw_addr, "reset"); + nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER); } static gboolean diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 433d7829c..dc7288642 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -53,6 +53,8 @@ gboolean nm_device_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmwar void nm_device_take_down (NMDevice *self, gboolean block); gboolean nm_device_update_hw_address (NMDevice *self); +gboolean nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, + const char *detail, guint64 hw_log_domain); gboolean nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 462d19620..ecd12f185 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -46,6 +46,8 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) #define NM_VLAN_ERROR (nm_vlan_error_quark ()) typedef struct { + guint8 initial_hw_addr[ETH_ALEN]; + gboolean disposed; gboolean invalid; @@ -76,6 +78,21 @@ nm_vlan_error_quark (void) /******************************************************************/ +static void +update_initial_hw_address (NMDevice *dev) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (dev); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + char *mac_str; + + memcpy (priv->initial_hw_addr, nm_device_get_hw_address (dev, NULL), ETH_ALEN); + + mac_str = nm_utils_hwaddr_ntoa (priv->initial_hw_addr, ARPHRD_ETHER); + nm_log_dbg (LOGD_DEVICE | LOGD_VLAN, "(%s): read initial MAC address %s", + nm_device_get_iface (dev), mac_str); + g_free (mac_str); +} + static guint32 get_generic_capabilities (NMDevice *dev) { @@ -294,6 +311,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) NMActRequest *req; NMConnection *connection; NMSettingVlan *s_vlan; + NMSettingWired *s_wired; + const GByteArray *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -308,6 +327,14 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) connection = nm_act_request_get_connection (req); g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) { + /* Set device MAC address if the connection wants to change it */ + cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); + if (cloned_mac && (cloned_mac->len == ETH_ALEN)) + nm_device_set_hw_addr (dev, (const guint8 *) cloned_mac->data, "set", LOGD_VLAN); + } + s_vlan = nm_connection_get_setting_vlan (connection); if (s_vlan) { int ifindex = nm_device_get_ifindex (dev); @@ -329,6 +356,34 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) return ret; } +static void +ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) +{ + NMConnection *connection; + NMSettingWired *s_wired; + guint32 mtu; + + connection = nm_device_get_connection (device); + g_assert (connection); + + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) { + mtu = nm_setting_wired_get_mtu (s_wired); + if (mtu) + nm_ip4_config_set_mtu (config, mtu); + } +} + +static void +deactivate (NMDevice *device) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (device); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + + /* Reset MAC address back to initial address */ + nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_VLAN); +} + /******************************************************************/ static void @@ -550,9 +605,12 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) object_class->set_property = set_property; object_class->dispose = dispose; + parent_class->update_initial_hw_address = update_initial_hw_address; parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->bring_up = bring_up; parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->ip4_config_pre_commit = ip4_config_pre_commit; + parent_class->deactivate = deactivate; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; diff --git a/src/devices/nm-device-wifi.c b/src/devices/nm-device-wifi.c index 4d2db865a..7c75dee40 100644 --- a/src/devices/nm-device-wifi.c +++ b/src/devices/nm-device-wifi.c @@ -784,48 +784,6 @@ bring_up (NMDevice *device, gboolean *no_firmware) return NM_DEVICE_CLASS (nm_device_wifi_parent_class)->bring_up (device, no_firmware); } -static gboolean -_set_hw_addr (NMDeviceWifi *self, const guint8 *addr, const char *detail) -{ - NMDevice *dev = NM_DEVICE (self); - const char *iface; - char *mac_str = NULL; - gboolean success = FALSE; - const guint8 *cur_addr = nm_device_get_hw_address (dev, NULL); - - g_return_val_if_fail (addr != NULL, FALSE); - - iface = nm_device_get_iface (dev); - - mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - - /* Do nothing if current MAC is same */ - if (cur_addr && !memcmp (cur_addr, addr, ETH_ALEN)) { - nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): no MAC address change needed", iface); - g_free (mac_str); - return TRUE; - } - - /* Can't change MAC address while device is up */ - nm_device_take_down (dev, FALSE); - - success = nm_platform_link_set_address (nm_device_get_ip_ifindex (dev), addr, ETH_ALEN); - if (success) { - /* MAC address succesfully changed; update the current MAC to match */ - nm_device_update_hw_address (dev); - nm_log_info (LOGD_DEVICE | LOGD_ETHER, "(%s): %s MAC address to %s", - iface, detail, mac_str); - } else { - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "(%s): failed to %s MAC address to %s", - iface, detail, mac_str); - } - bring_up (dev, NULL); - g_free (mac_str); - - return success; -} - static void remove_access_point (NMDeviceWifi *device, NMAccessPoint *ap, @@ -896,7 +854,7 @@ deactivate (NMDevice *dev) remove_access_point (self, orig_ap, TRUE); /* Reset MAC address back to initial address */ - _set_hw_addr (self, priv->initial_hw_addr, "reset"); + nm_device_set_hw_addr (dev, priv->initial_hw_addr, "reset", LOGD_WIFI); /* Ensure we're in infrastructure mode after deactivation; some devices * (usually older ones) don't scan well in adhoc mode. @@ -2881,7 +2839,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) /* Set spoof MAC to the interface */ cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - _set_hw_addr (self, (const guint8 *) cloned_mac->data, "set"); + nm_device_set_hw_addr (dev, (const guint8 *) cloned_mac->data, "set", LOGD_WIFI); /* AP mode never uses a specific object or existing scanned AP */ if (priv->mode != NM_802_11_MODE_AP) { diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 80e0cd064..9a3f53a33 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6704,6 +6704,55 @@ nm_device_update_hw_address (NMDevice *dev) return changed; } +gboolean +nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, + const char *detail, guint64 hw_log_domain) +{ + const char *iface; + char *mac_str = NULL; + gboolean success = FALSE; + guint len; + const guint8 *cur_addr = nm_device_get_hw_address (device, &len); + + g_return_val_if_fail (addr != NULL, FALSE); + + iface = nm_device_get_iface (device); + + /* Do nothing if current MAC is same */ + if (cur_addr && !memcmp (cur_addr, addr, len)) { + nm_log_dbg (LOGD_DEVICE | hw_log_domain, "(%s): no MAC address change needed", iface); + return TRUE; + } + + mac_str = nm_utils_hwaddr_ntoa_len (addr, len); + + /* Can't change MAC address while device is up */ + nm_device_take_down (device, FALSE); + + success = nm_platform_link_set_address (nm_device_get_ip_ifindex (device), addr, len); + if (success) { + /* MAC address succesfully changed; update the current MAC to match */ + nm_device_update_hw_address (device); + cur_addr = nm_device_get_hw_address (device, NULL); + if (memcmp (cur_addr, addr, len) == 0) { + nm_log_info (LOGD_DEVICE | hw_log_domain, "(%s): %s MAC address to %s", + iface, detail, mac_str); + } else { + nm_log_warn (LOGD_DEVICE | hw_log_domain, "(%s): new MAC address %s " + "not successfully set", + iface, mac_str); + success = FALSE; + } + } else { + nm_log_warn (LOGD_DEVICE | hw_log_domain, "(%s): failed to %s MAC address to %s", + iface, detail, mac_str); + } + nm_device_bring_up (device, NULL); + g_free (mac_str); + + return success; +} + void nm_device_add_pending_action (NMDevice *device, const char *action) {