diff --git a/src/nm-device-bt.c b/src/nm-device-bt.c index af2b962930..524c25362d 100644 --- a/src/nm-device-bt.c +++ b/src/nm-device-bt.c @@ -375,7 +375,11 @@ real_get_generic_capabilities (NMDevice *dev) } static gboolean -hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr) +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMSettingBluetooth *s_bt; @@ -392,7 +396,12 @@ hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_ g_return_val_if_fail (devmac != NULL, FALSE); g_return_val_if_fail (devmac->len == mac->len, FALSE); - matches = (memcmp (mac->data, devmac->data, mac->len) == 0) ? TRUE : FALSE; + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == devmac->len, FALSE); + matches = (memcmp (mac->data, other_hwaddr, mac->len) == 0) ? TRUE : FALSE; + } else + matches = (memcmp (mac->data, devmac->data, mac->len) == 0) ? TRUE : FALSE; + g_byte_array_free (devmac, TRUE); return matches; } else if (fail_if_no_hwaddr == FALSE) diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 3092e4e713..990ab3cffb 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -1519,7 +1519,11 @@ connection_match_config (NMDevice *self, const GSList *connections) } static gboolean -hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr) +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) { NMSettingWired *s_wired; const guint8 *devaddr; @@ -1536,7 +1540,11 @@ hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_ if (mac) { g_return_val_if_fail (mac->len == ETH_ALEN, FALSE); - if (memcmp (mac->data, devaddr, mac->len) == 0) + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == ETH_ALEN, FALSE); + if (memcmp (mac->data, other_hwaddr, mac->len) == 0) + return TRUE; + } else if (memcmp (mac->data, devaddr, mac->len) == 0) return TRUE; } else if (fail_if_no_hwaddr == FALSE) return TRUE; diff --git a/src/nm-device-infiniband.c b/src/nm-device-infiniband.c index 51fb9f3555..9eec0a1f41 100644 --- a/src/nm-device-infiniband.c +++ b/src/nm-device-infiniband.c @@ -396,7 +396,11 @@ connection_match_config (NMDevice *self, const GSList *connections) } static gboolean -hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr) +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) { NMSettingInfiniband *s_ib; const guint8 *devaddr; @@ -413,7 +417,11 @@ hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_ if (mac) { g_return_val_if_fail (mac->len == INFINIBAND_ALEN, FALSE); - if (memcmp (mac->data, devaddr, mac->len) == 0) + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == INFINIBAND_ALEN, FALSE); + if (memcmp (mac->data, other_hwaddr, mac->len) == 0) + return TRUE; + } else if (memcmp (mac->data, devaddr, mac->len) == 0) return TRUE; } else if (fail_if_no_hwaddr == FALSE) return TRUE; diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 1399f75ab3..8a99005101 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2983,7 +2983,11 @@ spec_match_list (NMDevice *device, const GSList *specs) } static gboolean -hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr) +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); NMSettingWireless *s_wifi; @@ -2995,7 +2999,11 @@ hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_ if (mac) { g_return_val_if_fail (mac->len == ETH_ALEN, FALSE); - if (memcmp (mac->data, priv->hw_addr, mac->len) == 0) + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == ETH_ALEN, FALSE); + if (memcmp (mac->data, other_hwaddr, mac->len) == 0) + return TRUE; + } else if (memcmp (mac->data, priv->hw_addr, mac->len) == 0) return TRUE; } else if (fail_if_no_hwaddr == FALSE) return TRUE; diff --git a/src/nm-device.c b/src/nm-device.c index 90fc53613f..5a3b1ebc5f 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -4522,16 +4522,43 @@ nm_device_connection_match_config (NMDevice *device, const GSList *connections) return NULL; } +/** + * nm_device_hwaddr_matches: + * @device: the device to use when matching the hardware address + * @connection: the connection which supplies the hardware address + * @other_hwaddr: if given, use this address instead of the device's actual + * hardware address + * @other_hwaddr_len: length in bytes of @other_hwaddr + * @fail_if_no_hwaddr: whether to fail the match if @connection does not contain + * a hardware address + * + * Matches a the devices hardware address (or @other_hwaddr if given) against + * the hardware-specific setting in @connection. Allows for device-agnostic + * hardware address matching without having to know the internal details of + * the connection and which settings are used by each device subclass. + * + * Returns: %TRUE if the @device 's hardware address or @other_hwaddr matches + * a hardware address in a hardware-specific setting in @connection + */ gboolean nm_device_hwaddr_matches (NMDevice *device, NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, gboolean fail_if_no_hwaddr) { g_return_val_if_fail (device != NULL, FALSE); g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + if (other_hwaddr) + g_return_val_if_fail (other_hwaddr_len > 0, FALSE); - if (NM_DEVICE_GET_CLASS (device)->hwaddr_matches) - return NM_DEVICE_GET_CLASS (device)->hwaddr_matches (device, connection, fail_if_no_hwaddr); + if (NM_DEVICE_GET_CLASS (device)->hwaddr_matches) { + return NM_DEVICE_GET_CLASS (device)->hwaddr_matches (device, + connection, + other_hwaddr, + other_hwaddr_len, + fail_if_no_hwaddr); + } return FALSE; } diff --git a/src/nm-device.h b/src/nm-device.h index d226adf643..d5cbd5418d 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -157,6 +157,8 @@ typedef struct { gboolean (* hwaddr_matches) (NMDevice *self, NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, gboolean fail_if_no_hwaddr); } NMDeviceClass; @@ -213,6 +215,8 @@ NMConnection * nm_device_connection_match_config (NMDevice *device, gboolean nm_device_hwaddr_matches (NMDevice *device, NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, gboolean fail_if_no_hwaddr); gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs); diff --git a/src/nm-manager.c b/src/nm-manager.c index 688ce61318..bf8f388a08 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -925,7 +925,7 @@ get_iface_from_hwaddr (NMManager *self, for (iter = priv->devices; iter; iter = g_slist_next (iter)) { NMDevice *candidate = iter->data; - if (nm_device_hwaddr_matches (candidate, connection, TRUE)) { + if (nm_device_hwaddr_matches (candidate, connection, NULL, 0, TRUE)) { if (out_ifindex) *out_ifindex = nm_device_get_ip_ifindex (candidate); return nm_device_get_ip_iface (candidate); diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 74f0f4cd6c..1f1a622c46 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -410,7 +410,11 @@ real_update_hw_address (NMDevice *dev) } static gboolean -hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr) +hwaddr_matches (NMDevice *device, + NMConnection *connection, + const guint8 *other_hwaddr, + guint other_hwaddr_len, + gboolean fail_if_no_hwaddr) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); NMSettingWimax *s_wimax; @@ -422,7 +426,11 @@ hwaddr_matches (NMDevice *device, NMConnection *connection, gboolean fail_if_no_ if (mac) { g_return_val_if_fail (mac->len == ETH_ALEN, FALSE); - if (memcmp (mac->data, priv->hw_addr.ether_addr_octet, mac->len) == 0) + if (other_hwaddr) { + g_return_val_if_fail (other_hwaddr_len == ETH_ALEN, FALSE); + if (memcmp (mac->data, other_hwaddr, mac->len) == 0) + return TRUE; + } else if (memcmp (mac->data, priv->hw_addr.ether_addr_octet, mac->len) == 0) return TRUE; } else if (fail_if_no_hwaddr == FALSE) return TRUE;