From 05d35647ece5681c8e6b9dcb185cc84508ff3b3d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 21 Jan 2017 15:26:53 +0100 Subject: core: refactor nm_match_spec_device() to use match-data structure Instead of passing on invdividual arguments for the match, create a MatchDeviceData structure and pass it on. This reduces the number of arguments and extending it later should be easier. Also, lazily parse the hardware address as needed. (cherry picked from commit b0aaff86b61b9267cbc7640836823bbba82668b8) --- src/nm-core-utils.c | 152 ++++++++++++++++++++++++++-------------------------- 1 file changed, 77 insertions(+), 75 deletions(-) (limited to 'src/nm-core-utils.c') diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 7bdf6eb224..9ca1f1b846 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -1213,8 +1213,26 @@ nm_utils_read_link_absolute (const char *link_file, GError **error) #define MATCH_TAG_CONFIG_NM_VERSION_MAX "nm-version-max:" #define MATCH_TAG_CONFIG_ENV "env:" +typedef struct { + const char *interface_name; + const char *device_type; + struct { + const char *value; + gboolean is_parsed; + guint len; + guint8 bin[NM_UTILS_HWADDR_LEN_MAX]; + } hwaddr; + struct { + const char *value; + gboolean is_parsed; + guint32 a; + guint32 b; + guint32 c; + } s390_subchannels; +} MatchDeviceData; + static gboolean -match_s390_subchannels_parse (const char *s390_subchannels, guint32 *a, guint32 *b, guint32 *c) +match_device_s390_subchannels_parse (const char *s390_subchannels, guint32 *a, guint32 *b, guint32 *c) { const int BUFSIZE = 10; long unsigned int tmp; @@ -1278,42 +1296,52 @@ match_s390_subchannels_parse (const char *s390_subchannels, guint32 *a, guint32 return TRUE; } -typedef struct { - const char *s390_subchannels; - gboolean is_parsed; - guint32 a; - guint32 b; - guint32 c; -} MatchS390SubchannelsData; - static gboolean -match_s390_subchannels_ensure (MatchS390SubchannelsData *data) +match_data_s390_subchannels_eval (const char *spec_str, + MatchDeviceData *match_data) { - nm_assert (data); + guint32 a, b, c; + + if (G_UNLIKELY (!match_data->s390_subchannels.is_parsed)) { + match_data->s390_subchannels.is_parsed = TRUE; - if (data->is_parsed) - return !!data->s390_subchannels; + if ( !match_data->s390_subchannels.value + || !match_device_s390_subchannels_parse (match_data->s390_subchannels.value, + &match_data->s390_subchannels.a, + &match_data->s390_subchannels.b, + &match_data->s390_subchannels.c)) { + match_data->s390_subchannels.value = NULL; + return FALSE; + } + } else if (!match_data->s390_subchannels.value) + return FALSE; - data->is_parsed = TRUE; - if (!match_s390_subchannels_parse (data->s390_subchannels, - &data->a, &data->b, &data->c)) { - data->s390_subchannels = NULL; + if (!match_device_s390_subchannels_parse (spec_str, &a, &b, &c)) return FALSE; - } - return TRUE; + return match_data->s390_subchannels.a == a + && match_data->s390_subchannels.b == b + && match_data->s390_subchannels.c == c; } static gboolean -match_s390_subchannels_eval (const char *spec_str, - MatchS390SubchannelsData *data) +match_device_hwaddr_eval (const char *spec_str, + MatchDeviceData *match_data) { - guint32 a, b, c; + if (G_UNLIKELY (!match_data->hwaddr.is_parsed)) { + match_data->hwaddr.is_parsed = TRUE; - if (!match_s390_subchannels_ensure (data)) - return FALSE; - if (!match_s390_subchannels_parse (spec_str, &a, &b, &c)) + if (match_data->hwaddr.value) { + gsize l; + + if (!_nm_utils_hwaddr_aton (match_data->hwaddr.value, match_data->hwaddr.bin, sizeof (match_data->hwaddr.bin), &l)) + g_return_val_if_reached (FALSE); + match_data->hwaddr.len = l; + } else + return FALSE; + } else if (!match_data->hwaddr.len) return FALSE; - return data->a == a && data->b == b && data->c == c; + + return nm_utils_hwaddr_matches (spec_str, -1, match_data->hwaddr.bin, match_data->hwaddr.len); } #define _MATCH_CHECK(spec_str, tag) \ @@ -1340,24 +1368,15 @@ match_except (const char *spec_str, gboolean *out_except) static gboolean match_device_eval (const char *spec_str, gboolean allow_fuzzy, - const char *interface_name, - const char *device_type, - const guint8 *hwaddr_bin, - guint hwaddr_len, - MatchS390SubchannelsData *s390_subchannels_data) + MatchDeviceData *match_data) { - nm_assert (!device_type || device_type[0]); - nm_assert (s390_subchannels_data); - if (_MATCH_CHECK (spec_str, DEVICE_TYPE_TAG)) { - return device_type - && nm_streq (spec_str, device_type); + return match_data->device_type + && nm_streq (spec_str, match_data->device_type); } - if (_MATCH_CHECK (spec_str, MAC_TAG)) { - return hwaddr_bin - && nm_utils_hwaddr_matches (spec_str, -1, hwaddr_bin, hwaddr_len); - } + if (_MATCH_CHECK (spec_str, MAC_TAG)) + return match_device_hwaddr_eval (spec_str, match_data); if (_MATCH_CHECK (spec_str, INTERFACE_NAME_TAG)) { gboolean use_pattern = FALSE; @@ -1370,24 +1389,23 @@ match_device_eval (const char *spec_str, use_pattern = TRUE; } - if (interface_name) { - if (nm_streq (spec_str, interface_name)) + if (match_data->interface_name) { + if (nm_streq (spec_str, match_data->interface_name)) return TRUE; - if (use_pattern && g_pattern_match_simple (spec_str, interface_name)) + if (use_pattern && g_pattern_match_simple (spec_str, match_data->interface_name)) return TRUE; } return FALSE; } if (_MATCH_CHECK (spec_str, SUBCHAN_TAG)) - return match_s390_subchannels_eval (spec_str, s390_subchannels_data); + return match_data_s390_subchannels_eval (spec_str, match_data); if (allow_fuzzy) { - if ( hwaddr_bin - && nm_utils_hwaddr_matches (spec_str, -1, hwaddr_bin, hwaddr_len)) + if (match_device_hwaddr_eval (spec_str, match_data)) return TRUE; - if ( interface_name - && nm_streq (spec_str, interface_name)) + if ( match_data->interface_name + && nm_streq (spec_str, match_data->interface_name)) return TRUE; } @@ -1405,11 +1423,15 @@ nm_match_spec_device (const GSList *specs, NMMatchSpecMatchType match; const char *spec_str; gboolean except; - guint hwaddr_len = 0; - const guint8 *hwaddr_bin = NULL; - guint8 hwaddr_bin_data[NM_UTILS_HWADDR_LEN_MAX]; - MatchS390SubchannelsData s390_subchannels_data = { - .s390_subchannels = s390_subchannels, + MatchDeviceData match_data = { + .interface_name = interface_name, + .device_type = nm_str_not_empty (device_type), + .hwaddr = { + .value = hwaddr, + }, + .s390_subchannels = { + .value = s390_subchannels, + }, }; nm_assert (!hwaddr || nm_utils_hwaddr_valid (hwaddr, -1)); @@ -1417,18 +1439,6 @@ nm_match_spec_device (const GSList *specs, if (!specs) return NM_MATCH_SPEC_NO_MATCH; - if (device_type && !*device_type) - device_type = NULL; - - if (hwaddr) { - gsize l; - - if (!_nm_utils_hwaddr_aton (hwaddr, hwaddr_bin_data, sizeof (hwaddr_bin_data), &l)) - g_return_val_if_reached (NM_MATCH_SPEC_NO_MATCH); - hwaddr_bin = hwaddr_bin_data; - hwaddr_len = l; - } - /* first see if there is an all-match "*" */ for (iter = specs; iter; iter = iter->next) { spec_str = iter->data; @@ -1449,11 +1459,7 @@ nm_match_spec_device (const GSList *specs, continue; if (!match_device_eval (spec_str, FALSE, - interface_name, - device_type, - hwaddr_bin, - hwaddr_len, - &s390_subchannels_data)) + &match_data)) continue; return NM_MATCH_SPEC_NEG_MATCH; } @@ -1480,11 +1486,7 @@ nm_match_spec_device (const GSList *specs, if (!match_device_eval (spec_str, !except, - interface_name, - device_type, - hwaddr_bin, - hwaddr_len, - &s390_subchannels_data)) + &match_data)) continue; if (except) -- cgit v1.2.1