From 17607e74a2bfdd0cab3dcc7cbb21686f4c8ded96 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 16 Sep 2013 16:27:38 -0400 Subject: [PATCH] infiniband: only check the last 8 bytes when doing hwaddr matches IPoIB "hardware addresses" are only partly based on the hardware, and partly based on the InfiniBand configuration. So when checking if a configuration matches a device, we should only match the fixed part. --- libnm-glib/nm-device-infiniband.c | 4 +++- src/devices/nm-device-infiniband.c | 38 +++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/libnm-glib/nm-device-infiniband.c b/libnm-glib/nm-device-infiniband.c index a42bce0456..070b8f8c63 100644 --- a/libnm-glib/nm-device-infiniband.c +++ b/libnm-glib/nm-device-infiniband.c @@ -169,7 +169,9 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return FALSE; } mac = nm_setting_infiniband_get_mac_address (s_infiniband); - if (mac && hwaddr && memcmp (mac->data, hwaddr, INFINIBAND_ALEN)) { + + /* We only match against the last 8 bytes */ + if (mac && hwaddr && memcmp (mac->data + INFINIBAND_ALEN - 8, hwaddr + INFINIBAND_ALEN - 8, 8)) { g_set_error (error, NM_DEVICE_INFINIBAND_ERROR, NM_DEVICE_INFINIBAND_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index eb17bf499c..4f71c7d7c3 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -236,7 +236,10 @@ check_connection_compatible (NMDevice *device, if (s_infiniband) { mac = nm_setting_infiniband_get_mac_address (s_infiniband); - if (mac && memcmp (mac->data, nm_device_get_hw_address (device, NULL), INFINIBAND_ALEN)) { + /* We only compare the last 8 bytes */ + if (mac && memcmp (mac->data + INFINIBAND_ALEN - 8, + nm_device_get_hw_address (device, NULL) + INFINIBAND_ALEN - 8, + 8)) { g_set_error (error, NM_INFINIBAND_ERROR, NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, @@ -306,6 +309,38 @@ match_l2_config (NMDevice *self, NMConnection *connection) return TRUE; } +static gboolean +spec_match_list (NMDevice *device, const GSList *specs) +{ + char *hwaddr_str, *spec_str; + const GSList *iter; + + if (NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->spec_match_list (device, specs)) + return TRUE; + + hwaddr_str = nm_utils_hwaddr_ntoa (nm_device_get_hw_address (device, NULL), + ARPHRD_INFINIBAND); + + /* InfiniBand hardware address matches only need to match the last + * 8 bytes. In string format, that means we skip the first 36 + * characters of hwaddr_str, and the first 40 of the spec (to skip + * "mac:" too). + */ + for (iter = specs; iter; iter = g_slist_next (iter)) { + spec_str = iter->data; + + if ( !g_ascii_strncasecmp (spec_str, "mac:", 4) + && strlen (spec_str) > 40 + && !g_ascii_strcasecmp (spec_str + 40, hwaddr_str + 36)) { + g_free (hwaddr_str); + return TRUE; + } + } + + g_free (hwaddr_str); + return FALSE; +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -344,6 +379,7 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; + parent_class->spec_match_list = spec_match_list; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->ip4_config_pre_commit = ip4_config_pre_commit;