diff options
| author | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
| commit | e74c568b07b50b97873fb4ee1d776dedefbd54d6 (patch) | |
| tree | 3469f17ea9af91f7ff169b890633bda68b0cf76e /src/core/nm-config-data.c | |
| parent | bfe522304da217296e2a61040f58e35ec5d6f3f2 (diff) | |
New upstream version 1.32.12 upstream/1.32.12
Diffstat (limited to 'src/core/nm-config-data.c')
| -rw-r--r-- | src/core/nm-config-data.c | 291 |
1 files changed, 236 insertions, 55 deletions
diff --git a/src/core/nm-config-data.c b/src/core/nm-config-data.c index d457f505..0cbff027 100644 --- a/src/core/nm-config-data.c +++ b/src/core/nm-config-data.c @@ -10,9 +10,9 @@ #include "nm-config.h" #include "devices/nm-device.h" -#include "nm-core-internal.h" -#include "nm-keyfile-internal.h" -#include "nm-keyfile-utils.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-intern/nm-keyfile-internal.h" +#include "libnm-core-intern/nm-keyfile-utils.h" /*****************************************************************************/ @@ -26,6 +26,17 @@ typedef struct { gboolean has; GSList * spec; } match_device; + union { + struct { + GSList * allowed_connections; + gboolean allowed_connections_has; + } device; + }; + gboolean is_device; + + /* List of key/value pairs in the section, sorted by key */ + gsize lookup_len; + const NMUtilsNamedValue *lookup_idx; } MatchSectionInfo; struct _NMGlobalDnsDomain { @@ -97,6 +108,8 @@ typedef struct { NMGlobalDnsConfig *global_dns; bool systemd_resolved : 1; + + char *iwd_config_path; } NMConfigDataPrivate; struct _NMConfigData { @@ -114,6 +127,11 @@ G_DEFINE_TYPE(NMConfigData, nm_config_data, G_TYPE_OBJECT) /*****************************************************************************/ +static const char * +_match_section_info_get_str(const MatchSectionInfo *m, GKeyFile *keyfile, const char *property); + +/*****************************************************************************/ + const char * nm_config_data_get_config_main_file(const NMConfigData *self) { @@ -341,12 +359,18 @@ nm_config_data_get_systemd_resolved(const NMConfigData *self) return NM_CONFIG_DATA_GET_PRIVATE(self)->systemd_resolved; } +const char * +nm_config_data_get_iwd_config_path(const NMConfigData *self) +{ + return NM_CONFIG_DATA_GET_PRIVATE(self)->iwd_config_path; +} + gboolean nm_config_data_get_ignore_carrier(const NMConfigData *self, NMDevice *device) { - gs_free char *value = NULL; - gboolean has_match; - int m; + const char *value; + gboolean has_match; + int m; g_return_val_if_fail(NM_IS_CONFIG_DATA(self), FALSE); g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); @@ -576,7 +600,7 @@ _merge_keyfiles(GKeyFile *keyfile_user, GKeyFile *keyfile_intern) const char * key = keys[k]; gs_free char *value = NULL; - if (is_atomic && strcmp(key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS) == 0) + if (is_atomic && nm_streq(key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS)) continue; if (!is_intern && !is_atomic @@ -684,6 +708,7 @@ static const struct { NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT, NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT}, {NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DHCP, NM_CONFIG_DEFAULT_MAIN_DHCP}, + {NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH, ""}, {NM_CONFIG_KEYFILE_GROUP_LOGGING, "backend", NM_CONFIG_DEFAULT_LOGGING_BACKEND}, {NM_CONFIG_KEYFILE_GROUP_LOGGING, "audit", NM_CONFIG_DEFAULT_LOGGING_AUDIT}, }; @@ -1116,7 +1141,7 @@ load_global_dns(GKeyFile *keyfile, gboolean internal) g_hash_table_insert(dns_config->domains, strdup(name), domain); - if (!strcmp(name, "*")) + if (name[0] == '*' && name[1] == '\0') default_found = TRUE; } @@ -1213,7 +1238,7 @@ global_dns_domain_from_dbus(char *name, GVariant *variant) g_variant_iter_init(&iter, variant); while (g_variant_iter_next(&iter, "{&sv}", &key, &val)) { - if (!g_strcmp0(key, "servers") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { + if (nm_streq0(key, "servers") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { strv = g_variant_dup_strv(val, NULL); _nm_utils_strv_cleanup(strv, TRUE, TRUE, TRUE); for (i = 0, j = 0; strv && strv[i]; i++) { @@ -1230,7 +1255,7 @@ global_dns_domain_from_dbus(char *name, GVariant *variant) g_strfreev(domain->servers); domain->servers = strv; } - } else if (!g_strcmp0(key, "options") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { + } else if (nm_streq0(key, "options") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { strv = g_variant_dup_strv(val, NULL); g_strfreev(domain->options); domain->options = _nm_utils_strv_cleanup(strv, TRUE, TRUE, TRUE); @@ -1278,10 +1303,10 @@ nm_global_dns_config_from_dbus(const GValue *value, GError **error) g_variant_iter_init(&iter, variant); while (g_variant_iter_next(&iter, "{&sv}", &key, &val)) { - if (!g_strcmp0(key, "searches") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { + if (nm_streq0(key, "searches") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { strv = g_variant_dup_strv(val, NULL); dns_config->searches = _nm_utils_strv_cleanup(strv, TRUE, TRUE, TRUE); - } else if (!g_strcmp0(key, "options") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { + } else if (nm_streq0(key, "options") && g_variant_is_of_type(val, G_VARIANT_TYPE("as"))) { strv = g_variant_dup_strv(val, NULL); _nm_utils_strv_cleanup(strv, TRUE, TRUE, TRUE); @@ -1297,7 +1322,7 @@ nm_global_dns_config_from_dbus(const GValue *value, GError **error) strv[j] = NULL; dns_config->options = strv; } - } else if (!g_strcmp0(key, "domains") + } else if (nm_streq0(key, "domains") && g_variant_is_of_type(val, G_VARIANT_TYPE("a{sv}"))) { NMGlobalDnsDomain *domain; GVariantIter domain_iter; @@ -1381,18 +1406,18 @@ _match_section_infos_lookup(const MatchSectionInfo *match_section_infos, NMDevice * device, const NMPlatformLink * pllink, const char * match_device_type, - char ** out_value) + const char ** out_value) { const char *match_dhcp_plugin; if (!match_section_infos) - return NULL; + goto out; match_dhcp_plugin = nm_dhcp_manager_get_config(nm_dhcp_manager_get()); for (; match_section_infos->group_name; match_section_infos++) { - char * value = NULL; - gboolean match; + const char *value; + gboolean match; /* FIXME: Here we use g_key_file_get_string(). This should be in sync with what keyfile-reader * does. @@ -1401,7 +1426,7 @@ _match_section_infos_lookup(const MatchSectionInfo *match_section_infos, * string_to_value(keyfile_to_string(keyfile)) in one. Optimally, keyfile library would * expose both functions, and we would return here keyfile_to_string(keyfile). * The caller then could convert the string to the proper value via string_to_value(value). */ - value = g_key_file_get_string(keyfile, match_section_infos->group_name, property, NULL); + value = _match_section_info_get_str(match_section_infos, keyfile, property); if (!value && !match_section_infos->stop_match) continue; @@ -1420,15 +1445,17 @@ _match_section_infos_lookup(const MatchSectionInfo *match_section_infos, match = TRUE; if (match) { - *out_value = value; + NM_SET_OUT(out_value, value); return match_section_infos; } - g_free(value); } + +out: + NM_SET_OUT(out_value, NULL); return NULL; } -char * +const char * nm_config_data_get_device_config(const NMConfigData *self, const char * property, NMDevice * device, @@ -1436,7 +1463,7 @@ nm_config_data_get_device_config(const NMConfigData *self, { const NMConfigDataPrivate *priv; const MatchSectionInfo * connection_info; - char * value = NULL; + const char * value; NM_SET_OUT(has_match, FALSE); @@ -1456,7 +1483,7 @@ nm_config_data_get_device_config(const NMConfigData *self, return value; } -char * +const char * nm_config_data_get_device_config_by_pllink(const NMConfigData * self, const char * property, const NMPlatformLink *pllink, @@ -1465,7 +1492,7 @@ nm_config_data_get_device_config_by_pllink(const NMConfigData * self, { const NMConfigDataPrivate *priv; const MatchSectionInfo * connection_info; - char * value = NULL; + const char * value; g_return_val_if_fail(self, NULL); g_return_val_if_fail(property && *property, NULL); @@ -1490,8 +1517,8 @@ nm_config_data_get_device_config_boolean(const NMConfigData *self, int val_no_match, int val_invalid) { - gs_free char *value = NULL; - gboolean has_match; + const char *value; + gboolean has_match; value = nm_config_data_get_device_config(self, property, device, &has_match); if (!has_match) @@ -1499,13 +1526,65 @@ nm_config_data_get_device_config_boolean(const NMConfigData *self, return nm_config_parse_boolean(value, val_invalid); } -char * +gint64 +nm_config_data_get_device_config_int64(const NMConfigData *self, + const char * property, + NMDevice * device, + int base, + gint64 min, + gint64 max, + gint64 val_no_match, + gint64 val_invalid) +{ + const char *value; + gboolean has_match; + + value = nm_config_data_get_device_config(self, property, device, &has_match); + if (!has_match) { + errno = ENOENT; + return val_no_match; + } + return _nm_utils_ascii_str_to_int64(value, base, min, max, val_invalid); +} + +const GSList * +nm_config_data_get_device_allowed_connections_specs(const NMConfigData *self, + NMDevice * device, + gboolean * has_match) +{ + const NMConfigDataPrivate *priv; + const MatchSectionInfo * connection_info; + const GSList * ret = NULL; + + g_return_val_if_fail(self, NULL); + + priv = NM_CONFIG_DATA_GET_PRIVATE(self); + + connection_info = _match_section_infos_lookup(&priv->device_infos[0], + priv->keyfile, + NM_CONFIG_KEYFILE_KEY_DEVICE_ALLOWED_CONNECTIONS, + device, + NULL, + NULL, + NULL); + + if (connection_info) { + nm_assert(connection_info->device.allowed_connections_has); + ret = connection_info->device.allowed_connections; + NM_SET_OUT(has_match, TRUE); + } else + NM_SET_OUT(has_match, FALSE); + + return ret; +} + +const char * nm_config_data_get_connection_default(const NMConfigData *self, const char * property, NMDevice * device) { const NMConfigDataPrivate *priv; - char * value = NULL; + const char * value; g_return_val_if_fail(self, NULL); g_return_val_if_fail(property && *property, NULL); @@ -1544,15 +1623,44 @@ nm_config_data_get_connection_default_int64(const NMConfigData *self, gint64 max, gint64 fallback) { - gs_free char *value = NULL; + const char *value; value = nm_config_data_get_connection_default(self, property, device); return _nm_utils_ascii_str_to_int64(value, 10, min, max, fallback); } +static const char * +_match_section_info_get_str(const MatchSectionInfo *m, GKeyFile *keyfile, const char *property) +{ + gssize idx; + const char *value; + + idx = nm_utils_named_value_list_find(m->lookup_idx, m->lookup_len, property, TRUE); + value = idx >= 0 ? m->lookup_idx[idx].value_str : NULL; + +#if NM_MORE_ASSERTS > 10 + { + gs_free char *value2 = g_key_file_get_string(keyfile, m->group_name, property, NULL); + + nm_assert(nm_streq0(value2, value)); + } +#endif + + return value; +} + static void -_get_connection_info_init(MatchSectionInfo *connection_info, GKeyFile *keyfile, char *group) +_match_section_info_init(MatchSectionInfo *connection_info, + GKeyFile * keyfile, + char * group, + gboolean is_device) { + char ** keys = NULL; + gsize n_keys; + gsize i; + gsize j; + NMUtilsNamedValue *vals; + /* pass ownership of @group on... */ connection_info->group_name = group; @@ -1563,29 +1671,93 @@ _get_connection_info_init(MatchSectionInfo *connection_info, GKeyFile *keyfile, &connection_info->match_device.has); connection_info->stop_match = nm_config_keyfile_get_boolean(keyfile, group, NM_CONFIG_KEYFILE_KEY_STOP_MATCH, FALSE); + + if (is_device) { + connection_info->device.allowed_connections = + nm_config_get_match_spec(keyfile, + group, + NM_CONFIG_KEYFILE_KEY_DEVICE_ALLOWED_CONNECTIONS, + &connection_info->device.allowed_connections_has); + } + + keys = g_key_file_get_keys(keyfile, group, &n_keys, NULL); + nm_utils_strv_sort(keys, n_keys); + + vals = g_new(NMUtilsNamedValue, n_keys); + + for (i = 0, j = 0; i < n_keys; i++) { + gs_free char *key = g_steal_pointer(&keys[i]); + char * value; + + if (NM_IN_STRSET(key, NM_CONFIG_KEYFILE_KEY_STOP_MATCH, NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE)) + continue; + + if (j > 0 && nm_streq(vals[j - 1].name, key)) + continue; + + value = g_key_file_get_string(keyfile, group, key, NULL); + if (!value) + continue; + + vals[j++] = (NMUtilsNamedValue){ + .name = g_steal_pointer(&key), + .value_str = value, + }; + } + + g_free(keys); + + if (n_keys != j) { + gs_free NMUtilsNamedValue *vals2 = vals; + + /* since this buffer will be kept around for a long time, + * get rid of the excess allocation. */ + vals = nm_memdup(vals2, sizeof(NMUtilsNamedValue) * j); + n_keys = j; + } + + if (n_keys == 0) + nm_clear_g_free(&vals); + + connection_info->lookup_idx = vals; + connection_info->lookup_len = n_keys; } static void _match_section_infos_free(MatchSectionInfo *match_section_infos) { - guint i; + MatchSectionInfo *m; + gsize i; if (!match_section_infos) return; - for (i = 0; match_section_infos[i].group_name; i++) { - g_free(match_section_infos[i].group_name); - g_slist_free_full(match_section_infos[i].match_device.spec, g_free); + + for (m = match_section_infos; m->group_name; m++) { + g_free(m->group_name); + g_slist_free_full(m->match_device.spec, g_free); + if (m->is_device) { + g_slist_free_full(m->device.allowed_connections, g_free); + } + for (i = 0; i < m->lookup_len; i++) { + g_free(m->lookup_idx[i].name_mutable); + g_free(m->lookup_idx[i].value_str_mutable); + } + g_free((gpointer) m->lookup_idx); } g_free(match_section_infos); } static MatchSectionInfo * -_match_section_infos_construct(GKeyFile *keyfile, const char *prefix) +_match_section_infos_construct(GKeyFile *keyfile, gboolean is_device) { char ** groups; gsize i, j, ngroups; char * connection_tag = NULL; MatchSectionInfo *match_section_infos = NULL; + const char * prefix; + + prefix = + is_device ? NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE : NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION; /* get the list of existing [connection.\+]/[device.\+] sections. * @@ -1617,13 +1789,17 @@ _match_section_infos_construct(GKeyFile *keyfile, const char *prefix) } match_section_infos = g_new0(MatchSectionInfo, ngroups + 1 + (connection_tag ? 1 : 0)); + match_section_infos->is_device = is_device; for (i = 0; i < ngroups; i++) { /* pass ownership of @group on... */ - _get_connection_info_init(&match_section_infos[i], keyfile, groups[ngroups - i - 1]); + _match_section_info_init(&match_section_infos[i], + keyfile, + groups[ngroups - i - 1], + is_device); } if (connection_tag) { /* pass ownership of @connection_tag on... */ - _get_connection_info_init(&match_section_infos[i], keyfile, connection_tag); + _match_section_info_init(&match_section_infos[i], keyfile, connection_tag, is_device); } g_free(groups); @@ -1644,28 +1820,26 @@ nm_config_data_diff(NMConfigData *old_data, NMConfigData *new_data) priv_old = NM_CONFIG_DATA_GET_PRIVATE(old_data); priv_new = NM_CONFIG_DATA_GET_PRIVATE(new_data); - if (!_nm_keyfile_equals(priv_old->keyfile_user, priv_new->keyfile_user, TRUE)) + if (!_nm_keyfile_equal(priv_old->keyfile_user, priv_new->keyfile_user, TRUE)) changes |= NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER; - if (!_nm_keyfile_equals(priv_old->keyfile_intern, priv_new->keyfile_intern, TRUE)) + if (!_nm_keyfile_equal(priv_old->keyfile_intern, priv_new->keyfile_intern, TRUE)) changes |= NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_INTERN; - if (g_strcmp0(nm_config_data_get_config_main_file(old_data), - nm_config_data_get_config_main_file(new_data)) - != 0 - || g_strcmp0(nm_config_data_get_config_description(old_data), - nm_config_data_get_config_description(new_data)) - != 0) + if (!nm_streq0(nm_config_data_get_config_main_file(old_data), + nm_config_data_get_config_main_file(new_data)) + || !nm_streq0(nm_config_data_get_config_description(old_data), + nm_config_data_get_config_description(new_data))) changes |= NM_CONFIG_CHANGE_CONFIG_FILES; if (nm_config_data_get_connectivity_enabled(old_data) != nm_config_data_get_connectivity_enabled(new_data) || nm_config_data_get_connectivity_interval(old_data) != nm_config_data_get_connectivity_interval(new_data) - || g_strcmp0(nm_config_data_get_connectivity_uri(old_data), - nm_config_data_get_connectivity_uri(new_data)) - || g_strcmp0(nm_config_data_get_connectivity_response(old_data), - nm_config_data_get_connectivity_response(new_data))) + || !nm_streq0(nm_config_data_get_connectivity_uri(old_data), + nm_config_data_get_connectivity_uri(new_data)) + || !nm_streq0(nm_config_data_get_connectivity_response(old_data), + nm_config_data_get_connectivity_response(new_data))) changes |= NM_CONFIG_CHANGE_CONNECTIVITY; if (nm_utils_g_slist_strlist_cmp(priv_old->no_auto_default.specs, @@ -1676,10 +1850,11 @@ nm_config_data_diff(NMConfigData *old_data, NMConfigData *new_data) != 0) changes |= NM_CONFIG_CHANGE_NO_AUTO_DEFAULT; - if (g_strcmp0(nm_config_data_get_dns_mode(old_data), nm_config_data_get_dns_mode(new_data))) + if (!nm_streq0(nm_config_data_get_dns_mode(old_data), nm_config_data_get_dns_mode(new_data))) changes |= NM_CONFIG_CHANGE_DNS_MODE; - if (g_strcmp0(nm_config_data_get_rc_manager(old_data), nm_config_data_get_rc_manager(new_data))) + if (!nm_streq0(nm_config_data_get_rc_manager(old_data), + nm_config_data_get_rc_manager(new_data))) changes |= NM_CONFIG_CHANGE_RC_MANAGER; if (!global_dns_equal(priv_old->global_dns, priv_new->global_dns)) @@ -1838,10 +2013,8 @@ constructed(GObject *object) priv->keyfile = _merge_keyfiles(priv->keyfile_user, priv->keyfile_intern); - priv->connection_infos = - _match_section_infos_construct(priv->keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION); - priv->device_infos = - _match_section_infos_construct(priv->keyfile, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE); + priv->connection_infos = _match_section_infos_construct(priv->keyfile, FALSE); + priv->device_infos = _match_section_infos_construct(priv->keyfile, TRUE); priv->connectivity.enabled = nm_config_keyfile_get_boolean(priv->keyfile, @@ -1910,6 +2083,12 @@ constructed(GObject *object) if (!priv->global_dns) priv->global_dns = load_global_dns(priv->keyfile_intern, TRUE); + priv->iwd_config_path = + nm_strstrip(g_key_file_get_string(priv->keyfile, + NM_CONFIG_KEYFILE_GROUP_MAIN, + NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH, + NULL)); + G_OBJECT_CLASS(nm_config_data_parent_class)->constructed(object); } @@ -1996,6 +2175,8 @@ finalize(GObject *gobject) nm_global_dns_config_free(priv->global_dns); + g_free(priv->iwd_config_path); + _match_section_infos_free(priv->connection_infos); _match_section_infos_free(priv->device_infos); |