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.
This commit is contained in:
Dan Williams 2012-02-22 23:51:42 -06:00
parent 29672c3f7d
commit 5ee7841475
8 changed files with 85 additions and 13 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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;