core: implement :mtu and :cloned-mac-address for VLAN
This commit is contained in:
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user