libnm: lookup route attributes attribute spec via binary search

This commit is contained in:
Thomas Haller 2019-11-27 13:13:48 +01:00
parent e7816a2508
commit 7cadc5e465
5 changed files with 99 additions and 25 deletions

View file

@ -874,4 +874,13 @@ const char *nm_utils_wifi_freq_to_band (guint32 freq);
gboolean _nm_utils_iaid_verify (const char *str, gint64 *out_value);
/*****************************************************************************/
gboolean _nmtst_variant_attribute_spec_assert_sorted (const NMVariantAttributeSpec *const*array,
gsize len);
const NMVariantAttributeSpec *_nm_variant_attribute_spec_find_binary_search (const NMVariantAttributeSpec *const*array,
gsize len,
const char *name);
#endif

View file

@ -1197,21 +1197,21 @@ nm_ip_route_set_attribute (NMIPRoute *route, const char *name, GVariant *value)
}
static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = {
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TABLE, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, .v4 = TRUE, .v6 = TRUE, .str_type = 'a', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_FROM, G_VARIANT_TYPE_STRING, .v6 = TRUE, .str_type = 'p', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, .v4 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_ONLINK, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_WINDOW, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_CWND, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_FROM, G_VARIANT_TYPE_STRING, .v6 = TRUE, .str_type = 'p', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_INITCWND, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_INITRWND, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_MTU, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_MTU, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_ONLINK, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, .v4 = TRUE, .v6 = TRUE, .str_type = 'a', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TABLE, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, .v4 = TRUE, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_WINDOW, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ),
NULL,
};
@ -1250,21 +1250,16 @@ nm_ip_route_attribute_validate (const char *name,
gboolean *known,
GError **error)
{
const NMVariantAttributeSpec *const *iter;
const NMVariantAttributeSpec *spec = NULL;
const NMVariantAttributeSpec *spec;
g_return_val_if_fail (name, FALSE);
g_return_val_if_fail (value, FALSE);
g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
for (iter = ip_route_attribute_spec; *iter; iter++) {
if (nm_streq (name, (*iter)->name)) {
spec = *iter;
break;
}
}
spec = _nm_variant_attribute_spec_find_binary_search (ip_route_attribute_spec,
G_N_ELEMENTS (ip_route_attribute_spec) - 1,
name);
if (!spec) {
NM_SET_OUT (known, FALSE);
g_set_error_literal (error,

View file

@ -127,21 +127,21 @@ gboolean nm_ip_route_attribute_validate (const char *name,
gboolean *known,
GError **error);
#define NM_IP_ROUTE_ATTRIBUTE_TABLE "table"
#define NM_IP_ROUTE_ATTRIBUTE_SRC "src"
#define NM_IP_ROUTE_ATTRIBUTE_FROM "from"
#define NM_IP_ROUTE_ATTRIBUTE_TOS "tos"
#define NM_IP_ROUTE_ATTRIBUTE_ONLINK "onlink"
#define NM_IP_ROUTE_ATTRIBUTE_WINDOW "window"
#define NM_IP_ROUTE_ATTRIBUTE_CWND "cwnd"
#define NM_IP_ROUTE_ATTRIBUTE_FROM "from"
#define NM_IP_ROUTE_ATTRIBUTE_INITCWND "initcwnd"
#define NM_IP_ROUTE_ATTRIBUTE_INITRWND "initrwnd"
#define NM_IP_ROUTE_ATTRIBUTE_MTU "mtu"
#define NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW "lock-window"
#define NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND "lock-cwnd"
#define NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND "lock-initcwnd"
#define NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND "lock-initrwnd"
#define NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU "lock-mtu"
#define NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW "lock-window"
#define NM_IP_ROUTE_ATTRIBUTE_MTU "mtu"
#define NM_IP_ROUTE_ATTRIBUTE_ONLINK "onlink"
#define NM_IP_ROUTE_ATTRIBUTE_SRC "src"
#define NM_IP_ROUTE_ATTRIBUTE_TABLE "table"
#define NM_IP_ROUTE_ATTRIBUTE_TOS "tos"
#define NM_IP_ROUTE_ATTRIBUTE_WINDOW "window"
/*****************************************************************************/

View file

@ -5555,6 +5555,48 @@ attribute_unescape (const char *start, const char *end)
return ret;
}
gboolean
_nmtst_variant_attribute_spec_assert_sorted (const NMVariantAttributeSpec *const*array,
gsize len)
{
gsize i;
g_assert (array);
g_assert (len > 0);
g_assert_cmpint(len, ==, NM_PTRARRAY_LEN (array));
for (i = 0; i < len; i++) {
nm_assert (array[i]->name);
nm_assert (array[i]->name[0]);
if (i > 0)
nm_assert (strcmp (array[i - 1]->name, array[i]->name) < 0);
}
nm_assert (!array[i]);
return TRUE;
}
const NMVariantAttributeSpec *
_nm_variant_attribute_spec_find_binary_search (const NMVariantAttributeSpec *const*array,
gsize len,
const char *name)
{
gssize idx;
G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMVariantAttributeSpec, name) == 0);
idx = nm_utils_ptrarray_find_binary_search ((gconstpointer *) array,
len,
&name,
nm_strcmp_p_with_data,
NULL,
NULL,
NULL);
if (idx < 0)
return NULL;
return array[idx];
}
/**
* nm_utils_parse_variant_attributes:
* @string: the input string

View file

@ -7986,6 +7986,33 @@ test_route_attributes_format (void)
/*****************************************************************************/
static void
test_variant_attribute_spec (void)
{
const NMVariantAttributeSpec *const *const specs_list[] = {
nm_ip_route_get_variant_attribute_spec (),
};
int i_specs;
for (i_specs = 0; i_specs < G_N_ELEMENTS (specs_list); i_specs++) {
const NMVariantAttributeSpec *const *const specs = specs_list[i_specs];
gsize len;
gsize i;
g_assert (specs);
len = NM_PTRARRAY_LEN (specs);
g_assert_cmpint (len, >, 0u);
_nmtst_variant_attribute_spec_assert_sorted (specs, len);
for (i = 0; i < len; i++)
g_assert (specs[i] == _nm_variant_attribute_spec_find_binary_search (specs, len, specs[i]->name));
g_assert (!_nm_variant_attribute_spec_find_binary_search (specs, len, "bogus"));
}
}
/*****************************************************************************/
static gboolean
do_test_nm_set_out_called (int *call_count)
{
@ -8448,6 +8475,7 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/nm-set-out", test_nm_set_out);
g_test_add_func ("/core/general/route_attributes/parse", test_route_attributes_parse);
g_test_add_func ("/core/general/route_attributes/format", test_route_attributes_format);
g_test_add_func ("/core/general/test_variant_attribute_spec", test_variant_attribute_spec);
g_test_add_func ("/core/general/get_start_time_for_pid", test_get_start_time_for_pid);
g_test_add_func ("/core/general/test_nm_va_args_macros", test_nm_va_args_macros);