From 5ee784147588ec207b91eebfafb37bf57b674eab Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 22 Feb 2012 23:51:42 -0600 Subject: [PATCH] core: extend nm_device_hwaddr_matches() to match specific addresses We'll want to eventually match (for VLAN) a given hardware address that's not the device's hardware address. Only the device itself knows which NMSetting should contain it's hardware address (ie the 'wired' setting for NMDeviceEthernet, 'infiniband' for NMDeviceInfiniband, etc) and VLANs take their hardware address from the parent interface. So eventually we'll have VLAN interfaces use these new arguments to ask their parent interface to match the VLAN hardware address in a connection, since the VLAN doesn't know (or need to know) what kind of interface it really is underneath. --- src/nm-device-bt.c | 13 +++++++++++-- src/nm-device-ethernet.c | 12 ++++++++++-- src/nm-device-infiniband.c | 12 ++++++++++-- src/nm-device-wifi.c | 12 ++++++++++-- src/nm-device.c | 31 +++++++++++++++++++++++++++++-- src/nm-device.h | 4 ++++ src/nm-manager.c | 2 +- src/wimax/nm-device-wimax.c | 12 ++++++++++-- 8 files changed, 85 insertions(+), 13 deletions(-) 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;