Commit b0aaff86 authored by Thomas Haller's avatar Thomas Haller

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.
parent 418733f2
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment