core: let device classes indicate their HW address will never change (bgo #701744)

Bluetooth device hardware addresses won't change during the lifetime
of the object (since that would mean a completely new device) and
they also won't have an ifindex because they aren't netdevices.

Various bits of the core periodically call nm_device_update_hw_address()
to update a device's hardware address, but this function expects that
any device with a hardware address also has an ifindex.  Except that
Bluetooth devices don't because they aren't netdevices.

Modify the get_hw_address_length() function to return a boolean
indicating whether or not the address can ever change, and set that
for BT devices.  nm_device_update_hw_address() then exits early if
there's no point in re-checking the hardware address, avoiding the
assertion.

https://bugzilla.gnome.org/show_bug.cgi?id=701744
This commit is contained in:
Dan Williams 2013-07-19 12:05:19 -05:00
parent 86a197f177
commit fe5f0d2070
5 changed files with 16 additions and 10 deletions

View file

@ -520,7 +520,7 @@ deactivate (NMDevice *device)
/**************************************************************/
static guint
get_hw_address_length (NMDevice *device)
get_hw_address_length (NMDevice *device, gboolean *out_permanent)
{
NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (device);

View file

@ -113,9 +113,11 @@ guint32 nm_device_bt_get_capabilities (NMDeviceBt *self)
}
static guint
get_hw_address_length (NMDevice *device)
get_hw_address_length (NMDevice *device, gboolean *out_permanent)
{
/* HW address is the Bluetooth HW address of the remote device */
if (out_permanent)
*out_permanent = TRUE; /* the bdaddr of the remote device will never change */
return ETH_ALEN;
}

View file

@ -213,7 +213,7 @@ device_state_changed (NMDevice *device,
}
static guint
get_hw_address_length (NMDevice *device)
get_hw_address_length (NMDevice *device, gboolean *out_permanent)
{
return 0;
}

View file

@ -691,7 +691,7 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface)
}
static guint
get_hw_address_length (NMDevice *dev)
get_hw_address_length (NMDevice *dev, gboolean *out_permanent)
{
size_t len;
@ -702,9 +702,9 @@ get_hw_address_length (NMDevice *dev)
}
static guint
nm_device_get_hw_address_length (NMDevice *dev)
nm_device_get_hw_address_length (NMDevice *dev, gboolean *out_permanent)
{
return NM_DEVICE_GET_CLASS (dev)->get_hw_address_length (dev);
return NM_DEVICE_GET_CLASS (dev)->get_hw_address_length (dev, out_permanent);
}
const guint8 *
@ -4949,7 +4949,7 @@ set_property (GObject *object, guint prop_id,
priv->is_master = g_value_get_boolean (value);
break;
case PROP_HW_ADDRESS:
priv->hw_addr_len = nm_device_get_hw_address_length (NM_DEVICE (object));
priv->hw_addr_len = nm_device_get_hw_address_length (NM_DEVICE (object), NULL);
hw_addr = g_value_get_string (value);
if (!hw_addr)
@ -6385,9 +6385,13 @@ gboolean
nm_device_update_hw_address (NMDevice *dev)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
gboolean changed = FALSE;
gboolean changed = FALSE, permanent = FALSE;
priv->hw_addr_len = nm_device_get_hw_address_length (dev);
priv->hw_addr_len = nm_device_get_hw_address_length (dev, &permanent);
/* If the address can't be changed, don't bother trying */
if (permanent)
return FALSE;
if (priv->hw_addr_len) {
int ifindex = nm_device_get_ip_ifindex (dev);

View file

@ -112,7 +112,7 @@ typedef struct {
void (* update_hw_address) (NMDevice *self);
void (* update_permanent_hw_address) (NMDevice *self);
void (* update_initial_hw_address) (NMDevice *self);
guint (* get_hw_address_length) (NMDevice *self);
guint (* get_hw_address_length) (NMDevice *self, gboolean *out_permanent);
guint32 (* get_generic_capabilities) (NMDevice *self);