libnm/keyfile: merge branch 'th/keyfile-cleanup'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1161
This commit is contained in:
Thomas Haller 2022-03-28 18:31:41 +02:00
commit 2bdca1f5d6
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
8 changed files with 647 additions and 373 deletions

File diff suppressed because it is too large Load diff

View file

@ -153,6 +153,68 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
#undef _D
};
const NMSetting8021xSchemeVtable *
nm_setting_8021x_scheme_vtable_by_setting_key(const char *key)
{
static const NMSetting8021xSchemeType sorted_index[] = {
NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY,
NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY,
};
int imin, imax;
nm_assert(key);
if (NM_MORE_ASSERT_ONCE(5)) {
const NMSetting8021xSchemeVtable *vtable_prev = NULL;
int i, j;
for (i = 0; i < (int) G_N_ELEMENTS(sorted_index); i++) {
const NMSetting8021xSchemeType t = sorted_index[i];
const NMSetting8021xSchemeVtable *vtable;
nm_assert(_NM_INT_NOT_NEGATIVE(t));
nm_assert(t < G_N_ELEMENTS(nm_setting_8021x_scheme_vtable) - 1);
for (j = 0; j < i; j++)
nm_assert(t != sorted_index[j]);
vtable = &nm_setting_8021x_scheme_vtable[t];
nm_assert(vtable->scheme_type == t);
nm_assert(vtable->setting_key);
if (vtable_prev)
nm_assert(strcmp(vtable_prev->setting_key, vtable->setting_key) < 0);
vtable_prev = vtable;
}
}
imin = 0;
imax = G_N_ELEMENTS(sorted_index) - 1;
while (imin <= imax) {
const NMSetting8021xSchemeVtable *vtable;
const int imid = imin + (imax - imin) / 2;
int cmp;
vtable = &nm_setting_8021x_scheme_vtable[sorted_index[imid]];
cmp = strcmp(vtable->setting_key, key);
if (cmp == 0)
return vtable;
if (cmp < 0)
imin = imid + 1;
else
imax = imid - 1;
}
return NULL;
}
/*****************************************************************************/
const NMMetaSettingInfo nm_meta_setting_infos[] = {

View file

@ -3975,7 +3975,7 @@ nm_setting_option_set(NMSetting *setting, const char *opt_name, GVariant *varian
g_hash_table_insert(hash, g_strdup(opt_name), g_variant_ref_sink(variant));
if (changed_value)
_nm_setting_option_notify(setting, !changed_name);
_nm_setting_option_notify(setting, changed_name);
}
/**
@ -4012,7 +4012,7 @@ nm_setting_option_set_boolean(NMSetting *setting, const char *opt_name, gboolean
g_hash_table_insert(hash, g_strdup(opt_name), g_variant_ref_sink(g_variant_new_boolean(value)));
if (changed_value)
_nm_setting_option_notify(setting, !changed_name);
_nm_setting_option_notify(setting, changed_name);
}
/**
@ -4047,7 +4047,7 @@ nm_setting_option_set_uint32(NMSetting *setting, const char *opt_name, guint32 v
g_hash_table_insert(hash, g_strdup(opt_name), g_variant_ref_sink(g_variant_new_uint32(value)));
if (changed_value)
_nm_setting_option_notify(setting, !changed_name);
_nm_setting_option_notify(setting, changed_name);
}
/*****************************************************************************/

View file

@ -5,16 +5,18 @@
#include "libnm-core-impl/nm-default-libnm-core.h"
#include "libnm-glib-aux/nm-json-aux.h"
#include "libnm-core-intern/nm-keyfile-utils.h"
#include "libnm-base/nm-ethtool-utils-base.h"
#include "libnm-core-intern/nm-keyfile-internal.h"
#include "nm-simple-connection.h"
#include "nm-setting-connection.h"
#include "nm-setting-wired.h"
#include "libnm-core-intern/nm-keyfile-utils.h"
#include "libnm-glib-aux/nm-json-aux.h"
#include "nm-setting-8021x.h"
#include "nm-setting-connection.h"
#include "nm-setting-ethtool.h"
#include "nm-setting-proxy.h"
#include "nm-setting-team.h"
#include "nm-setting-user.h"
#include "nm-setting-proxy.h"
#include "nm-setting-wired.h"
#include "nm-simple-connection.h"
#include "libnm-glib-aux/nm-test-utils.h"
@ -887,6 +889,100 @@ test_bridge_port_vlans(void)
/*****************************************************************************/
typedef struct {
bool expect;
guint n_calls;
} InvalidOptionWriteData;
static gboolean
_invalid_option_write_handler(NMConnection *connection,
GKeyFile *keyfile,
NMKeyfileHandlerType handler_type,
NMKeyfileHandlerData *handler_data,
void *user_data)
{
InvalidOptionWriteData *data = user_data;
const char *message;
NMKeyfileWarnSeverity severity;
g_assert(data);
g_assert(data->expect);
g_assert(data->n_calls == 0);
data->n_calls++;
switch (handler_type) {
case NM_KEYFILE_HANDLER_TYPE_WARN:
nm_keyfile_handler_data_warn_get(handler_data, &message, &severity);
g_assert(message && strstr(message, "ethtool.bogus"));
break;
default:
g_assert_not_reached();
}
return TRUE;
}
static void
test_invalid_option(void)
{
gs_unref_object NMConnection *con = NULL;
NMSetting *s_ethtool;
nm_auto_unref_keyfile GKeyFile *kf = NULL;
gs_free_error GError *error = NULL;
InvalidOptionWriteData data;
con = nmtst_create_minimal_connection("test invalid option",
NULL,
NM_SETTING_WIRED_SETTING_NAME,
NULL);
s_ethtool = nm_setting_ethtool_new();
nm_connection_add_setting(con, s_ethtool);
nm_setting_option_set_boolean(s_ethtool, NM_ETHTOOL_OPTNAME_PAUSE_RX, TRUE);
data = (InvalidOptionWriteData){};
kf = nm_keyfile_write(con,
NM_KEYFILE_HANDLER_FLAGS_NONE,
_invalid_option_write_handler,
&data,
nmtst_get_rand_bool() ? &error : NULL);
nmtst_assert_success(kf, error);
nm_clear_pointer(&kf, g_key_file_unref);
nmtst_connection_normalize(con);
nmtst_assert_connection_verifies_without_normalization(con);
data = (InvalidOptionWriteData){};
kf = nm_keyfile_write(con,
NM_KEYFILE_HANDLER_FLAGS_NONE,
_invalid_option_write_handler,
&data,
nmtst_get_rand_bool() ? &error : NULL);
nmtst_assert_success(kf, error);
nm_clear_pointer(&kf, g_key_file_unref);
nm_setting_option_set(s_ethtool, "bogus", g_variant_new_int64(0));
data = (InvalidOptionWriteData){
.expect = TRUE,
};
kf = nm_keyfile_write(con,
NM_KEYFILE_HANDLER_FLAGS_NONE,
_invalid_option_write_handler,
&data,
nmtst_get_rand_bool() ? &error : NULL);
nmtst_assert_success(kf, error);
nm_clear_pointer(&kf, g_key_file_unref);
g_assert_cmpint(data.n_calls, ==, 1);
}
/*****************************************************************************/
NMTST_DEFINE();
int
@ -904,6 +1000,7 @@ main(int argc, char **argv)
g_test_add_func("/core/keyfile/test_vpn/1", test_vpn_1);
g_test_add_func("/core/keyfile/bridge/vlans", test_bridge_vlans);
g_test_add_func("/core/keyfile/bridge-port/vlans", test_bridge_port_vlans);
g_test_add_func("/core/keyfile/invalid-option", test_invalid_option);
return g_test_run();
}

View file

@ -51,7 +51,7 @@ typedef enum /*< skip >*/ {
/*****************************************************************************/
typedef enum {
typedef enum _nm_packed {
NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT,
@ -92,6 +92,8 @@ typedef struct {
extern const NMSetting8021xSchemeVtable
nm_setting_8021x_scheme_vtable[_NM_SETTING_802_1X_SCHEME_TYPE_NUM + 1];
const NMSetting8021xSchemeVtable *nm_setting_8021x_scheme_vtable_by_setting_key(const char *key);
/*****************************************************************************/
typedef enum _nm_packed {

View file

@ -620,10 +620,16 @@ nm_str_realloc(char *str)
/* invokes _notify() for all arguments (of type _PropertyEnums). Note, that if
* there are more than one prop arguments, this will involve a freeze/thaw
* of GObject property notifications. */
#define nm_gobject_notify_together_full(suffix, obj, ...) \
_nm_gobject_notify_together_impl##suffix(obj, \
NM_NARG(__VA_ARGS__), \
(const _PropertyEnums##suffix[]){__VA_ARGS__})
#define nm_gobject_notify_together_full(suffix, obj, ...) \
G_STMT_START \
{ \
const _PropertyEnums##suffix _props[] = {__VA_ARGS__}; \
\
G_STATIC_ASSERT(G_N_ELEMENTS(_props) == NM_NARG(__VA_ARGS__)); \
\
_nm_gobject_notify_together_impl##suffix(obj, G_N_ELEMENTS(_props), _props); \
} \
G_STMT_END
#define nm_gobject_notify_together(obj, ...) nm_gobject_notify_together_full(, obj, __VA_ARGS__)

View file

@ -153,6 +153,68 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
#undef _D
};
const NMSetting8021xSchemeVtable *
nm_setting_8021x_scheme_vtable_by_setting_key(const char *key)
{
static const NMSetting8021xSchemeType sorted_index[] = {
NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY,
NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY,
};
int imin, imax;
nm_assert(key);
if (NM_MORE_ASSERT_ONCE(5)) {
const NMSetting8021xSchemeVtable *vtable_prev = NULL;
int i, j;
for (i = 0; i < (int) G_N_ELEMENTS(sorted_index); i++) {
const NMSetting8021xSchemeType t = sorted_index[i];
const NMSetting8021xSchemeVtable *vtable;
nm_assert(_NM_INT_NOT_NEGATIVE(t));
nm_assert(t < G_N_ELEMENTS(nm_setting_8021x_scheme_vtable) - 1);
for (j = 0; j < i; j++)
nm_assert(t != sorted_index[j]);
vtable = &nm_setting_8021x_scheme_vtable[t];
nm_assert(vtable->scheme_type == t);
nm_assert(vtable->setting_key);
if (vtable_prev)
nm_assert(strcmp(vtable_prev->setting_key, vtable->setting_key) < 0);
vtable_prev = vtable;
}
}
imin = 0;
imax = G_N_ELEMENTS(sorted_index) - 1;
while (imin <= imax) {
const NMSetting8021xSchemeVtable *vtable;
const int imid = imin + (imax - imin) / 2;
int cmp;
vtable = &nm_setting_8021x_scheme_vtable[sorted_index[imid]];
cmp = strcmp(vtable->setting_key, key);
if (cmp == 0)
return vtable;
if (cmp < 0)
imin = imid + 1;
else
imax = imid - 1;
}
return NULL;
}
/*****************************************************************************/
const NMMetaSettingInfo nm_meta_setting_infos[] = {

View file

@ -51,7 +51,7 @@ typedef enum /*< skip >*/ {
/*****************************************************************************/
typedef enum {
typedef enum _nm_packed {
NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT,
NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT,
@ -92,6 +92,8 @@ typedef struct {
extern const NMSetting8021xSchemeVtable
nm_setting_8021x_scheme_vtable[_NM_SETTING_802_1X_SCHEME_TYPE_NUM + 1];
const NMSetting8021xSchemeVtable *nm_setting_8021x_scheme_vtable_by_setting_key(const char *key);
/*****************************************************************************/
typedef enum _nm_packed {