summaryrefslogtreecommitdiff
path: root/src/libnmc-setting
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-03-01 12:42:48 +0100
committerThomas Haller <thaller@redhat.com>2021-03-02 08:38:25 +0100
commit54976f23cd95d11e0f6a39d628458d8ba6308876 (patch)
tree7f0e98f8141c6a164c6b9f7dbf4fa819be2807b4 /src/libnmc-setting
parent044da26bb71ff5ee1dabb28020abf5f418ff1a3b (diff)
downloadNetworkManager-54976f23cd95d11e0f6a39d628458d8ba6308876.tar.gz
build: move "clients/common/" to "src/libnmc-{base,setting}/"
Diffstat (limited to 'src/libnmc-setting')
-rw-r--r--src/libnmc-setting/meson.build52
-rw-r--r--src/libnmc-setting/nm-meta-setting-access.c653
-rw-r--r--src/libnmc-setting/nm-meta-setting-access.h99
-rw-r--r--src/libnmc-setting/nm-meta-setting-base-impl.c641
-rw-r--r--src/libnmc-setting/nm-meta-setting-base-impl.h187
-rw-r--r--src/libnmc-setting/nm-meta-setting-base.h10
-rw-r--r--src/libnmc-setting/nm-meta-setting-desc.c8575
-rw-r--r--src/libnmc-setting/nm-meta-setting-desc.h541
-rw-r--r--src/libnmc-setting/settings-docs.h.in423
-rw-r--r--src/libnmc-setting/settings-docs.xsl49
-rw-r--r--src/libnmc-setting/tests/meson.build26
-rw-r--r--src/libnmc-setting/tests/test-libnmc-setting.c366
-rw-r--r--src/libnmc-setting/tests/wg-test0.conf20
-rw-r--r--src/libnmc-setting/tests/wg-test1.conf3
-rw-r--r--src/libnmc-setting/tests/wg-test2.conf8
-rw-r--r--src/libnmc-setting/tests/wg-test3.conf3
16 files changed, 11656 insertions, 0 deletions
diff --git a/src/libnmc-setting/meson.build b/src/libnmc-setting/meson.build
new file mode 100644
index 0000000000..8f07ae634e
--- /dev/null
+++ b/src/libnmc-setting/meson.build
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+if enable_docs
+ settings_docs_input_xml = custom_target(
+ 'settings-docs-input.xml',
+ input: [nm_settings_docs_xml_gir, nm_property_infos_xml['nmcli']],
+ output: 'settings-docs-input.xml',
+ command: [
+ python.path(),
+ join_paths(meson.source_root(), 'tools', 'generate-docs-nm-settings-docs-merge.py'),
+ '@OUTPUT@',
+ nm_property_infos_xml['nmcli'],
+ nm_settings_docs_xml_gir,
+ ],
+ )
+
+ settings_docs_source = custom_target(
+ 'settings-docs.h',
+ input: settings_docs_input_xml,
+ output: 'settings-docs.h',
+ command: [xsltproc, '--output', '@OUTPUT@', join_paths(meson.current_source_dir(), 'settings-docs.xsl'), '@INPUT@'],
+ )
+
+ test(
+ 'check-settings-docs',
+ find_program(join_paths(source_root, 'tools', 'check-compare-generated.sh')),
+ args: [
+ source_root,
+ build_root,
+ 'src/libnmc-setting/settings-docs.h',
+ ],
+ )
+else
+ settings_docs_source = configure_file(
+ input: 'settings-docs.h.in',
+ output: '@BASENAME@',
+ configuration: configuration_data(),
+ )
+endif
+
+libnmc_setting = static_library(
+ 'nmc-setting',
+ sources: [settings_docs_source] + files(
+ 'nm-meta-setting-access.c',
+ 'nm-meta-setting-base-impl.c',
+ 'nm-meta-setting-desc.c',
+ ),
+ dependencies: [
+ libnm_dep,
+ ],
+ link_depends: settings_docs_source,
+)
diff --git a/src/libnmc-setting/nm-meta-setting-access.c b/src/libnmc-setting/nm-meta-setting-access.c
new file mode 100644
index 0000000000..cd4cbdd548
--- /dev/null
+++ b/src/libnmc-setting/nm-meta-setting-access.c
@@ -0,0 +1,653 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2010 - 2017 Red Hat, Inc.
+ */
+
+#include "libnm-client-aux-extern/nm-default-client.h"
+
+#include "nm-meta-setting-access.h"
+
+/*****************************************************************************/
+
+static const NMMetaSettingInfoEditor *
+_get_meta_setting_info_editor_from_msi(const NMMetaSettingInfo *meta_setting_info)
+{
+ const NMMetaSettingInfoEditor *setting_info;
+
+ if (!meta_setting_info)
+ return NULL;
+
+ nm_assert(meta_setting_info->get_setting_gtype);
+ nm_assert(meta_setting_info->meta_type < G_N_ELEMENTS(nm_meta_setting_infos_editor));
+
+ setting_info = &nm_meta_setting_infos_editor[meta_setting_info->meta_type];
+
+ nm_assert(setting_info->general == meta_setting_info);
+ return setting_info;
+}
+
+const NMMetaSettingInfoEditor *
+nm_meta_setting_info_editor_find_by_name(const char *setting_name, gboolean use_alias)
+{
+ const NMMetaSettingInfoEditor *setting_info;
+ guint i;
+
+ g_return_val_if_fail(setting_name, NULL);
+
+ setting_info =
+ _get_meta_setting_info_editor_from_msi(nm_meta_setting_infos_by_name(setting_name));
+ if (!setting_info && use_alias) {
+ for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) {
+ if (nm_streq0(nm_meta_setting_infos_editor[i].alias, setting_name)) {
+ setting_info = &nm_meta_setting_infos_editor[i];
+ break;
+ }
+ }
+ }
+
+ return setting_info;
+}
+
+const NMMetaSettingInfoEditor *
+nm_meta_setting_info_editor_find_by_gtype(GType gtype)
+{
+ return _get_meta_setting_info_editor_from_msi(nm_meta_setting_infos_by_gtype(gtype));
+}
+
+const NMMetaSettingInfoEditor *
+nm_meta_setting_info_editor_find_by_setting(NMSetting *setting)
+{
+ const NMMetaSettingInfoEditor *setting_info;
+
+ g_return_val_if_fail(NM_IS_SETTING(setting), NULL);
+
+ setting_info = nm_meta_setting_info_editor_find_by_gtype(G_OBJECT_TYPE(setting));
+
+ nm_assert(setting_info);
+ nm_assert(G_TYPE_CHECK_INSTANCE_TYPE(setting, setting_info->general->get_setting_gtype()));
+ return setting_info;
+}
+
+/*****************************************************************************/
+
+const NMMetaPropertyInfo *
+nm_meta_setting_info_editor_get_property_info(const NMMetaSettingInfoEditor *setting_info,
+ const char * property_name)
+{
+ guint i;
+
+ g_return_val_if_fail(setting_info, NULL);
+ g_return_val_if_fail(property_name, NULL);
+
+ for (i = 0; i < setting_info->properties_num; i++) {
+ nm_assert(setting_info->properties[i]->property_name);
+ nm_assert(setting_info->properties[i]->setting_info == setting_info);
+ if (nm_streq(setting_info->properties[i]->property_name, property_name))
+ return setting_info->properties[i];
+ }
+
+ return NULL;
+}
+
+gboolean
+nm_meta_setting_info_editor_has_secrets(const NMMetaSettingInfoEditor *setting_info)
+{
+ guint i;
+
+ if (!setting_info)
+ return FALSE;
+
+ for (i = 0; i < setting_info->properties_num; i++) {
+ if (setting_info->properties[i]->is_secret)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+const NMMetaPropertyInfo *
+nm_meta_property_info_find_by_name(const char *setting_name, const char *property_name)
+{
+ const NMMetaSettingInfoEditor *setting_info;
+ const NMMetaPropertyInfo * property_info;
+
+ setting_info = nm_meta_setting_info_editor_find_by_name(setting_name, FALSE);
+ if (!setting_info)
+ return NULL;
+
+ property_info = nm_meta_setting_info_editor_get_property_info(setting_info, property_name);
+ if (!property_info)
+ return NULL;
+
+ nm_assert(property_info->setting_info == setting_info);
+
+ return property_info;
+}
+
+const NMMetaPropertyInfo *
+nm_meta_property_info_find_by_setting(NMSetting *setting, const char *property_name)
+{
+ const NMMetaSettingInfoEditor *setting_info;
+ const NMMetaPropertyInfo * property_info;
+
+ setting_info = nm_meta_setting_info_editor_find_by_setting(setting);
+ if (!setting_info)
+ return NULL;
+ property_info = nm_meta_setting_info_editor_get_property_info(setting_info, property_name);
+ if (!property_info)
+ return NULL;
+
+ nm_assert(property_info->setting_info == setting_info);
+ nm_assert(property_info
+ == nm_meta_property_info_find_by_name(nm_setting_get_name(setting), property_name));
+
+ return property_info;
+}
+
+NMSetting *
+nm_meta_setting_info_editor_new_setting(const NMMetaSettingInfoEditor *setting_info,
+ NMMetaAccessorSettingInitType init_type)
+{
+ NMSetting *setting;
+
+ g_return_val_if_fail(setting_info, NULL);
+
+ setting = g_object_new(setting_info->general->get_setting_gtype(), NULL);
+
+ if (setting_info->setting_init_fcn && init_type != NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT) {
+ setting_info->setting_init_fcn(setting_info, setting, init_type);
+ }
+
+ return setting;
+}
+
+/*****************************************************************************/
+
+const NMMetaSettingInfoEditor *const *
+nm_meta_setting_infos_editor_p(void)
+{
+ static const NMMetaSettingInfoEditor *cache[_NM_META_SETTING_TYPE_NUM + 1] = {NULL};
+ guint i;
+
+ if (G_UNLIKELY(!cache[0])) {
+ for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++)
+ cache[i] = &nm_meta_setting_infos_editor[i];
+ }
+ return cache;
+}
+
+/*****************************************************************************/
+
+const char *
+nm_meta_abstract_info_get_name(const NMMetaAbstractInfo *abstract_info, gboolean for_header)
+{
+ const char *n;
+
+ nm_assert(abstract_info);
+ nm_assert(abstract_info->meta_type);
+ nm_assert(abstract_info->meta_type->get_name);
+ n = abstract_info->meta_type->get_name(abstract_info, for_header);
+ nm_assert(n && n[0]);
+ return n;
+}
+
+const NMMetaAbstractInfo *const *
+nm_meta_abstract_info_get_nested(const NMMetaAbstractInfo *abstract_info,
+ guint * out_len,
+ gpointer * nested_to_free)
+{
+ const NMMetaAbstractInfo *const *nested;
+ guint l = 0;
+ gs_free gpointer f = NULL;
+
+ nm_assert(abstract_info);
+ nm_assert(abstract_info->meta_type);
+ nm_assert(nested_to_free && !*nested_to_free);
+
+ if (abstract_info->meta_type->get_nested) {
+ nested = abstract_info->meta_type->get_nested(abstract_info, &l, &f);
+ nm_assert(NM_PTRARRAY_LEN(nested) == l);
+ nm_assert(!f || nested == f);
+ if (nested && nested[0]) {
+ NM_SET_OUT(out_len, l);
+ *nested_to_free = g_steal_pointer(&f);
+ return nested;
+ }
+ }
+ NM_SET_OUT(out_len, 0);
+ return NULL;
+}
+
+gconstpointer
+nm_meta_abstract_info_get(const NMMetaAbstractInfo * abstract_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ gpointer target,
+ gpointer target_data,
+ NMMetaAccessorGetType get_type,
+ NMMetaAccessorGetFlags get_flags,
+ NMMetaAccessorGetOutFlags *out_flags,
+ gboolean * out_is_default,
+ gpointer * out_to_free)
+{
+ nm_assert(abstract_info);
+ nm_assert(abstract_info->meta_type);
+ nm_assert(!out_to_free || !*out_to_free);
+ nm_assert(out_flags);
+
+ *out_flags = NM_META_ACCESSOR_GET_OUT_FLAGS_NONE;
+ NM_SET_OUT(out_is_default, FALSE);
+
+ if (!abstract_info->meta_type->get_fcn)
+ g_return_val_if_reached(NULL);
+
+ return abstract_info->meta_type->get_fcn(abstract_info,
+ environment,
+ environment_user_data,
+ target,
+ target_data,
+ get_type,
+ get_flags,
+ out_flags,
+ out_is_default,
+ out_to_free);
+}
+
+const char *const *
+nm_meta_abstract_info_complete(const NMMetaAbstractInfo * abstract_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ const NMMetaOperationContext *operation_context,
+ const char * text,
+ gboolean * out_complete_filename,
+ char *** out_to_free)
+{
+ const char *const *values;
+ gsize i, j, text_len;
+
+ nm_assert(abstract_info);
+ nm_assert(abstract_info->meta_type);
+ nm_assert(out_to_free && !*out_to_free);
+
+ *out_to_free = NULL;
+
+ if (!abstract_info->meta_type->complete_fcn)
+ return NULL;
+
+ values = abstract_info->meta_type->complete_fcn(abstract_info,
+ environment,
+ environment_user_data,
+ operation_context,
+ text,
+ out_complete_filename,
+ out_to_free);
+
+ nm_assert(!*out_to_free || values == (const char *const *) *out_to_free);
+
+ if (!values)
+ return NULL;
+
+ if (!values[0]) {
+ nm_clear_g_free(out_to_free);
+ return NULL;
+ }
+
+ if (!text || !text[0])
+ return values;
+
+ /* for convenience, we allow the complete_fcn() implementations to
+ * ignore "text". We filter out invalid matches here. */
+
+ text_len = strlen(text);
+
+ if (*out_to_free) {
+ char **v = *out_to_free;
+
+ for (i = 0, j = 0; v[i]; i++) {
+ if (strncmp(v[i], text, text_len) != 0) {
+ g_free(v[i]);
+ continue;
+ }
+ v[j++] = v[i];
+ }
+ if (j)
+ v[j++] = NULL;
+ else {
+ g_free(v);
+ *out_to_free = v = NULL;
+ }
+ return (const char *const *) v;
+ } else {
+ const char *const *v = values;
+ char ** r;
+
+ for (i = 0, j = 0; v[i]; i++) {
+ if (strncmp(v[i], text, text_len) != 0)
+ continue;
+ j++;
+ }
+ if (j == i)
+ return values;
+ else if (!j)
+ return NULL;
+
+ r = g_new(char *, j + 1);
+ v = values;
+ for (i = 0, j = 0; v[i]; i++) {
+ if (strncmp(v[i], text, text_len) != 0)
+ continue;
+ r[j++] = g_strdup(v[i]);
+ }
+ r[j++] = NULL;
+ return (const char *const *) (*out_to_free = r);
+ }
+}
+
+/*****************************************************************************/
+
+char *
+nm_meta_abstract_info_get_nested_names_str(const NMMetaAbstractInfo *abstract_info,
+ const char * name_prefix)
+{
+ gs_free gpointer nested_to_free = NULL;
+ const NMMetaAbstractInfo *const *nested;
+
+ nested = nm_meta_abstract_info_get_nested(abstract_info, NULL, &nested_to_free);
+ if (!nested)
+ return NULL;
+
+ if (!name_prefix)
+ name_prefix = nm_meta_abstract_info_get_name(abstract_info, FALSE);
+
+ return nm_meta_abstract_infos_get_names_str(nested, name_prefix);
+}
+
+char *
+nm_meta_abstract_infos_get_names_str(const NMMetaAbstractInfo *const *fields_array,
+ const char * name_prefix)
+{
+ GString *str;
+ guint i;
+
+ if (!fields_array || !fields_array[0])
+ return NULL;
+
+ str = g_string_sized_new(128);
+ for (i = 0; fields_array[i]; i++) {
+ if (str->len > 0)
+ g_string_append_c(str, ',');
+ if (name_prefix) {
+ g_string_append(str, name_prefix);
+ g_string_append_c(str, '.');
+ }
+ g_string_append(str, nm_meta_abstract_info_get_name(fields_array[i], FALSE));
+ }
+ return g_string_free(str, FALSE);
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ guint idx;
+ gsize self_offset_plus_1;
+ gsize sub_offset_plus_1;
+} OutputSelectionItem;
+
+static NMMetaSelectionResultList *
+_output_selection_pack(const NMMetaAbstractInfo *const *fields_array, GArray *array, GString *str)
+{
+ NMMetaSelectionResultList *result;
+ guint i;
+ guint len;
+
+ len = array ? array->len : 0;
+
+ /* re-organize the collected output data in one buffer that can be freed using
+ * g_free(). This makes allocation more complicated, but saves us from special
+ * handling for free. */
+ result = g_malloc0(sizeof(NMMetaSelectionResultList) + (len * sizeof(NMMetaSelectionItem))
+ + (str ? str->len : 0));
+ *((guint *) &result->num) = len;
+ if (len > 0) {
+ char *pdata =
+ &((char *)
+ result)[sizeof(NMMetaSelectionResultList) + (len * sizeof(NMMetaSelectionItem))];
+
+ if (str)
+ memcpy(pdata, str->str, str->len);
+ for (i = 0; i < len; i++) {
+ const OutputSelectionItem *a = &g_array_index(array, OutputSelectionItem, i);
+ NMMetaSelectionItem * p = (NMMetaSelectionItem *) &result->items[i];
+
+ p->info = fields_array[a->idx];
+ p->idx = a->idx;
+ if (a->self_offset_plus_1 > 0)
+ p->self_selection = &pdata[a->self_offset_plus_1 - 1];
+ if (a->sub_offset_plus_1 > 0)
+ p->sub_selection = &pdata[a->sub_offset_plus_1 - 1];
+ }
+ }
+
+ return result;
+}
+
+static gboolean
+_output_selection_select_one(const NMMetaAbstractInfo *const *fields_array,
+ const char * fields_prefix,
+ const char * fields_str,
+ gboolean validate_nested,
+ GArray ** p_array,
+ GString ** p_str,
+ GError ** error)
+{
+ guint i, j;
+ const char * i_name;
+ const char * right;
+ gboolean found = FALSE;
+ const NMMetaAbstractInfo *fields_array_failure = NULL;
+ gs_free char * fields_str_clone = NULL;
+
+ nm_assert(fields_str);
+ nm_assert(p_array);
+ nm_assert(p_str);
+ nm_assert(!error || !*error);
+
+ right = strchr(fields_str, '.');
+ if (right) {
+ fields_str_clone = g_strdup(fields_str);
+ fields_str_clone[right - fields_str] = '\0';
+ i_name = fields_str_clone;
+ right = &fields_str_clone[right - fields_str + 1];
+ } else
+ i_name = fields_str;
+
+ if (!fields_array)
+ goto not_found;
+
+ for (i = 0; fields_array[i]; i++) {
+ const NMMetaAbstractInfo * fi = fields_array[i];
+ const NMMetaAbstractInfo *const *nested;
+ gs_free gpointer nested_to_free = NULL;
+
+ if (g_ascii_strcasecmp(i_name, nm_meta_abstract_info_get_name(fi, FALSE)) != 0)
+ continue;
+
+ if (!right || !validate_nested) {
+ found = TRUE;
+ break;
+ }
+
+ nested = nm_meta_abstract_info_get_nested(fi, NULL, &nested_to_free);
+ if (nested) {
+ for (j = 0; nested[j]; nested++) {
+ if (g_ascii_strcasecmp(right, nm_meta_abstract_info_get_name(nested[j], FALSE))
+ == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ fields_array_failure = fields_array[i];
+ break;
+ }
+
+ if (!found) {
+not_found:
+ if (!right && !fields_prefix
+ && (!g_ascii_strcasecmp(i_name, "all") || !g_ascii_strcasecmp(i_name, "common")))
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_UNKNOWN,
+ _("field '%s' has to be alone"),
+ i_name);
+ else {
+ gs_free char *allowed_fields = NULL;
+
+ if (fields_array_failure) {
+ gs_free char *p = NULL;
+
+ if (fields_prefix) {
+ p = g_strdup_printf(
+ "%s.%s",
+ fields_prefix,
+ nm_meta_abstract_info_get_name(fields_array_failure, FALSE));
+ }
+ allowed_fields =
+ nm_meta_abstract_info_get_nested_names_str(fields_array_failure, p);
+ } else
+ allowed_fields = nm_meta_abstract_infos_get_names_str(fields_array, NULL);
+
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_UNKNOWN,
+ _("invalid field '%s%s%s%s%s'; %s%s%s"),
+ fields_prefix ?: "",
+ fields_prefix ? "." : "",
+ i_name,
+ right ? "." : "",
+ right ?: "",
+ NM_PRINT_FMT_QUOTED(allowed_fields,
+ "allowed fields: ",
+ allowed_fields,
+ "",
+ "no fields"));
+ }
+ return FALSE;
+ }
+
+ {
+ GString * str;
+ OutputSelectionItem s = {
+ .idx = i,
+ };
+
+ if (!*p_str)
+ *p_str = g_string_sized_new(64);
+ str = *p_str;
+
+ s.self_offset_plus_1 = str->len + 1;
+ if (fields_prefix) {
+ g_string_append(str, fields_prefix);
+ g_string_append_c(str, '.');
+ }
+ g_string_append_len(str, i_name, strlen(i_name) + 1);
+
+ if (right) {
+ s.sub_offset_plus_1 = str->len + 1;
+ g_string_append_len(str, right, strlen(right) + 1);
+ }
+
+ if (!*p_array)
+ *p_array = g_array_new(FALSE, FALSE, sizeof(OutputSelectionItem));
+ g_array_append_val(*p_array, s);
+ }
+
+ return TRUE;
+}
+
+NMMetaSelectionResultList *
+nm_meta_selection_create_all(const NMMetaAbstractInfo *const *fields_array)
+{
+ gs_unref_array GArray *array = NULL;
+ guint i;
+
+ if (fields_array) {
+ array = g_array_new(FALSE, FALSE, sizeof(OutputSelectionItem));
+ for (i = 0; fields_array[i]; i++) {
+ OutputSelectionItem s = {
+ .idx = i,
+ };
+
+ g_array_append_val(array, s);
+ }
+ }
+
+ return _output_selection_pack(fields_array, array, NULL);
+}
+
+NMMetaSelectionResultList *
+nm_meta_selection_create_parse_one(
+ const NMMetaAbstractInfo *const *fields_array,
+ const char * fields_prefix,
+ const char *
+ fields_str, /* one field selector (contains no commas) and is already stripped of spaces. */
+ gboolean validate_nested,
+ GError **error)
+{
+ gs_unref_array GArray *array = NULL;
+ nm_auto_free_gstring GString *str = NULL;
+
+ g_return_val_if_fail(!error || !*error, NULL);
+ nm_assert(fields_str && !strchr(fields_str, ','));
+
+ if (!_output_selection_select_one(fields_array,
+ fields_prefix,
+ fields_str,
+ validate_nested,
+ &array,
+ &str,
+ error))
+ return NULL;
+ return _output_selection_pack(fields_array, array, str);
+}
+
+NMMetaSelectionResultList *
+nm_meta_selection_create_parse_list(
+ const NMMetaAbstractInfo *const *fields_array,
+ const char * fields_str, /* a comma separated list of selectors */
+ gboolean validate_nested,
+ GError ** error)
+{
+ gs_unref_array GArray *array = NULL;
+ nm_auto_free_gstring GString *str = NULL;
+ gs_free char * fields_str_clone = NULL;
+ char * fields_str_cur;
+ char * fields_str_next;
+
+ g_return_val_if_fail(!error || !*error, NULL);
+
+ if (!fields_str)
+ return nm_meta_selection_create_all(fields_array);
+
+ fields_str_clone = g_strdup(fields_str);
+ for (fields_str_cur = fields_str_clone; fields_str_cur; fields_str_cur = fields_str_next) {
+ fields_str_cur = nm_str_skip_leading_spaces(fields_str_cur);
+ fields_str_next = strchr(fields_str_cur, ',');
+ if (fields_str_next)
+ *fields_str_next++ = '\0';
+
+ g_strchomp(fields_str_cur);
+ if (!fields_str_cur[0])
+ continue;
+ if (!_output_selection_select_one(fields_array,
+ NULL,
+ fields_str_cur,
+ validate_nested,
+ &array,
+ &str,
+ error))
+ return NULL;
+ }
+
+ return _output_selection_pack(fields_array, array, str);
+}
diff --git a/src/libnmc-setting/nm-meta-setting-access.h b/src/libnmc-setting/nm-meta-setting-access.h
new file mode 100644
index 0000000000..81aa3b6f67
--- /dev/null
+++ b/src/libnmc-setting/nm-meta-setting-access.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2010 - 2017 Red Hat, Inc.
+ */
+
+#ifndef _NM_META_SETTING_ACCESS_H__
+#define _NM_META_SETTING_ACCESS_H__
+
+#include "nm-meta-setting-desc.h"
+
+/*****************************************************************************/
+
+NMSetting *nm_meta_setting_info_editor_new_setting(const NMMetaSettingInfoEditor *setting_info,
+ NMMetaAccessorSettingInitType init_type);
+
+const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_name(const char *setting_name,
+ gboolean use_alias);
+const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_gtype(GType gtype);
+const NMMetaSettingInfoEditor *nm_meta_setting_info_editor_find_by_setting(NMSetting *setting);
+
+const NMMetaPropertyInfo *
+nm_meta_setting_info_editor_get_property_info(const NMMetaSettingInfoEditor *setting_info,
+ const char * property_name);
+const NMMetaPropertyInfo *nm_meta_property_info_find_by_name(const char *setting_name,
+ const char *property_name);
+const NMMetaPropertyInfo *nm_meta_property_info_find_by_setting(NMSetting * setting,
+ const char *property_name);
+
+gboolean nm_meta_setting_info_editor_has_secrets(const NMMetaSettingInfoEditor *setting_info);
+
+/*****************************************************************************/
+
+const NMMetaSettingInfoEditor *const *nm_meta_setting_infos_editor_p(void);
+
+/*****************************************************************************/
+
+const char *nm_meta_abstract_info_get_name(const NMMetaAbstractInfo *abstract_info,
+ gboolean for_header);
+
+const NMMetaAbstractInfo *const *
+nm_meta_abstract_info_get_nested(const NMMetaAbstractInfo *abstract_info,
+ guint * out_len,
+ gpointer * nested_to_free);
+
+gconstpointer nm_meta_abstract_info_get(const NMMetaAbstractInfo * abstract_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ gpointer target,
+ gpointer target_data,
+ NMMetaAccessorGetType get_type,
+ NMMetaAccessorGetFlags get_flags,
+ NMMetaAccessorGetOutFlags *out_flags,
+ gboolean * out_is_default,
+ gpointer * out_to_free);
+
+const char *const *nm_meta_abstract_info_complete(const NMMetaAbstractInfo *abstract_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ const NMMetaOperationContext *operation_context,
+ const char * text,
+ gboolean *out_complete_filename,
+ char *** out_to_free);
+
+/*****************************************************************************/
+
+char *nm_meta_abstract_info_get_nested_names_str(const NMMetaAbstractInfo *abstract_info,
+ const char * name_prefix);
+char *nm_meta_abstract_infos_get_names_str(const NMMetaAbstractInfo *const *fields_array,
+ const char * name_prefix);
+
+/*****************************************************************************/
+
+typedef struct {
+ const NMMetaAbstractInfo *info;
+ const char * self_selection;
+ const char * sub_selection;
+ guint idx;
+} NMMetaSelectionItem;
+
+typedef struct {
+ const guint num;
+ const NMMetaSelectionItem items[];
+} NMMetaSelectionResultList;
+
+NMMetaSelectionResultList *
+nm_meta_selection_create_all(const NMMetaAbstractInfo *const *fields_array);
+NMMetaSelectionResultList *
+nm_meta_selection_create_parse_one(const NMMetaAbstractInfo *const *fields_array,
+ const char * fields_prefix,
+ const char * fields_str,
+ gboolean validate_nested,
+ GError ** error);
+NMMetaSelectionResultList *
+nm_meta_selection_create_parse_list(const NMMetaAbstractInfo *const *fields_array,
+ const char * fields_str,
+ gboolean validate_nested,
+ GError ** error);
+
+#endif /* _NM_META_SETTING_ACCESS_H__ */
diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.c b/src/libnmc-setting/nm-meta-setting-base-impl.c
new file mode 100644
index 0000000000..da85e5683b
--- /dev/null
+++ b/src/libnmc-setting/nm-meta-setting-base-impl.c
@@ -0,0 +1,641 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2017 - 2018 Red Hat, Inc.
+ */
+
+#include "libnm-glib-aux/nm-default-glib-i18n-lib.h"
+
+#include "nm-meta-setting-base.h"
+
+#include "nm-setting-6lowpan.h"
+#include "nm-setting-8021x.h"
+#include "nm-setting-adsl.h"
+#include "nm-setting-bluetooth.h"
+#include "nm-setting-bond.h"
+#include "nm-setting-bridge-port.h"
+#include "nm-setting-bridge.h"
+#include "nm-setting-cdma.h"
+#include "nm-setting-connection.h"
+#include "nm-setting-dcb.h"
+#include "nm-setting-dummy.h"
+#include "nm-setting-ethtool.h"
+#include "nm-setting-generic.h"
+#include "nm-setting-gsm.h"
+#include "nm-setting-hostname.h"
+#include "nm-setting-infiniband.h"
+#include "nm-setting-ip-config.h"
+#include "nm-setting-ip-tunnel.h"
+#include "nm-setting-ip4-config.h"
+#include "nm-setting-ip6-config.h"
+#include "nm-setting-macsec.h"
+#include "nm-setting-macvlan.h"
+#include "nm-setting-match.h"
+#include "nm-setting-olpc-mesh.h"
+#include "nm-setting-ovs-bridge.h"
+#include "nm-setting-ovs-interface.h"
+#include "nm-setting-ovs-dpdk.h"
+#include "nm-setting-ovs-external-ids.h"
+#include "nm-setting-ovs-patch.h"
+#include "nm-setting-ovs-port.h"
+#include "nm-setting-ppp.h"
+#include "nm-setting-pppoe.h"
+#include "nm-setting-proxy.h"
+#include "nm-setting-serial.h"
+#include "nm-setting-tc-config.h"
+#include "nm-setting-team-port.h"
+#include "nm-setting-team.h"
+#include "nm-setting-tun.h"
+#include "nm-setting-user.h"
+#include "nm-setting-veth.h"
+#include "nm-setting-vlan.h"
+#include "nm-setting-vpn.h"
+#include "nm-setting-vrf.h"
+#include "nm-setting-vxlan.h"
+#include "nm-setting-wifi-p2p.h"
+#include "nm-setting-wimax.h"
+#include "nm-setting-wired.h"
+#include "nm-setting-wireguard.h"
+#include "nm-setting-wireless-security.h"
+#include "nm-setting-wireless.h"
+#include "nm-setting-wpan.h"
+
+/*****************************************************************************/
+
+const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
+
+#define _D(_scheme_type, ...) [(_scheme_type)] = {.scheme_type = (_scheme_type), __VA_ARGS__}
+
+ _D(NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN),
+
+ _D(NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT,
+ .setting_key = NM_SETTING_802_1X_CA_CERT,
+ .scheme_func = nm_setting_802_1x_get_ca_cert_scheme,
+ .format_func = NULL,
+ .path_func = nm_setting_802_1x_get_ca_cert_path,
+ .blob_func = nm_setting_802_1x_get_ca_cert_blob,
+ .uri_func = nm_setting_802_1x_get_ca_cert_uri,
+ .passwd_func = nm_setting_802_1x_get_ca_cert_password,
+ .pwflag_func = nm_setting_802_1x_get_ca_cert_password_flags,
+ .set_cert_func = nm_setting_802_1x_set_ca_cert,
+ .file_suffix = "ca-cert", ),
+
+ _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT,
+ .setting_key = NM_SETTING_802_1X_PHASE2_CA_CERT,
+ .scheme_func = nm_setting_802_1x_get_phase2_ca_cert_scheme,
+ .format_func = NULL,
+ .path_func = nm_setting_802_1x_get_phase2_ca_cert_path,
+ .blob_func = nm_setting_802_1x_get_phase2_ca_cert_blob,
+ .uri_func = nm_setting_802_1x_get_phase2_ca_cert_uri,
+ .passwd_func = nm_setting_802_1x_get_phase2_ca_cert_password,
+ .pwflag_func = nm_setting_802_1x_get_phase2_ca_cert_password_flags,
+ .set_cert_func = nm_setting_802_1x_set_phase2_ca_cert,
+ .file_suffix = "inner-ca-cert", ),
+
+ _D(NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT,
+ .setting_key = NM_SETTING_802_1X_CLIENT_CERT,
+ .scheme_func = nm_setting_802_1x_get_client_cert_scheme,
+ .format_func = NULL,
+ .path_func = nm_setting_802_1x_get_client_cert_path,
+ .blob_func = nm_setting_802_1x_get_client_cert_blob,
+ .uri_func = nm_setting_802_1x_get_client_cert_uri,
+ .passwd_func = nm_setting_802_1x_get_client_cert_password,
+ .pwflag_func = nm_setting_802_1x_get_client_cert_password_flags,
+ .set_cert_func = nm_setting_802_1x_set_client_cert,
+ .file_suffix = "client-cert", ),
+
+ _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT,
+ .setting_key = NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+ .scheme_func = nm_setting_802_1x_get_phase2_client_cert_scheme,
+ .format_func = NULL,
+ .path_func = nm_setting_802_1x_get_phase2_client_cert_path,
+ .blob_func = nm_setting_802_1x_get_phase2_client_cert_blob,
+ .uri_func = nm_setting_802_1x_get_phase2_client_cert_uri,
+ .passwd_func = nm_setting_802_1x_get_phase2_client_cert_password,
+ .pwflag_func = nm_setting_802_1x_get_phase2_client_cert_password_flags,
+ .set_cert_func = nm_setting_802_1x_set_phase2_client_cert,
+ .file_suffix = "inner-client-cert", ),
+
+ _D(NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY,
+ .setting_key = NM_SETTING_802_1X_PRIVATE_KEY,
+ .scheme_func = nm_setting_802_1x_get_private_key_scheme,
+ .format_func = nm_setting_802_1x_get_private_key_format,
+ .path_func = nm_setting_802_1x_get_private_key_path,
+ .blob_func = nm_setting_802_1x_get_private_key_blob,
+ .uri_func = nm_setting_802_1x_get_private_key_uri,
+ .passwd_func = nm_setting_802_1x_get_private_key_password,
+ .pwflag_func = nm_setting_802_1x_get_private_key_password_flags,
+ .set_private_key_func = nm_setting_802_1x_set_private_key,
+ .file_suffix = "private-key",
+ .is_secret = TRUE, ),
+
+ _D(NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY,
+ .setting_key = NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ .scheme_func = nm_setting_802_1x_get_phase2_private_key_scheme,
+ .format_func = nm_setting_802_1x_get_phase2_private_key_format,
+ .path_func = nm_setting_802_1x_get_phase2_private_key_path,
+ .blob_func = nm_setting_802_1x_get_phase2_private_key_blob,
+ .uri_func = nm_setting_802_1x_get_phase2_private_key_uri,
+ .passwd_func = nm_setting_802_1x_get_phase2_private_key_password,
+ .pwflag_func = nm_setting_802_1x_get_phase2_private_key_password_flags,
+ .set_private_key_func = nm_setting_802_1x_set_phase2_private_key,
+ .file_suffix = "inner-private-key",
+ .is_secret = TRUE, ),
+
+#undef _D
+};
+
+/*****************************************************************************/
+
+const NMMetaSettingInfo nm_meta_setting_infos[] = {
+ [NM_META_SETTING_TYPE_6LOWPAN] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_6LOWPAN,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_6LOWPAN_SETTING_NAME,
+ .get_setting_gtype = nm_setting_6lowpan_get_type,
+ },
+ [NM_META_SETTING_TYPE_802_1X] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_802_1X,
+ .setting_priority = NM_SETTING_PRIORITY_HW_AUX,
+ .setting_name = NM_SETTING_802_1X_SETTING_NAME,
+ .get_setting_gtype = nm_setting_802_1x_get_type,
+ },
+ [NM_META_SETTING_TYPE_ADSL] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_ADSL,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_ADSL_SETTING_NAME,
+ .get_setting_gtype = nm_setting_adsl_get_type,
+ },
+ [NM_META_SETTING_TYPE_BLUETOOTH] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_BLUETOOTH,
+ .setting_priority = NM_SETTING_PRIORITY_HW_NON_BASE,
+ .setting_name = NM_SETTING_BLUETOOTH_SETTING_NAME,
+ .get_setting_gtype = nm_setting_bluetooth_get_type,
+ },
+ [NM_META_SETTING_TYPE_BOND] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_BOND,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_BOND_SETTING_NAME,
+ .get_setting_gtype = nm_setting_bond_get_type,
+ },
+ [NM_META_SETTING_TYPE_BRIDGE] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_BRIDGE,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_BRIDGE_SETTING_NAME,
+ .get_setting_gtype = nm_setting_bridge_get_type,
+ },
+ [NM_META_SETTING_TYPE_BRIDGE_PORT] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_BRIDGE_PORT,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_BRIDGE_PORT_SETTING_NAME,
+ .get_setting_gtype = nm_setting_bridge_port_get_type,
+ },
+ [NM_META_SETTING_TYPE_CDMA] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_CDMA,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_CDMA_SETTING_NAME,
+ .get_setting_gtype = nm_setting_cdma_get_type,
+ },
+ [NM_META_SETTING_TYPE_CONNECTION] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_CONNECTION,
+ .setting_priority = NM_SETTING_PRIORITY_CONNECTION,
+ .setting_name = NM_SETTING_CONNECTION_SETTING_NAME,
+ .get_setting_gtype = nm_setting_connection_get_type,
+ },
+ [NM_META_SETTING_TYPE_DCB] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_DCB,
+ .setting_priority = NM_SETTING_PRIORITY_HW_AUX,
+ .setting_name = NM_SETTING_DCB_SETTING_NAME,
+ .get_setting_gtype = nm_setting_dcb_get_type,
+ },
+ [NM_META_SETTING_TYPE_DUMMY] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_DUMMY,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_DUMMY_SETTING_NAME,
+ .get_setting_gtype = nm_setting_dummy_get_type,
+ },
+ [NM_META_SETTING_TYPE_ETHTOOL] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_ETHTOOL,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_ETHTOOL_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ethtool_get_type,
+ },
+ [NM_META_SETTING_TYPE_GENERIC] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_GENERIC,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_GENERIC_SETTING_NAME,
+ .get_setting_gtype = nm_setting_generic_get_type,
+ },
+ [NM_META_SETTING_TYPE_GSM] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_GSM,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_GSM_SETTING_NAME,
+ .get_setting_gtype = nm_setting_gsm_get_type,
+ },
+ [NM_META_SETTING_TYPE_HOSTNAME] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_HOSTNAME,
+ .setting_priority = NM_SETTING_PRIORITY_IP,
+ .setting_name = NM_SETTING_HOSTNAME_SETTING_NAME,
+ .get_setting_gtype = nm_setting_hostname_get_type,
+ },
+ [NM_META_SETTING_TYPE_INFINIBAND] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_INFINIBAND,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_INFINIBAND_SETTING_NAME,
+ .get_setting_gtype = nm_setting_infiniband_get_type,
+ },
+ [NM_META_SETTING_TYPE_IP4_CONFIG] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_IP4_CONFIG,
+ .setting_priority = NM_SETTING_PRIORITY_IP,
+ .setting_name = NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ip4_config_get_type,
+ },
+ [NM_META_SETTING_TYPE_IP6_CONFIG] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_IP6_CONFIG,
+ .setting_priority = NM_SETTING_PRIORITY_IP,
+ .setting_name = NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ip6_config_get_type,
+ },
+ [NM_META_SETTING_TYPE_IP_TUNNEL] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_IP_TUNNEL,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ip_tunnel_get_type,
+ },
+ [NM_META_SETTING_TYPE_MACSEC] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_MACSEC,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_MACSEC_SETTING_NAME,
+ .get_setting_gtype = nm_setting_macsec_get_type,
+ },
+ [NM_META_SETTING_TYPE_MACVLAN] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_MACVLAN,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_MACVLAN_SETTING_NAME,
+ .get_setting_gtype = nm_setting_macvlan_get_type,
+ },
+ [NM_META_SETTING_TYPE_MATCH] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_MATCH,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_MATCH_SETTING_NAME,
+ .get_setting_gtype = nm_setting_match_get_type,
+ },
+ [NM_META_SETTING_TYPE_OLPC_MESH] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_OLPC_MESH,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_OLPC_MESH_SETTING_NAME,
+ .get_setting_gtype = nm_setting_olpc_mesh_get_type,
+ },
+ [NM_META_SETTING_TYPE_OVS_BRIDGE] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_OVS_BRIDGE,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_OVS_BRIDGE_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ovs_bridge_get_type,
+ },
+ [NM_META_SETTING_TYPE_OVS_DPDK] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_OVS_DPDK,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_OVS_DPDK_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ovs_dpdk_get_type,
+ },
+ [NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ovs_external_ids_get_type,
+ },
+ [NM_META_SETTING_TYPE_OVS_INTERFACE] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_OVS_INTERFACE,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_OVS_INTERFACE_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ovs_interface_get_type,
+ },
+ [NM_META_SETTING_TYPE_OVS_PATCH] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_OVS_PATCH,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_OVS_PATCH_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ovs_patch_get_type,
+ },
+ [NM_META_SETTING_TYPE_OVS_PORT] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_OVS_PORT,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_OVS_PORT_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ovs_port_get_type,
+ },
+ [NM_META_SETTING_TYPE_PPPOE] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_PPPOE,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_PPPOE_SETTING_NAME,
+ .get_setting_gtype = nm_setting_pppoe_get_type,
+ },
+ [NM_META_SETTING_TYPE_PPP] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_PPP,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_PPP_SETTING_NAME,
+ .get_setting_gtype = nm_setting_ppp_get_type,
+ },
+ [NM_META_SETTING_TYPE_PROXY] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_PROXY,
+ .setting_priority = NM_SETTING_PRIORITY_IP,
+ .setting_name = NM_SETTING_PROXY_SETTING_NAME,
+ .get_setting_gtype = nm_setting_proxy_get_type,
+ },
+ [NM_META_SETTING_TYPE_SERIAL] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_SERIAL,
+ .setting_priority = NM_SETTING_PRIORITY_HW_AUX,
+ .setting_name = NM_SETTING_SERIAL_SETTING_NAME,
+ .get_setting_gtype = nm_setting_serial_get_type,
+ },
+ [NM_META_SETTING_TYPE_SRIOV] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_SRIOV,
+ .setting_priority = NM_SETTING_PRIORITY_HW_AUX,
+ .setting_name = NM_SETTING_SRIOV_SETTING_NAME,
+ .get_setting_gtype = nm_setting_sriov_get_type,
+ },
+ [NM_META_SETTING_TYPE_TC_CONFIG] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_TC_CONFIG,
+ .setting_priority = NM_SETTING_PRIORITY_IP,
+ .setting_name = NM_SETTING_TC_CONFIG_SETTING_NAME,
+ .get_setting_gtype = nm_setting_tc_config_get_type,
+ },
+ [NM_META_SETTING_TYPE_TEAM] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_TEAM,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_TEAM_SETTING_NAME,
+ .get_setting_gtype = nm_setting_team_get_type,
+ },
+ [NM_META_SETTING_TYPE_TEAM_PORT] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_TEAM_PORT,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_TEAM_PORT_SETTING_NAME,
+ .get_setting_gtype = nm_setting_team_port_get_type,
+ },
+ [NM_META_SETTING_TYPE_TUN] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_TUN,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_TUN_SETTING_NAME,
+ .get_setting_gtype = nm_setting_tun_get_type,
+ },
+ [NM_META_SETTING_TYPE_USER] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_USER,
+ .setting_priority = NM_SETTING_PRIORITY_USER,
+ .setting_name = NM_SETTING_USER_SETTING_NAME,
+ .get_setting_gtype = nm_setting_user_get_type,
+ },
+ [NM_META_SETTING_TYPE_VETH] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_VETH,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_VETH_SETTING_NAME,
+ .get_setting_gtype = nm_setting_veth_get_type,
+ },
+ [NM_META_SETTING_TYPE_VLAN] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_VLAN,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_VLAN_SETTING_NAME,
+ .get_setting_gtype = nm_setting_vlan_get_type,
+ },
+ [NM_META_SETTING_TYPE_VPN] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_VPN,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_VPN_SETTING_NAME,
+ .get_setting_gtype = nm_setting_vpn_get_type,
+ },
+ [NM_META_SETTING_TYPE_VRF] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_VRF,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_VRF_SETTING_NAME,
+ .get_setting_gtype = nm_setting_vrf_get_type,
+ },
+ [NM_META_SETTING_TYPE_VXLAN] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_VXLAN,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_VXLAN_SETTING_NAME,
+ .get_setting_gtype = nm_setting_vxlan_get_type,
+ },
+ [NM_META_SETTING_TYPE_WIFI_P2P] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_WIFI_P2P,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_WIFI_P2P_SETTING_NAME,
+ .get_setting_gtype = nm_setting_wifi_p2p_get_type,
+ },
+ [NM_META_SETTING_TYPE_WIMAX] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_WIMAX,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_WIMAX_SETTING_NAME,
+ .get_setting_gtype = nm_setting_wimax_get_type,
+ },
+ [NM_META_SETTING_TYPE_WIRED] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_WIRED,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_WIRED_SETTING_NAME,
+ .get_setting_gtype = nm_setting_wired_get_type,
+ },
+ [NM_META_SETTING_TYPE_WIREGUARD] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_WIREGUARD,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_WIREGUARD_SETTING_NAME,
+ .get_setting_gtype = nm_setting_wireguard_get_type,
+ },
+ [NM_META_SETTING_TYPE_WIRELESS] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_WIRELESS,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_WIRELESS_SETTING_NAME,
+ .get_setting_gtype = nm_setting_wireless_get_type,
+ },
+ [NM_META_SETTING_TYPE_WIRELESS_SECURITY] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_WIRELESS_SECURITY,
+ .setting_priority = NM_SETTING_PRIORITY_HW_AUX,
+ .setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ .get_setting_gtype = nm_setting_wireless_security_get_type,
+ },
+ [NM_META_SETTING_TYPE_WPAN] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_WPAN,
+ .setting_priority = NM_SETTING_PRIORITY_HW_BASE,
+ .setting_name = NM_SETTING_WPAN_SETTING_NAME,
+ .get_setting_gtype = nm_setting_wpan_get_type,
+ },
+
+ [NM_META_SETTING_TYPE_UNKNOWN] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_UNKNOWN,
+ },
+};
+
+const NMMetaSettingInfo *
+nm_meta_setting_infos_by_name(const char *name)
+{
+ gssize idx;
+
+ if (NM_MORE_ASSERTS > 10) {
+ guint i, j;
+
+ for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) {
+ const NMMetaSettingInfo *setting_info = &nm_meta_setting_infos[i];
+
+ nm_assert(setting_info->meta_type == (NMMetaSettingType) i);
+ nm_assert(setting_info->setting_name);
+ nm_assert(setting_info->setting_name[0]);
+ nm_assert(setting_info->get_setting_gtype);
+ nm_assert(setting_info->setting_priority != NM_SETTING_PRIORITY_INVALID);
+ if (i > 0
+ && strcmp(nm_meta_setting_infos[i - 1].setting_name, setting_info->setting_name)
+ >= 0) {
+ g_error("nm_meta_setting_infos[%u, \"%s\"] is wrongly sorted before "
+ "nm_meta_setting_infos[%u, \"%s\"]. Rearange NMMetaSettingType enum",
+ i - 1,
+ nm_meta_setting_infos[i - 1].setting_name,
+ i,
+ setting_info->setting_name);
+ }
+ for (j = 0; j < i; j++) {
+ const NMMetaSettingInfo *s = &nm_meta_setting_infos[j];
+
+ nm_assert(setting_info->get_setting_gtype != s->get_setting_gtype);
+ }
+ }
+ }
+
+ G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMMetaSettingInfo, setting_name) == 0);
+ idx = nm_utils_array_find_binary_search(nm_meta_setting_infos,
+ sizeof(NMMetaSettingInfo),
+ _NM_META_SETTING_TYPE_NUM,
+ &name,
+ nm_strcmp_p_with_data,
+ NULL);
+
+ return idx >= 0 ? &nm_meta_setting_infos[idx] : NULL;
+}
+
+const NMMetaSettingInfo *
+nm_meta_setting_infos_by_gtype(GType gtype)
+{
+#if _NM_META_SETTING_BASE_IMPL_LIBNM
+ nm_auto_unref_gtypeclass GTypeClass *gtypeclass_unref = NULL;
+ GTypeClass * gtypeclass;
+ NMSettingClass * klass;
+
+ if (!g_type_is_a(gtype, NM_TYPE_SETTING))
+ goto out_none;
+
+ gtypeclass = g_type_class_peek(gtype);
+ if (!gtypeclass)
+ gtypeclass = gtypeclass_unref = g_type_class_ref(gtype);
+
+ nm_assert(NM_IS_SETTING_CLASS(gtypeclass));
+
+ klass = (NMSettingClass *) gtypeclass;
+
+ if (!klass->setting_info)
+ goto out_none;
+
+ nm_assert(klass->setting_info->get_setting_gtype);
+ nm_assert(klass->setting_info->get_setting_gtype() == gtype);
+
+ return klass->setting_info;
+
+out_none:
+
+ if (NM_MORE_ASSERTS > 10) {
+ int i;
+
+ /* this might hint to a bug, but it would be expected for NM_TYPE_SETTING
+ * and NM_TYPE_SETTING_IP_CONFIG.
+ *
+ * Assert that we didn't lookup for a gtype, which we would expect to find.
+ * An assertion failure here, hints to a bug in nm_setting_*_class_init().
+ */
+ for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++)
+ nm_assert(nm_meta_setting_infos[i].get_setting_gtype() != gtype);
+ }
+
+ return NULL;
+#else
+ guint i;
+
+ for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) {
+ if (nm_meta_setting_infos[i].get_setting_gtype() == gtype)
+ return &nm_meta_setting_infos[i];
+ }
+ return NULL;
+#endif
+}
+
+/*****************************************************************************/
+
+NMSettingPriority
+nm_meta_setting_info_get_base_type_priority(const NMMetaSettingInfo *setting_info, GType gtype)
+{
+ /* Historical oddity: PPPoE is a base-type even though it's not
+ * priority 1. It needs to be sorted *after* lower-level stuff like
+ * Wi-Fi security or 802.1x for secrets, but it's still allowed as a
+ * base type.
+ */
+
+ if (setting_info) {
+ if (NM_IN_SET(setting_info->setting_priority,
+ NM_SETTING_PRIORITY_HW_BASE,
+ NM_SETTING_PRIORITY_HW_NON_BASE)
+ || gtype == NM_TYPE_SETTING_PPPOE)
+ return setting_info->setting_priority;
+ }
+
+ return NM_SETTING_PRIORITY_INVALID;
+}
+
+NMSettingPriority
+_nm_setting_type_get_base_type_priority(GType type)
+{
+ return nm_meta_setting_info_get_base_type_priority(nm_meta_setting_infos_by_gtype(type), type);
+}
+
+/*****************************************************************************/
diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.h b/src/libnmc-setting/nm-meta-setting-base-impl.h
new file mode 100644
index 0000000000..94b14e844f
--- /dev/null
+++ b/src/libnmc-setting/nm-meta-setting-base-impl.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2017 - 2018 Red Hat, Inc.
+ */
+
+#ifndef __NM_META_SETTING_BASE_IMPL_H__
+#define __NM_META_SETTING_BASE_IMPL_H__
+
+#include "nm-setting-8021x.h"
+
+/*****************************************************************************/
+
+/*
+ * A setting's priority should roughly follow the OSI layer model, but it also
+ * controls which settings get asked for secrets first. Thus settings which
+ * relate to things that must be working first, like hardware, should get a
+ * higher priority than things which layer on top of the hardware. For example,
+ * the GSM/CDMA settings should provide secrets before the PPP setting does,
+ * because a PIN is required to unlock the device before PPP can even start.
+ * Even settings without secrets should be assigned the right priority.
+ *
+ * 0: reserved for invalid
+ *
+ * 1: reserved for the Connection setting
+ *
+ * 2,3: hardware-related settings like Ethernet, Wi-Fi, InfiniBand, Bridge, etc.
+ * These priority 1 settings are also "base types", which means that at least
+ * one of them is required for the connection to be valid, and their name is
+ * valid in the 'type' property of the Connection setting.
+ *
+ * 4: hardware-related auxiliary settings that require a base setting to be
+ * successful first, like Wi-Fi security, 802.1x, etc.
+ *
+ * 5: hardware-independent settings that are required before IP connectivity
+ * can be established, like PPP, PPPoE, etc.
+ *
+ * 6: IP-level stuff
+ *
+ * 10: NMSettingUser
+ */
+typedef enum { /*< skip >*/
+ NM_SETTING_PRIORITY_INVALID = 0,
+ NM_SETTING_PRIORITY_CONNECTION = 1,
+ NM_SETTING_PRIORITY_HW_BASE = 2,
+ NM_SETTING_PRIORITY_HW_NON_BASE = 3,
+ NM_SETTING_PRIORITY_HW_AUX = 4,
+ NM_SETTING_PRIORITY_AUX = 5,
+ NM_SETTING_PRIORITY_IP = 6,
+ NM_SETTING_PRIORITY_USER = 10,
+} NMSettingPriority;
+
+/*****************************************************************************/
+
+typedef enum {
+ 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,
+ NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT,
+ NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY,
+ NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY,
+
+ NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN,
+
+ _NM_SETTING_802_1X_SCHEME_TYPE_NUM = NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN,
+} NMSetting8021xSchemeType;
+
+typedef struct {
+ const char *setting_key;
+ NMSetting8021xCKScheme (*scheme_func)(NMSetting8021x *setting);
+ NMSetting8021xCKFormat (*format_func)(NMSetting8021x *setting);
+ const char *(*path_func)(NMSetting8021x *setting);
+ GBytes *(*blob_func)(NMSetting8021x *setting);
+ const char *(*uri_func)(NMSetting8021x *setting);
+ const char *(*passwd_func)(NMSetting8021x *setting);
+ NMSettingSecretFlags (*pwflag_func)(NMSetting8021x *setting);
+ gboolean (*set_cert_func)(NMSetting8021x * setting,
+ const char * value,
+ NMSetting8021xCKScheme scheme,
+ NMSetting8021xCKFormat *out_format,
+ GError ** error);
+ gboolean (*set_private_key_func)(NMSetting8021x * setting,
+ const char * value,
+ const char * password,
+ NMSetting8021xCKScheme scheme,
+ NMSetting8021xCKFormat *out_format,
+ GError ** error);
+ const char * file_suffix;
+ NMSetting8021xSchemeType scheme_type;
+ bool is_secret : 1;
+} NMSetting8021xSchemeVtable;
+
+extern const NMSetting8021xSchemeVtable
+ nm_setting_8021x_scheme_vtable[_NM_SETTING_802_1X_SCHEME_TYPE_NUM + 1];
+
+/*****************************************************************************/
+
+typedef enum {
+ /* the enum (and their numeric values) are internal API. Do not assign
+ * any meaning the numeric values, because they already have one:
+ *
+ * they are sorted in a way, that corresponds to the asciibetical sort
+ * order of the corresponding setting-name. */
+
+ NM_META_SETTING_TYPE_6LOWPAN,
+ NM_META_SETTING_TYPE_OLPC_MESH,
+ NM_META_SETTING_TYPE_WIRELESS,
+ NM_META_SETTING_TYPE_WIRELESS_SECURITY,
+ NM_META_SETTING_TYPE_802_1X,
+ NM_META_SETTING_TYPE_WIRED,
+ NM_META_SETTING_TYPE_ADSL,
+ NM_META_SETTING_TYPE_BLUETOOTH,
+ NM_META_SETTING_TYPE_BOND,
+ NM_META_SETTING_TYPE_BRIDGE,
+ NM_META_SETTING_TYPE_BRIDGE_PORT,
+ NM_META_SETTING_TYPE_CDMA,
+ NM_META_SETTING_TYPE_CONNECTION,
+ NM_META_SETTING_TYPE_DCB,
+ NM_META_SETTING_TYPE_DUMMY,
+ NM_META_SETTING_TYPE_ETHTOOL,
+ NM_META_SETTING_TYPE_GENERIC,
+ NM_META_SETTING_TYPE_GSM,
+ NM_META_SETTING_TYPE_HOSTNAME,
+ NM_META_SETTING_TYPE_INFINIBAND,
+ NM_META_SETTING_TYPE_IP_TUNNEL,
+ NM_META_SETTING_TYPE_IP4_CONFIG,
+ NM_META_SETTING_TYPE_IP6_CONFIG,
+ NM_META_SETTING_TYPE_MACSEC,
+ NM_META_SETTING_TYPE_MACVLAN,
+ NM_META_SETTING_TYPE_MATCH,
+ NM_META_SETTING_TYPE_OVS_BRIDGE,
+ NM_META_SETTING_TYPE_OVS_DPDK,
+ NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS,
+ NM_META_SETTING_TYPE_OVS_INTERFACE,
+ NM_META_SETTING_TYPE_OVS_PATCH,
+ NM_META_SETTING_TYPE_OVS_PORT,
+ NM_META_SETTING_TYPE_PPP,
+ NM_META_SETTING_TYPE_PPPOE,
+ NM_META_SETTING_TYPE_PROXY,
+ NM_META_SETTING_TYPE_SERIAL,
+ NM_META_SETTING_TYPE_SRIOV,
+ NM_META_SETTING_TYPE_TC_CONFIG,
+ NM_META_SETTING_TYPE_TEAM,
+ NM_META_SETTING_TYPE_TEAM_PORT,
+ NM_META_SETTING_TYPE_TUN,
+ NM_META_SETTING_TYPE_USER,
+ NM_META_SETTING_TYPE_VETH,
+ NM_META_SETTING_TYPE_VLAN,
+ NM_META_SETTING_TYPE_VPN,
+ NM_META_SETTING_TYPE_VRF,
+ NM_META_SETTING_TYPE_VXLAN,
+ NM_META_SETTING_TYPE_WIFI_P2P,
+ NM_META_SETTING_TYPE_WIMAX,
+ NM_META_SETTING_TYPE_WIREGUARD,
+ NM_META_SETTING_TYPE_WPAN,
+
+ NM_META_SETTING_TYPE_UNKNOWN,
+
+ _NM_META_SETTING_TYPE_NUM = NM_META_SETTING_TYPE_UNKNOWN,
+} NMMetaSettingType;
+
+#if _NM_META_SETTING_BASE_IMPL_LIBNM
+ #define _NMMetaSettingInfo_Alias _NMMetaSettingInfo
+#else
+ #define _NMMetaSettingInfo_Alias _NMMetaSettingInfoCli
+#endif
+
+struct _NMMetaSettingInfo_Alias {
+ const char *setting_name;
+ GType (*get_setting_gtype)(void);
+ NMMetaSettingType meta_type;
+ NMSettingPriority setting_priority;
+};
+
+typedef struct _NMMetaSettingInfo_Alias NMMetaSettingInfo;
+
+extern const NMMetaSettingInfo nm_meta_setting_infos[_NM_META_SETTING_TYPE_NUM + 1];
+
+const NMMetaSettingInfo *nm_meta_setting_infos_by_name(const char *name);
+const NMMetaSettingInfo *nm_meta_setting_infos_by_gtype(GType gtype);
+
+/*****************************************************************************/
+
+NMSettingPriority nm_meta_setting_info_get_base_type_priority(const NMMetaSettingInfo *setting_info,
+ GType gtype);
+NMSettingPriority _nm_setting_type_get_base_type_priority(GType type);
+
+#endif /* __NM_META_SETTING_BASE_IMPL_H__ */
diff --git a/src/libnmc-setting/nm-meta-setting-base.h b/src/libnmc-setting/nm-meta-setting-base.h
new file mode 100644
index 0000000000..85d790a331
--- /dev/null
+++ b/src/libnmc-setting/nm-meta-setting-base.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#ifndef __NM_META_SETTING_BASE_H__
+#define __NM_META_SETTING_BASE_H__
+
+#define _NM_META_SETTING_BASE_IMPL_LIBNM 0
+
+#include "nm-meta-setting-base-impl.h"
+
+#endif /* __NM_META_SETTING_BASE_H__ */
diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c
new file mode 100644
index 0000000000..3daa6ad1d8
--- /dev/null
+++ b/src/libnmc-setting/nm-meta-setting-desc.c
@@ -0,0 +1,8575 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2010 - 2018 Red Hat, Inc.
+ */
+
+#include "libnm-client-aux-extern/nm-default-client.h"
+
+#include "nm-meta-setting-desc.h"
+
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <linux/if_ether.h>
+#include <linux/if_infiniband.h>
+
+#include "libnm-core-aux-intern/nm-common-macros.h"
+#include "libnm-glib-aux/nm-enum-utils.h"
+#include "libnm-glib-aux/nm-secret-utils.h"
+#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
+#include "libnm-core-aux-extern/nm-libnm-core-aux.h"
+
+#include "libnmc-base/nm-vpn-helpers.h"
+#include "libnmc-base/nm-client-utils.h"
+#include "nm-meta-setting-access.h"
+
+/*****************************************************************************/
+
+static char *secret_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type);
+
+#define ALL_SECRET_FLAGS \
+ (NM_SETTING_SECRET_FLAG_NONE | NM_SETTING_SECRET_FLAG_AGENT_OWNED \
+ | NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED)
+
+/*****************************************************************************/
+
+static GType
+_gobject_property_get_gtype(GObject *gobject, const char *property_name)
+{
+ GParamSpec *param_spec;
+
+ param_spec = g_object_class_find_property(G_OBJECT_GET_CLASS(gobject), property_name);
+ if (param_spec)
+ return param_spec->value_type;
+ g_return_val_if_reached(G_TYPE_INVALID);
+}
+
+static GType
+_gtype_property_get_gtype(GType gtype, const char *property_name)
+{
+ /* given @gtype, a type for a GObject, lookup the property @property_name
+ * and return its value_type. */
+ if (G_TYPE_IS_CLASSED(gtype)) {
+ GParamSpec * param_spec;
+ nm_auto_unref_gtypeclass GTypeClass *gtypeclass = g_type_class_ref(gtype);
+
+ if (G_IS_OBJECT_CLASS(gtypeclass)) {
+ param_spec = g_object_class_find_property(G_OBJECT_CLASS(gtypeclass), property_name);
+ if (param_spec)
+ return param_spec->value_type;
+ }
+ }
+ g_return_val_if_reached(G_TYPE_INVALID);
+}
+
+/*****************************************************************************/
+
+static char *
+bytes_to_string(GBytes *bytes)
+{
+ const guint8 *data;
+ gsize len;
+
+ if (!bytes)
+ return NULL;
+
+ data = g_bytes_get_data(bytes, &len);
+ return nm_utils_bin2hexstr_full(data, len, '\0', TRUE, NULL);
+}
+
+/*****************************************************************************/
+
+static int
+_int64_cmp_desc(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ NM_CMP_DIRECT(*((const gint64 *) b), *((const gint64 *) a));
+ return 0;
+}
+
+static gint64 *
+_value_str_as_index_list(const char *value, gsize *out_len)
+{
+ gs_free char *str_clone_free = NULL;
+ gboolean str_cloned = FALSE;
+ char * str;
+ gsize i, j;
+ gsize n_alloc;
+ gsize len;
+ gs_free gint64 *arr = NULL;
+
+ *out_len = 0;
+
+ if (!value)
+ return NULL;
+
+ str = (char *) value;
+ n_alloc = 0;
+ len = 0;
+ while (TRUE) {
+ gint64 i64;
+ const char *s;
+ gsize good;
+
+ good = strcspn(str, "," NM_ASCII_SPACES);
+ if (good == 0) {
+ if (str[0] == '\0')
+ break;
+ str++;
+ continue;
+ }
+ if (str[good] == '\0') {
+ s = str;
+ str += good;
+ } else {
+ if (!str_cloned) {
+ str_cloned = TRUE;
+ str = nm_strndup_a(200, str, strlen(str), &str_clone_free);
+ }
+ s = str;
+ str[good] = '\0';
+ str += good + 1;
+ }
+
+ i64 = _nm_utils_ascii_str_to_int64(s, 10, 0, G_MAXINT64, -1);
+ if (i64 == -1)
+ return NULL;
+
+ if (len >= n_alloc) {
+ if (n_alloc > 0) {
+ n_alloc = n_alloc * 2;
+ arr = g_realloc(arr, n_alloc * sizeof(gint64));
+ } else {
+ n_alloc = 4;
+ arr = g_new(gint64, n_alloc);
+ }
+ }
+ arr[len++] = i64;
+ }
+
+ if (len > 1) {
+ /* sort the list of indexes descendingly, and drop duplicates. */
+ g_qsort_with_data(arr, len, sizeof(gint64), _int64_cmp_desc, NULL);
+ j = 1;
+ for (i = 1; i < len; i++) {
+ nm_assert(arr[i - 1] >= arr[i]);
+ if (arr[i - 1] > arr[i])
+ arr[j++] = arr[i];
+ }
+ len = j;
+ }
+
+ *out_len = len;
+ return g_steal_pointer(&arr);
+}
+
+#define ESCAPED_TOKENS_WITH_SPACES_DELIMTER ' '
+#define ESCAPED_TOKENS_WITH_SPACES_DELIMTERS NM_ASCII_SPACES ","
+
+#define ESCAPED_TOKENS_DELIMITER ','
+#define ESCAPED_TOKENS_DELIMITERS ","
+
+typedef enum {
+ VALUE_STRSPLIT_MODE_OBJLIST,
+ VALUE_STRSPLIT_MODE_MULTILIST,
+ VALUE_STRSPLIT_MODE_ESCAPED_TOKENS,
+ VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES,
+} ValueStrsplitMode;
+
+static const char **
+_value_strsplit(const char *value, ValueStrsplitMode split_mode, gsize *out_len)
+{
+ gs_free const char **strv = NULL;
+
+ /* FIXME: some modes should support backslash escaping.
+ * In particular, to distinguish from _value_str_as_index_list(), which
+ * does not accept '\\'. */
+
+ /* note that all modes remove empty tokens (",", "a,,b", ",,"). */
+ switch (split_mode) {
+ case VALUE_STRSPLIT_MODE_OBJLIST:
+ strv = nm_utils_strsplit_set_full(value,
+ ESCAPED_TOKENS_DELIMITERS,
+ NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP);
+ break;
+ case VALUE_STRSPLIT_MODE_MULTILIST:
+ strv = nm_utils_strsplit_set_full(value,
+ ESCAPED_TOKENS_WITH_SPACES_DELIMTERS,
+ NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP);
+ break;
+ case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS:
+ strv = nm_utils_escaped_tokens_split(value, ESCAPED_TOKENS_DELIMITERS);
+ break;
+ case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES:
+ strv = nm_utils_escaped_tokens_split(value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS);
+ break;
+ }
+
+ NM_SET_OUT(out_len, NM_PTRARRAY_LEN(strv));
+ return g_steal_pointer(&strv);
+}
+
+static gboolean
+_value_strsplit_assert_unsplitable(const char *str)
+{
+#if NM_MORE_ASSERTS > 5
+ gs_free const char **strv_test = NULL;
+ gsize j, l;
+
+ /* Assert that we cannot split the token and that it
+ * has no unescaped delimiters. */
+
+ strv_test = _value_strsplit(str, VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, NULL);
+ nm_assert(NM_PTRARRAY_LEN(strv_test) == 1);
+
+ for (j = 0; str[j] != '\0';) {
+ if (str[j] == '\\') {
+ j++;
+ nm_assert(str[j] != '\0');
+ } else
+ nm_assert(!NM_IN_SET(str[j], '\0', ','));
+ j++;
+ }
+ l = j;
+ nm_assert(!g_ascii_isspace(str[l - 1]) || (l >= 2 && str[l - 2] == '\\'));
+#endif
+
+ return TRUE;
+}
+
+static NMIPAddress *
+_parse_ip_address(int family, const char *address, GError **error)
+{
+ gs_free char *ip_str = NULL;
+ const int MAX_PREFIX = (family == AF_INET) ? 32 : 128;
+ NMIPAddress * addr;
+ char * plen;
+ int prefix;
+ GError * local = NULL;
+
+ g_return_val_if_fail(address, NULL);
+ g_return_val_if_fail(!error || !*error, NULL);
+
+ ip_str = g_strstrip(g_strdup(address));
+
+ prefix = MAX_PREFIX;
+
+ plen = strchr(ip_str, '/');
+ if (plen) {
+ *plen++ = '\0';
+ if ((prefix = _nm_utils_ascii_str_to_int64(plen, 10, 1, MAX_PREFIX, -1)) == -1) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid prefix '%s'; <1-%d> allowed"),
+ plen,
+ MAX_PREFIX);
+ return NULL;
+ }
+ }
+
+ addr = nm_ip_address_new(family, ip_str, prefix, &local);
+ if (!addr) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid IP address: %s"),
+ local->message);
+ g_clear_error(&local);
+ }
+ return addr;
+}
+
+static NMIPRoute *
+_parse_ip_route(int family, const char *str, GError **error)
+{
+ const int MAX_PREFIX = (family == AF_INET) ? 32 : 128;
+ const char * next_hop = NULL;
+ int prefix;
+ NMIPRoute * route = NULL;
+ GError * local = NULL;
+ gint64 metric = -1;
+ guint i;
+ gs_free const char **routev = NULL;
+ gs_free char * str_clean_free = NULL;
+ const char * str_clean;
+ gs_free char * dest_clone = NULL;
+ const char * dest;
+ const char * plen;
+ gs_unref_hashtable GHashTable *attrs = NULL;
+#define ROUTE_SYNTAX \
+ _("The valid syntax is: 'ip[/prefix] [next-hop] [metric] [attribute=val]... [,ip[/prefix] " \
+ "...]'")
+
+ nm_assert(NM_IN_SET(family, AF_INET, AF_INET6));
+ nm_assert(str);
+ nm_assert(!error || !*error);
+
+ str_clean = nm_strstrip_avoid_copy_a(300, str, &str_clean_free);
+ routev = nm_utils_strsplit_set(str_clean, " \t");
+ if (!routev) {
+ g_set_error(error, 1, 0, "'%s' is not valid. %s", str, ROUTE_SYNTAX);
+ return NULL;
+ }
+
+ dest = routev[0];
+ plen = strchr(dest, '/'); /* prefix delimiter */
+ if (plen) {
+ dest_clone = g_strdup(dest);
+ plen = &dest_clone[plen - dest];
+ dest = dest_clone;
+ *((char *) plen) = '\0';
+ plen++;
+ }
+ prefix = MAX_PREFIX;
+ if (plen) {
+ if ((prefix = _nm_utils_ascii_str_to_int64(plen, 10, 0, MAX_PREFIX, -1)) == -1) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid prefix '%s'; <1-%d> allowed"),
+ plen,
+ MAX_PREFIX);
+ return NULL;
+ }
+ }
+
+ for (i = 1; routev[i]; i++) {
+ gint64 tmp64;
+
+ if (nm_utils_ipaddr_is_valid(family, routev[i])) {
+ if (metric != -1 || attrs) {
+ g_set_error(error, 1, 0, _("the next hop ('%s') must be first"), routev[i]);
+ return NULL;
+ }
+ next_hop = routev[i];
+ } else if ((tmp64 = _nm_utils_ascii_str_to_int64(routev[i], 10, 0, G_MAXUINT32, -1))
+ != -1) {
+ if (attrs) {
+ g_set_error(error,
+ 1,
+ 0,
+ _("the metric ('%s') must be before attributes"),
+ routev[i]);
+ return NULL;
+ }
+ metric = tmp64;
+ } else if (strchr(routev[i], '=')) {
+ GHashTableIter iter;
+ char * iter_key;
+ GVariant * iter_value;
+ gs_unref_hashtable GHashTable *tmp_attrs = NULL;
+
+ tmp_attrs = nm_utils_parse_variant_attributes(routev[i],
+ ' ',
+ '=',
+ FALSE,
+ nm_ip_route_get_variant_attribute_spec(),
+ error);
+ if (!tmp_attrs) {
+ g_prefix_error(error, "invalid option '%s': ", routev[i]);
+ return NULL;
+ }
+
+ if (!attrs) {
+ attrs = g_hash_table_new_full(nm_str_hash,
+ g_str_equal,
+ g_free,
+ (GDestroyNotify) g_variant_unref);
+ }
+
+ g_hash_table_iter_init(&iter, tmp_attrs);
+ while (
+ g_hash_table_iter_next(&iter, (gpointer *) &iter_key, (gpointer *) &iter_value)) {
+ /* need to sink the reference, because nm_utils_parse_variant_attributes() returns
+ * floating refs. */
+ g_variant_ref_sink(iter_value);
+
+ if (!nm_ip_route_attribute_validate(iter_key, iter_value, family, NULL, error)) {
+ g_prefix_error(error, "%s: ", iter_key);
+ return NULL;
+ }
+ g_hash_table_insert(attrs, iter_key, iter_value);
+ g_hash_table_iter_steal(&iter);
+ }
+ } else {
+ g_set_error(error, 1, 0, "%s", ROUTE_SYNTAX);
+ return NULL;
+ }
+ }
+
+ route = nm_ip_route_new(family, dest, prefix, next_hop, metric, &local);
+ if (!route) {
+ g_set_error(error, 1, 0, _("invalid route: %s. %s"), local->message, ROUTE_SYNTAX);
+ g_clear_error(&local);
+ return NULL;
+ }
+
+ if (attrs) {
+ GHashTableIter iter;
+ char * name;
+ GVariant * variant;
+
+ g_hash_table_iter_init(&iter, attrs);
+ while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant))
+ nm_ip_route_set_attribute(route, name, variant);
+ }
+
+ return route;
+}
+
+/*****************************************************************************/
+
+/* Max priority values from libnm-core/nm-setting-vlan.c */
+#define MAX_SKB_PRIO G_MAXUINT32
+#define MAX_8021P_PRIO 7 /* Max 802.1p priority */
+
+/*
+ * nmc_proxy_check_script:
+ * @script: file name with PAC script, or raw PAC Script data
+ * @out_script: raw PAC Script (with removed new-line characters)
+ * @error: location to store error, or %NULL
+ *
+ * Check PAC Script from @script parameter and return the checked/sanitized
+ * config in @out_script.
+ *
+ * Returns: %TRUE if the script is valid, %FALSE if it is invalid
+ */
+static gboolean
+nmc_proxy_check_script(const char *script, char **out_script, GError **error)
+{
+ enum {
+ _PAC_SCRIPT_TYPE_GUESS,
+ _PAC_SCRIPT_TYPE_FILE,
+ _PAC_SCRIPT_TYPE_JSON,
+ } desired_type = _PAC_SCRIPT_TYPE_GUESS;
+ const char * filename = NULL;
+ size_t c_len = 0;
+ gs_free char *script_clone = NULL;
+
+ *out_script = NULL;
+
+ if (!script || !script[0])
+ return TRUE;
+
+ if (g_str_has_prefix(script, "file://")) {
+ script += NM_STRLEN("file://");
+ desired_type = _PAC_SCRIPT_TYPE_FILE;
+ } else if (g_str_has_prefix(script, "js://")) {
+ script += NM_STRLEN("js://");
+ desired_type = _PAC_SCRIPT_TYPE_JSON;
+ }
+
+ if (NM_IN_SET(desired_type, _PAC_SCRIPT_TYPE_FILE, _PAC_SCRIPT_TYPE_GUESS)) {
+ gs_free char *contents = NULL;
+
+ if (!g_file_get_contents(script, &contents, &c_len, NULL)) {
+ if (desired_type == _PAC_SCRIPT_TYPE_FILE) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("cannot read pac-script from file '%s'"),
+ script);
+ return FALSE;
+ }
+ } else {
+ if (c_len != strlen(contents)) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("file '%s' contains non-valid utf-8"),
+ script);
+ return FALSE;
+ }
+ filename = script;
+ script = script_clone = g_steal_pointer(&contents);
+ }
+ }
+
+ if (!strstr(script, "FindProxyForURL") || !g_utf8_validate(script, -1, NULL)) {
+ if (filename) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' does not contain a valid PAC Script"),
+ filename);
+ } else {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("Not a valid PAC Script"));
+ }
+ return FALSE;
+ }
+
+ *out_script = (script == script_clone) ? g_steal_pointer(&script_clone) : g_strdup(script);
+ return TRUE;
+}
+
+/*
+ * nmc_team_check_config:
+ * @config: file name with team config, or raw team JSON config data
+ * @out_config: raw team JSON config data
+ * The value must be freed with g_free().
+ * @error: location to store error, or %NUL
+ *
+ * Check team config from @config parameter and return the checked
+ * config in @out_config.
+ *
+ * Returns: %TRUE if the config is valid, %FALSE if it is invalid
+ */
+static gboolean
+nmc_team_check_config(const char *config, char **out_config, GError **error)
+{
+ enum {
+ _TEAM_CONFIG_TYPE_GUESS,
+ _TEAM_CONFIG_TYPE_FILE,
+ _TEAM_CONFIG_TYPE_JSON,
+ } desired_type = _TEAM_CONFIG_TYPE_GUESS;
+ size_t c_len = 0;
+ gs_free char *config_clone = NULL;
+
+ *out_config = NULL;
+
+ if (!config || !config[0])
+ return TRUE;
+
+ if (g_str_has_prefix(config, "file://")) {
+ config += NM_STRLEN("file://");
+ desired_type = _TEAM_CONFIG_TYPE_FILE;
+ } else if (g_str_has_prefix(config, "json://")) {
+ config += NM_STRLEN("json://");
+ desired_type = _TEAM_CONFIG_TYPE_JSON;
+ }
+
+ if (NM_IN_SET(desired_type, _TEAM_CONFIG_TYPE_FILE, _TEAM_CONFIG_TYPE_GUESS)) {
+ gs_free char *contents = NULL;
+
+ if (!g_file_get_contents(config, &contents, &c_len, NULL)) {
+ if (desired_type == _TEAM_CONFIG_TYPE_FILE) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("cannot read team config from file '%s'"),
+ config);
+ return FALSE;
+ }
+ } else {
+ if (c_len != strlen(contents)) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("team config file '%s' contains non-valid utf-8"),
+ config);
+ return FALSE;
+ }
+ config = config_clone = g_steal_pointer(&contents);
+ }
+ }
+
+ *out_config = (config == config_clone) ? g_steal_pointer(&config_clone) : g_strdup(config);
+ return TRUE;
+}
+
+static const char *
+_get_text_hidden(NMMetaAccessorGetType get_type)
+{
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ return _(NM_META_TEXT_HIDDEN);
+ return NM_META_TEXT_HIDDEN;
+}
+
+/*****************************************************************************/
+
+G_GNUC_PRINTF(4, 5)
+static void
+_env_warn_fcn(const NMMetaEnvironment *environment,
+ gpointer environment_user_data,
+ NMMetaEnvWarnLevel warn_level,
+ const char * fmt_l10n,
+ ...)
+{
+ va_list ap;
+
+ if (!environment || !environment->warn_fcn)
+ return;
+
+ va_start(ap, fmt_l10n);
+ environment->warn_fcn(environment, environment_user_data, warn_level, fmt_l10n, ap);
+ va_end(ap);
+}
+
+/*****************************************************************************/
+
+#define ARGS_DESCRIBE_FCN const NMMetaPropertyInfo *property_info, char **out_to_free
+
+#define ARGS_GET_FCN \
+ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \
+ gpointer environment_user_data, NMSetting *setting, NMMetaAccessorGetType get_type, \
+ NMMetaAccessorGetFlags get_flags, NMMetaAccessorGetOutFlags *out_flags, \
+ gboolean *out_is_default, gpointer *out_to_free
+
+#define ARGS_SET_FCN \
+ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \
+ gpointer environment_user_data, NMSetting *setting, NMMetaAccessorModifier modifier, \
+ const char *value, GError **error
+
+#define ARGS_REMOVE_FCN \
+ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \
+ gpointer environment_user_data, NMSetting *setting, const char *value, GError **error
+
+#define ARGS_COMPLETE_FCN \
+ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, \
+ gpointer environment_user_data, const NMMetaOperationContext *operation_context, \
+ const char *text, gboolean *out_complete_filename, char ***out_to_free
+
+#define ARGS_VALUES_FCN const NMMetaPropertyInfo *property_info, char ***out_to_free
+
+#define ARGS_SETTING_INIT_FCN \
+ const NMMetaSettingInfoEditor *setting_info, NMSetting *setting, \
+ NMMetaAccessorSettingInitType init_type
+
+static gboolean _set_fcn_optionlist(ARGS_SET_FCN);
+
+static gboolean
+_SET_FCN_DO_RESET_DEFAULT(const NMMetaPropertyInfo *property_info,
+ NMMetaAccessorModifier modifier,
+ const char * value)
+{
+ nm_assert(property_info);
+ nm_assert(!property_info->property_type->set_supports_remove);
+ nm_assert(NM_IN_SET(modifier, NM_META_ACCESSOR_MODIFIER_SET, NM_META_ACCESSOR_MODIFIER_ADD));
+ nm_assert(value || modifier == NM_META_ACCESSOR_MODIFIER_SET);
+
+ return value == NULL;
+}
+
+static gboolean
+_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(const NMMetaPropertyInfo *property_info,
+ NMMetaAccessorModifier modifier,
+ const char * value)
+{
+ nm_assert(property_info);
+ nm_assert(property_info->property_type->set_supports_remove);
+ nm_assert(NM_IN_SET(modifier,
+ NM_META_ACCESSOR_MODIFIER_SET,
+ NM_META_ACCESSOR_MODIFIER_ADD,
+ NM_META_ACCESSOR_MODIFIER_DEL));
+ nm_assert(value || modifier == NM_META_ACCESSOR_MODIFIER_SET);
+
+ return value == NULL;
+}
+
+static gboolean
+_SET_FCN_DO_SET_ALL(NMMetaAccessorModifier modifier, const char *value)
+{
+ nm_assert(NM_IN_SET(modifier,
+ NM_META_ACCESSOR_MODIFIER_SET,
+ NM_META_ACCESSOR_MODIFIER_ADD,
+ NM_META_ACCESSOR_MODIFIER_DEL));
+ nm_assert(value);
+
+ return modifier == NM_META_ACCESSOR_MODIFIER_SET;
+}
+
+static gboolean
+_SET_FCN_DO_REMOVE(NMMetaAccessorModifier modifier, const char *value)
+{
+ nm_assert(NM_IN_SET(modifier,
+ NM_META_ACCESSOR_MODIFIER_SET,
+ NM_META_ACCESSOR_MODIFIER_ADD,
+ NM_META_ACCESSOR_MODIFIER_DEL));
+ nm_assert(value);
+
+ return modifier == NM_META_ACCESSOR_MODIFIER_DEL;
+}
+
+#define RETURN_UNSUPPORTED_GET_TYPE() \
+ G_STMT_START \
+ { \
+ if (!NM_IN_SET(get_type, \
+ NM_META_ACCESSOR_GET_TYPE_PARSABLE, \
+ NM_META_ACCESSOR_GET_TYPE_PRETTY)) { \
+ nm_assert_not_reached(); \
+ return NULL; \
+ } \
+ } \
+ G_STMT_END;
+
+#define RETURN_STR_TO_FREE(val) \
+ G_STMT_START \
+ { \
+ char *_val = (val); \
+ \
+ return ((*(out_to_free)) = _val); \
+ } \
+ G_STMT_END
+
+#define RETURN_STR_TEMPORARY(val) \
+ G_STMT_START \
+ { \
+ const char *_val = (val); \
+ \
+ if (_val == NULL) \
+ return NULL; \
+ if (_val[0] == '\0') \
+ return ""; \
+ return ((*(out_to_free)) = g_strdup(_val)); \
+ } \
+ G_STMT_END
+
+static gboolean
+_gobject_property_is_default(NMSetting *setting, const char *prop_name)
+{
+ nm_auto_unset_gvalue GValue v = G_VALUE_INIT;
+ GParamSpec * pspec;
+ GHashTable * ht;
+ char ** strv;
+
+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), prop_name);
+ if (!G_IS_PARAM_SPEC(pspec))
+ g_return_val_if_reached(FALSE);
+
+ g_value_init(&v, pspec->value_type);
+ g_object_get_property(G_OBJECT(setting), prop_name, &v);
+
+ if (pspec->value_type == G_TYPE_STRV) {
+ strv = g_value_get_boxed(&v);
+ return !strv || !strv[0];
+ } else if (pspec->value_type == G_TYPE_HASH_TABLE) {
+ ht = g_value_get_boxed(&v);
+ return !ht || !g_hash_table_size(ht);
+ }
+
+ return g_param_value_defaults(pspec, &v);
+}
+
+static gboolean
+_gobject_property_reset(NMSetting *setting, const char *prop_name, gboolean reset_default)
+{
+ nm_auto_unset_gvalue GValue v = G_VALUE_INIT;
+ GParamSpec * pspec;
+
+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), prop_name);
+ if (!G_IS_PARAM_SPEC(pspec))
+ g_return_val_if_reached(FALSE);
+
+ g_value_init(&v, pspec->value_type);
+ if (reset_default)
+ g_param_value_set_default(pspec, &v);
+ g_object_set_property(G_OBJECT(setting), prop_name, &v);
+ return TRUE;
+}
+
+static gboolean
+_gobject_property_reset_default(NMSetting *setting, const char *prop_name)
+{
+ return _gobject_property_reset(setting, prop_name, TRUE);
+}
+
+static const char *
+_coerce_str_emptyunset(NMMetaAccessorGetType get_type,
+ gboolean is_default,
+ const char * cstr,
+ char ** out_str)
+{
+ nm_assert(out_str && !*out_str);
+ nm_assert((!is_default && cstr && cstr[0] != '\0') || NM_IN_STRSET(cstr, NULL, ""));
+
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) {
+ if (!cstr || cstr[0] == '\0') {
+ if (is_default)
+ return "";
+ else
+ return "\"\"";
+ }
+ nm_assert(!is_default);
+ return (*out_str = g_strdup_printf("\"%s\"", cstr));
+ }
+
+ /* we coerce NULL/"" to either "" or " ". */
+ if (!cstr || cstr[0] == '\0') {
+ if (is_default)
+ return "";
+ else
+ return " ";
+ }
+ nm_assert(!is_default);
+ return cstr;
+}
+
+#define RETURN_STR_EMPTYUNSET(get_type, is_default, cstr) \
+ G_STMT_START \
+ { \
+ char * _str = NULL; \
+ const char *_cstr; \
+ \
+ _cstr = _coerce_str_emptyunset((get_type), (is_default), (cstr), &_str); \
+ if (_str) \
+ RETURN_STR_TO_FREE(_str); \
+ RETURN_STR_TEMPORARY(_cstr); \
+ } \
+ G_STMT_END
+
+static gboolean
+_is_default(const NMMetaPropertyInfo *property_info, NMSetting *setting)
+{
+ if (property_info->property_typ_data && property_info->property_typ_data->is_default_fcn)
+ return !!(property_info->property_typ_data->is_default_fcn(setting));
+
+ return _gobject_property_is_default(setting, property_info->property_name);
+}
+
+static gconstpointer
+_get_fcn_gobject_impl(const NMMetaPropertyInfo *property_info,
+ NMSetting * setting,
+ NMMetaAccessorGetType get_type,
+ gboolean handle_emptyunset,
+ gboolean * out_is_default,
+ gpointer * out_to_free)
+{
+ const char * cstr;
+ GType gtype_prop;
+ nm_auto_unset_gvalue GValue val = G_VALUE_INIT;
+ gboolean is_default;
+ gboolean glib_handles_str_transform;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ is_default = _is_default(property_info, setting);
+
+ NM_SET_OUT(out_is_default, is_default);
+
+ gtype_prop = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name);
+
+ glib_handles_str_transform =
+ !NM_IN_SET(gtype_prop, G_TYPE_BOOLEAN, G_TYPE_STRV, G_TYPE_BYTES, G_TYPE_HASH_TABLE);
+
+ if (glib_handles_str_transform) {
+ /* We rely on the type conversion of the gobject property to string. */
+ g_value_init(&val, G_TYPE_STRING);
+ } else
+ g_value_init(&val, gtype_prop);
+
+ g_object_get_property(G_OBJECT(setting), property_info->property_name, &val);
+
+ /* Currently, only one particular property asks us to "handle_emptyunset".
+ * So, don't implement it (yet) for the other types, where it's unneeded. */
+ nm_assert(!handle_emptyunset || (gtype_prop == G_TYPE_STRV && !glib_handles_str_transform));
+
+ if (gtype_prop == G_TYPE_STRING) {
+ nm_assert(glib_handles_str_transform);
+ nm_assert(!handle_emptyunset);
+ if (property_info->property_typ_data
+ && property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) {
+ /* This string property can both be empty and NULL. We need to
+ * signal them differently. */
+ cstr = g_value_get_string(&val);
+ nm_assert((!!is_default) == (cstr == NULL));
+ RETURN_STR_EMPTYUNSET(get_type, is_default, NULL);
+ }
+ }
+
+ if (glib_handles_str_transform)
+ RETURN_STR_TEMPORARY(g_value_get_string(&val));
+
+ if (gtype_prop == G_TYPE_BOOLEAN) {
+ gboolean b;
+
+ b = g_value_get_boolean(&val);
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ cstr = b ? _("yes") : _("no");
+ else
+ cstr = b ? "yes" : "no";
+ return cstr;
+ }
+
+ if (gtype_prop == G_TYPE_STRV) {
+ const char *const *strv;
+
+ strv = g_value_get_boxed(&val);
+ if (strv && strv[0])
+ RETURN_STR_TO_FREE(g_strjoinv(",", (char **) strv));
+
+ if (handle_emptyunset) {
+ /* we need to express empty lists from unset lists differently. */
+ RETURN_STR_EMPTYUNSET(get_type, is_default, NULL);
+ }
+
+ return "";
+ }
+
+ if (gtype_prop == G_TYPE_BYTES) {
+ char *str;
+
+ str = bytes_to_string(g_value_get_boxed(&val));
+ NM_SET_OUT(out_is_default, !str || !str[0]);
+ RETURN_STR_TO_FREE(str);
+ }
+
+ if (gtype_prop == G_TYPE_HASH_TABLE) {
+ GHashTable * strdict;
+ gs_free const char **keys = NULL;
+ GString * str;
+ gsize i;
+
+ nm_assert(property_info->setting_info
+ == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_WIRED]
+ && NM_IN_STRSET(property_info->property_name, NM_SETTING_WIRED_S390_OPTIONS));
+ nm_assert(property_info->property_type->set_fcn == _set_fcn_optionlist);
+
+ strdict = g_value_get_boxed(&val);
+ keys = nm_utils_strdict_get_keys(strdict, TRUE, NULL);
+ if (!keys)
+ return NULL;
+
+ str = g_string_new(NULL);
+ for (i = 0; keys[i]; i++) {
+ const char * key = keys[i];
+ const char * v = g_hash_table_lookup(strdict, key);
+ gs_free char *escaped_key = NULL;
+ gs_free char *escaped_val = NULL;
+
+ if (str->len > 0)
+ g_string_append_c(str, ',');
+ g_string_append(str, nm_utils_escaped_tokens_options_escape_key(key, &escaped_key));
+ g_string_append_c(str, '=');
+ g_string_append(str, nm_utils_escaped_tokens_options_escape_val(v, &escaped_val));
+ }
+ RETURN_STR_TO_FREE(g_string_free(str, FALSE));
+ }
+
+ nm_assert_not_reached();
+ return NULL;
+}
+
+static gconstpointer _get_fcn_gobject(ARGS_GET_FCN)
+{
+ return _get_fcn_gobject_impl(property_info,
+ setting,
+ get_type,
+ FALSE,
+ out_is_default,
+ out_to_free);
+}
+
+static gconstpointer _get_fcn_gobject_int(ARGS_GET_FCN)
+{
+ GParamSpec * pspec;
+ nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
+ gboolean is_uint64 = FALSE;
+ NMMetaSignUnsignInt64 v;
+ guint base = 10;
+ const NMMetaUtilsIntValueInfo *value_infos;
+ char * return_str;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)),
+ property_info->property_name);
+ if (!G_IS_PARAM_SPEC(pspec))
+ g_return_val_if_reached(FALSE);
+
+ g_value_init(&gval, pspec->value_type);
+ g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval);
+ NM_SET_OUT(out_is_default, g_param_value_defaults(pspec, &gval));
+ switch (pspec->value_type) {
+ case G_TYPE_INT:
+ v.i64 = g_value_get_int(&gval);
+ break;
+ case G_TYPE_UINT:
+ v.u64 = g_value_get_uint(&gval);
+ is_uint64 = TRUE;
+ break;
+ case G_TYPE_INT64:
+ v.i64 = g_value_get_int64(&gval);
+ break;
+ case G_TYPE_UINT64:
+ v.u64 = g_value_get_uint64(&gval);
+ is_uint64 = TRUE;
+ break;
+ default:
+ g_return_val_if_reached(NULL);
+ break;
+ }
+
+ if (property_info->property_typ_data
+ && property_info->property_typ_data->subtype.gobject_int.base > 0) {
+ base = property_info->property_typ_data->subtype.gobject_int.base;
+ }
+
+ switch (base) {
+ case 10:
+ if (is_uint64)
+ return_str = g_strdup_printf("%" G_GUINT64_FORMAT, v.u64);
+ else
+ return_str = g_strdup_printf("%" G_GINT64_FORMAT, v.i64);
+ break;
+ case 16:
+ if (is_uint64)
+ return_str = g_strdup_printf("0x%" G_GINT64_MODIFIER "x", v.u64);
+ else
+ return_str = g_strdup_printf("0x%" G_GINT64_MODIFIER "x", (guint64) v.i64);
+ break;
+ default:
+ return_str = NULL;
+ g_assert_not_reached();
+ }
+
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY && property_info->property_typ_data
+ && (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) {
+ for (; value_infos->nick; value_infos++) {
+ if ((is_uint64 && value_infos->value.u64 == v.u64)
+ || (!is_uint64 && value_infos->value.i64 == v.i64)) {
+ gs_free char *old_str = return_str;
+
+ return_str = g_strdup_printf("%s (%s)", old_str, value_infos->nick);
+ break;
+ }
+ }
+ }
+
+ RETURN_STR_TO_FREE(return_str);
+}
+
+static gconstpointer _get_fcn_gobject_mtu(ARGS_GET_FCN)
+{
+ guint32 mtu;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ if (!property_info->property_typ_data || !property_info->property_typ_data->subtype.mtu.get_fcn)
+ return _get_fcn_gobject_impl(property_info,
+ setting,
+ get_type,
+ FALSE,
+ out_is_default,
+ out_to_free);
+
+ mtu = property_info->property_typ_data->subtype.mtu.get_fcn(setting);
+ if (mtu == 0) {
+ NM_SET_OUT(out_is_default, TRUE);
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ return _("auto");
+ return "auto";
+ }
+ RETURN_STR_TO_FREE(g_strdup_printf("%u", (unsigned) mtu));
+}
+
+static gconstpointer _get_fcn_gobject_secret_flags(ARGS_GET_FCN)
+{
+ guint v;
+ GValue val = G_VALUE_INIT;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ g_value_init(&val, G_TYPE_UINT);
+ g_object_get_property(G_OBJECT(setting), property_info->property_name, &val);
+ v = g_value_get_uint(&val);
+ g_value_unset(&val);
+ RETURN_STR_TO_FREE(secret_flags_to_string(v, get_type));
+}
+
+static gconstpointer _get_fcn_gobject_enum(ARGS_GET_FCN)
+{
+ GType gtype = 0;
+ nm_auto_unref_gtypeclass GTypeClass *gtype_class = NULL;
+ nm_auto_unref_gtypeclass GTypeClass *gtype_prop_class = NULL;
+ const struct _NMUtilsEnumValueInfo * value_infos = NULL;
+ gboolean has_gtype = FALSE;
+ nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
+ gint64 v;
+ gboolean format_numeric = FALSE;
+ gboolean format_numeric_hex = FALSE;
+ gboolean format_numeric_hex_unknown = FALSE;
+ gboolean format_text = FALSE;
+ gboolean format_text_l10n = FALSE;
+ gs_free char * s = NULL;
+ char s_numeric[64];
+ GParamSpec * pspec;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ if (property_info->property_typ_data) {
+ if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) {
+ gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype();
+ has_gtype = TRUE;
+ }
+ }
+
+ if (property_info->property_typ_data && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY
+ && NM_FLAGS_ANY(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N)) {
+ format_numeric_hex = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX);
+ format_numeric = format_numeric_hex
+ || NM_FLAGS_HAS(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC);
+ format_text_l10n = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N);
+ format_text = format_text_l10n
+ || NM_FLAGS_HAS(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT);
+ } else if (property_info->property_typ_data && get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY
+ && NM_FLAGS_ANY(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT)) {
+ format_numeric_hex = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX);
+ format_numeric = format_numeric
+ && NM_FLAGS_HAS(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC);
+ format_text = NM_FLAGS_HAS(property_info->property_typ_data->typ_flags,
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT);
+ } else if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) {
+ /* by default, output in format "%u (%s)" (with hex for flags and l10n). */
+ format_numeric = TRUE;
+ format_numeric_hex_unknown = TRUE;
+ format_text = TRUE;
+ format_text_l10n = TRUE;
+ } else {
+ /* by default, output only numeric (with hex for flags). */
+ format_numeric = TRUE;
+ format_numeric_hex_unknown = TRUE;
+ }
+
+ nm_assert(format_text || format_numeric);
+
+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(setting), property_info->property_name);
+ g_return_val_if_fail(pspec, NULL);
+
+ g_value_init(&gval, pspec->value_type);
+ g_object_get_property(G_OBJECT(setting), property_info->property_name, &gval);
+ NM_SET_OUT(out_is_default, g_param_value_defaults(pspec, &gval));
+
+ if (pspec->value_type == G_TYPE_INT
+ || (G_TYPE_IS_CLASSED(pspec->value_type)
+ && G_IS_ENUM_CLASS(
+ (gtype_prop_class ?: (gtype_prop_class = g_type_class_ref(pspec->value_type)))))) {
+ if (pspec->value_type == G_TYPE_INT) {
+ if (!has_gtype)
+ g_return_val_if_reached(NULL);
+ v = g_value_get_int(&gval);
+ } else
+ v = g_value_get_enum(&gval);
+ } else if (pspec->value_type == G_TYPE_UINT
+ || (G_TYPE_IS_CLASSED(pspec->value_type)
+ && G_IS_FLAGS_CLASS(
+ (gtype_prop_class
+ ?: (gtype_prop_class = g_type_class_ref(pspec->value_type)))))) {
+ if (pspec->value_type == G_TYPE_UINT) {
+ if (!has_gtype)
+ g_return_val_if_reached(NULL);
+ v = g_value_get_uint(&gval);
+ } else
+ v = g_value_get_flags(&gval);
+ } else
+ g_return_val_if_reached(NULL);
+
+ if (!has_gtype) {
+ gtype = pspec->value_type;
+ gtype_class = g_steal_pointer(&gtype_prop_class);
+ }
+
+ nm_assert(({
+ nm_auto_unref_gtypeclass GTypeClass *t = NULL;
+
+ (G_TYPE_IS_CLASSED(gtype) && (t = g_type_class_ref(gtype))
+ && (G_IS_ENUM_CLASS(t) || G_IS_FLAGS_CLASS(t)));
+ }));
+
+ if (format_numeric && !format_text) {
+ s = format_numeric_hex
+ || (format_numeric_hex_unknown
+ && !G_IS_ENUM_CLASS(gtype_class ?: (gtype_class = g_type_class_ref(gtype))))
+ ? g_strdup_printf("0x%" G_GINT64_MODIFIER "x", v)
+ : g_strdup_printf("%" G_GINT64_FORMAT, v);
+ RETURN_STR_TO_FREE(g_steal_pointer(&s));
+ }
+
+ /* the gobject_enum.value_infos are currently ignored for the getter. They
+ * only declare additional aliases for the setter. */
+
+ if (property_info->property_typ_data)
+ value_infos = property_info->property_typ_data->subtype.gobject_enum.value_infos_get;
+ s = _nm_utils_enum_to_str_full(gtype, (int) v, ", ", value_infos);
+
+ if (!format_numeric)
+ RETURN_STR_TO_FREE(g_steal_pointer(&s));
+
+ if (format_numeric_hex
+ || (format_numeric_hex_unknown
+ && !G_IS_ENUM_CLASS(gtype_class ?: (gtype_class = g_type_class_ref(gtype)))))
+ nm_sprintf_buf(s_numeric, "0x%" G_GINT64_MODIFIER "x", v);
+ else
+ nm_sprintf_buf(s_numeric, "%" G_GINT64_FORMAT, v);
+
+ if (nm_streq0(s, s_numeric))
+ RETURN_STR_TO_FREE(g_steal_pointer(&s));
+
+ if (format_text_l10n)
+ RETURN_STR_TO_FREE(g_strdup_printf(_("%s (%s)"), s_numeric, s));
+ else
+ RETURN_STR_TO_FREE(g_strdup_printf("%s (%s)", s_numeric, s));
+}
+
+/*****************************************************************************/
+
+static gboolean _set_fcn_gobject_string(ARGS_SET_FCN)
+{
+ gs_free char *to_free = NULL;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (property_info->property_typ_data) {
+ if (property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) {
+ if (value && value[0] && NM_STRCHAR_ALL(value, ch, ch == ' ')) {
+ /* this string property can both be %NULL and empty. To express that, we coerce
+ * a value of all whitespaces to dropping the first whitespace. That means,
+ * " " gives "", " " gives " ", and so on.
+ *
+ * This way the user can set the string value to "" (meaning NULL) and to
+ * " " (meaning ""), and any other string.
+ *
+ * This is and non-obvious escaping mechanism. But out of all the possible
+ * solutions, it seems the most sensible one. */
+ value++;
+ }
+ }
+ if (property_info->property_typ_data->subtype.gobject_string.validate_fcn) {
+ value = property_info->property_typ_data->subtype.gobject_string.validate_fcn(value,
+ &to_free,
+ error);
+ if (!value)
+ return FALSE;
+ } else if (property_info->property_typ_data->values_static) {
+ value =
+ nmc_string_is_valid(value,
+ (const char **) property_info->property_typ_data->values_static,
+ error);
+ if (!value)
+ return FALSE;
+ }
+ }
+ g_object_set(setting, property_info->property_name, value, NULL);
+ return TRUE;
+}
+
+static gboolean _set_fcn_gobject_bool(ARGS_SET_FCN)
+{
+ gboolean val_bool;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (!nmc_string_to_bool(value, &val_bool, error))
+ return FALSE;
+
+ g_object_set(setting, property_info->property_name, val_bool, NULL);
+ return TRUE;
+}
+
+static gboolean _set_fcn_gobject_int(ARGS_SET_FCN)
+{
+ int errsv;
+ const GParamSpec * pspec;
+ nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
+ gboolean is_uint64;
+ NMMetaSignUnsignInt64 v;
+ gboolean has_minmax = FALSE;
+ NMMetaSignUnsignInt64 min = {0};
+ NMMetaSignUnsignInt64 max = {0};
+ guint base = 10;
+ const NMMetaUtilsIntValueInfo *value_infos;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)),
+ property_info->property_name);
+ if (!G_IS_PARAM_SPEC(pspec))
+ g_return_val_if_reached(FALSE);
+
+ is_uint64 = NM_IN_SET(pspec->value_type, G_TYPE_UINT, G_TYPE_UINT64);
+
+ if (property_info->property_typ_data) {
+ if (value
+ && (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) {
+ gs_free char *vv_free = NULL;
+ const char * vv;
+
+ vv = nm_strstrip_avoid_copy_a(300, value, &vv_free);
+ for (; value_infos->nick; value_infos++) {
+ if (nm_streq(value_infos->nick, vv)) {
+ v = value_infos->value;
+ goto have_value_from_nick;
+ }
+ }
+ }
+
+ if (property_info->property_typ_data->subtype.gobject_int.base > 0)
+ base = property_info->property_typ_data->subtype.gobject_int.base;
+
+ if ((is_uint64
+ && (property_info->property_typ_data->subtype.gobject_int.min.u64
+ || property_info->property_typ_data->subtype.gobject_int.max.u64))
+ || (!is_uint64
+ && (property_info->property_typ_data->subtype.gobject_int.min.i64
+ || property_info->property_typ_data->subtype.gobject_int.max.i64))) {
+ min = property_info->property_typ_data->subtype.gobject_int.min;
+ max = property_info->property_typ_data->subtype.gobject_int.max;
+ has_minmax = TRUE;
+ }
+ }
+
+ if (!has_minmax) {
+ switch (pspec->value_type) {
+ case G_TYPE_INT:
+ {
+ const GParamSpecInt *p = (GParamSpecInt *) pspec;
+
+ min.i64 = p->minimum;
+ max.i64 = p->maximum;
+ } break;
+ case G_TYPE_UINT:
+ {
+ const GParamSpecUInt *p = (GParamSpecUInt *) pspec;
+
+ min.u64 = p->minimum;
+ max.u64 = p->maximum;
+ } break;
+ case G_TYPE_INT64:
+ {
+ const GParamSpecInt64 *p = (GParamSpecInt64 *) pspec;
+
+ min.i64 = p->minimum;
+ max.i64 = p->maximum;
+ } break;
+ case G_TYPE_UINT64:
+ {
+ const GParamSpecUInt64 *p = (GParamSpecUInt64 *) pspec;
+
+ min.u64 = p->minimum;
+ max.u64 = p->maximum;
+ } break;
+ default:
+ g_return_val_if_reached(FALSE);
+ }
+ }
+
+ if (is_uint64)
+ v.u64 = _nm_utils_ascii_str_to_uint64(value, base, min.u64, max.u64, 0);
+ else
+ v.i64 = _nm_utils_ascii_str_to_int64(value, base, min.i64, max.i64, 0);
+
+ if ((errsv = errno) != 0) {
+ if (errsv == ERANGE) {
+ if (is_uint64) {
+ g_set_error(
+ error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is out of range [%" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT "]"),
+ value,
+ min.u64,
+ max.u64);
+ } else {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is out of range [%" G_GINT64_FORMAT ", %" G_GINT64_FORMAT "]"),
+ value,
+ min.i64,
+ max.i64);
+ }
+ } else {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is not a valid number"),
+ value);
+ }
+ return FALSE;
+ }
+
+have_value_from_nick:
+
+ g_value_init(&gval, pspec->value_type);
+ switch (pspec->value_type) {
+ case G_TYPE_INT:
+ g_value_set_int(&gval, v.i64);
+ break;
+ case G_TYPE_UINT:
+ g_value_set_uint(&gval, v.u64);
+ break;
+ case G_TYPE_INT64:
+ g_value_set_int64(&gval, v.i64);
+ break;
+ case G_TYPE_UINT64:
+ g_value_set_uint64(&gval, v.u64);
+ break;
+ default:
+ g_return_val_if_reached(FALSE);
+ break;
+ }
+
+ /* Validate the number according to the property spec */
+ if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, error))
+ g_return_val_if_reached(FALSE);
+
+ return TRUE;
+}
+
+static gboolean _set_fcn_gobject_mtu(ARGS_SET_FCN)
+{
+ nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
+ const GParamSpec * pspec;
+ gint64 v;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (nm_streq(value, "auto"))
+ value = "0";
+
+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)),
+ property_info->property_name);
+ if (!pspec || pspec->value_type != G_TYPE_UINT)
+ g_return_val_if_reached(FALSE);
+
+ v = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT32, -1);
+ if (v < 0) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is out of range [0, %u]"),
+ value,
+ (unsigned) G_MAXUINT32);
+ return FALSE;
+ }
+
+ g_value_init(&gval, pspec->value_type);
+ g_value_set_uint(&gval, v);
+
+ if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, error))
+ g_return_val_if_reached(FALSE);
+
+ return TRUE;
+}
+
+/* Ideally we'll be able to get this from a public header. */
+#ifndef IEEE802154_ADDR_LEN
+ #define IEEE802154_ADDR_LEN 8
+#endif
+
+static gboolean _set_fcn_gobject_mac(ARGS_SET_FCN)
+{
+ NMMetaPropertyTypeMacMode mode;
+ gboolean valid;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (property_info->property_typ_data)
+ mode = property_info->property_typ_data->subtype.mac.mode;
+ else
+ mode = NM_META_PROPERTY_TYPE_MAC_MODE_DEFAULT;
+
+ if (mode == NM_META_PROPERTY_TYPE_MAC_MODE_INFINIBAND) {
+ valid = nm_utils_hwaddr_valid(value, INFINIBAND_ALEN);
+ } else if (mode == NM_META_PROPERTY_TYPE_MAC_MODE_WPAN) {
+ valid = nm_utils_hwaddr_valid(value, IEEE802154_ADDR_LEN);
+ } else {
+ valid =
+ nm_utils_hwaddr_valid(value, ETH_ALEN)
+ || (mode == NM_META_PROPERTY_TYPE_MAC_MODE_CLONED && NM_CLONED_MAC_IS_SPECIAL(value));
+ }
+
+ if (!valid) {
+ g_set_error(error, 1, 0, _("'%s' is not a valid Ethernet MAC"), value);
+ return FALSE;
+ }
+
+ g_object_set(setting, property_info->property_name, value, NULL);
+ return TRUE;
+}
+
+static gboolean _set_fcn_gobject_enum(ARGS_SET_FCN)
+{
+ GType gtype = 0;
+ GType gtype_prop;
+ gboolean has_gtype = FALSE;
+ nm_auto_unset_gvalue GValue gval = G_VALUE_INIT;
+ nm_auto_unref_gtypeclass GTypeClass *gtype_prop_class = NULL;
+ nm_auto_unref_gtypeclass GTypeClass *gtype_class = NULL;
+ gboolean is_flags;
+ int v;
+
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (property_info->property_typ_data) {
+ if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) {
+ gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype();
+ has_gtype = TRUE;
+ }
+ }
+
+ gtype_prop = _gobject_property_get_gtype(G_OBJECT(setting), property_info->property_name);
+
+ if (has_gtype && NM_IN_SET(gtype_prop, G_TYPE_INT, G_TYPE_UINT) && G_TYPE_IS_CLASSED(gtype)
+ && (gtype_prop_class = g_type_class_ref(gtype))
+ && ((is_flags = G_IS_FLAGS_CLASS(gtype_prop_class)) || G_IS_ENUM_CLASS(gtype_prop_class))) {
+ /* valid */
+ } else if (!has_gtype && G_TYPE_IS_CLASSED(gtype_prop)
+ && (gtype_prop_class = g_type_class_ref(gtype_prop))
+ && ((is_flags = G_IS_FLAGS_CLASS(gtype_prop_class))
+ || G_IS_ENUM_CLASS(gtype_prop_class))) {
+ gtype = gtype_prop;
+ } else
+ g_return_val_if_reached(FALSE);
+
+ if (!_nm_utils_enum_from_str_full(
+ gtype,
+ value,
+ &v,
+ NULL,
+ property_info->property_typ_data
+ ? property_info->property_typ_data->subtype.gobject_enum.value_infos
+ : NULL))
+ goto fail;
+
+ if (property_info->property_typ_data
+ && property_info->property_typ_data->subtype.gobject_enum.pre_set_notify) {
+ property_info->property_typ_data->subtype.gobject_enum.pre_set_notify(property_info,
+ environment,
+ environment_user_data,
+ setting,
+ v);
+ }
+
+ gtype_class = g_type_class_ref(gtype);
+
+ if (G_IS_FLAGS_CLASS(gtype_class) && !_SET_FCN_DO_SET_ALL(modifier, value)) {
+ nm_auto_unset_gvalue GValue int_value = {};
+ guint v_flag;
+
+ g_value_init(&int_value, G_TYPE_UINT);
+ g_object_get_property(G_OBJECT(setting), property_info->property_name, &int_value);
+ v_flag = g_value_get_uint(&int_value);
+
+ if (_SET_FCN_DO_REMOVE(modifier, value))
+ v = (int) (v_flag & ~((guint) v));
+ else
+ v = (int) (v_flag | ((guint) v));
+ }
+
+ g_value_init(&gval, gtype_prop);
+ if (gtype_prop == G_TYPE_INT)
+ g_value_set_int(&gval, v);
+ else if (gtype_prop == G_TYPE_UINT)
+ g_value_set_uint(&gval, v);
+ else if (is_flags) {
+ nm_assert(G_IS_FLAGS_CLASS(gtype_prop_class));
+ g_value_set_flags(&gval, v);
+ } else {
+ nm_assert(G_IS_ENUM_CLASS(gtype_prop_class));
+ g_value_set_enum(&gval, v);
+ }
+
+ if (!nm_g_object_set_property(G_OBJECT(setting), property_info->property_name, &gval, NULL))
+ goto fail;
+
+ return TRUE;
+
+fail:
+ if (error) {
+ gs_free const char **valid_all = NULL;
+ gs_free const char * valid_str = NULL;
+ gboolean has_minmax = FALSE;
+ int min = G_MININT;
+ int max = G_MAXINT;
+
+ if (property_info->property_typ_data) {
+ if (property_info->property_typ_data->subtype.gobject_enum.min
+ || property_info->property_typ_data->subtype.gobject_enum.max) {
+ min = property_info->property_typ_data->subtype.gobject_enum.min;
+ max = property_info->property_typ_data->subtype.gobject_enum.max;
+ has_minmax = TRUE;
+ }
+ }
+
+ if (!has_minmax && is_flags) {
+ min = 0;
+ max = (int) G_MAXUINT;
+ }
+
+ valid_all = nm_utils_enum_get_values(gtype, min, max);
+ valid_str = g_strjoinv(",", (char **) valid_all);
+ if (is_flags) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid option '%s', use a combination of [%s]"),
+ value,
+ valid_str);
+ } else {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid option '%s', use one of [%s]"),
+ value,
+ valid_str);
+ }
+ }
+ return FALSE;
+}
+
+/*****************************************************************************/
+
+static const char *const *_values_fcn_gobject_enum(ARGS_VALUES_FCN)
+{
+ GType gtype = 0;
+ gboolean has_gtype = FALSE;
+ gboolean has_minmax = FALSE;
+ int min = G_MININT;
+ int max = G_MAXINT;
+ char ** v;
+
+ if (property_info->property_typ_data) {
+ if (property_info->property_typ_data->subtype.gobject_enum.min
+ || property_info->property_typ_data->subtype.gobject_enum.max) {
+ min = property_info->property_typ_data->subtype.gobject_enum.min;
+ max = property_info->property_typ_data->subtype.gobject_enum.max;
+ has_minmax = TRUE;
+ }
+ if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) {
+ gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype();
+ has_gtype = TRUE;
+ }
+ }
+
+ if (!has_gtype) {
+ gtype = _gtype_property_get_gtype(property_info->setting_info->general->get_setting_gtype(),
+ property_info->property_name);
+ }
+
+ if (!has_minmax && G_TYPE_IS_CLASSED(gtype)) {
+ nm_auto_unref_gtypeclass GTypeClass *class = NULL;
+
+ class = g_type_class_ref(gtype);
+ if (G_IS_FLAGS_CLASS(class)) {
+ min = 0;
+ max = (int) G_MAXUINT;
+ }
+ }
+
+ /* the gobject_enum.value_infos are currently ignored for the list of
+ * values. They only declare additional (hidden) aliases for the setter. */
+
+ v = nm_utils_strv_make_deep_copied(nm_utils_enum_get_values(gtype, min, max));
+ return (const char *const *) (*out_to_free = v);
+}
+
+/*****************************************************************************/
+
+static const char *const *_complete_fcn_gobject_bool(ARGS_COMPLETE_FCN)
+{
+ static const char *const v[] = {
+ "true",
+ "false",
+ "on",
+ "off",
+ "1",
+ "0",
+ "yes",
+ "no",
+ NULL,
+ };
+
+ if (!text || !text[0])
+ return &v[6];
+ return v;
+}
+
+static const char *const *_complete_fcn_gobject_devices(ARGS_COMPLETE_FCN)
+{
+ NMDevice *const *devices = NULL;
+ guint i, j;
+ guint len = 0;
+ char ** ifnames;
+
+ if (environment && environment->get_nm_devices) {
+ devices = environment->get_nm_devices(environment, environment_user_data, &len);
+ }
+
+ if (len == 0)
+ return NULL;
+
+ ifnames = g_new(char *, len + 1);
+ for (i = 0, j = 0; i < len; i++) {
+ const char *ifname;
+
+ nm_assert(NM_IS_DEVICE(devices[i]));
+
+ ifname = nm_device_get_iface(devices[i]);
+ if (ifname)
+ ifnames[j++] = g_strdup(ifname);
+ }
+ ifnames[j++] = NULL;
+
+ *out_to_free = ifnames;
+ return (const char *const *) ifnames;
+}
+
+/*****************************************************************************/
+
+static char *
+wep_key_type_to_string(NMWepKeyType type)
+{
+ switch (type) {
+ case NM_WEP_KEY_TYPE_KEY:
+ return g_strdup_printf(_("%d (key)"), type);
+ case NM_WEP_KEY_TYPE_PASSPHRASE:
+ return g_strdup_printf(_("%d (passphrase)"), type);
+ case NM_WEP_KEY_TYPE_UNKNOWN:
+ default:
+ return g_strdup_printf(_("%d (unknown)"), type);
+ }
+}
+
+static char *
+vlan_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type)
+{
+ GString *flag_str;
+
+ if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ return g_strdup_printf("%u", flags);
+
+ if (flags == 0)
+ return g_strdup(_("0 (NONE)"));
+
+ flag_str = g_string_new(NULL);
+ g_string_printf(flag_str, "%d (", flags);
+
+ if (flags & NM_VLAN_FLAG_REORDER_HEADERS)
+ g_string_append(flag_str, _("REORDER_HEADERS, "));
+ if (flags & NM_VLAN_FLAG_GVRP)
+ g_string_append(flag_str, _("GVRP, "));
+ if (flags & NM_VLAN_FLAG_LOOSE_BINDING)
+ g_string_append(flag_str, _("LOOSE_BINDING, "));
+ if (flags & NM_VLAN_FLAG_MVRP)
+ g_string_append(flag_str, _("MVRP, "));
+
+ if (flag_str->str[flag_str->len - 1] == '(')
+ g_string_append(flag_str, _("unknown"));
+ else
+ g_string_truncate(flag_str, flag_str->len - 2); /* chop off trailing ', ' */
+
+ g_string_append_c(flag_str, ')');
+
+ return g_string_free(flag_str, FALSE);
+}
+
+static char *
+secret_flags_to_string(guint32 flags, NMMetaAccessorGetType get_type)
+{
+ GString *flag_str;
+
+ if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ return g_strdup_printf("%u", flags);
+
+ if (flags == 0)
+ return g_strdup(_("0 (none)"));
+
+ flag_str = g_string_new(NULL);
+ g_string_printf(flag_str, "%u (", flags);
+
+ if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)
+ g_string_append(flag_str, _("agent-owned, "));
+ if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)
+ g_string_append(flag_str, _("not saved, "));
+ if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)
+ g_string_append(flag_str, _("not required, "));
+
+ if (flag_str->str[flag_str->len - 1] == '(')
+ g_string_append(flag_str, _("unknown"));
+ else
+ g_string_truncate(flag_str, flag_str->len - 2); /* chop off trailing ', ' */
+
+ g_string_append_c(flag_str, ')');
+
+ return g_string_free(flag_str, FALSE);
+}
+
+static const char *
+_multilist_do_validate(const NMMetaPropertyInfo *property_info,
+ NMSetting * setting,
+ const char * item,
+ GError ** error)
+{
+ if (property_info->property_typ_data->values_static) {
+ nm_assert(!property_info->property_typ_data->subtype.multilist.validate_fcn);
+ return nmc_string_is_valid(item,
+ (const char **) property_info->property_typ_data->values_static,
+ error);
+ }
+ if (property_info->property_typ_data->subtype.multilist.validate_fcn) {
+ return property_info->property_typ_data->subtype.multilist.validate_fcn(item, error);
+ }
+ if (property_info->property_typ_data->subtype.multilist.validate2_fcn) {
+ return property_info->property_typ_data->subtype.multilist.validate2_fcn(setting,
+ item,
+ error);
+ }
+
+ return item;
+}
+
+static gconstpointer _get_fcn_multilist(ARGS_GET_FCN)
+{
+ return _get_fcn_gobject_impl(
+ property_info,
+ setting,
+ get_type,
+ property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn != NULL,
+ out_is_default,
+ out_to_free);
+}
+
+static gboolean
+_multilist_clear_property(const NMMetaPropertyInfo *property_info,
+ NMSetting * setting,
+ gboolean is_set /* or else set default */)
+{
+ if (property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn) {
+ property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn(setting, is_set);
+ return TRUE;
+ }
+ if (property_info->property_typ_data->subtype.multilist.clear_all_fcn) {
+ property_info->property_typ_data->subtype.multilist.clear_all_fcn(setting);
+ return TRUE;
+ }
+ return _gobject_property_reset(setting, property_info->property_name, FALSE);
+}
+
+static gboolean _set_fcn_multilist(ARGS_SET_FCN)
+{
+ gs_free const char **strv = NULL;
+ gsize i, j, nstrv;
+
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value))
+ return _multilist_clear_property(property_info, setting, FALSE);
+
+ if (_SET_FCN_DO_REMOVE(modifier, value)
+ && (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32
+ || property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s
+ || property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u)) {
+ gs_free gint64 *indexes = NULL;
+
+ indexes = _value_str_as_index_list(value, &nstrv);
+ if (indexes) {
+ gint64 num;
+
+ if (property_info->property_typ_data->subtype.multilist.get_num_fcn_u32)
+ num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u32(setting);
+ else
+ num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u(setting);
+ for (i = 0; i < nstrv; i++) {
+ gint64 idx = indexes[i];
+
+ if (idx >= num)
+ continue;
+
+ if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32)
+ property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32(
+ setting,
+ idx);
+ else if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s)
+ property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s(setting,
+ idx);
+ else
+ property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u(setting,
+ idx);
+ }
+ return TRUE;
+ }
+ }
+
+ if (_SET_FCN_DO_SET_ALL(modifier, value)
+ && property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn
+ && value[0] == '\0')
+ return _multilist_clear_property(property_info, setting, FALSE);
+
+ strv = _value_strsplit(
+ value,
+ property_info->property_typ_data->subtype.multilist.strsplit_plain
+ ? VALUE_STRSPLIT_MODE_MULTILIST
+ : (property_info->property_typ_data->subtype.multilist.strsplit_with_spaces
+ ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES
+ : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS),
+ &nstrv);
+
+ j = 0;
+ for (i = 0; i < nstrv; i++) {
+ const char *item = strv[i];
+
+ item = _multilist_do_validate(property_info, setting, item, error);
+ if (!item)
+ return FALSE;
+ strv[j++] = item;
+ }
+ nstrv = j;
+
+ if (_SET_FCN_DO_SET_ALL(modifier, value))
+ _multilist_clear_property(property_info, setting, TRUE);
+ else if (property_info->property_typ_data->subtype.multilist.clear_emptyunset_fcn
+ && _is_default(property_info, setting)) {
+ /* the property is already the default. But we hav here a '+' / '-' modifier, so
+ * that always makes it non-default (empty) first. */
+ _multilist_clear_property(property_info, setting, TRUE);
+ }
+
+ for (i = 0; i < nstrv; i++) {
+ if (_SET_FCN_DO_REMOVE(modifier, value)) {
+ property_info->property_typ_data->subtype.multilist.remove_by_value_fcn(setting,
+ strv[i]);
+ } else {
+ if (property_info->property_typ_data->subtype.multilist.add2_fcn)
+ property_info->property_typ_data->subtype.multilist.add2_fcn(setting, strv[i]);
+ else
+ property_info->property_typ_data->subtype.multilist.add_fcn(setting, strv[i]);
+ }
+ }
+ return TRUE;
+}
+
+static gboolean _set_fcn_optionlist(ARGS_SET_FCN)
+{
+ gs_free const char **strv = NULL;
+ gs_free const char **strv_val = NULL;
+ gsize strv_len;
+ gsize i, nstrv;
+
+ nm_assert(!error || !*error);
+
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ nstrv = 0;
+ strv = nm_utils_escaped_tokens_options_split_list(value);
+ if (strv) {
+ strv_len = NM_PTRARRAY_LEN(strv);
+
+ strv_val = g_new(const char *, strv_len);
+ for (i = 0; strv[i]; i++) {
+ const char *opt_name;
+ const char *opt_value;
+
+ nm_utils_escaped_tokens_options_split((char *) strv[i], &opt_name, &opt_value);
+
+ if (property_info->property_type->values_fcn
+ || property_info->property_typ_data->values_static) {
+ gs_strfreev char **valid_options_to_free = NULL;
+ const char *const *valid_options;
+
+ if (property_info->property_type->values_fcn)
+ valid_options =
+ property_info->property_type->values_fcn(property_info,
+ &valid_options_to_free);
+ else
+ valid_options = property_info->property_typ_data->values_static;
+
+ opt_name = nmc_string_is_valid(opt_name, (const char **) valid_options, error);
+ if (!opt_name)
+ return FALSE;
+ }
+
+ if (opt_value) {
+ if (_SET_FCN_DO_REMOVE(modifier, value))
+ opt_value = NULL;
+ } else {
+ if (!_SET_FCN_DO_REMOVE(modifier, value)) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is not valid; use <option>=<value>"),
+ opt_name);
+ return FALSE;
+ }
+ }
+
+ if (opt_value && opt_value[0] == '\0'
+ && property_info->property_typ_data->subtype.optionlist.no_empty_value) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("cannot set empty \"%s\" option"),
+ opt_name);
+ return FALSE;
+ }
+
+ strv[nstrv] = opt_name;
+ strv_val[nstrv] = opt_value;
+ nstrv++;
+ }
+ }
+
+ if (_SET_FCN_DO_SET_ALL(modifier, value))
+ _gobject_property_reset(setting, property_info->property_name, FALSE);
+
+ for (i = 0; i < nstrv; i++) {
+ if (!property_info->property_typ_data->subtype.optionlist.set_fcn(setting,
+ strv[i],
+ strv_val[i],
+ error))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static char *
+flag_values_to_string(GFlagsValue *array, guint n)
+{
+ GString *str;
+ guint i;
+
+ str = g_string_new(NULL);
+ for (i = 0; i < n; i++)
+ g_string_append_printf(str, "%u, ", array[i].value);
+ if (str->len)
+ g_string_truncate(str, str->len - 2); /* chop off trailing ', ' */
+ return g_string_free(str, FALSE);
+}
+
+static gboolean
+validate_flags(NMSetting *setting, const char *prop, guint val, GError **error)
+{
+ GParamSpec *pspec;
+ GValue value = G_VALUE_INIT;
+ gboolean success = TRUE;
+
+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(setting)), prop);
+ g_assert(G_IS_PARAM_SPEC(pspec));
+
+ g_value_init(&value, pspec->value_type);
+ g_value_set_flags(&value, val);
+
+ if (g_param_value_validate(pspec, &value)) {
+ GParamSpecFlags *pspec_flags = (GParamSpecFlags *) pspec;
+ gs_free char * flag_values = NULL;
+
+ flag_values = flag_values_to_string(pspec_flags->flags_class->values,
+ pspec_flags->flags_class->n_values);
+
+ g_set_error(error,
+ 1,
+ 0,
+ _("'%u' flags are not valid; use combination of %s"),
+ val,
+ flag_values);
+ success = FALSE;
+ }
+ g_value_unset(&value);
+ return success;
+}
+
+static gboolean _set_fcn_gobject_flags(ARGS_SET_FCN)
+{
+ unsigned long val_int;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (!nmc_string_to_uint(value, TRUE, 0, G_MAXUINT, &val_int)) {
+ g_set_error(error, 1, 0, _("'%s' is not a valid number (or out of range)"), value);
+ return FALSE;
+ }
+
+ /* Validate the flags according to the property spec */
+ if (!validate_flags(setting, property_info->property_name, (guint) val_int, error))
+ return FALSE;
+
+ g_object_set(setting, property_info->property_name, (guint) val_int, NULL);
+ return TRUE;
+}
+
+static gboolean _set_fcn_gobject_ssid(ARGS_SET_FCN)
+{
+ gs_unref_bytes GBytes *ssid = NULL;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (strlen(value) > 32) {
+ g_set_error(error, 1, 0, _("'%s' is not valid"), value);
+ return FALSE;
+ }
+
+ ssid = g_bytes_new(value, strlen(value));
+ g_object_set(setting, property_info->property_name, ssid, NULL);
+ return TRUE;
+}
+
+static gboolean _set_fcn_gobject_ifname(ARGS_SET_FCN)
+{
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ g_object_set(setting, property_info->property_name, value, NULL);
+ return TRUE;
+}
+
+static gboolean _set_fcn_vpn_service_type(ARGS_SET_FCN)
+{
+ gs_free char *service_name = NULL;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ service_name = nm_vpn_plugin_info_list_find_service_type(nm_vpn_get_plugin_infos(), value);
+ g_object_set(setting, property_info->property_name, service_name ?: value, NULL);
+ return TRUE;
+}
+
+static const char *const *_complete_fcn_vpn_service_type(ARGS_COMPLETE_FCN)
+{
+ gsize i, j;
+ char **values;
+
+ values = nm_vpn_plugin_info_list_get_service_types(nm_vpn_get_plugin_infos(), FALSE, TRUE);
+ if (!values)
+ return NULL;
+
+ if (!text || !*text) {
+ /* If the prompt text is empty or contains no '.',
+ * filter out full names. */
+ for (i = 0, j = 0; values[i]; i++) {
+ if (strchr(values[i], '.')) {
+ g_free(values[i]);
+ continue;
+ }
+
+ if (i != j)
+ values[j] = values[i];
+ j++;
+ }
+ if (j)
+ values[j++] = NULL;
+ else {
+ g_free(values);
+ values = NULL;
+ }
+ }
+ return (const char *const *) (*out_to_free = values);
+}
+
+static const char *
+_multilist_validate_fcn_is_domain(const char *domain, GError **error)
+{
+ //FIXME: implement
+ return domain;
+}
+
+static const char *
+_multilist_validate_fcn_is_ipv4_addr_or_subnet(const char *value, GError **error)
+{
+ if (!nm_utils_parse_inaddr_prefix_bin(AF_INET, value, NULL, NULL, NULL)) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid IPv4 or subnet \"%s\""),
+ value);
+ return NULL;
+ }
+
+ return value;
+}
+
+static gboolean _set_fcn_gobject_bytes(ARGS_SET_FCN)
+{
+ gs_free char * val_strip_free = NULL;
+ gs_free const char **strv = NULL;
+ const char * val_strip;
+ const char ** iter;
+ gs_unref_bytes GBytes *bytes = NULL;
+ GByteArray * array;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ val_strip = nm_strstrip_avoid_copy_a(300, value, &val_strip_free);
+
+ /* First try hex string in the format of AAbbCCDd */
+ bytes = nm_utils_hexstr2bin(val_strip);
+ if (bytes)
+ goto done;
+
+ if (!property_info->property_typ_data
+ || !property_info->property_typ_data->subtype.gobject_bytes.legacy_format) {
+ if (value && value[0]) {
+ g_set_error_literal(error, 1, 0, _("not a valid hex-string"));
+ return FALSE;
+ }
+ /* accept the empty word to reset the property to %NULL. */
+ goto done;
+ }
+
+ /* Otherwise, consider the following format: AA b 0xCc D */
+ strv = nm_utils_strsplit_set(value, " \t");
+ array = g_byte_array_sized_new(NM_PTRARRAY_LEN(strv));
+ for (iter = strv; iter && *iter; iter++) {
+ int v;
+ guint8 v8;
+
+ v = _nm_utils_ascii_str_to_int64(*iter, 16, 0, 255, -1);
+ if (v == -1) {
+ g_set_error(error, 1, 0, _("'%s' is not a valid hex character"), *iter);
+ g_byte_array_free(array, TRUE);
+ return FALSE;
+ }
+ v8 = v;
+ g_byte_array_append(array, &v8, 1);
+ }
+ bytes = g_byte_array_free_to_bytes(array);
+
+done:
+ g_object_set(setting, property_info->property_name, bytes, NULL);
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+static gconstpointer _get_fcn_cert_8021x(ARGS_GET_FCN)
+{
+ NMSetting8021x * s_8021X = NM_SETTING_802_1X(setting);
+ const NMSetting8021xSchemeVtable *vtable;
+ char * str = NULL;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x
+ .scheme_type];
+
+ switch (vtable->scheme_func(s_8021X)) {
+ case NM_SETTING_802_1X_CK_SCHEME_BLOB:
+ if (!NM_FLAGS_HAS(get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS))
+ return _get_text_hidden(get_type);
+ str = bytes_to_string(vtable->blob_func(s_8021X));
+ break;
+ case NM_SETTING_802_1X_CK_SCHEME_PATH:
+ str = g_strdup(vtable->path_func(s_8021X));
+ break;
+ case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
+ str = g_strdup(vtable->uri_func(s_8021X));
+ break;
+ case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
+ break;
+ }
+
+ NM_SET_OUT(out_is_default, !str || !str[0]);
+ RETURN_STR_TO_FREE(str);
+}
+
+static gboolean _set_fcn_cert_8021x(ARGS_SET_FCN)
+{
+ gs_free char * value_to_free = NULL;
+ NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_PATH;
+ const NMSetting8021xSchemeVtable *vtable;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ value = nm_strstrip_avoid_copy_a(300, value, &value_to_free);
+
+ if (strncmp(value,
+ NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11,
+ NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11))
+ == 0)
+ scheme = NM_SETTING_802_1X_CK_SCHEME_PKCS11;
+ else if (strncmp(value,
+ NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH,
+ NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH))
+ == 0)
+ value += NM_STRLEN(NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH);
+
+ vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x
+ .scheme_type];
+
+ if (vtable->is_secret) {
+ nm_auto_free_secret char *password_free = NULL;
+ gs_free const char ** strv = NULL;
+ const char * password;
+ const char * path;
+ gsize len;
+
+ strv = nm_utils_escaped_tokens_split(value, NM_ASCII_SPACES);
+ len = NM_PTRARRAY_LEN(strv);
+ if (len > 2) {
+ g_set_error_literal(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("too many arguments. Please only specify a private key file and "
+ "optionally a password"));
+ return FALSE;
+ }
+
+ path = len > 0 ? strv[0] : NULL;
+ if (len == 2) {
+ password = strv[1];
+ } else {
+ password_free = g_strdup(vtable->passwd_func(NM_SETTING_802_1X(setting)));
+ password = password_free;
+ }
+
+ return vtable
+ ->set_private_key_func(NM_SETTING_802_1X(setting), path, password, scheme, NULL, error);
+ } else {
+ return vtable->set_cert_func(NM_SETTING_802_1X(setting), value, scheme, NULL, error);
+ }
+}
+
+static const char *const *_complete_fcn_cert_8021x(ARGS_COMPLETE_FCN)
+{
+ const NMSetting8021xSchemeVtable *vtable;
+
+ vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x
+ .scheme_type];
+
+ if (vtable->is_secret) {
+ gs_free const char **strv = NULL;
+
+ strv = nm_utils_escaped_tokens_split(text, NM_ASCII_SPACES);
+ /* don't try to complete the password */
+ if (NM_PTRARRAY_LEN(strv) > 1)
+ return NULL;
+ }
+
+ NM_SET_OUT(out_complete_filename, TRUE);
+ return NULL;
+}
+
+static gconstpointer _get_fcn_bond_options(ARGS_GET_FCN)
+{
+ NMSettingBond *s_bond = NM_SETTING_BOND(setting);
+ GString * str;
+ guint32 i, len;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ str = g_string_new(NULL);
+ len = nm_setting_bond_get_num_options(s_bond);
+ for (i = 0; i < len; i++) {
+ const char * key;
+ const char * val;
+ gs_free char *val_tmp = NULL;
+ char * p;
+ gs_free char *escaped_key = NULL;
+ gs_free char *escaped_val = NULL;
+
+ nm_setting_bond_get_option(s_bond, i, &key, &val);
+
+ if (nm_streq(key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
+ val_tmp = g_strdup(val);
+ for (p = val_tmp; p && *p; p++) {
+ if (*p == ',')
+ *p = ' ';
+ }
+ val = val_tmp;
+ }
+
+ if (str->len > 0u)
+ g_string_append_c(str, ',');
+ g_string_append(str, nm_utils_escaped_tokens_options_escape_key(key, &escaped_key));
+ g_string_append_c(str, '=');
+ g_string_append(str, nm_utils_escaped_tokens_options_escape_val(val, &escaped_val));
+ }
+
+ NM_SET_OUT(out_is_default, str->len == 0);
+ RETURN_STR_TO_FREE(g_string_free(str, FALSE));
+}
+
+gboolean
+_nm_meta_setting_bond_add_option(NMSetting * setting,
+ const char *name,
+ const char *value,
+ GError ** error)
+{
+ NMSettingBond *s_bond = NM_SETTING_BOND(setting);
+ gs_free char * tmp_value = NULL;
+ const char * val2;
+ char * p;
+
+ if (!value || !value[0]) {
+ /* This call only fails if name is currently not tracked. It's not an
+ * error to remove an option that is not set. */
+ nm_setting_bond_remove_option(s_bond, name);
+ return TRUE;
+ }
+
+ if (nm_streq(name, NM_SETTING_BOND_OPTION_MODE)) {
+ value = nmc_bond_validate_mode(value, error);
+ if (!value)
+ return FALSE;
+ } else if (nm_streq(name, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
+ value = tmp_value = g_strdup(value);
+ for (p = tmp_value; p && *p; p++)
+ if (*p == ' ')
+ *p = ',';
+ }
+
+ if (!nm_setting_bond_validate_option(name, value)) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("failed to set bond option \"%s\""),
+ name);
+ return FALSE;
+ }
+
+ nm_setting_bond_add_option(s_bond, name, value);
+
+ if (nm_streq(name, NM_SETTING_BOND_OPTION_ARP_INTERVAL)) {
+ if (_nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXINT, 0) > 0)
+ _nm_setting_bond_remove_options_miimon(s_bond);
+ } else if (nm_streq(name, NM_SETTING_BOND_OPTION_MIIMON)) {
+ if (_nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXINT, 0) > 0)
+ _nm_setting_bond_remove_options_arp_interval(s_bond);
+ } else if (nm_streq(name, NM_SETTING_BOND_OPTION_PRIMARY)) {
+ if ((val2 = nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE))
+ && !nm_streq(val2, value)) {
+ /* "active_slave" option is deprecated and an alias for "primary". When
+ * setting "primary" to a different value, remove the deprecated "active_slave"
+ * setting.
+ *
+ * If we wouldn't do this, then the profile would work as requested, but ignoring
+ * the (redundant, differing) "active_slave" option. That is confusing, thus clean
+ * it up. */
+ nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE);
+ }
+ } else if (nm_streq(name, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE)) {
+ if ((val2 = nm_setting_bond_get_option_by_name(s_bond, NM_SETTING_BOND_OPTION_PRIMARY))
+ && !nm_streq(val2, value)) {
+ /* "active_slave" is a deprecated alias for "primary". NetworkManager will ignore
+ * "active_slave" if "primary" is set, we thus need to coerce the primary option
+ * too. */
+ nm_setting_bond_add_option(s_bond, NM_SETTING_BOND_OPTION_PRIMARY, value);
+ }
+ }
+
+ return TRUE;
+}
+
+static const char *_describe_fcn_bond_options(ARGS_DESCRIBE_FCN)
+{
+ gs_free char *options_str = NULL;
+ const char ** valid_options;
+ char * s;
+
+ valid_options = nm_setting_bond_get_valid_options(NULL);
+ options_str = g_strjoinv(", ", (char **) valid_options);
+
+ s = g_strdup_printf(_("Enter a list of bonding options formatted as:\n"
+ " option = <value>, option = <value>,... \n"
+ "Valid options are: %s\n"
+ "'mode' can be provided as a name or a number:\n"
+ "balance-rr = 0\n"
+ "active-backup = 1\n"
+ "balance-xor = 2\n"
+ "broadcast = 3\n"
+ "802.3ad = 4\n"
+ "balance-tlb = 5\n"
+ "balance-alb = 6\n\n"
+ "Example: mode=2,miimon=120\n"),
+ options_str);
+ return (*out_to_free = s);
+}
+
+static const char *const *_values_fcn_bond_options(ARGS_VALUES_FCN)
+{
+ return nm_setting_bond_get_valid_options(NULL);
+}
+
+static gconstpointer _get_fcn_connection_permissions(ARGS_GET_FCN)
+{
+ NMSettingConnection *s_con = NM_SETTING_CONNECTION(setting);
+ GString * perm = NULL;
+ const char * perm_item;
+ const char * perm_type;
+ guint i, n;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ n = nm_setting_connection_get_num_permissions(s_con);
+ for (i = 0; i < n; i++) {
+ if (!nm_setting_connection_get_permission(s_con, i, &perm_type, &perm_item, NULL))
+ continue;
+ if (!nm_streq(perm_type, NM_SETTINGS_CONNECTION_PERMISSION_USER))
+ continue;
+
+ if (!perm)
+ perm = g_string_new(NULL);
+ else
+ g_string_append_c(perm, ',');
+ g_string_append_printf(perm, NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX "%s", perm_item);
+ }
+
+ NM_SET_OUT(out_is_default, !perm);
+
+ if (perm)
+ RETURN_STR_TO_FREE(g_string_free(perm, FALSE));
+
+ return NULL;
+}
+
+static gboolean _set_fcn_connection_type(ARGS_SET_FCN)
+{
+ gs_free char *uuid = NULL;
+
+ if (nm_setting_connection_get_uuid(NM_SETTING_CONNECTION(setting))) {
+ /* Don't allow setting type unless the connection is brand new.
+ * Just because it's a bad idea and the user wouldn't probably want that.
+ * No technical reason, really.
+ * Also, using uuid to see if the connection is brand new is a bit
+ * hacky: we can not see if the type is already set, because
+ * nmc_setting_set_property() is called only after the property
+ * we're setting (type) has been removed. */
+ g_set_error(error, 1, 0, _("Can not change the connection type"));
+ return FALSE;
+ }
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) {
+ g_object_set(G_OBJECT(setting), property_info->property_name, NULL, NULL);
+ return TRUE;
+ }
+
+ uuid = nm_utils_uuid_generate();
+ g_object_set(G_OBJECT(setting), NM_SETTING_CONNECTION_UUID, uuid, NULL);
+
+ g_object_set(G_OBJECT(setting), property_info->property_name, value, NULL);
+ return TRUE;
+}
+
+static const char *const *_complete_fcn_connection_type(ARGS_COMPLETE_FCN)
+{
+ guint i, j;
+ char ** result;
+ gsize text_len;
+ const char *slave_types[] = {"bond-slave", "bridge-slave", "team-slave"};
+
+ result = g_new(char *, _NM_META_SETTING_TYPE_NUM * 2 + G_N_ELEMENTS(slave_types) + 1);
+
+ text_len = text ? strlen(text) : 0;
+
+ for (i = 0, j = 0; i < _NM_META_SETTING_TYPE_NUM; i++) {
+ const NMMetaSettingInfoEditor *setting_info = &nm_meta_setting_infos_editor[i];
+ GType gtype = setting_info->general->get_setting_gtype();
+ const char * v;
+
+ if (_nm_setting_type_get_base_type_priority(gtype) == NM_SETTING_PRIORITY_INVALID) {
+ nm_assert(!setting_info->valid_parts);
+ continue;
+ }
+
+ nm_assert(setting_info->valid_parts);
+
+ v = setting_info->alias;
+ if (v) {
+ if (!text || strncmp(text, v, text_len) == 0)
+ result[j++] = g_strdup(v);
+ }
+ v = setting_info->general->setting_name;
+ if (!text || strncmp(text, v, text_len) == 0)
+ result[j++] = g_strdup(v);
+ }
+ for (i = 0; i < G_N_ELEMENTS(slave_types); i++) {
+ const char *v = slave_types[i];
+
+ if (!text || strncmp(text, v, text_len) == 0)
+ result[j++] = g_strdup(v);
+ }
+ if (j)
+ result[j++] = NULL;
+ else {
+ g_free(result);
+ result = NULL;
+ }
+
+ return (const char *const *) (*out_to_free = result);
+}
+
+static const char *
+_sanitize_connection_permission_user(const char *perm)
+{
+ if (NM_STR_HAS_PREFIX(perm, NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX))
+ perm += NM_STRLEN(NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX);
+ if (!nm_settings_connection_validate_permission_user(perm, -1))
+ return NULL;
+ return perm;
+}
+
+static const char *
+_multilist_validate2_fcn_connection_permissions(NMSetting * setting,
+ const char *item,
+ GError ** error)
+{
+ if (!_sanitize_connection_permission_user(item)) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid permission \"%s\""),
+ item);
+ return NULL;
+ }
+ return item;
+}
+
+static gboolean
+_multilist_set_fcn_connection_permissions(NMSetting *setting, const char *item)
+{
+ item = _sanitize_connection_permission_user(item);
+ if (!item)
+ return FALSE;
+ if (!nm_setting_connection_add_permission(NM_SETTING_CONNECTION(setting),
+ NM_SETTINGS_CONNECTION_PERMISSION_USER,
+ item,
+ NULL))
+ nm_assert_not_reached();
+ return TRUE;
+}
+
+static gboolean
+_multilist_remove_by_value_fcn_connection_permissions(NMSetting *setting, const char *item)
+{
+ item = _sanitize_connection_permission_user(item);
+ if (!item)
+ return FALSE;
+ nm_setting_connection_remove_permission_by_value(NM_SETTING_CONNECTION(setting),
+ NM_SETTINGS_CONNECTION_PERMISSION_USER,
+ item,
+ NULL);
+ return TRUE;
+}
+
+static const char *const *_complete_fcn_connection_master(ARGS_COMPLETE_FCN)
+{
+ NMRemoteConnection *const *connections = NULL;
+ guint len = 0;
+ guint i, j;
+ char ** result;
+ NMSettingConnection * s_con;
+ const char * expected_type = NULL;
+ gsize text_len;
+
+ if (environment && environment->get_nm_connections) {
+ connections = environment->get_nm_connections(environment, environment_user_data, &len);
+ }
+ if (!len)
+ return NULL;
+
+ if ((!text || !*text) && operation_context && operation_context->connection) {
+ /* if we have no text yet, initially only complete for matching
+ * slave-type. */
+ s_con = nm_connection_get_setting_connection(operation_context->connection);
+ if (s_con)
+ expected_type = nm_setting_connection_get_slave_type(s_con);
+ }
+
+ text_len = text ? strlen(text) : 0;
+
+ result = g_new(char *, (2 * len) + 1);
+ for (i = 0, j = 0; i < len; i++) {
+ const char *v;
+
+ s_con = nm_connection_get_setting_connection(NM_CONNECTION(connections[i]));
+ if (!s_con)
+ continue;
+
+ if (expected_type
+ && !nm_streq0(nm_setting_connection_get_connection_type(s_con), expected_type))
+ continue;
+
+ if (text && text[0]) {
+ /* if we have text, also complete for the UUID. */
+ v = nm_setting_connection_get_uuid(s_con);
+ if (v && (!text || strncmp(text, v, text_len) == 0))
+ result[j++] = g_strdup(v);
+ }
+
+ v = nm_setting_connection_get_interface_name(s_con);
+ if (v && (!text || strncmp(text, v, text_len) == 0))
+ result[j++] = g_strdup(v);
+ }
+ if (j)
+ result[j++] = NULL;
+ else {
+ g_free(result);
+ result = NULL;
+ }
+
+ return (const char *const *) (*out_to_free = result);
+}
+
+static const char *
+_multilist_validate2_fcn_uuid(NMSetting *setting, const char *item, GError **error)
+{
+ if (!nm_utils_is_uuid(item)) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("the value '%s' is not a valid UUID"),
+ item);
+ return NULL;
+ }
+
+ return item;
+}
+
+static gconstpointer _get_fcn_connection_metered(ARGS_GET_FCN)
+{
+ NMSettingConnection *s_conn = NM_SETTING_CONNECTION(setting);
+ const char * s;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ switch (nm_setting_connection_get_metered(s_conn)) {
+ case NM_METERED_YES:
+ s = N_("yes");
+ break;
+ case NM_METERED_NO:
+ s = N_("no");
+ break;
+ case NM_METERED_UNKNOWN:
+ default:
+ NM_SET_OUT(out_is_default, TRUE);
+ s = N_("unknown");
+ break;
+ }
+
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ return _(s);
+ return s;
+}
+
+static gboolean _set_fcn_connection_metered(ARGS_SET_FCN)
+{
+ NMMetered metered;
+ NMTernary ts_val;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (!nmc_string_to_ternary(value, &ts_val, error))
+ return FALSE;
+
+ switch (ts_val) {
+ case NM_TERNARY_TRUE:
+ metered = NM_METERED_YES;
+ break;
+ case NM_TERNARY_FALSE:
+ metered = NM_METERED_NO;
+ break;
+ case NM_TERNARY_DEFAULT:
+ metered = NM_METERED_UNKNOWN;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ g_object_set(setting, property_info->property_name, metered, NULL);
+ return TRUE;
+}
+
+static char *
+dcb_flags_to_string(NMSettingDcbFlags flags)
+{
+ GString *flag_str;
+
+ if (flags == 0)
+ return g_strdup(_("0 (disabled)"));
+
+ flag_str = g_string_new(NULL);
+ g_string_printf(flag_str, "%d (", flags);
+
+ if (flags & NM_SETTING_DCB_FLAG_ENABLE)
+ g_string_append(flag_str, _("enabled, "));
+ if (flags & NM_SETTING_DCB_FLAG_ADVERTISE)
+ g_string_append(flag_str, _("advertise, "));
+ if (flags & NM_SETTING_DCB_FLAG_WILLING)
+ g_string_append(flag_str, _("willing, "));
+
+ if (flag_str->str[flag_str->len - 1] == '(')
+ g_string_append(flag_str, _("unknown"));
+ else
+ g_string_truncate(flag_str, flag_str->len - 2); /* chop off trailing ', ' */
+
+ g_string_append_c(flag_str, ')');
+
+ return g_string_free(flag_str, FALSE);
+}
+
+static gconstpointer _get_fcn_dcb(ARGS_GET_FCN)
+{
+ NMSettingDcb *s_dcb = NM_SETTING_DCB(setting);
+ GString * str;
+ guint i;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ str = g_string_new(NULL);
+ for (i = 0; i < 8; i++) {
+ guint v;
+
+ v = property_info->property_typ_data->subtype.dcb.get_fcn(s_dcb, i);
+
+ if (i > 0)
+ g_string_append_c(str, ',');
+ g_string_append_printf(str, "%u", v);
+ }
+
+ RETURN_STR_TO_FREE(g_string_free(str, FALSE));
+}
+
+#define DCB_ALL_FLAGS \
+ (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING)
+
+static gconstpointer _get_fcn_dcb_flags(ARGS_GET_FCN)
+{
+ nm_auto_unset_gvalue GValue val = G_VALUE_INIT;
+ guint v;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ g_value_init(&val, G_TYPE_UINT);
+ g_object_get_property(G_OBJECT(setting), property_info->property_name, &val);
+ v = g_value_get_uint(&val);
+
+ RETURN_STR_TO_FREE(dcb_flags_to_string(v));
+}
+
+static gboolean _set_fcn_dcb_flags(ARGS_SET_FCN)
+{
+ NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
+ long int t;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ /* Check for overall hex numeric value */
+ t = _nm_utils_ascii_str_to_int64(value, 0, 0, DCB_ALL_FLAGS, -1);
+ if (t != -1)
+ flags = (guint) t;
+ else {
+ gs_free const char **strv = NULL;
+ const char *const * iter;
+
+ /* Check for individual flag numbers */
+ strv = nm_utils_strsplit_set(value, " \t,");
+ for (iter = strv; iter && *iter; iter++) {
+ t = _nm_utils_ascii_str_to_int64(*iter, 0, 0, DCB_ALL_FLAGS, -1);
+
+ if (g_ascii_strcasecmp(*iter, "enable") == 0
+ || g_ascii_strcasecmp(*iter, "enabled") == 0 || t == NM_SETTING_DCB_FLAG_ENABLE)
+ flags |= NM_SETTING_DCB_FLAG_ENABLE;
+ else if (g_ascii_strcasecmp(*iter, "advertise") == 0
+ || t == NM_SETTING_DCB_FLAG_ADVERTISE)
+ flags |= NM_SETTING_DCB_FLAG_ADVERTISE;
+ else if (g_ascii_strcasecmp(*iter, "willing") == 0 || t == NM_SETTING_DCB_FLAG_WILLING)
+ flags |= NM_SETTING_DCB_FLAG_WILLING;
+ else if (g_ascii_strcasecmp(*iter, "disable") == 0
+ || g_ascii_strcasecmp(*iter, "disabled") == 0 || t == 0) {
+ /* pass */
+ } else {
+ g_set_error(error, 1, 0, _("'%s' is not a valid DCB flag"), *iter);
+ return FALSE;
+ }
+ }
+ }
+
+ /* Validate the flags according to the property spec */
+ if (!validate_flags(setting, property_info->property_name, (guint) flags, error))
+ return FALSE;
+
+ g_object_set(setting, property_info->property_name, (guint) flags, NULL);
+ return TRUE;
+}
+
+static gboolean
+dcb_parse_uint_array(const char *val,
+ guint max,
+ guint other,
+ guint out_array[static 8],
+ GError ** error)
+{
+ gs_free const char **items = NULL;
+ const char *const * iter;
+ gsize i;
+
+ items = nm_utils_strsplit_set_with_empty(val, ",");
+ if (NM_PTRARRAY_LEN(items) != 8) {
+ g_set_error_literal(error, 1, 0, _("must contain 8 comma-separated numbers"));
+ return FALSE;
+ }
+
+ i = 0;
+ for (iter = items; *iter; iter++) {
+ gint64 num;
+
+ num = _nm_utils_ascii_str_to_int64(*iter, 10, 0, other ?: max, -1);
+
+ /* If number is greater than 'max' it must equal 'other' */
+ if (num == -1 || (other && (num > max) && (num != other))) {
+ if (other) {
+ g_set_error(error,
+ 1,
+ 0,
+ _("'%s' not a number between 0 and %u (inclusive) or %u"),
+ *iter,
+ max,
+ other);
+ } else {
+ g_set_error(error,
+ 1,
+ 0,
+ _("'%s' not a number between 0 and %u (inclusive)"),
+ *iter,
+ max);
+ }
+ return FALSE;
+ }
+ nm_assert(i < 8);
+ out_array[i++] = (guint) num;
+ }
+
+ return TRUE;
+}
+
+static void
+dcb_check_feature_enabled(const NMMetaEnvironment *environment,
+ gpointer * environment_user_data,
+ NMSettingDcb * s_dcb,
+ const char * flags_prop)
+{
+ NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
+
+ g_object_get(s_dcb, flags_prop, &flags, NULL);
+ if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
+ _env_warn_fcn(environment,
+ environment_user_data,
+ NM_META_ENV_WARN_LEVEL_WARN,
+ N_("changes will have no effect until '%s' includes 1 (enabled)"),
+ flags_prop);
+ }
+}
+
+static gboolean _set_fcn_dcb(ARGS_SET_FCN)
+{
+ guint i = 0;
+ guint nums[8] = {
+ 0,
+ };
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (!dcb_parse_uint_array(value,
+ property_info->property_typ_data->subtype.dcb.max,
+ property_info->property_typ_data->subtype.dcb.other,
+ nums,
+ error))
+ return FALSE;
+
+ if (property_info->property_typ_data->subtype.dcb.is_percent) {
+ guint sum = 0;
+
+ for (i = 0; i < 8; i++) {
+ sum += nums[i];
+ if (nums[i] > 100 || sum > 100)
+ break;
+ }
+ if (sum != 100) {
+ g_set_error_literal(error, 1, 0, _("bandwidth percentages must total 100%%"));
+ return FALSE;
+ }
+ }
+
+ for (i = 0; i < 8; i++)
+ property_info->property_typ_data->subtype.dcb.set_fcn(NM_SETTING_DCB(setting), i, nums[i]);
+
+ dcb_check_feature_enabled(environment,
+ environment_user_data,
+ NM_SETTING_DCB(setting),
+ NM_SETTING_DCB_PRIORITY_GROUP_FLAGS);
+ return TRUE;
+}
+
+static gconstpointer _get_fcn_dcb_bool(ARGS_GET_FCN)
+{
+ NMSettingDcb *s_dcb = NM_SETTING_DCB(setting);
+ GString * str;
+ guint i;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ str = g_string_new(NULL);
+ for (i = 0; i < 8; i++) {
+ gboolean v;
+
+ v = property_info->property_typ_data->subtype.dcb_bool.get_fcn(s_dcb, i);
+
+ if (i > 0)
+ g_string_append_c(str, ',');
+ g_string_append_c(str, v ? '1' : '0');
+ }
+
+ RETURN_STR_TO_FREE(g_string_free(str, FALSE));
+}
+
+static gboolean _set_fcn_dcb_bool(ARGS_SET_FCN)
+{
+ guint i = 0;
+ guint nums[8] = {
+ 0,
+ };
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (!dcb_parse_uint_array(value, 1, 0, nums, error))
+ return FALSE;
+
+ for (i = 0; i < 8; i++) {
+ property_info->property_typ_data->subtype.dcb_bool.set_fcn(NM_SETTING_DCB(setting),
+ i,
+ !!nums[i]);
+ }
+
+ dcb_check_feature_enabled(
+ environment,
+ environment_user_data,
+ NM_SETTING_DCB(setting),
+ (property_info->property_typ_data->subtype.dcb_bool.with_flow_control_flags
+ ? NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS
+ : NM_SETTING_DCB_PRIORITY_GROUP_FLAGS));
+ return TRUE;
+}
+
+static gboolean _set_fcn_gsm_sim_operator_id(ARGS_SET_FCN)
+{
+ const char *p = value;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (!NM_IN_SET(strlen(value), 5, 6)) {
+ g_set_error_literal(error, 1, 0, _("SIM operator ID must be a 5 or 6 number MCCMNC code"));
+ return FALSE;
+ }
+
+ while (p && *p) {
+ if (!g_ascii_isdigit(*p++)) {
+ g_set_error_literal(error,
+ 1,
+ 0,
+ _("SIM operator ID must be a 5 or 6 number MCCMNC code"));
+ return FALSE;
+ }
+ }
+ g_object_set(G_OBJECT(setting), NM_SETTING_GSM_SIM_OPERATOR_ID, value, NULL);
+ return TRUE;
+}
+
+static gboolean _set_fcn_infiniband_p_key(ARGS_SET_FCN)
+{
+ gint64 p_key;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (nm_streq(value, "default"))
+ p_key = -1;
+ else {
+ p_key = _nm_utils_ascii_str_to_int64(value, 0, -1, G_MAXUINT16, -2);
+ if (p_key == -2) {
+ g_set_error(error, 1, 0, _("'%s' is not a valid IBoIP P_Key"), value);
+ return FALSE;
+ }
+ }
+
+ g_object_set(setting, property_info->property_name, (int) p_key, NULL);
+ return TRUE;
+}
+
+static gconstpointer _get_fcn_infiniband_p_key(ARGS_GET_FCN)
+{
+ NMSettingInfiniband *s_infiniband = NM_SETTING_INFINIBAND(setting);
+ int p_key;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ p_key = nm_setting_infiniband_get_p_key(s_infiniband);
+ if (p_key == -1) {
+ NM_SET_OUT(out_is_default, TRUE);
+ if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ return "default";
+ else
+ return _("default");
+ }
+
+ RETURN_STR_TO_FREE(g_strdup_printf("0x%04x", p_key));
+}
+
+static gconstpointer _get_fcn_objlist(ARGS_GET_FCN)
+{
+ GString *str = NULL;
+ guint num;
+ guint idx;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ num = property_info->property_typ_data->subtype.objlist.get_num_fcn(setting);
+
+ for (idx = 0; idx < num; idx++) {
+ gsize start_offset;
+
+ if (!str)
+ str = g_string_new(NULL);
+ else if (str->len > 0) {
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY
+ && property_info->property_typ_data->subtype.objlist.delimit_pretty_with_semicolon)
+ g_string_append(str, "; ");
+ else {
+ G_STATIC_ASSERT_EXPR(ESCAPED_TOKENS_DELIMITER == ',');
+ g_string_append(str, ", ");
+ }
+ }
+
+ start_offset = str->len;
+
+ property_info->property_typ_data->subtype.objlist.obj_to_str_fcn(get_type,
+ setting,
+ idx,
+ str);
+
+ if (start_offset == str->len) {
+ /* nothing was appended. Remove the delimiter again. */
+ nm_assert_not_reached();
+ if (str->len > 0)
+ g_string_truncate(str, str->len - 2);
+ continue;
+ }
+
+ nm_assert(start_offset < str->len);
+ nm_assert(strlen(str->str) == str->len);
+ nm_assert(property_info->property_typ_data->subtype.objlist.strsplit_plain
+ || get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY
+ || _value_strsplit_assert_unsplitable(&str->str[start_offset]));
+ }
+
+ NM_SET_OUT(out_is_default, num == 0);
+ if (str)
+ RETURN_STR_TO_FREE(g_string_free(str, FALSE));
+ return NULL;
+}
+
+static void
+_objlist_obj_to_str_fcn_ip_config_addresses(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str)
+{
+ NMIPAddress *obj;
+
+ obj = nm_setting_ip_config_get_address(NM_SETTING_IP_CONFIG(setting), idx);
+ g_string_append_printf(str,
+ "%s/%u",
+ nm_ip_address_get_address(obj),
+ nm_ip_address_get_prefix(obj));
+}
+
+static void
+_objlist_obj_to_str_fcn_ip_config_routes(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str)
+{
+ NMIPRoute * route;
+ gs_free char * attr_str = NULL;
+ gs_strfreev char **attr_names = NULL;
+ gs_unref_hashtable GHashTable *hash = g_hash_table_new(nm_str_hash, g_str_equal);
+ int j;
+
+ route = nm_setting_ip_config_get_route(NM_SETTING_IP_CONFIG(setting), idx);
+
+ attr_names = nm_ip_route_get_attribute_names(route);
+ for (j = 0; attr_names && attr_names[j]; j++) {
+ g_hash_table_insert(hash, attr_names[j], nm_ip_route_get_attribute(route, attr_names[j]));
+ }
+
+ attr_str = nm_utils_format_variant_attributes(hash, ' ', '=');
+
+ if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) {
+ g_string_append_printf(str,
+ "%s/%u",
+ nm_ip_route_get_dest(route),
+ nm_ip_route_get_prefix(route));
+
+ if (nm_ip_route_get_next_hop(route))
+ g_string_append_printf(str, " %s", nm_ip_route_get_next_hop(route));
+ if (nm_ip_route_get_metric(route) != -1)
+ g_string_append_printf(str, " %u", (guint32) nm_ip_route_get_metric(route));
+ if (attr_str)
+ g_string_append_printf(str, " %s", attr_str);
+ } else {
+ g_string_append(str, "{ ");
+
+ g_string_append_printf(str,
+ "ip = %s/%u",
+ nm_ip_route_get_dest(route),
+ nm_ip_route_get_prefix(route));
+
+ if (nm_ip_route_get_next_hop(route)) {
+ g_string_append_printf(str, ", nh = %s", nm_ip_route_get_next_hop(route));
+ }
+
+ if (nm_ip_route_get_metric(route) != -1)
+ g_string_append_printf(str, ", mt = %u", (guint32) nm_ip_route_get_metric(route));
+ if (attr_str)
+ g_string_append_printf(str, " %s", attr_str);
+
+ g_string_append(str, " }");
+ }
+}
+
+static gboolean _set_fcn_ip_config_method(ARGS_SET_FCN)
+{
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ /* Silently accept "static" and convert to "manual" */
+ if (strlen(value) > 1 && matches(value, "static")) {
+ if (nm_setting_ip_config_get_addr_family(NM_SETTING_IP_CONFIG(setting)) == AF_INET)
+ value = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
+ else
+ value = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
+ }
+
+ value = nmc_string_is_valid(value,
+ (const char **) property_info->property_typ_data->values_static,
+ error);
+ if (!value)
+ return FALSE;
+
+ g_object_set(setting, property_info->property_name, value, NULL);
+ return TRUE;
+}
+
+static const char *
+_multilist_validate2_fcn_ip_config_dns(NMSetting *setting, const char *value, GError **error)
+{
+ int addr_family = nm_setting_ip_config_get_addr_family(NM_SETTING_IP_CONFIG(setting));
+
+ if (!nm_utils_parse_inaddr(addr_family, value, NULL)) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid IPv%c address '%s'"),
+ nm_utils_addr_family_to_char(addr_family),
+ value);
+ return NULL;
+ }
+
+ return value;
+}
+
+static gboolean
+_multilist_add_fcn_ip_config_dns_options(NMSetting *setting, const char *item)
+{
+ NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG(setting);
+
+ if (!nm_setting_ip_config_add_dns_option(s_ip, item)) {
+ /* maybe it failed, because the element already existed. *sigh*. */
+ nm_setting_ip_config_remove_dns_option_by_value(s_ip, item);
+ return nm_setting_ip_config_add_dns_option(s_ip, item);
+ }
+ return TRUE;
+}
+
+static gboolean _set_fcn_objlist(ARGS_SET_FCN)
+{
+ gs_free const char **strv = NULL;
+ gsize i, nstrv;
+
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value)) {
+ if (property_info->property_typ_data->subtype.objlist.clear_all_fcn) {
+ property_info->property_typ_data->subtype.objlist.clear_all_fcn(setting);
+ return TRUE;
+ }
+ return _gobject_property_reset_default(setting, property_info->property_name);
+ }
+
+ if (_SET_FCN_DO_REMOVE(modifier, value)
+ && (property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u
+ || property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_s)) {
+ gs_free gint64 *indexes = NULL;
+
+ indexes = _value_str_as_index_list(value, &nstrv);
+ if (indexes) {
+ gint64 num;
+
+ num = property_info->property_typ_data->subtype.objlist.get_num_fcn(setting);
+ for (i = 0; i < nstrv; i++) {
+ gint64 idx = indexes[i];
+
+ if (idx >= num)
+ continue;
+ if (property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u)
+ property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u(setting,
+ idx);
+ else
+ property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_s(setting,
+ idx);
+ }
+ return TRUE;
+ }
+ }
+
+ strv = _value_strsplit(value,
+ property_info->property_typ_data->subtype.objlist.strsplit_plain
+ ? VALUE_STRSPLIT_MODE_OBJLIST
+ : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS,
+ &nstrv);
+
+ if (_SET_FCN_DO_SET_ALL(modifier, value)) {
+ if (property_info->property_typ_data->subtype.objlist.clear_all_fcn)
+ property_info->property_typ_data->subtype.objlist.clear_all_fcn(setting);
+ else
+ _gobject_property_reset(setting, property_info->property_name, FALSE);
+ }
+
+ for (i = 0; i < nstrv; i++) {
+ /* FIXME: there is the problem here that set_fcn() might succeed on the first item
+ * (modifying it), and fail to parse the second one.
+ *
+ * Optimally, we would first parse all input strings before starting the
+ * modify the setting. The setting should only be modified if (and only if)
+ * the entire operation succeeds to set all items.
+ *
+ * Currently, in interactive mode this leads to odd behavior.
+ *
+ * This does not only affect objlist.set_fcn() or _pt_objlist properties.
+ * E.g. we also call _gobject_property_reset() before validating the input. */
+ if (!property_info->property_typ_data->subtype.objlist
+ .set_fcn(setting, !_SET_FCN_DO_REMOVE(modifier, value), strv[i], error))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+_objlist_set_fcn_ip_config_addresses(NMSetting * setting,
+ gboolean do_add,
+ const char *value,
+ GError ** error)
+{
+ int addr_family = nm_setting_ip_config_get_addr_family(NM_SETTING_IP_CONFIG(setting));
+ nm_auto_unref_ip_address NMIPAddress *addr = NULL;
+
+ addr = _parse_ip_address(addr_family, value, error);
+ if (!addr)
+ return FALSE;
+ if (do_add)
+ nm_setting_ip_config_add_address(NM_SETTING_IP_CONFIG(setting), addr);
+ else
+ nm_setting_ip_config_remove_address_by_value(NM_SETTING_IP_CONFIG(setting), addr);
+ return TRUE;
+}
+
+static gboolean _set_fcn_ip_config_gateway(ARGS_SET_FCN)
+{
+ gs_free char *value_to_free = NULL;
+ int addr_family = nm_setting_ip_config_get_addr_family(NM_SETTING_IP_CONFIG(setting));
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ value = nm_strstrip_avoid_copy_a(300, value, &value_to_free);
+
+ if (!nm_utils_ipaddr_is_valid(addr_family, value)) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid gateway address '%s'"),
+ value);
+ return FALSE;
+ }
+
+ /* Since commit c1907a218a6b6bfe8175eb6ed87a523aaabc69ae, having a gateway and never-default=yes
+ * will be normalized away. That means, when we set a gateway, we also want to unset never-default,
+ * otherwise the operation gets silently reverted. */
+ g_object_set(setting,
+ property_info->property_name,
+ value,
+ NM_SETTING_IP_CONFIG_NEVER_DEFAULT,
+ FALSE,
+ NULL);
+ return TRUE;
+}
+
+static gboolean
+_objlist_set_fcn_ip_config_routes(NMSetting * setting,
+ gboolean do_add,
+ const char *value,
+ GError ** error)
+{
+ int addr_family = nm_setting_ip_config_get_addr_family(NM_SETTING_IP_CONFIG(setting));
+ nm_auto_unref_ip_route NMIPRoute *route = NULL;
+
+ route = _parse_ip_route(addr_family, value, error);
+ if (!route)
+ return FALSE;
+ if (do_add)
+ nm_setting_ip_config_add_route(NM_SETTING_IP_CONFIG(setting), route);
+ else
+ nm_setting_ip_config_remove_route_by_value(NM_SETTING_IP_CONFIG(setting), route);
+ return TRUE;
+}
+
+static gboolean
+_is_default_func_ip_config_dns_options(NMSetting *setting)
+{
+ return !nm_setting_ip_config_has_dns_options(NM_SETTING_IP_CONFIG(setting));
+}
+
+static void
+_objlist_obj_to_str_fcn_ip_config_routing_rules(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str)
+{
+ NMIPRoutingRule *rule;
+ gs_free char * s = NULL;
+
+ rule = nm_setting_ip_config_get_routing_rule(NM_SETTING_IP_CONFIG(setting), idx);
+ s = nm_ip_routing_rule_to_string(rule, NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE, NULL, NULL);
+ if (s)
+ nm_utils_escaped_tokens_escape_gstr(s, ESCAPED_TOKENS_DELIMITERS, str);
+}
+
+static gboolean
+_objlist_set_fcn_ip_config_routing_rules(NMSetting * setting,
+ gboolean do_add,
+ const char *str,
+ GError ** error)
+{
+ NMSettingIPConfig * s_ip = NM_SETTING_IP_CONFIG(setting);
+ nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL;
+ guint i, n;
+
+ rule = nm_ip_routing_rule_from_string(
+ str,
+ (NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE
+ | (NM_IS_SETTING_IP4_CONFIG(setting) ? NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET
+ : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6)),
+ NULL,
+ error);
+ if (!rule)
+ return FALSE;
+
+ /* also for @do_add, we first always search whether such a rule already exist
+ * and remove the first occurrence.
+ *
+ * The effect is, that we don't add multiple times the same rule,
+ * and that if the rule already exists, it gets moved to the end (append).
+ */
+ n = nm_setting_ip_config_get_num_routing_rules(s_ip);
+ for (i = 0; i < n; i++) {
+ NMIPRoutingRule *rr;
+
+ rr = nm_setting_ip_config_get_routing_rule(s_ip, i);
+ if (nm_ip_routing_rule_cmp(rule, rr) == 0) {
+ nm_setting_ip_config_remove_routing_rule(s_ip, i);
+ break;
+ }
+ }
+ if (do_add)
+ nm_setting_ip_config_add_routing_rule(s_ip, rule);
+ return TRUE;
+}
+
+static guint
+_multilist_get_num_fcn_ip_config_dhcp_reject_servers(NMSettingIPConfig *setting)
+{
+ guint num;
+
+ nm_setting_ip_config_get_dhcp_reject_servers(setting, &num);
+
+ return num;
+}
+
+static gboolean
+_multilist_remove_by_value_fcn_ip_config_dhcp_reject_servers(NMSettingIPConfig *setting,
+ const char * item)
+{
+ const char *const *strv;
+ guint num;
+ gssize idx;
+
+ strv = nm_setting_ip_config_get_dhcp_reject_servers(setting, &num);
+ idx = nm_utils_strv_find_first((char **) strv, num, item);
+ if (idx >= 0)
+ nm_setting_ip_config_remove_dhcp_reject_server(setting, idx);
+ return TRUE;
+}
+
+static gconstpointer _get_fcn_olpc_mesh_ssid(ARGS_GET_FCN)
+{
+ NMSettingOlpcMesh *s_olpc_mesh = NM_SETTING_OLPC_MESH(setting);
+ GBytes * ssid;
+ char * ssid_str = NULL;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ ssid = nm_setting_olpc_mesh_get_ssid(s_olpc_mesh);
+ if (ssid) {
+ ssid_str = nm_utils_ssid_to_utf8(g_bytes_get_data(ssid, NULL), g_bytes_get_size(ssid));
+ }
+
+ NM_SET_OUT(out_is_default, !ssid_str);
+ RETURN_STR_TO_FREE(ssid_str);
+}
+
+static gboolean _set_fcn_olpc_mesh_channel(ARGS_SET_FCN)
+{
+ unsigned long chan_int;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (!nmc_string_to_uint(value, TRUE, 1, 13, &chan_int)) {
+ g_set_error(error, 1, 0, _("'%s' is not a valid channel; use <1-13>"), value);
+ return FALSE;
+ }
+ g_object_set(setting, property_info->property_name, chan_int, NULL);
+ return TRUE;
+}
+
+static const char *
+_validate_fcn_proxy_pac_script(const char *value, char **out_to_free, GError **error)
+{
+ char *script = NULL;
+
+ if (!nmc_proxy_check_script(value, &script, error))
+ return NULL;
+ RETURN_STR_TO_FREE(script);
+}
+
+static void
+_objlist_obj_to_str_fcn_sriov_vfs(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str)
+{
+ gs_free char *s = NULL;
+ NMSriovVF * vf;
+
+ vf = nm_setting_sriov_get_vf(NM_SETTING_SRIOV(setting), idx);
+ s = nm_utils_sriov_vf_to_str(vf, FALSE, NULL);
+ if (s)
+ g_string_append(str, s);
+}
+
+static void
+_objlist_obj_to_str_fcn_tc_config_qdiscs(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str)
+{
+ gs_free char *s = NULL;
+ NMTCQdisc * qdisc;
+
+ qdisc = nm_setting_tc_config_get_qdisc(NM_SETTING_TC_CONFIG(setting), idx);
+ s = nm_utils_tc_qdisc_to_str(qdisc, NULL);
+ if (s)
+ g_string_append(str, s);
+}
+
+static void
+_objlist_obj_to_str_fcn_bridge_vlans(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str)
+{
+ gs_free char *s = NULL;
+ NMBridgeVlan *vlan;
+
+ if (NM_IS_SETTING_BRIDGE(setting))
+ vlan = nm_setting_bridge_get_vlan(NM_SETTING_BRIDGE(setting), idx);
+ else
+ vlan = nm_setting_bridge_port_get_vlan(NM_SETTING_BRIDGE_PORT(setting), idx);
+
+ s = nm_bridge_vlan_to_str(vlan, NULL);
+ if (s)
+ nm_utils_escaped_tokens_escape_gstr_assert(s, ESCAPED_TOKENS_DELIMITERS, str);
+}
+
+static gboolean
+_objlist_set_fcn_sriov_vfs(NMSetting *setting, gboolean do_add, const char *value, GError **error)
+{
+ nm_auto_unref_sriov_vf NMSriovVF *vf = NULL;
+ gs_free_error GError *local = NULL;
+
+ vf = nm_utils_sriov_vf_from_str(value, &local);
+ if (!vf) {
+ nm_utils_error_set(
+ error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ "%s. %s",
+ local->message,
+ _("The valid syntax is: vf [attribute=value]... [,vf [attribute=value]...]"));
+ return FALSE;
+ }
+ if (do_add)
+ nm_setting_sriov_add_vf(NM_SETTING_SRIOV(setting), vf);
+ else
+ nm_setting_sriov_remove_vf_by_index(NM_SETTING_SRIOV(setting), nm_sriov_vf_get_index(vf));
+ return TRUE;
+}
+
+static gboolean
+_objlist_set_fcn_tc_config_qdiscs(NMSetting * setting,
+ gboolean do_add,
+ const char *value,
+ GError ** error)
+{
+ nm_auto_unref_tc_qdisc NMTCQdisc *tc_qdisc = NULL;
+ gs_free_error GError *local = NULL;
+
+ tc_qdisc = nm_utils_tc_qdisc_from_str(value, &local);
+ if (!tc_qdisc) {
+ nm_utils_error_set(
+ error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ "%s. %s",
+ local->message,
+ _("The valid syntax is: '[root | parent <handle>] [handle <handle>] <kind>'"));
+ return FALSE;
+ }
+ if (do_add)
+ nm_setting_tc_config_add_qdisc(NM_SETTING_TC_CONFIG(setting), tc_qdisc);
+ else
+ nm_setting_tc_config_remove_qdisc_by_value(NM_SETTING_TC_CONFIG(setting), tc_qdisc);
+ return TRUE;
+}
+
+static gboolean
+_objlist_set_fcn_bridge_vlans(NMSetting * setting,
+ gboolean do_add,
+ const char *value,
+ GError ** error)
+{
+ nm_auto_unref_bridge_vlan NMBridgeVlan *vlan = NULL;
+ gs_free_error GError *local = NULL;
+ guint16 vid_start, vid_end;
+
+ vlan = nm_bridge_vlan_from_str(value, &local);
+ if (!vlan) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ "%s. %s",
+ local->message,
+ _("The valid syntax is: '<vid>[-<vid>] [pvid] [untagged]'"));
+ return FALSE;
+ }
+
+ if (NM_IS_SETTING_BRIDGE(setting)) {
+ if (do_add)
+ nm_setting_bridge_add_vlan(NM_SETTING_BRIDGE(setting), vlan);
+ else {
+ nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end);
+ nm_setting_bridge_remove_vlan_by_vid(NM_SETTING_BRIDGE(setting), vid_start, vid_end);
+ }
+ } else {
+ if (do_add)
+ nm_setting_bridge_port_add_vlan(NM_SETTING_BRIDGE_PORT(setting), vlan);
+ else {
+ nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end);
+ nm_setting_bridge_port_remove_vlan_by_vid(NM_SETTING_BRIDGE_PORT(setting),
+ vid_start,
+ vid_end);
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+_objlist_obj_to_str_fcn_tc_config_tfilters(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str)
+{
+ NMTCTfilter * tfilter;
+ gs_free char *s = NULL;
+
+ tfilter = nm_setting_tc_config_get_tfilter(NM_SETTING_TC_CONFIG(setting), idx);
+ s = nm_utils_tc_tfilter_to_str(tfilter, NULL);
+ if (s)
+ g_string_append(str, s);
+}
+
+static gboolean
+_objlist_set_fcn_tc_config_tfilters(NMSetting * setting,
+ gboolean do_add,
+ const char *value,
+ GError ** error)
+{
+ gs_free_error GError * local = NULL;
+ nm_auto_unref_tc_tfilter NMTCTfilter *tc_tfilter = NULL;
+
+ tc_tfilter = nm_utils_tc_tfilter_from_str(value, &local);
+ if (!tc_tfilter) {
+ nm_utils_error_set(
+ error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ "%s. %s",
+ local->message,
+ _("The valid syntax is: '[root | parent <handle>] [handle <handle>] <kind>'"));
+ return FALSE;
+ }
+ if (do_add)
+ nm_setting_tc_config_add_tfilter(NM_SETTING_TC_CONFIG(setting), tc_tfilter);
+ else
+ nm_setting_tc_config_remove_tfilter_by_value(NM_SETTING_TC_CONFIG(setting), tc_tfilter);
+ return TRUE;
+}
+
+static const char *
+_validate_fcn_team_config(const char *value, char **out_to_free, GError **error)
+{
+ char *json = NULL;
+
+ if (!nmc_team_check_config(value, &json, error))
+ return NULL;
+ RETURN_STR_TO_FREE(json);
+}
+
+static void
+_objlist_obj_to_str_fcn_team_link_watchers(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str)
+{
+ NMTeamLinkWatcher *watcher;
+ gs_free char * s = NULL;
+
+ if (NM_IS_SETTING_TEAM(setting))
+ watcher = nm_setting_team_get_link_watcher(NM_SETTING_TEAM(setting), idx);
+ else
+ watcher = nm_setting_team_port_get_link_watcher(NM_SETTING_TEAM_PORT(setting), idx);
+
+ s = nm_utils_team_link_watcher_to_string(watcher);
+ if (s)
+ nm_utils_escaped_tokens_escape_gstr(s, ESCAPED_TOKENS_DELIMITERS, str);
+}
+
+static gboolean
+_objlist_set_fcn_team_link_watchers(NMSetting * setting,
+ gboolean do_add,
+ const char *value,
+ GError ** error)
+{
+ nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher = NULL;
+
+ watcher = nm_utils_team_link_watcher_from_string(value, error);
+ if (!watcher)
+ return FALSE;
+ if (NM_IS_SETTING_TEAM(setting)) {
+ if (do_add)
+ nm_setting_team_add_link_watcher(NM_SETTING_TEAM(setting), watcher);
+ else
+ nm_setting_team_remove_link_watcher_by_value(NM_SETTING_TEAM(setting), watcher);
+ } else {
+ if (do_add)
+ nm_setting_team_port_add_link_watcher(NM_SETTING_TEAM_PORT(setting), watcher);
+ else
+ nm_setting_team_port_remove_link_watcher_by_value(NM_SETTING_TEAM_PORT(setting),
+ watcher);
+ }
+ return TRUE;
+}
+
+static gconstpointer _get_fcn_vlan_flags(ARGS_GET_FCN)
+{
+ NMSettingVlan *s_vlan = NM_SETTING_VLAN(setting);
+ guint32 flags;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ flags = nm_setting_vlan_get_flags(s_vlan);
+ NM_SET_OUT(out_is_default, flags == 0);
+ RETURN_STR_TO_FREE(vlan_flags_to_string(flags, get_type));
+}
+
+static NMVlanPriorityMap
+_vlan_priority_map_type_from_property_info(const NMMetaPropertyInfo *property_info)
+{
+ nm_assert(property_info);
+ nm_assert(property_info->setting_info
+ == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_VLAN]);
+ nm_assert(NM_IN_STRSET(property_info->property_name,
+ NM_SETTING_VLAN_INGRESS_PRIORITY_MAP,
+ NM_SETTING_VLAN_EGRESS_PRIORITY_MAP));
+
+ return nm_streq(property_info->property_name, NM_SETTING_VLAN_INGRESS_PRIORITY_MAP)
+ ? NM_VLAN_INGRESS_MAP
+ : NM_VLAN_EGRESS_MAP;
+}
+
+static gconstpointer _get_fcn_vlan_xgress_priority_map(ARGS_GET_FCN)
+{
+ NMVlanPriorityMap map_type = _vlan_priority_map_type_from_property_info(property_info);
+ NMSettingVlan * s_vlan = NM_SETTING_VLAN(setting);
+ GString * str = NULL;
+ gint32 i, num;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ num = nm_setting_vlan_get_num_priorities(s_vlan, map_type);
+ for (i = 0; i < num; i++) {
+ guint32 from, to;
+
+ if (!nm_setting_vlan_get_priority(s_vlan, map_type, i, &from, &to))
+ continue;
+
+ if (!str)
+ str = g_string_new(NULL);
+ else
+ g_string_append_c(str, ESCAPED_TOKENS_WITH_SPACES_DELIMTER);
+ g_string_append_printf(str, "%d:%d", from, to);
+ }
+
+ NM_SET_OUT(out_is_default, num == 0);
+ if (!str)
+ return NULL;
+ RETURN_STR_TO_FREE(g_string_free(str, FALSE));
+}
+
+static gboolean _set_fcn_vlan_xgress_priority_map(ARGS_SET_FCN)
+{
+ NMVlanPriorityMap map_type = _vlan_priority_map_type_from_property_info(property_info);
+ gs_free const char **prio_map = NULL;
+ gsize i, len;
+
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE(property_info, modifier, value)) {
+ nm_setting_vlan_clear_priorities(NM_SETTING_VLAN(setting), map_type);
+ return TRUE;
+ }
+
+ prio_map = _value_strsplit(value, VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES, &len);
+
+ for (i = 0; i < len; i++) {
+ if (!nm_utils_vlan_priority_map_parse_str(map_type,
+ prio_map[i],
+ _SET_FCN_DO_REMOVE(modifier, value),
+ NULL,
+ NULL,
+ NULL)) {
+ g_set_error(error, 1, 0, _("invalid priority map '%s'"), prio_map[i]);
+ return FALSE;
+ }
+ }
+
+ if (_SET_FCN_DO_SET_ALL(modifier, value))
+ nm_setting_vlan_clear_priorities(NM_SETTING_VLAN(setting), map_type);
+
+ for (i = 0; i < len; i++) {
+ if (_SET_FCN_DO_REMOVE(modifier, value)) {
+ nm_setting_vlan_remove_priority_str_by_value(NM_SETTING_VLAN(setting),
+ map_type,
+ prio_map[i]);
+ } else {
+ nm_setting_vlan_add_priority_str(NM_SETTING_VLAN(setting), map_type, prio_map[i]);
+ }
+ }
+ return TRUE;
+}
+
+static void
+_vpn_options_callback(const char *key, const char *val, gpointer user_data)
+{
+ GString * str = user_data;
+ gs_free char *escaped_key = NULL;
+ gs_free char *escaped_val = NULL;
+
+ if (str->len > 0u)
+ g_string_append(str, ", ");
+
+ g_string_append(str, nm_utils_escaped_tokens_options_escape_key(key, &escaped_key));
+ g_string_append(str, " = ");
+ g_string_append(str, nm_utils_escaped_tokens_options_escape_val(val, &escaped_val));
+}
+
+static gconstpointer _get_fcn_vpn_options(ARGS_GET_FCN)
+{
+ NMSettingVpn *s_vpn = NM_SETTING_VPN(setting);
+ GString * str;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ str = g_string_new(NULL);
+ if (nm_streq(property_info->property_name, NM_SETTING_VPN_SECRETS))
+ nm_setting_vpn_foreach_secret(s_vpn, _vpn_options_callback, str);
+ else
+ nm_setting_vpn_foreach_data_item(s_vpn, _vpn_options_callback, str);
+ NM_SET_OUT(out_is_default, str->len == 0);
+ RETURN_STR_TO_FREE(g_string_free(str, FALSE));
+}
+
+static gboolean
+_optionlist_set_fcn_vpn_data(NMSetting * setting,
+ const char *option,
+ const char *value,
+ GError ** error)
+{
+ if (value)
+ nm_setting_vpn_add_data_item(NM_SETTING_VPN(setting), option, value);
+ else
+ nm_setting_vpn_remove_data_item(NM_SETTING_VPN(setting), option);
+ return TRUE;
+}
+
+static gboolean
+_optionlist_set_fcn_vpn_secrets(NMSetting * setting,
+ const char *option,
+ const char *value,
+ GError ** error)
+{
+ if (value)
+ nm_setting_vpn_add_secret(NM_SETTING_VPN(setting), option, value);
+ else
+ nm_setting_vpn_remove_secret(NM_SETTING_VPN(setting), option);
+ return TRUE;
+}
+
+static gboolean _set_fcn_wired_s390_subchannels(ARGS_SET_FCN)
+{
+ gs_free const char **strv = NULL;
+ gsize len;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ strv = nm_utils_strsplit_set(value, " ,\t");
+ len = NM_PTRARRAY_LEN(strv);
+ if (len != 2 && len != 3) {
+ g_set_error(error, 1, 0, _("'%s' is not valid; 2 or 3 strings should be provided"), value);
+ return FALSE;
+ }
+
+ g_object_set(setting, property_info->property_name, strv, NULL);
+ return TRUE;
+}
+
+static gboolean
+_optionlist_set_fcn_wired_s390_options(NMSetting * setting,
+ const char *name,
+ const char *value,
+ GError ** error)
+{
+ if (value)
+ nm_setting_wired_add_s390_option(NM_SETTING_WIRED(setting), name, value);
+ else
+ nm_setting_wired_remove_s390_option(NM_SETTING_WIRED(setting), name);
+ return TRUE;
+}
+
+static const char *const *_values_fcn_wired_s390_options(ARGS_VALUES_FCN)
+{
+ return nm_setting_wired_get_valid_s390_options(NULL);
+}
+
+static const char *_describe_fcn_wired_s390_options(ARGS_DESCRIBE_FCN)
+{
+ gs_free char *options_str = NULL;
+ const char ** valid_options;
+ char * s;
+
+ valid_options = nm_setting_wired_get_valid_s390_options(NULL);
+
+ options_str = g_strjoinv(", ", (char **) valid_options);
+
+ s = g_strdup_printf(_("Enter a list of S/390 options formatted as:\n"
+ " option = <value>, option = <value>,...\n"
+ "Valid options are: %s\n"),
+ options_str);
+ return (*out_to_free = s);
+}
+
+static gconstpointer _get_fcn_wireless_ssid(ARGS_GET_FCN)
+{
+ NMSettingWireless *s_wireless = NM_SETTING_WIRELESS(setting);
+ GBytes * ssid;
+ char * ssid_str = NULL;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ ssid = nm_setting_wireless_get_ssid(s_wireless);
+ if (ssid) {
+ ssid_str = nm_utils_ssid_to_utf8(g_bytes_get_data(ssid, NULL), g_bytes_get_size(ssid));
+ }
+
+ NM_SET_OUT(out_is_default, !ssid_str || !ssid_str[0]);
+ RETURN_STR_TO_FREE(ssid_str);
+}
+
+static gboolean _set_fcn_wireless_channel(ARGS_SET_FCN)
+{
+ unsigned long chan_int;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ return _gobject_property_reset_default(setting, property_info->property_name);
+
+ if (!nmc_string_to_uint(value, FALSE, 0, 0, &chan_int)) {
+ g_set_error(error, 1, 0, _("'%s' is not a valid channel"), value);
+ return FALSE;
+ }
+
+ if (!nm_utils_wifi_is_channel_valid(chan_int, "a")
+ && !nm_utils_wifi_is_channel_valid(chan_int, "bg")) {
+ g_set_error(error, 1, 0, _("'%ld' is not a valid channel"), chan_int);
+ return FALSE;
+ }
+
+ g_object_set(setting, property_info->property_name, chan_int, NULL);
+ return TRUE;
+}
+
+static const char *
+_multilist_validate2_fcn_mac_addr(NMSetting *setting, const char *item, GError **error)
+{
+ guint8 buf[ETH_ALEN];
+
+ if (!nm_utils_hwaddr_aton(item, buf, ETH_ALEN)) {
+ nm_utils_error_set(error,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is not a valid MAC address"),
+ item);
+ return NULL;
+ }
+
+ return item;
+}
+
+static gconstpointer _get_fcn_wireless_security_wep_key(ARGS_GET_FCN)
+{
+ NMSettingWirelessSecurity *s_wireless_sec = NM_SETTING_WIRELESS_SECURITY(setting);
+ char * key;
+ guint index;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ nm_assert(g_str_has_prefix(property_info->property_name, "wep-key"));
+ nm_assert(NM_IN_SET(property_info->property_name[7], '0', '1', '2', '3'));
+ nm_assert(property_info->property_name[8] == '\0');
+
+ index = property_info->property_name[7] - '0';
+
+ key = g_strdup(nm_setting_wireless_security_get_wep_key(s_wireless_sec, index));
+ NM_SET_OUT(out_is_default, !key);
+ RETURN_STR_TO_FREE(key);
+}
+
+static gboolean _set_fcn_wireless_wep_key(ARGS_SET_FCN)
+{
+ NMWepKeyType guessed_type = NM_WEP_KEY_TYPE_UNKNOWN;
+ NMWepKeyType type;
+ guint32 prev_idx, idx;
+
+ nm_assert(!error || !*error);
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) {
+ g_object_set(setting, property_info->property_name, NULL, NULL);
+ return TRUE;
+ }
+
+ /* Get currently set type */
+ type = nm_setting_wireless_security_get_wep_key_type(NM_SETTING_WIRELESS_SECURITY(setting));
+
+ /* Guess key type */
+ if (nm_utils_wep_key_valid(value, NM_WEP_KEY_TYPE_KEY))
+ guessed_type = NM_WEP_KEY_TYPE_KEY;
+ else if (nm_utils_wep_key_valid(value, NM_WEP_KEY_TYPE_PASSPHRASE))
+ guessed_type = NM_WEP_KEY_TYPE_PASSPHRASE;
+
+ if (guessed_type == NM_WEP_KEY_TYPE_UNKNOWN) {
+ g_set_error(error, 1, 0, _("'%s' is not valid"), value);
+ return FALSE;
+ }
+
+ if (type != NM_WEP_KEY_TYPE_UNKNOWN && type != guessed_type) {
+ if (nm_utils_wep_key_valid(value, type))
+ guessed_type = type;
+ else {
+ g_set_error(error,
+ 1,
+ 0,
+ _("'%s' not compatible with %s '%s', please change the key or set the "
+ "right %s first."),
+ value,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE,
+ wep_key_type_to_string(type),
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE);
+ return FALSE;
+ }
+ }
+ prev_idx =
+ nm_setting_wireless_security_get_wep_tx_keyidx(NM_SETTING_WIRELESS_SECURITY(setting));
+ idx = property_info->property_name[strlen(property_info->property_name) - 1] - '0';
+ _env_warn_fcn(environment,
+ environment_user_data,
+ NM_META_ENV_WARN_LEVEL_INFO,
+ N_("WEP key is guessed to be of '%s'"),
+ wep_key_type_to_string(guessed_type));
+ if (idx != prev_idx) {
+ _env_warn_fcn(environment,
+ environment_user_data,
+ NM_META_ENV_WARN_LEVEL_INFO,
+ N_("WEP key index set to '%d'"),
+ idx);
+ }
+
+ g_object_set(setting, property_info->property_name, value, NULL);
+ g_object_set(setting, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, guessed_type, NULL);
+ if (idx != prev_idx)
+ g_object_set(setting, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, idx, NULL);
+ return TRUE;
+}
+
+static void
+_gobject_enum_pre_set_notify_fcn_wireless_security_wep_key_type(
+ const NMMetaPropertyInfo *property_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ NMSetting * setting,
+ int value)
+{
+ guint i;
+ const char *key;
+ const char *keynames[] = {
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY1,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY2,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY3,
+ };
+
+ /* Check type compatibility with set keys */
+ if (!NM_IN_SET(value, NM_WEP_KEY_TYPE_UNKNOWN, NM_WEP_KEY_TYPE_KEY, NM_WEP_KEY_TYPE_PASSPHRASE))
+ return;
+
+ for (i = 0; i < 4; i++) {
+ key = nm_setting_wireless_security_get_wep_key(NM_SETTING_WIRELESS_SECURITY(setting), i);
+ if (key && !nm_utils_wep_key_valid(key, value)) {
+ _env_warn_fcn(
+ environment,
+ environment_user_data,
+ NM_META_ENV_WARN_LEVEL_WARN,
+ N_("'%s' is not compatible with '%s' type, please change or delete the key."),
+ keynames[i],
+ wep_key_type_to_string(value));
+ }
+ }
+}
+
+/*****************************************************************************/
+
+static gconstpointer _get_fcn_ethtool(ARGS_GET_FCN)
+{
+ NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
+ const char *s;
+ guint32 u32;
+ gboolean b;
+
+ RETURN_UNSUPPORTED_GET_TYPE();
+
+ if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) {
+ if (!nm_setting_option_get_uint32(setting, nm_ethtool_data[ethtool_id]->optname, &u32)) {
+ NM_SET_OUT(out_is_default, TRUE);
+ return NULL;
+ }
+
+ RETURN_STR_TO_FREE(nm_strdup_int(u32));
+ }
+
+ nm_assert(nm_ethtool_id_is_feature(ethtool_id));
+
+ if (!nm_setting_option_get_boolean(setting, nm_ethtool_data[ethtool_id]->optname, &b)) {
+ NM_SET_OUT(out_is_default, TRUE);
+ return NULL;
+ }
+
+ s = b ? N_("on") : N_("off");
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ s = gettext(s);
+ return s;
+}
+
+static gboolean _set_fcn_ethtool(ARGS_SET_FCN)
+{
+ NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
+ gs_free char *value_to_free = NULL;
+ gint64 i64;
+ gboolean b;
+
+ if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
+ goto do_unset;
+
+ if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) {
+ i64 = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT32, -1);
+ if (i64 == -1) {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is out of range [%" G_GUINT32_FORMAT ", %" G_GUINT32_FORMAT "]"),
+ value,
+ 0,
+ G_MAXUINT32);
+ return FALSE;
+ }
+
+ nm_setting_option_set_uint32(setting, nm_ethtool_data[ethtool_id]->optname, i64);
+ return TRUE;
+ }
+
+ nm_assert(nm_ethtool_id_is_feature(ethtool_id));
+
+ value = nm_strstrip_avoid_copy_a(300, value, &value_to_free);
+ if (NM_IN_STRSET(value, "1", "yes", "true", "on"))
+ b = TRUE;
+ else if (NM_IN_STRSET(value, "0", "no", "false", "off"))
+ b = FALSE;
+ else if (NM_IN_STRSET(value, "", "ignore", "default"))
+ goto do_unset;
+ else {
+ g_set_error(error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is not valid; use 'on', 'off', or 'ignore'"),
+ value);
+ return FALSE;
+ }
+
+ nm_setting_option_set_boolean(setting, nm_ethtool_data[ethtool_id]->optname, b);
+ return TRUE;
+
+do_unset:
+ nm_setting_option_set(setting, nm_ethtool_data[ethtool_id]->optname, NULL);
+ return TRUE;
+}
+
+static const char *const *_complete_fcn_ethtool(ARGS_COMPLETE_FCN)
+{
+ static const char *const v[] = {
+ "true",
+ "false",
+ "1",
+ "0",
+ "yes",
+ "no",
+ "default",
+ "on",
+ "off",
+ "ignore",
+ NULL,
+ };
+ NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
+
+ if (nm_ethtool_id_is_feature(ethtool_id)) {
+ if (!text || !text[0])
+ return &v[7];
+ return v;
+ }
+ return NULL;
+}
+
+/*****************************************************************************/
+
+/* clang-format off */
+
+static const NMMetaPropertyInfo property_info_BOND_OPTIONS;
+
+#define NESTED_PROPERTY_INFO_BOND(...) \
+ .parent_info = &property_info_BOND_OPTIONS, \
+ .base = { \
+ .meta_type = &nm_meta_type_nested_property_info, \
+ .setting_info = &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_BOND], \
+ __VA_ARGS__ \
+ }
+
+static const NMMetaNestedPropertyInfo meta_nested_property_infos_bond[] = {
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ .property_alias = "mode",
+ .prompt = NM_META_TEXT_PROMPT_BOND_MODE,
+ .def_hint = "[balance-rr]",
+ )
+ },
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ .property_alias = "primary",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .prompt = N_("Bonding primary interface [none]"),
+ )
+ },
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ /* this is a virtual property, only needed during "ask" mode. */
+ .prompt = N_("Bonding monitoring mode"),
+ .def_hint = NM_META_TEXT_PROMPT_BOND_MON_MODE_CHOICES,
+ )
+ },
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ .property_alias = "miimon",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .prompt = N_("Bonding miimon [100]"),
+ )
+ },
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ .property_alias = "downdelay",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .prompt = N_("Bonding downdelay [0]"),
+ )
+ },
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ .property_alias = "updelay",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .prompt = N_("Bonding updelay [0]"),
+ )
+ },
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ .property_alias = "arp-interval",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .prompt = N_("Bonding arp-interval [0]"),
+ )
+ },
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ .property_alias = "arp-ip-target",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .prompt = N_("Bonding arp-ip-target [none]"),
+ )
+ },
+ {
+ NESTED_PROPERTY_INFO_BOND (
+ .property_name = NM_SETTING_BOND_OPTIONS,
+ .property_alias = "lacp-rate",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .prompt = N_("LACP rate ('slow' or 'fast') [slow]"),
+ )
+ },
+};
+
+const NMMetaPropertyTypDataNested nm_meta_property_typ_data_bond = {
+ .nested = meta_nested_property_infos_bond,
+ .nested_len = G_N_ELEMENTS (meta_nested_property_infos_bond),
+};
+
+/*****************************************************************************/
+
+#define DEFINE_PROPERTY_TYPE(...) \
+ (&((NMMetaPropertyType) { __VA_ARGS__ } ))
+
+#define DEFINE_PROPERTY_TYP_DATA(...) \
+ (&((NMMetaPropertyTypData) { __VA_ARGS__ } ))
+
+#define PROPERTY_TYP_DATA_SUBTYPE(stype, ...) \
+ .subtype = { \
+ .stype = { __VA_ARGS__ }, \
+ }
+
+#define DEFINE_PROPERTY_TYP_DATA_SUBTYPE(stype, ...) \
+ DEFINE_PROPERTY_TYP_DATA ( \
+ PROPERTY_TYP_DATA_SUBTYPE (stype, __VA_ARGS__), \
+ )
+
+static const NMMetaPropertyType _pt_gobject_readonly = {
+ .get_fcn = _get_fcn_gobject,
+};
+
+static const NMMetaPropertyType _pt_gobject_string = {
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gobject_string,
+};
+
+static const NMMetaPropertyType _pt_gobject_bool = {
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gobject_bool,
+ .complete_fcn = _complete_fcn_gobject_bool,
+};
+
+static const NMMetaPropertyType _pt_gobject_int = {
+ .get_fcn = _get_fcn_gobject_int,
+ .set_fcn = _set_fcn_gobject_int,
+};
+
+static const NMMetaPropertyType _pt_gobject_mtu = {
+ .get_fcn = _get_fcn_gobject_mtu,
+ .set_fcn = _set_fcn_gobject_mtu,
+};
+
+static const NMMetaPropertyType _pt_gobject_bytes = {
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gobject_bytes,
+};
+
+static const NMMetaPropertyType _pt_gobject_mac = {
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gobject_mac,
+};
+
+static const NMMetaPropertyType _pt_gobject_secret_flags = {
+ .get_fcn = _get_fcn_gobject_secret_flags,
+ .set_fcn = _set_fcn_gobject_enum,
+ .values_fcn = _values_fcn_gobject_enum,
+ .set_supports_remove = TRUE,
+};
+
+static const NMMetaPropertyType _pt_gobject_enum = {
+ .get_fcn = _get_fcn_gobject_enum,
+ .set_fcn = _set_fcn_gobject_enum,
+ .values_fcn = _values_fcn_gobject_enum,
+ .set_supports_remove = TRUE,
+};
+
+static const NMMetaPropertyType _pt_gobject_devices = {
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gobject_string,
+ .complete_fcn = _complete_fcn_gobject_devices,
+};
+
+static const NMMetaPropertyType _pt_dcb_flags = {
+ .get_fcn = _get_fcn_dcb_flags,
+ .set_fcn = _set_fcn_dcb_flags,
+};
+
+static const NMMetaPropertyType _pt_dcb_bool = {
+ .get_fcn = _get_fcn_dcb_bool,
+ .set_fcn = _set_fcn_dcb_bool,
+};
+
+static const NMMetaPropertyType _pt_dcb = {
+ .get_fcn = _get_fcn_dcb,
+ .set_fcn = _set_fcn_dcb,
+};
+
+static const NMMetaPropertyType _pt_cert_8021x = {
+ .get_fcn = _get_fcn_cert_8021x,
+ .set_fcn = _set_fcn_cert_8021x,
+ .complete_fcn = _complete_fcn_cert_8021x,
+};
+
+static const NMMetaPropertyType _pt_ethtool = {
+ .get_fcn = _get_fcn_ethtool,
+ .set_fcn = _set_fcn_ethtool,
+ .complete_fcn = _complete_fcn_ethtool,
+};
+
+static const NMMetaPropertyType _pt_multilist = {
+ .get_fcn = _get_fcn_multilist,
+ .set_fcn = _set_fcn_multilist,
+ .set_supports_remove = TRUE,
+};
+
+static const NMMetaPropertyType _pt_objlist = {
+ .get_fcn = _get_fcn_objlist,
+ .set_fcn = _set_fcn_objlist,
+ .set_supports_remove = TRUE,
+};
+
+#define MULTILIST_GET_NUM_FCN_U32(type, func) (((func) == ((guint32 (*) (type * )) (func))) ? ((guint32 (*) (NMSetting * )) (func)) : NULL)
+#define MULTILIST_GET_NUM_FCN_U(type, func) (((func) == ((guint (*) (type * )) (func))) ? ((guint (*) (NMSetting * )) (func)) : NULL)
+#define MULTILIST_ADD_FCN(type, func) (((func) == ((gboolean (*) (type *, const char *)) (func))) ? ((gboolean (*) (NMSetting *, const char *)) (func)) : NULL)
+#define MULTILIST_ADD2_FCN(type, func) (((func) == ((void (*) (type *, const char *)) (func))) ? ((void (*) (NMSetting *, const char *)) (func)) : NULL)
+#define MULTILIST_REMOVE_BY_IDX_FCN_U32(type, func) (((func) == ((void (*) (type *, guint32 )) (func))) ? ((void (*) (NMSetting *, guint32 )) (func)) : NULL)
+#define MULTILIST_REMOVE_BY_IDX_FCN_S(type, func) (((func) == ((void (*) (type *, int )) (func))) ? ((void (*) (NMSetting *, int )) (func)) : NULL)
+#define MULTILIST_REMOVE_BY_IDX_FCN_U(type, func) (((func) == ((void (*) (type *, guint )) (func))) ? ((void (*) (NMSetting *, guint )) (func)) : NULL)
+#define MULTILIST_REMOVE_BY_VALUE_FCN(type, func) (((func) == ((gboolean (*) (type *, const char *)) (func))) ? ((gboolean (*) (NMSetting *, const char *)) (func)) : NULL)
+#define MULTILIST_CLEAR_EMPTYUNSET_FCN(type, func) (((func) == ((void (*) (type *, gboolean )) (func))) ? ((void (*) (NMSetting *, gboolean )) (func)) : NULL)
+
+#define OBJLIST_GET_NUM_FCN(type, func) (((func) == ((guint (*) (type * )) (func))) ? ((guint (*) (NMSetting * )) (func)) : NULL)
+#define OBJLIST_CLEAR_ALL_FCN(type, func) (((func) == ((void (*) (type * )) (func))) ? ((void (*) (NMSetting * )) (func)) : NULL)
+#define OBJLIST_REMOVE_BY_IDX_FCN_U(type, func) (((func) == ((void (*) (type *, guint )) (func))) ? ((void (*) (NMSetting *, guint )) (func)) : NULL)
+#define OBJLIST_REMOVE_BY_IDX_FCN_S(type, func) (((func) == ((void (*) (type *, int )) (func))) ? ((void (*) (NMSetting *, int )) (func)) : NULL)
+
+/*****************************************************************************/
+
+#include "libnmc-setting/settings-docs.h"
+
+/*****************************************************************************/
+
+#define PROPERTY_INFO_INIT(name, doc, ...) \
+ { \
+ .meta_type = &nm_meta_type_property_info, \
+ .setting_info = &nm_meta_setting_infos_editor[_CURRENT_NM_META_SETTING_TYPE], \
+ .property_name = name, \
+ .describe_doc = doc, \
+ __VA_ARGS__ \
+ }
+
+#define PROPERTY_INFO(name, doc, ...) \
+ (&((const NMMetaPropertyInfo) PROPERTY_INFO_INIT (name, doc, __VA_ARGS__)))
+
+#define PROPERTY_INFO_WITH_DESC(name, ...) \
+ PROPERTY_INFO (name, DESCRIBE_DOC_##name, ##__VA_ARGS__)
+
+#define ENUM_VALUE_INFOS(...) (((const NMUtilsEnumValueInfo []) { __VA_ARGS__ { .nick = NULL, }, }))
+#define INT_VALUE_INFOS(...) (((const NMMetaUtilsIntValueInfo []) { __VA_ARGS__ { .nick = NULL, }, }))
+
+#define MTU_GET_FCN(type, func) \
+ /* macro that returns @func as const (guint32(*)(NMSetting*)) type, but checks
+ * that the actual type is (guint32(*)(type *)). */ \
+ ((guint32 (*) (NMSetting *)) ((sizeof (func == ((guint32 (*) (type *)) func))) ? func : func) )
+
+#define TEAM_DESCRIBE_MESSAGE \
+ N_("nmcli can accepts both direct JSON configuration data and a file name containing " \
+ "the configuration. In the latter case the file is read and the contents is put " \
+ "into this property.\n\n" \
+ "Examples: set team.config " \
+ "{ \"device\": \"team0\", \"runner\": {\"name\": \"roundrobin\"}, \"ports\": {\"eth1\": {}, \"eth2\": {}} }\n" \
+ " set team.config /etc/my-team.conf\n")
+
+#define TEAM_LINK_WATCHERS_DESCRIBE_MESSAGE \
+ N_("Enter a list of link watchers formatted as dictionaries where the keys " \
+ "are teamd properties. Dictionary pairs are in the form: key=value and pairs " \
+ "are separated by ' '. Dictionaries are separated with ','.\n" \
+ "The keys allowed/required in the dictionary change on the basis of the link " \
+ "watcher type, while the only property common to all the link watchers is " \
+ " 'name'*, which defines the link watcher to be specified.\n\n" \
+ "Properties available for the 'ethtool' link watcher:\n" \
+ " 'delay-up', 'delay-down'\n\n" \
+ "Properties available for the 'nsna_ping' link watcher:\n" \
+ " 'init-wait', 'interval', 'missed-max', 'target-host'*\n\n" \
+ "Properties available for the 'arp_ping' include all the ones for 'nsna_ping' and:\n" \
+ " 'source-host'*, 'validate-active', 'validate-inactive', 'send-always'.\n\n" \
+ "Properties flagged with a '*' are mandatory.\n\n" \
+ "Example:\n" \
+ " name=arp_ping source-host=172.16.1.1 target-host=172.16.1.254, name=ethtool delay-up=3\n")
+
+#define DEFINE_DCB_PROPRITY_PROPERTY_TYPE \
+ .property_type = &_pt_gobject_int, \
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, \
+ .value_infos = INT_VALUE_INFOS ( \
+ { \
+ .value.i64 = -1, \
+ .nick = "unset", \
+ }, \
+ ), \
+ ),
+
+static const NMMetaPropertyTypData _ptd_gobject_int_timeout = {
+ PROPERTY_TYP_DATA_SUBTYPE (
+ gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = 0,
+ .nick = "default",
+ },
+ {
+ .value.i64 = G_MAXINT32,
+ .nick = "infinity",
+ },
+ ),
+ ),
+};
+
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_6LOWPAN
+static const NMMetaPropertyInfo *const property_infos_6LOWPAN[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_6LOWPAN_PARENT,
+ .is_cli_option = TRUE,
+ .property_alias = "dev",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("IEEE 802.15.4 (WPAN) parent device or connection UUID"),
+ .property_type = &_pt_gobject_string,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_802_1X
+static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_OPTIONAL,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_EAP,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSetting8021x, nm_setting_802_1x_get_num_eap_methods),
+ .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_eap_method),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_eap_method),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_eap_method_by_value),
+ .strsplit_plain = TRUE,
+ ),
+ .values_static = NM_MAKE_STRV ("leap", "md5", "tls", "peap", "ttls", "sim", "fast", "pwd"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_IDENTITY,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_ANONYMOUS_IDENTITY,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PAC_FILE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CA_CERT,
+ .describe_message =
+ N_("Enter file path to CA certificate (optionally prefixed with file://).\n"
+ " [file://]<file path>\n"
+ "Note that nmcli does not support specifying certificates as raw blob data.\n"
+ "Example: /home/cimrman/cacert.crt\n"),
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CA_CERT_PASSWORD,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CA_CERT_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CA_PATH,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_SUBJECT_MATCH,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_ALTSUBJECT_MATCHES,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSetting8021x, nm_setting_802_1x_get_num_altsubject_matches),
+ .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_altsubject_match),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_altsubject_match),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_altsubject_match_by_value),
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_DOMAIN_MATCH,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CLIENT_CERT,
+ .describe_message =
+ N_("Enter file path to client certificate (optionally prefixed with file://).\n"
+ " [file://]<file path>\n"
+ "Note that nmcli does not support specifying certificates as raw blob data.\n"
+ "Example: /home/cimrman/jara.crt\n"),
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CLIENT_CERT_PASSWORD,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CLIENT_CERT_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE1_PEAPVER,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("0", "1"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE1_PEAPLABEL,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("0", "1"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("0", "1", "2", "3"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE1_AUTH_FLAGS,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_802_1x_auth_flags_get_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_AUTH,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", "tls"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_AUTHEAP,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("md5", "mschapv2", "otp", "gtc", "tls"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CA_CERT,
+ .describe_message =
+ N_("Enter file path to CA certificate for inner authentication (optionally prefixed\n"
+ "with file://).\n"
+ " [file://]<file path>\n"
+ "Note that nmcli does not support specifying certificates as raw blob data.\n"
+ "Example: /home/cimrman/ca-zweite-phase.crt\n"),
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CA_PATH,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSetting8021x, nm_setting_802_1x_get_num_phase2_altsubject_matches),
+ .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_phase2_altsubject_match),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_phase2_altsubject_match),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_phase2_altsubject_match_by_value),
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+ .describe_message =
+ N_("Enter file path to client certificate for inner authentication (optionally prefixed\n"
+ "with file://).\n"
+ " [file://]<file path>\n"
+ "Note that nmcli does not support specifying certificates as raw blob data.\n"
+ "Example: /home/cimrman/jara-zweite-phase.crt\n"),
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PASSWORD,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PASSWORD_RAW,
+ .is_secret = TRUE,
+ .describe_message =
+ N_("Enter bytes as a list of hexadecimal values.\n"
+ "Two formats are accepted:\n"
+ "(a) a string of hexadecimal digits, where each two digits represent one byte\n"
+ "(b) space-separated list of bytes written as hexadecimal digits "
+ "(with optional 0x/0X prefix, and optional leading 0).\n\n"
+ "Examples: ab0455a6ea3a74C2\n"
+ " ab 4 55 0xa6 ea 3a 74 C2\n"),
+ .property_type = &_pt_gobject_bytes,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_bytes,
+ .legacy_format = TRUE,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PRIVATE_KEY,
+ .describe_message =
+ N_("Enter path to a private key and the key password (if not set yet):\n"
+ " [file://]<file path> [<password>]\n"
+ "Note that nmcli does not support specifying private key as raw blob data.\n"
+ "Example: /home/cimrman/jara-priv-key Dardanely\n"),
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ .describe_message =
+ N_("Enter path to a private key and the key password (if not set yet):\n"
+ " [file://]<file path> [<password>]\n"
+ "Note that nmcli does not support specifying private key as raw blob data.\n"
+ "Example: /home/cimrman/jara-priv-key Dardanely\n"),
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PIN,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PIN_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_SYSTEM_CA_CERTS,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_AUTH_TIMEOUT,
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_ADSL
+static const NMMetaPropertyInfo *const property_infos_ADSL[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_USERNAME,
+ .is_cli_option = TRUE,
+ .property_alias = "username",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("Username"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_PASSWORD,
+ .is_cli_option = TRUE,
+ .property_alias = "password",
+ .prompt = N_("Password [none]"),
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_PROTOCOL,
+ .is_cli_option = TRUE,
+ .property_alias = "protocol",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = NM_META_TEXT_PROMPT_ADSL_PROTO,
+ .def_hint = NM_META_TEXT_PROMPT_ADSL_PROTO_CHOICES,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_ADSL_PROTOCOL_PPPOA,
+ NM_SETTING_ADSL_PROTOCOL_PPPOE,
+ NM_SETTING_ADSL_PROTOCOL_IPOATM),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_ENCAPSULATION,
+ .is_cli_option = TRUE,
+ .property_alias = "encapsulation",
+ .prompt = NM_META_TEXT_PROMPT_ADSL_ENCAP,
+ .def_hint = NM_META_TEXT_PROMPT_ADSL_ENCAP_CHOICES,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_ADSL_ENCAPSULATION_VCMUX,
+ NM_SETTING_ADSL_ENCAPSULATION_LLC),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_VPI,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_ADSL_VCI,
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BLUETOOTH
+static const NMMetaPropertyInfo *const property_infos_BLUETOOTH[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BLUETOOTH_BDADDR,
+ .is_cli_option = TRUE,
+ .property_alias = "addr",
+ .prompt = N_("Bluetooth device address"),
+ .property_type = &_pt_gobject_mac,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BLUETOOTH_TYPE,
+ .is_cli_option = TRUE,
+ .property_alias = "bt-type",
+ .prompt = NM_META_TEXT_PROMPT_BT_TYPE,
+ .def_hint = NM_META_TEXT_PROMPT_BT_TYPE_CHOICES,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_BLUETOOTH_TYPE_DUN,
+ NM_SETTING_BLUETOOTH_TYPE_PANU,
+ NM_SETTING_BLUETOOTH_TYPE_NAP),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BOND
+static const NMMetaPropertyInfo property_info_BOND_OPTIONS =
+ PROPERTY_INFO_INIT (NM_SETTING_BOND_OPTIONS, DESCRIBE_DOC_NM_SETTING_BOND_OPTIONS,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .describe_fcn = _describe_fcn_bond_options,
+ .get_fcn = _get_fcn_bond_options,
+ .set_fcn = _set_fcn_optionlist,
+ .set_supports_remove = TRUE,
+ .values_fcn = _values_fcn_bond_options,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (optionlist,
+ .set_fcn = _nm_meta_setting_bond_add_option,
+ ),
+ .nested = &nm_meta_property_typ_data_bond,
+ ),
+ );
+
+static const NMMetaPropertyInfo *const property_infos_BOND[] = {
+ &property_info_BOND_OPTIONS,
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BRIDGE
+static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MAC_ADDRESS,
+ .is_cli_option = TRUE,
+ .property_alias = "mac",
+ .prompt = N_("MAC [none]"),
+ .property_type = &_pt_gobject_mac,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_STP,
+ .is_cli_option = TRUE,
+ .property_alias = "stp",
+ .prompt = N_("Enable STP [no]"),
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PRIORITY,
+ .is_cli_option = TRUE,
+ .property_alias = "priority",
+ .prompt = N_("STP priority [32768]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_FORWARD_DELAY,
+ .is_cli_option = TRUE,
+ .property_alias = "forward-delay",
+ .prompt = N_("Forward delay [15]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_HELLO_TIME,
+ .is_cli_option = TRUE,
+ .property_alias = "hello-time",
+ .prompt = N_("Hello time [2]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MAX_AGE,
+ .is_cli_option = TRUE,
+ .property_alias = "max-age",
+ .prompt = N_("Max age [20]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_AGEING_TIME,
+ .is_cli_option = TRUE,
+ .property_alias = "ageing-time",
+ .prompt = N_("MAC address ageing time [300]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_GROUP_ADDRESS,
+ .property_type = &_pt_gobject_mac,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_GROUP_FORWARD_MASK,
+ .is_cli_option = TRUE,
+ .property_alias = "group-forward-mask",
+ .prompt = N_("Group forward mask [0]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_HASH_MAX,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERIER,
+ .property_type = &_pt_gobject_bool,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR,
+ .property_type = &_pt_gobject_bool,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_SNOOPING,
+ .is_cli_option = TRUE,
+ .property_alias = "multicast-snooping",
+ .prompt = N_("Enable IGMP snooping [no]"),
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_ROUTER,
+ .property_type = &_pt_gobject_string,
+ .hide_if_default = TRUE,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("auto",
+ "disabled",
+ "enabled"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_FILTERING,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_STATS_ENABLED,
+ .property_type = &_pt_gobject_bool,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_PROTOCOL,
+ .property_type = &_pt_gobject_string,
+ .hide_if_default = TRUE,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("802.1Q",
+ "802.1ad"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLANS,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingBridge, nm_setting_bridge_get_num_vlans),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingBridge, nm_setting_bridge_clear_vlans),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_bridge_vlans,
+ .set_fcn = _objlist_set_fcn_bridge_vlans,
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BRIDGE_PORT
+static const NMMetaPropertyInfo *const property_infos_BRIDGE_PORT[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PORT_PRIORITY,
+ .is_cli_option = TRUE,
+ .property_alias = "priority",
+ .prompt = N_("Bridge port priority [32]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PORT_PATH_COST,
+ .is_cli_option = TRUE,
+ .property_alias = "path-cost",
+ .prompt = N_("Bridge port STP path cost [100]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE,
+ .is_cli_option = TRUE,
+ .property_alias = "hairpin",
+ .prompt = N_("Hairpin [no]"),
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_PORT_VLANS,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingBridgePort, nm_setting_bridge_port_get_num_vlans),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingBridgePort, nm_setting_bridge_port_clear_vlans),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_bridge_vlans,
+ .set_fcn = _objlist_set_fcn_bridge_vlans,
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_CDMA
+static const NMMetaPropertyInfo *const property_infos_CDMA[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CDMA_NUMBER,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CDMA_USERNAME,
+ .is_cli_option = TRUE,
+ .property_alias = "user",
+ .prompt = N_("Username [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CDMA_PASSWORD,
+ .is_cli_option = TRUE,
+ .property_alias = "password",
+ .prompt = N_("Password [none]"),
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CDMA_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CDMA_MTU,
+ .property_type = &_pt_gobject_mtu,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu,
+ .get_fcn = MTU_GET_FCN (NMSettingCdma, nm_setting_cdma_get_mtu),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_CONNECTION
+static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_ID,
+ .is_cli_option = TRUE,
+ .property_alias = "con-name",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_UUID,
+ .property_type = DEFINE_PROPERTY_TYPE ( .get_fcn = _get_fcn_gobject ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_STABLE_ID,
+ .property_type = &_pt_gobject_string,
+ ),
+[_NM_META_PROPERTY_TYPE_CONNECTION_TYPE] =
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_TYPE,
+ .is_cli_option = TRUE,
+ .property_alias = "type",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = NM_META_TEXT_PROMPT_CON_TYPE,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_connection_type,
+ .complete_fcn = _complete_fcn_connection_type,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_INTERFACE_NAME,
+ .is_cli_option = TRUE,
+ .property_alias = "ifname",
+ .prompt = NM_META_TEXT_PROMPT_IFNAME,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gobject_ifname,
+ .complete_fcn = _complete_fcn_gobject_devices,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_AUTOCONNECT,
+ .is_cli_option = TRUE,
+ .property_alias = "autoconnect",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "default",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "forever",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_MULTI_CONNECT,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_connection_multi_connect_get_type,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_AUTH_RETRIES,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_TIMESTAMP,
+ .property_type = &_pt_gobject_readonly,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_READ_ONLY,
+ .property_type = &_pt_gobject_readonly,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_PERMISSIONS,
+ .describe_message =
+ N_("Enter a list of user permissions. This is a list of user names formatted as:\n"
+ " [user:]<user name 1>, [user:]<user name 2>,...\n"
+ "The items can be separated by commas or spaces.\n\n"
+ "Example: alice bob charlie\n"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_connection_permissions,
+ .set_fcn = _set_fcn_multilist,
+ .set_supports_remove = TRUE,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingConnection, nm_setting_connection_get_num_permissions),
+ .add_fcn = _multilist_set_fcn_connection_permissions,
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingConnection, nm_setting_connection_remove_permission),
+ .remove_by_value_fcn = _multilist_remove_by_value_fcn_connection_permissions,
+ .validate2_fcn = _multilist_validate2_fcn_connection_permissions,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_ZONE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_MASTER,
+ .is_cli_option = TRUE,
+ .property_alias = "master",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .prompt = NM_META_TEXT_PROMPT_MASTER,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gobject_string,
+ .complete_fcn = _complete_fcn_connection_master,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_SLAVE_TYPE,
+ .is_cli_option = TRUE,
+ .property_alias = "slave-type",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_DONT_ASK,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_BOND_SETTING_NAME,
+ NM_SETTING_BRIDGE_SETTING_NAME,
+ NM_SETTING_OVS_BRIDGE_SETTING_NAME,
+ NM_SETTING_OVS_PORT_SETTING_NAME,
+ NM_SETTING_TEAM_SETTING_NAME,
+ NM_SETTING_VRF_SETTING_NAME),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES,
+ .property_type = &_pt_gobject_enum,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_SECONDARIES,
+ .describe_message =
+ N_("Enter secondary connections that should be activated when this connection is\n"
+ "activated. Connections can be specified either by UUID or ID (name). nmcli\n"
+ "transparently translates names to UUIDs. Note that NetworkManager only supports\n"
+ "VPNs as secondary connections at the moment.\n"
+ "The items can be separated by commas or spaces.\n\n"
+ "Example: private-openvpn, fe6ba5d8-c2fc-4aae-b2e3-97efddd8d9a7\n"),
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingConnection, nm_setting_connection_get_num_secondaries),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingConnection, nm_setting_connection_add_secondary),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingConnection, nm_setting_connection_remove_secondary),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingConnection, nm_setting_connection_remove_secondary_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_uuid,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_METERED,
+ .describe_message =
+ N_("Enter a value which indicates whether the connection is subject to a data\n"
+ "quota, usage costs or other limitations. Accepted options are:\n"
+ "'true','yes','on' to set the connection as metered\n"
+ "'false','no','off' to set the connection as not metered\n"
+ "'unknown' to let NetworkManager choose a value using some heuristics\n"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_connection_metered,
+ .set_fcn = _set_fcn_connection_metered,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("yes", "no", "unknown"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_LLDP,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_connection_lldp_get_type,
+ .value_infos = ENUM_VALUE_INFOS (
+ {
+ .value = NM_SETTING_CONNECTION_LLDP_ENABLE_RX,
+ .nick = "enable",
+ },
+ ),
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_MDNS,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_connection_mdns_get_type,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_LLMNR,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_connection_llmnr_get_type,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_MUD_URL,
+ .property_type = &_pt_gobject_string,
+ .hide_if_default = TRUE,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT,
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_DCB
+static const NMMetaPropertyInfo *const property_infos_DCB[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FCOE_FLAGS,
+ .property_type = &_pt_dcb_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FCOE_PRIORITY,
+ DEFINE_DCB_PROPRITY_PROPERTY_TYPE
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FCOE_MODE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_DCB_FCOE_MODE_FABRIC,
+ NM_SETTING_DCB_FCOE_MODE_VN2VN),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_ISCSI_FLAGS,
+ .property_type = &_pt_dcb_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_ISCSI_PRIORITY,
+ DEFINE_DCB_PROPRITY_PROPERTY_TYPE
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FIP_FLAGS,
+ .property_type = &_pt_dcb_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FIP_PRIORITY,
+ DEFINE_DCB_PROPRITY_PROPERTY_TYPE
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS,
+ .property_type = &_pt_dcb_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL,
+ .property_type = &_pt_dcb_bool,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb_bool,
+ .get_fcn = nm_setting_dcb_get_priority_flow_control,
+ .set_fcn = nm_setting_dcb_set_priority_flow_control,
+ .with_flow_control_flags = TRUE,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS,
+ .property_type = &_pt_dcb_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_GROUP_ID,
+ .property_type = &_pt_dcb,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb,
+ .get_fcn = nm_setting_dcb_get_priority_group_id,
+ .set_fcn = nm_setting_dcb_set_priority_group_id,
+ .max = 7,
+ .other = 15,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH,
+ .property_type = &_pt_dcb,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb,
+ .get_fcn = nm_setting_dcb_get_priority_group_bandwidth,
+ .set_fcn = nm_setting_dcb_set_priority_group_bandwidth,
+ .max = 100,
+ .other = 0,
+ .is_percent = TRUE,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_BANDWIDTH,
+ .property_type = &_pt_dcb,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb,
+ .get_fcn = nm_setting_dcb_get_priority_bandwidth,
+ .set_fcn = nm_setting_dcb_set_priority_bandwidth,
+ .max = 100,
+ .other = 0,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH,
+ .property_type = &_pt_dcb_bool,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb_bool,
+ .get_fcn = nm_setting_dcb_get_priority_strict_bandwidth,
+ .set_fcn = nm_setting_dcb_set_priority_strict_bandwidth,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS,
+ .property_type = &_pt_dcb,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb,
+ .get_fcn = nm_setting_dcb_get_priority_traffic_class,
+ .set_fcn = nm_setting_dcb_set_priority_traffic_class,
+ .max = 7,
+ .other = 0,
+ ),
+ ),
+ NULL
+};
+
+#define PROPERTY_INFO_ETHTOOL(xname) \
+ PROPERTY_INFO (NM_ETHTOOL_OPTNAME_##xname, NULL, \
+ .property_type = &_pt_ethtool, \
+ .hide_if_default = TRUE, \
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (ethtool, \
+ .ethtool_id = NM_ETHTOOL_ID_##xname, \
+ ), \
+ )
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_ETHTOOL
+static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = {
+ PROPERTY_INFO_ETHTOOL (FEATURE_ESP_HW_OFFLOAD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_ESP_TX_CSUM_HW_OFFLOAD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_FCOE_MTU),
+ PROPERTY_INFO_ETHTOOL (FEATURE_GRO),
+ PROPERTY_INFO_ETHTOOL (FEATURE_GSO),
+ PROPERTY_INFO_ETHTOOL (FEATURE_HIGHDMA),
+ PROPERTY_INFO_ETHTOOL (FEATURE_HW_TC_OFFLOAD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_L2_FWD_OFFLOAD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_LOOPBACK),
+ PROPERTY_INFO_ETHTOOL (FEATURE_LRO),
+ PROPERTY_INFO_ETHTOOL (FEATURE_MACSEC_HW_OFFLOAD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_NTUPLE),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RXHASH),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RXVLAN),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_ALL),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_FCS),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_GRO_HW),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_GRO_LIST),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_UDP_GRO_FORWARDING),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_VLAN_FILTER),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_VLAN_STAG_FILTER),
+ PROPERTY_INFO_ETHTOOL (FEATURE_RX_VLAN_STAG_HW_PARSE),
+ PROPERTY_INFO_ETHTOOL (FEATURE_SG),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TLS_HW_RECORD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TLS_HW_RX_OFFLOAD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TLS_HW_TX_OFFLOAD),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TSO),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TXVLAN),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_FCOE_CRC),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_IPV4),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_IPV6),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_IP_GENERIC),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_CHECKSUM_SCTP),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_ESP_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_FCOE_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_GRE_CSUM_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_GRE_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_GSO_LIST),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_GSO_PARTIAL),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_GSO_ROBUST),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_IPXIP4_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_IPXIP6_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_NOCACHE_COPY),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_SCATTER_GATHER),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_SCATTER_GATHER_FRAGLIST),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_SCTP_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP6_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP_ECN_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP_MANGLEID_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_TCP_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_TUNNEL_REMCSUM_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_UDP_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_UDP_TNL_SEGMENTATION),
+ PROPERTY_INFO_ETHTOOL (FEATURE_TX_VLAN_STAG_HW_INSERT),
+ PROPERTY_INFO_ETHTOOL (COALESCE_ADAPTIVE_RX),
+ PROPERTY_INFO_ETHTOOL (COALESCE_ADAPTIVE_TX),
+ PROPERTY_INFO_ETHTOOL (COALESCE_PKT_RATE_HIGH),
+ PROPERTY_INFO_ETHTOOL (COALESCE_PKT_RATE_LOW),
+ PROPERTY_INFO_ETHTOOL (COALESCE_RX_FRAMES),
+ PROPERTY_INFO_ETHTOOL (COALESCE_RX_FRAMES_IRQ),
+ PROPERTY_INFO_ETHTOOL (COALESCE_RX_FRAMES_HIGH),
+ PROPERTY_INFO_ETHTOOL (COALESCE_RX_FRAMES_LOW),
+ PROPERTY_INFO_ETHTOOL (COALESCE_RX_USECS),
+ PROPERTY_INFO_ETHTOOL (COALESCE_RX_USECS_IRQ),
+ PROPERTY_INFO_ETHTOOL (COALESCE_RX_USECS_HIGH),
+ PROPERTY_INFO_ETHTOOL (COALESCE_RX_USECS_LOW),
+ PROPERTY_INFO_ETHTOOL (COALESCE_SAMPLE_INTERVAL),
+ PROPERTY_INFO_ETHTOOL (COALESCE_STATS_BLOCK_USECS),
+ PROPERTY_INFO_ETHTOOL (COALESCE_TX_FRAMES),
+ PROPERTY_INFO_ETHTOOL (COALESCE_TX_FRAMES_IRQ),
+ PROPERTY_INFO_ETHTOOL (COALESCE_TX_FRAMES_HIGH),
+ PROPERTY_INFO_ETHTOOL (COALESCE_TX_FRAMES_LOW),
+ PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS),
+ PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_IRQ),
+ PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_HIGH),
+ PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_LOW),
+ PROPERTY_INFO_ETHTOOL (RING_RX),
+ PROPERTY_INFO_ETHTOOL (RING_RX_JUMBO),
+ PROPERTY_INFO_ETHTOOL (RING_RX_MINI),
+ PROPERTY_INFO_ETHTOOL (RING_TX),
+ NULL,
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_GSM
+static const NMMetaPropertyInfo *const property_infos_GSM[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_AUTO_CONFIG,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_NUMBER,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_USERNAME,
+ .is_cli_option = TRUE,
+ .property_alias = "user",
+ .prompt = N_("Username [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_PASSWORD,
+ .is_cli_option = TRUE,
+ .property_alias = "password",
+ .prompt = N_("Password [none]"),
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_APN,
+ .is_cli_option = TRUE,
+ .property_alias = "apn",
+ .prompt = N_("APN"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_NETWORK_ID,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_PIN,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_PIN_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_HOME_ONLY,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_DEVICE_ID,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_SIM_ID,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_SIM_OPERATOR_ID,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gsm_sim_operator_id,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_MTU,
+ .property_type = &_pt_gobject_mtu,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu,
+ .get_fcn = MTU_GET_FCN (NMSettingGsm, nm_setting_gsm_get_mtu),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_HOSTNAME
+static const NMMetaPropertyInfo *const property_infos_HOSTNAME[] = {
+ PROPERTY_INFO (NM_SETTING_HOSTNAME_PRIORITY, DESCRIBE_DOC_NM_SETTING_HOSTNAME_PRIORITY,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO (NM_SETTING_HOSTNAME_FROM_DHCP, DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DHCP,
+ .property_type = &_pt_gobject_enum,
+ ),
+ PROPERTY_INFO (NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP, DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP,
+ .property_type = &_pt_gobject_enum,
+ ),
+ PROPERTY_INFO (NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT, DESCRIBE_DOC_NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT,
+ .property_type = &_pt_gobject_enum,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_INFINIBAND
+static const NMMetaPropertyInfo *const property_infos_INFINIBAND[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_MAC_ADDRESS,
+ .is_cli_option = TRUE,
+ .property_alias = "mac",
+ .prompt = N_("MAC [none]"),
+ .property_type = &_pt_gobject_mac,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mac,
+ .mode = NM_META_PROPERTY_TYPE_MAC_MODE_INFINIBAND,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_MTU,
+ .is_cli_option = TRUE,
+ .property_alias = "mtu",
+ .prompt = N_("MTU [auto]"),
+ .property_type = &_pt_gobject_mtu,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu,
+ .get_fcn = MTU_GET_FCN (NMSettingInfiniband, nm_setting_infiniband_get_mtu),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_TRANSPORT_MODE,
+ .is_cli_option = TRUE,
+ .property_alias = "transport-mode",
+ .prompt = NM_META_TEXT_PROMPT_IB_MODE,
+ .def_hint = NM_META_TEXT_PROMPT_IB_MODE_CHOICES,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("datagram", "connected"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_P_KEY,
+ .is_cli_option = TRUE,
+ .property_alias = "p-key",
+ .prompt = N_("P_KEY [none]"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_infiniband_p_key,
+ .set_fcn = _set_fcn_infiniband_p_key,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_INFINIBAND_PARENT,
+ .is_cli_option = TRUE,
+ .property_alias = "parent",
+ .prompt = N_("Parent interface [none]"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_gobject_ifname,
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_IP4_CONFIG
+static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = {
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_METHOD, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_METHOD,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_ip_config_method,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
+ NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NM_SETTING_IP4_CONFIG_METHOD_SHARED,
+ NM_SETTING_IP4_CONFIG_METHOD_DISABLED),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS,
+ .describe_message =
+ N_("Enter a list of IPv4 addresses of DNS servers.\n\n"
+ "Example: 8.8.8.8, 8.8.4.4\n"),
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dns),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_ip_config_dns,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_SEARCH, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns_searches),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dns_search),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search_by_value),
+ .validate_fcn = _multilist_validate_fcn_is_domain,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_OPTIONS, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns_options),
+ .add_fcn = _multilist_add_fcn_ip_config_dns_options,
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option_by_value),
+ .clear_emptyunset_fcn = MULTILIST_CLEAR_EMPTYUNSET_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_dns_options),
+ .strsplit_plain = TRUE,
+ ),
+ .is_default_fcn = _is_default_func_ip_config_dns_options,
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_PRIORITY, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ADDRESSES, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES,
+ .is_cli_option = TRUE,
+ .property_alias = "ip4",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_MULTI,
+ .prompt = N_("IPv4 address (IP[/plen]) [none]"),
+ .describe_message =
+ N_("Enter a list of IPv4 addresses formatted as:\n"
+ " ip[/prefix], ip[/prefix],...\n"
+ "Missing prefix is regarded as prefix of 32.\n\n"
+ "Example: 192.168.1.5/24, 10.0.0.11/24\n"),
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_addresses),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_addresses),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_addresses,
+ .set_fcn = _objlist_set_fcn_ip_config_addresses,
+ .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_address),
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_GATEWAY, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY,
+ .is_cli_option = TRUE,
+ .property_alias = "gw4",
+ .prompt = N_("IPv4 gateway [none]"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_ip_config_gateway,
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTES, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTES,
+ .describe_message =
+ N_("Enter a list of IPv4 routes formatted as:\n"
+ " ip[/prefix] [next-hop] [metric],...\n\n"
+ "Missing prefix is regarded as a prefix of 32.\n"
+ "Missing next-hop is regarded as 0.0.0.0.\n"
+ "Missing metric means default (NM/kernel will set a default value).\n\n"
+ "Examples: 192.168.2.0/24 192.168.2.1 3, 10.1.0.0/16 10.0.0.254\n"
+ " 10.1.2.0/24\n"),
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_routes),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_routes),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_routes,
+ .set_fcn = _objlist_set_fcn_ip_config_routes,
+ .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_route),
+ .delimit_pretty_with_semicolon = TRUE,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTE_METRIC, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_METRIC,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTE_TABLE, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_TABLE,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = 0,
+ .nick = "unspec",
+ },
+ {
+ .value.i64 = 254,
+ .nick = "main",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTING_RULES, NULL,
+ .describe_message =
+ N_("Enter a list of IPv4 routing rules formatted as:\n"
+ " priority [prio] [from [src]] [to [dst]], ,...\n"
+ "\n"),
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_routing_rules),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_routing_rules),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_routing_rules,
+ .set_fcn = _objlist_set_fcn_ip_config_routing_rules,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingIPConfig, nm_setting_ip_config_remove_routing_rule),
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_IAID, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_IAID,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = &_ptd_gobject_int_timeout,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP4_CONFIG_DHCP_FQDN,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME_FLAGS,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_dhcp_hostname_flags_get_type,
+ ),
+ )
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_NEVER_DEFAULT, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_NEVER_DEFAULT,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_MAY_FAIL, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_MAY_FAIL,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DAD_TIMEOUT, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DAD_TIMEOUT,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "default",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "off",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_REJECT_SERVERS,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, _multilist_get_num_fcn_ip_config_dhcp_reject_servers),
+ .add2_fcn = MULTILIST_ADD2_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dhcp_reject_server),
+ .remove_by_idx_fcn_u = MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingIPConfig, nm_setting_ip_config_remove_dhcp_reject_server),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, _multilist_remove_by_value_fcn_ip_config_dhcp_reject_servers),
+ .validate_fcn = _multilist_validate_fcn_is_ipv4_addr_or_subnet,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_IP6_CONFIG
+static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = {
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_METHOD, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_METHOD,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_ip_config_method,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+ NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+ NM_SETTING_IP6_CONFIG_METHOD_DHCP,
+ NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
+ NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+ NM_SETTING_IP6_CONFIG_METHOD_SHARED,
+ NM_SETTING_IP6_CONFIG_METHOD_DISABLED),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS,
+ .describe_message =
+ N_("Enter a list of IPv6 addresses of DNS servers. If the IPv6 "
+ "configuration method is 'auto' these DNS servers are appended "
+ "to those (if any) returned by automatic configuration. DNS "
+ "servers cannot be used with the 'shared' or 'link-local' IPv6 "
+ "configuration methods, as there is no upstream network. In "
+ "all other IPv6 configuration methods, these DNS "
+ "servers are used as the only DNS servers for this connection.\n\n"
+ "Example: 2607:f0d0:1002:51::4, 2607:f0d0:1002:51::1\n"),
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dns),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_ip_config_dns,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_SEARCH, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns_searches),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dns_search),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search_by_value),
+ .validate_fcn = _multilist_validate_fcn_is_domain,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_OPTIONS, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns_options),
+ .add_fcn = _multilist_add_fcn_ip_config_dns_options,
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option_by_value),
+ .clear_emptyunset_fcn = MULTILIST_CLEAR_EMPTYUNSET_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_dns_options),
+ .strsplit_plain = TRUE,
+ ),
+ .is_default_fcn = _is_default_func_ip_config_dns_options,
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_PRIORITY, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ADDRESSES, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDRESSES,
+ .is_cli_option = TRUE,
+ .property_alias = "ip6",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_MULTI,
+ .prompt = N_("IPv6 address (IP[/plen]) [none]"),
+ .describe_message =
+ N_("Enter a list of IPv6 addresses formatted as:\n"
+ " ip[/prefix], ip[/prefix],...\n"
+ "Missing prefix is regarded as prefix of 128.\n\n"
+ "Example: 2607:f0d0:1002:51::4/64, 1050:0:0:0:5:600:300c:326b\n"),
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_addresses),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_addresses),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_addresses,
+ .set_fcn = _objlist_set_fcn_ip_config_addresses,
+ .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_address),
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_GATEWAY, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY,
+ .is_cli_option = TRUE,
+ .property_alias = "gw6",
+ .prompt = N_("IPv6 gateway [none]"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_ip_config_gateway,
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTES, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTES,
+ .describe_message =
+ N_("Enter a list of IPv6 routes formatted as:\n"
+ " ip[/prefix] [next-hop] [metric],...\n\n"
+ "Missing prefix is regarded as a prefix of 128.\n"
+ "Missing next-hop is regarded as \"::\".\n"
+ "Missing metric means default (NM/kernel will set a default value).\n\n"
+ "Examples: 2001:db8:beef:2::/64 2001:db8:beef::2, 2001:db8:beef:3::/64 2001:db8:beef::3 2\n"
+ " abbe::/64 55\n"),
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_routes),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_routes),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_routes,
+ .set_fcn = _objlist_set_fcn_ip_config_routes,
+ .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_route),
+ .delimit_pretty_with_semicolon = TRUE,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTE_METRIC, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_METRIC,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTE_TABLE, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_TABLE,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = 0,
+ .nick = "unspec",
+ },
+ {
+ .value.i64 = 254,
+ .nick = "main",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTING_RULES, NULL,
+ .describe_message =
+ N_("Enter a list of IPv6 routing rules formatted as:\n"
+ " priority [prio] [from [src]] [to [dst]], ,...\n"
+ "\n"),
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_routing_rules),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_routing_rules),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_routing_rules,
+ .set_fcn = _objlist_set_fcn_ip_config_routing_rules,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingIPConfig, nm_setting_ip_config_remove_routing_rule),
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_NEVER_DEFAULT, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_NEVER_DEFAULT,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_MAY_FAIL, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_MAY_FAIL,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .value_infos_get = ENUM_VALUE_INFOS (
+ {
+ .value = NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR,
+ .nick = "enabled, prefer public IP",
+ },
+ {
+ .value = NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
+ .nick = "enabled, prefer temporary IP",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_ip6_config_addr_gen_mode_get_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_IP6_CONFIG_RA_TIMEOUT, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_RA_TIMEOUT,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = &_ptd_gobject_int_timeout,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP6_CONFIG_DHCP_DUID, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_DUID,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_IAID, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_IAID,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_TIMEOUT,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = &_ptd_gobject_int_timeout,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME_FLAGS,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_dhcp_hostname_flags_get_type,
+ ),
+ )
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP6_CONFIG_TOKEN,
+ .property_type = &_pt_gobject_string,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_IP_TUNNEL
+static const NMMetaPropertyInfo *const property_infos_IP_TUNNEL[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_MODE,
+ .is_cli_option = TRUE,
+ .property_alias = "mode",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = NM_META_TEXT_PROMPT_IP_TUNNEL_MODE,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_ip_tunnel_mode_get_type,
+ .min = NM_IP_TUNNEL_MODE_UNKNOWN + 1,
+ .max = G_MAXINT,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_PARENT,
+ .is_cli_option = TRUE,
+ .property_alias = "dev",
+ .prompt = N_("Parent device [none]"),
+ .property_type = &_pt_gobject_devices,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_LOCAL,
+ .is_cli_option = TRUE,
+ .property_alias = "local",
+ .prompt = N_("Local endpoint [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_REMOTE,
+ .is_cli_option = TRUE,
+ .property_alias = "remote",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("Remote"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_TTL,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_TOS,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_INPUT_KEY,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_OUTPUT_KEY,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_FLOW_LABEL,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_MTU,
+ .property_type = &_pt_gobject_mtu,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_FLAGS,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_ip_tunnel_flags_get_type,
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_MACSEC
+static const NMMetaPropertyInfo *const property_infos_MACSEC[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_PARENT,
+ .is_cli_option = TRUE,
+ .property_alias = "dev",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("MACsec parent device or connection UUID"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_MODE,
+ .is_cli_option = TRUE,
+ .property_alias = "mode",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = NM_META_TEXT_PROMPT_MACSEC_MODE,
+ .def_hint = NM_META_TEXT_PROMPT_MACSEC_MODE_CHOICES,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_macsec_mode_get_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_ENCRYPT,
+ .is_cli_option = TRUE,
+ .property_alias = "encrypt",
+ .prompt = N_("Enable encryption [yes]"),
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_MKA_CAK,
+ .is_cli_option = TRUE,
+ .property_alias = "cak",
+ .prompt = N_("MKA CAK"),
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_MKA_CAK_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_MKA_CKN,
+ .is_cli_option = TRUE,
+ .property_alias = "ckn",
+ .prompt = N_("MKA_CKN"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_PORT,
+ .is_cli_option = TRUE,
+ .property_alias = "port",
+ .prompt = N_("SCI port [1]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_VALIDATION,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_macsec_validation_get_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_SEND_SCI,
+ .property_type = &_pt_gobject_bool,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_MACVLAN
+static const NMMetaPropertyInfo *const property_infos_MACVLAN[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_PARENT,
+ .is_cli_option = TRUE,
+ .property_alias = "dev",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("MACVLAN parent device or connection UUID"),
+ .property_type = &_pt_gobject_devices,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_MODE,
+ .is_cli_option = TRUE,
+ .property_alias = "mode",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = NM_META_TEXT_PROMPT_MACVLAN_MODE,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_macvlan_mode_get_type,
+ .min = NM_SETTING_MACVLAN_MODE_UNKNOWN + 1,
+ .max = G_MAXINT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_PROMISCUOUS,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACVLAN_TAP,
+ .is_cli_option = TRUE,
+ .property_alias = "tap",
+ .prompt = N_("Tap [no]"),
+ .property_type = &_pt_gobject_bool,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_MATCH
+static const NMMetaPropertyInfo *const property_infos_MATCH[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_INTERFACE_NAME,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingMatch, nm_setting_match_get_num_interface_names),
+ .add2_fcn = MULTILIST_ADD2_FCN (NMSettingMatch, nm_setting_match_add_interface_name),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingMatch, nm_setting_match_remove_interface_name),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_interface_name_by_value),
+ .strsplit_with_spaces = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_KERNEL_COMMAND_LINE,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingMatch, nm_setting_match_get_num_kernel_command_lines),
+ .add2_fcn = MULTILIST_ADD2_FCN (NMSettingMatch, nm_setting_match_add_kernel_command_line),
+ .remove_by_idx_fcn_u = MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingMatch, nm_setting_match_remove_kernel_command_line),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_kernel_command_line_by_value),
+ .strsplit_with_spaces = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_DRIVER,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingMatch, nm_setting_match_get_num_drivers),
+ .add2_fcn = MULTILIST_ADD2_FCN (NMSettingMatch, nm_setting_match_add_driver),
+ .remove_by_idx_fcn_u = MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingMatch, nm_setting_match_remove_driver),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_driver_by_value),
+ .strsplit_with_spaces = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_PATH,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingMatch, nm_setting_match_get_num_paths),
+ .add2_fcn = MULTILIST_ADD2_FCN (NMSettingMatch, nm_setting_match_add_path),
+ .remove_by_idx_fcn_u = MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingMatch, nm_setting_match_remove_path),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_path_by_value),
+ .strsplit_with_spaces = TRUE,
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OLPC_MESH
+static const NMMetaPropertyInfo *const property_infos_OLPC_MESH[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OLPC_MESH_SSID,
+ .is_cli_option = TRUE,
+ .property_alias = "ssid",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("SSID"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_olpc_mesh_ssid,
+ .set_fcn = _set_fcn_gobject_ssid,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OLPC_MESH_CHANNEL,
+ .is_cli_option = TRUE,
+ .property_alias = "channel",
+ .prompt = N_("OLPC Mesh channel [1]"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_olpc_mesh_channel,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS,
+ .is_cli_option = TRUE,
+ .property_alias = "dhcp-anycast",
+ .prompt = N_("DHCP anycast MAC address [none]"),
+ .property_type = &_pt_gobject_mac,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_BRIDGE
+static const NMMetaPropertyInfo *const property_infos_OVS_BRIDGE[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_FAIL_MODE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("secure", "standalone"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_RSTP_ENABLE,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_STP_ENABLE,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_DATAPATH_TYPE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("system", "netdev"),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_DPDK
+static const NMMetaPropertyInfo *const property_infos_OVS_DPDK[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_DPDK_DEVARGS,
+ .property_type = &_pt_gobject_string,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_INTERFACE
+static const NMMetaPropertyInfo *const property_infos_OVS_INTERFACE[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_INTERFACE_TYPE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("internal", "system", "patch", "dpdk"),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_PATCH
+static const NMMetaPropertyInfo *const property_infos_OVS_PATCH[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PATCH_PEER,
+ .property_type = &_pt_gobject_string,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_PORT
+static const NMMetaPropertyInfo *const property_infos_OVS_PORT[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_VLAN_MODE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("access", "native-tagged", "native-untagged", "trunk"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_TAG,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_LACP,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("active", "off", "passive"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_BOND_MODE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("active-backup", "balance-slb", "balance-tcp"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_BOND_UPDELAY,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_BOND_DOWNDELAY,
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_PPP
+static const NMMetaPropertyInfo *const property_infos_PPP[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_NOAUTH,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_REFUSE_EAP,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_REFUSE_PAP,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_REFUSE_CHAP,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_REFUSE_MSCHAP,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_REFUSE_MSCHAPV2,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_NOBSDCOMP,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_NODEFLATE,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_NO_VJ_COMP,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_REQUIRE_MPPE,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_REQUIRE_MPPE_128,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_MPPE_STATEFUL,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_CRTSCTS,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_BAUD,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_MRU,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_MTU,
+ .property_type = &_pt_gobject_mtu,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu,
+ .get_fcn = MTU_GET_FCN (NMSettingPpp, nm_setting_ppp_get_mtu),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_LCP_ECHO_FAILURE,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPP_LCP_ECHO_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_PPPOE
+static const NMMetaPropertyInfo *const property_infos_PPPOE[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_PARENT,
+ .is_cli_option = TRUE,
+ .property_alias = "parent",
+ .prompt = N_("PPPoE parent device"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_SERVICE,
+ .is_cli_option = TRUE,
+ .property_alias = "service",
+ .prompt = N_("Service [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_USERNAME,
+ .is_cli_option = TRUE,
+ .property_alias = "username",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("PPPoE username"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_PASSWORD,
+ .is_cli_option = TRUE,
+ .property_alias = "password",
+ .prompt = N_("Password [none]"),
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PPPOE_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_PROXY
+static const NMMetaPropertyInfo *const property_infos_PROXY[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_METHOD,
+ .is_cli_option = TRUE,
+ .property_alias = "method",
+ .prompt = NM_META_TEXT_PROMPT_PROXY_METHOD,
+ .def_hint = NM_META_TEXT_PROMPT_PROXY_METHOD_CHOICES,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_proxy_method_get_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_BROWSER_ONLY,
+ .is_cli_option = TRUE,
+ .property_alias = "browser-only",
+ .prompt = N_("Browser only [no]"),
+ .property_type = &_pt_gobject_bool
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_PAC_URL,
+ .is_cli_option = TRUE,
+ .property_alias = "pac-url",
+ .prompt = N_("PAC URL"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_PROXY_PAC_SCRIPT,
+ .is_cli_option = TRUE,
+ .property_alias = "pac-script",
+ .prompt = N_("PAC script"),
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_string,
+ .validate_fcn = _validate_fcn_proxy_pac_script,
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_SERIAL
+static const NMMetaPropertyInfo *const property_infos_SERIAL[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_SERIAL_BAUD,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_SERIAL_BITS,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_SERIAL_PARITY,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .value_infos = ENUM_VALUE_INFOS (
+ {
+ .value = NM_SETTING_SERIAL_PARITY_EVEN,
+ .nick = "E",
+ },
+ {
+ .value = NM_SETTING_SERIAL_PARITY_EVEN,
+ .nick = "e",
+ },
+ {
+ .value = NM_SETTING_SERIAL_PARITY_ODD,
+ .nick = "O",
+ },
+ {
+ .value = NM_SETTING_SERIAL_PARITY_ODD,
+ .nick = "o",
+ },
+ {
+ .value = NM_SETTING_SERIAL_PARITY_NONE,
+ .nick = "N",
+ },
+ {
+ .value = NM_SETTING_SERIAL_PARITY_NONE,
+ .nick = "n",
+ },
+ ),
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_SERIAL_STOPBITS,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_SERIAL_SEND_DELAY,
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_SRIOV
+static const NMMetaPropertyInfo *const property_infos_SRIOV[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_SRIOV_TOTAL_VFS,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_SRIOV_VFS,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingSriov, nm_setting_sriov_get_num_vfs),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingSriov, nm_setting_sriov_clear_vfs),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_sriov_vfs,
+ .set_fcn = _objlist_set_fcn_sriov_vfs,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_SRIOV_AUTOPROBE_DRIVERS,
+ .property_type = &_pt_gobject_enum,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_TC_CONFIG
+static const NMMetaPropertyInfo *const property_infos_TC_CONFIG[] = {
+ PROPERTY_INFO (NM_SETTING_TC_CONFIG_QDISCS, DESCRIBE_DOC_NM_SETTING_TC_CONFIG_QDISCS,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingTCConfig, nm_setting_tc_config_get_num_qdiscs),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingTCConfig, nm_setting_tc_config_clear_qdiscs),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_tc_config_qdiscs,
+ .set_fcn = _objlist_set_fcn_tc_config_qdiscs,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTCConfig, nm_setting_tc_config_remove_qdisc),
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO (NM_SETTING_TC_CONFIG_TFILTERS, DESCRIBE_DOC_NM_SETTING_TC_CONFIG_TFILTERS,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingTCConfig, nm_setting_tc_config_get_num_tfilters),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingTCConfig, nm_setting_tc_config_clear_tfilters),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_tc_config_tfilters,
+ .set_fcn = _objlist_set_fcn_tc_config_tfilters,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTCConfig, nm_setting_tc_config_remove_tfilter),
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_TEAM
+static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_CONFIG,
+ .is_cli_option = TRUE,
+ .property_alias = "config",
+ .prompt = N_("Team JSON configuration [none]"),
+ .describe_message = TEAM_DESCRIBE_MESSAGE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_string,
+ .validate_fcn = _validate_fcn_team_config,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "disabled",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_MCAST_REJOIN_COUNT,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "disabled",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_BROADCAST,
+ NM_SETTING_TEAM_RUNNER_ROUNDROBIN,
+ NM_SETTING_TEAM_RUNNER_RANDOM,
+ NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP,
+ NM_SETTING_TEAM_RUNNER_LOADBALANCE,
+ NM_SETTING_TEAM_RUNNER_LACP),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL,
+ NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE,
+ NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_HASH,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingTeam, nm_setting_team_get_num_runner_tx_hash),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingTeam, nm_setting_team_add_runner_tx_hash),
+ .remove_by_idx_fcn_u = MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingTeam, nm_setting_team_remove_runner_tx_hash),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingTeam, nm_setting_team_remove_runner_tx_hash_by_value),
+ .strsplit_plain = TRUE,
+ ),
+ .values_static = NM_MAKE_STRV ("eth", "vlan", "ipv4", "ipv6", "ip",
+ "l3", "tcp", "udp", "sctp", "l4"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("basic"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_ACTIVE,
+ .property_type = & _pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_FAST_RATE,
+ .property_type = & _pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_SYS_PRIO,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_MIN_PORTS,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 1,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO,
+ NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO_STABLE,
+ NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_BANDWIDTH,
+ NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_COUNT,
+ NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_PORT_CONFIG),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_LINK_WATCHERS,
+ .describe_message = TEAM_LINK_WATCHERS_DESCRIBE_MESSAGE,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingTeam, nm_setting_team_get_num_link_watchers),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_team_link_watchers,
+ .set_fcn = _objlist_set_fcn_team_link_watchers,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTeam, nm_setting_team_remove_link_watcher),
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_TEAM_PORT
+static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_CONFIG,
+ .is_cli_option = TRUE,
+ .property_alias = "config",
+ .prompt = N_("Team JSON configuration [none]"),
+ .describe_message = TEAM_DESCRIBE_MESSAGE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_string,
+ .validate_fcn = _validate_fcn_team_config,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_QUEUE_ID,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_PRIO,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = 0,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_STICKY,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LACP_PRIO,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LACP_KEY,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = -1,
+ .nick = "unset",
+ },
+ {
+ .value.i64 = 0,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LINK_WATCHERS,
+ .describe_message = TEAM_LINK_WATCHERS_DESCRIBE_MESSAGE,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingTeamPort, nm_setting_team_port_get_num_link_watchers),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_team_link_watchers,
+ .set_fcn = _objlist_set_fcn_team_link_watchers,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTeamPort, nm_setting_team_port_remove_link_watcher),
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_TUN
+static const NMMetaPropertyInfo *const property_infos_TUN[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_MODE,
+ .is_cli_option = TRUE,
+ .property_alias = "mode",
+ .prompt = NM_META_TEXT_PROMPT_TUN_MODE,
+ .def_hint = NM_META_TEXT_PROMPT_TUN_MODE_CHOICES,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_tun_mode_get_type,
+ .min = NM_SETTING_TUN_MODE_UNKNOWN + 1,
+ .max = G_MAXINT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_OWNER,
+ .is_cli_option = TRUE,
+ .property_alias = "owner",
+ .prompt = N_("User ID [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_GROUP,
+ .is_cli_option = TRUE,
+ .property_alias = "group",
+ .prompt = N_("Group ID [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_PI,
+ .is_cli_option = TRUE,
+ .property_alias = "pi",
+ .prompt = N_("Enable PI [no]"),
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_VNET_HDR,
+ .is_cli_option = TRUE,
+ .property_alias = "vnet-hdr",
+ .prompt = N_("Enable VNET header [no]"),
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_TUN_MULTI_QUEUE,
+ .is_cli_option = TRUE,
+ .property_alias = "multi-queue",
+ .prompt = N_("Enable multi queue [no]"),
+ .property_type = &_pt_gobject_bool,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VETH
+static const NMMetaPropertyInfo *const property_infos_VETH[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VETH_PEER,
+ .is_cli_option = TRUE,
+ .property_alias = "peer",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("veth peer"),
+ .property_type = &_pt_gobject_string,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VLAN
+static const NMMetaPropertyInfo *const property_infos_VLAN[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_PARENT,
+ .is_cli_option = TRUE,
+ .property_alias = "dev",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("VLAN parent device or connection UUID"),
+ .property_type = &_pt_gobject_devices,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_ID,
+ .is_cli_option = TRUE,
+ .property_alias = "id",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("VLAN ID (<0-4094>)"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_FLAGS,
+ .is_cli_option = TRUE,
+ .property_alias = "flags",
+ .prompt = N_("VLAN flags (<0-7>) [none]"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_vlan_flags,
+ .set_fcn = _set_fcn_gobject_flags,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_INGRESS_PRIORITY_MAP,
+ .is_cli_option = TRUE,
+ .property_alias = "ingress",
+ .prompt = N_("Ingress priority maps [none]"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_vlan_xgress_priority_map,
+ .set_fcn = _set_fcn_vlan_xgress_priority_map,
+ .set_supports_remove = TRUE,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_EGRESS_PRIORITY_MAP,
+ .is_cli_option = TRUE,
+ .property_alias = "egress",
+ .prompt = N_("Egress priority maps [none]"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_vlan_xgress_priority_map,
+ .set_fcn = _set_fcn_vlan_xgress_priority_map,
+ .set_supports_remove = TRUE,
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VPN
+static const NMMetaPropertyInfo *const property_infos_VPN[] = {
+[_NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE] =
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_SERVICE_TYPE,
+ .is_cli_option = TRUE,
+ .property_alias = "vpn-type",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = NM_META_TEXT_PROMPT_VPN_TYPE,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_vpn_service_type,
+ .complete_fcn = _complete_fcn_vpn_service_type,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_USER_NAME,
+ .is_cli_option = TRUE,
+ .property_alias = "user",
+ .prompt = N_("Username [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_DATA,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_vpn_options,
+ .set_fcn = _set_fcn_optionlist,
+ .set_supports_remove = TRUE,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (optionlist,
+ .set_fcn = _optionlist_set_fcn_vpn_data,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_SECRETS,
+ .is_secret = TRUE,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_vpn_options,
+ .set_fcn = _set_fcn_optionlist,
+ .set_supports_remove = TRUE,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (optionlist,
+ .set_fcn = _optionlist_set_fcn_vpn_secrets,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_PERSISTENT,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_TIMEOUT,
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VRF
+static const NMMetaPropertyInfo *const property_infos_VRF[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VRF_TABLE,
+ .is_cli_option = TRUE,
+ .property_alias = "table",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("Table [0]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VXLAN
+static const NMMetaPropertyInfo *const property_infos_VXLAN[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_PARENT,
+ .is_cli_option = TRUE,
+ .property_alias = "dev",
+ .prompt = N_("Parent device [none]"),
+ .property_type = &_pt_gobject_devices,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_ID,
+ .is_cli_option = TRUE,
+ .property_alias = "id",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("VXLAN ID"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_LOCAL,
+ .is_cli_option = TRUE,
+ .property_alias = "local",
+ .prompt = N_("Local address [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_REMOTE,
+ .is_cli_option = TRUE,
+ .property_alias = "remote",
+ .prompt = N_("Remote"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_SOURCE_PORT_MIN,
+ .is_cli_option = TRUE,
+ .property_alias = "source-port-min",
+ .prompt = N_("Minimum source port [0]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_SOURCE_PORT_MAX,
+ .is_cli_option = TRUE,
+ .property_alias = "source-port-max",
+ .prompt = N_("Maximum source port [0]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_DESTINATION_PORT,
+ .is_cli_option = TRUE,
+ .property_alias = "destination-port",
+ .prompt = N_("Destination port [8472]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_TOS,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_TTL,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_AGEING,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_LIMIT,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_LEARNING,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_PROXY,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_RSC,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_L2_MISS,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_L3_MISS,
+ .property_type = &_pt_gobject_bool,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIFI_P2P
+static const NMMetaPropertyInfo *const property_infos_WIFI_P2P[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIFI_P2P_PEER,
+ .is_cli_option = TRUE,
+ .property_alias = "peer",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("Peer"),
+ .property_type = &_pt_gobject_mac,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIFI_P2P_WPS_METHOD,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_wireless_security_wps_method_get_type,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIFI_P2P_WFD_IES,
+ .property_type = &_pt_gobject_bytes,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIMAX
+static const NMMetaPropertyInfo *const property_infos_WIMAX[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIMAX_MAC_ADDRESS,
+ .is_cli_option = TRUE,
+ .property_alias = "mac",
+ .prompt = N_("MAC [none]"),
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIMAX_NETWORK_NAME,
+ .is_cli_option = TRUE,
+ .property_alias = "nsp",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("WiMAX NSP name"),
+ .property_type = &_pt_gobject_mac,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIRED
+static const NMMetaPropertyInfo *const property_infos_WIRED[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_PORT,
+ /* Do not allow setting 'port' for now. It is not implemented in
+ * NM core, nor in ifcfg-rh plugin. Enable this when it gets done.
+ * wired_valid_ports[] = { "tp", "aui", "bnc", "mii", NULL };
+ */
+ .property_type = &_pt_gobject_readonly,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_SPEED,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_DUPLEX,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("half", "full"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_AUTO_NEGOTIATE,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_MAC_ADDRESS,
+ .is_cli_option = TRUE,
+ .property_alias = "mac",
+ .prompt = N_("MAC [none]"),
+ .property_type = &_pt_gobject_mac,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
+ .is_cli_option = TRUE,
+ .property_alias = "cloned-mac",
+ .prompt = N_("Cloned MAC [none]"),
+ .property_type = &_pt_gobject_mac,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mac,
+ .mode = NM_META_PROPERTY_TYPE_MAC_MODE_CLONED,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWired, nm_setting_wired_get_num_mac_blacklist_items),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWired, nm_setting_wired_add_mac_blacklist_item),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWired, nm_setting_wired_remove_mac_blacklist_item),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWired, nm_setting_wired_remove_mac_blacklist_item_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_mac_addr,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_MTU,
+ .is_cli_option = TRUE,
+ .property_alias = "mtu",
+ .prompt = N_("MTU [auto]"),
+ .property_type = &_pt_gobject_mtu,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu,
+ .get_fcn = MTU_GET_FCN (NMSettingWired, nm_setting_wired_get_mtu),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_S390_SUBCHANNELS,
+ .describe_message =
+ N_("Enter a list of subchannels (comma or space separated).\n\n"
+ "Example: 0.0.0e20 0.0.0e21 0.0.0e22\n"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_wired_s390_subchannels,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_S390_NETTYPE,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("qeth", "lcs", "ctc"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_S390_OPTIONS,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .describe_fcn = _describe_fcn_wired_s390_options,
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_optionlist,
+ .set_supports_remove = TRUE,
+ .values_fcn = _values_fcn_wired_s390_options,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (optionlist,
+ .set_fcn = _optionlist_set_fcn_wired_s390_options,
+ .no_empty_value = TRUE,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_WAKE_ON_LAN,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_wired_wake_on_lan_get_type,
+ .value_infos = ENUM_VALUE_INFOS (
+ {
+ .value = NM_SETTING_WIRED_WAKE_ON_LAN_NONE,
+ .nick = "none",
+ },
+ {
+ .value = NM_SETTING_WIRED_WAKE_ON_LAN_NONE,
+ .nick = "disable",
+ },
+ {
+ .value = NM_SETTING_WIRED_WAKE_ON_LAN_NONE,
+ .nick = "disabled",
+ },
+ ),
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD,
+ .property_type = &_pt_gobject_mac,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIREGUARD
+static const NMMetaPropertyInfo *const property_infos_WIREGUARD[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_PRIVATE_KEY,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_LISTEN_PORT,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_FWMARK,
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, \
+ .base = 16,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_PEER_ROUTES,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_MTU,
+ .property_type = &_pt_gobject_mtu,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE,
+ .property_type = &_pt_gobject_enum,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE,
+ .property_type = &_pt_gobject_enum,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIRELESS
+static const NMMetaPropertyInfo *const property_infos_WIRELESS[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SSID,
+ .is_cli_option = TRUE,
+ .property_alias = "ssid",
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .prompt = N_("SSID"),
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_wireless_ssid,
+ .set_fcn = _set_fcn_gobject_ssid,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MODE,
+ .is_cli_option = TRUE,
+ .property_alias = "mode",
+ .prompt = NM_META_TEXT_PROMPT_WIFI_MODE,
+ .def_hint = NM_META_TEXT_PROMPT_WIFI_MODE_CHOICES,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV (NM_SETTING_WIRELESS_MODE_INFRA,
+ NM_SETTING_WIRELESS_MODE_ADHOC,
+ NM_SETTING_WIRELESS_MODE_AP,
+ NM_SETTING_WIRELESS_MODE_MESH),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_BAND,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("a", "bg"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_CHANNEL,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_wireless_channel,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_BSSID,
+ .property_type = &_pt_gobject_mac,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_RATE,
+ /* Do not allow setting 'rate'. It is not implemented in NM core. */
+ .property_type = &_pt_gobject_readonly,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_TX_POWER,
+ /* Do not allow setting 'tx-power'. It is not implemented in NM core. */
+ .property_type = &_pt_gobject_readonly,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MAC_ADDRESS,
+ .property_type = &_pt_gobject_mac,
+ .is_cli_option = TRUE,
+ .property_alias = "mac",
+ .prompt = N_("MAC [none]"),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
+ .is_cli_option = TRUE,
+ .property_alias = "cloned-mac",
+ .prompt = N_("Cloned MAC [none]"),
+ .property_type = &_pt_gobject_mac,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mac,
+ .mode = NM_META_PROPERTY_TYPE_MAC_MODE_CLONED,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWireless, nm_setting_wireless_get_num_mac_blacklist_items),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWireless, nm_setting_wireless_add_mac_blacklist_item),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWireless, nm_setting_wireless_remove_mac_blacklist_item),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWireless, nm_setting_wireless_remove_mac_blacklist_item_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_mac_addr,
+ .strsplit_plain = TRUE,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_mac_randomization_get_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MTU,
+ .is_cli_option = TRUE,
+ .property_alias = "mtu",
+ .prompt = N_("MTU [auto]"),
+ .property_type = &_pt_gobject_mtu,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mtu,
+ .get_fcn = MTU_GET_FCN (NMSettingWireless, nm_setting_wireless_get_mtu),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SEEN_BSSIDS,
+ .property_type = &_pt_gobject_readonly,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_HIDDEN,
+ .property_type = &_pt_gobject_bool,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_POWERSAVE,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_wireless_powersave_get_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_WAKE_ON_WLAN,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_wireless_wake_on_wlan_get_type,
+ .value_infos = ENUM_VALUE_INFOS (
+ {
+ .value = NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE,
+ .nick = "disabled",
+ },
+ ),
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_AP_ISOLATION,
+ .property_type = &_pt_gobject_enum,
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WIRELESS_SECURITY
+static const NMMetaPropertyInfo *const property_infos_WIRELESS_SECURITY[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("none", "ieee8021x", "wpa-psk", "wpa-eap", "wpa-eap-suite-b-192", "sae", "owe"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX,
+ .property_type = &_pt_gobject_int,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG,
+ .property_type = &_pt_gobject_string,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ .values_static = NM_MAKE_STRV ("open", "shared", "leap"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PROTO,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_get_num_protos),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_proto),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_proto),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_proto_by_value),
+ .strsplit_plain = TRUE,
+ ),
+ .values_static = NM_MAKE_STRV ("wpa", "rsn"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PAIRWISE,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_get_num_pairwise),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_pairwise),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_pairwise),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_pairwise_by_value),
+ .strsplit_plain = TRUE,
+ ),
+ .values_static = NM_MAKE_STRV ("tkip", "ccmp"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_GROUP,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_get_num_groups),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_group),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_group),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_group_by_value),
+ .strsplit_plain = TRUE,
+ ),
+ .values_static = NM_MAKE_STRV ("wep40", "wep104", "tkip", "ccmp"),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PMF,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_wireless_security_pmf_get_type,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0,
+ .is_secret = TRUE,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_wireless_security_wep_key,
+ .set_fcn = _set_fcn_wireless_wep_key,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1,
+ .is_secret = TRUE,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_wireless_security_wep_key,
+ .set_fcn = _set_fcn_wireless_wep_key,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2,
+ .is_secret = TRUE,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_wireless_security_wep_key,
+ .set_fcn = _set_fcn_wireless_wep_key,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3,
+ .is_secret = TRUE,
+ .property_type = DEFINE_PROPERTY_TYPE (
+ .get_fcn = _get_fcn_wireless_security_wep_key,
+ .set_fcn = _set_fcn_wireless_wep_key,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE,
+ .describe_message =
+ N_("Enter the type of WEP keys. The accepted values are: "
+ "0 or unknown, 1 or key, and 2 or passphrase.\n"),
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .pre_set_notify = _gobject_enum_pre_set_notify_fcn_wireless_security_wep_key_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PSK,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
+ .is_secret = TRUE,
+ .property_type = &_pt_gobject_string,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS,
+ .property_type = &_pt_gobject_secret_flags,
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WPS_METHOD,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_wireless_security_wps_method_get_type,
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_FILS,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_setting_wireless_security_fils_get_type,
+ ),
+ ),
+ ),
+ NULL
+};
+
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_WPAN
+static const NMMetaPropertyInfo *const property_infos_WPAN[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WPAN_MAC_ADDRESS,
+ .property_type = &_pt_gobject_mac,
+ .is_cli_option = TRUE,
+ .property_alias = "mac",
+ .prompt = N_("MAC [none]"),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (mac,
+ .mode = NM_META_PROPERTY_TYPE_MAC_MODE_WPAN,
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WPAN_SHORT_ADDRESS,
+ .is_cli_option = TRUE,
+ .property_alias = "short-addr",
+ .prompt = N_("Short address (<0x0000-0xffff>)"),
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, \
+ .base = 16,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = G_MAXUINT16,
+ .nick = "unset",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WPAN_PAN_ID,
+ .is_cli_option = TRUE,
+ .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
+ .property_alias = "pan-id",
+ .prompt = N_("PAN Identifier (<0x0000-0xffff>)"),
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, \
+ .base = 16,
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = G_MAXUINT16,
+ .nick = "unset",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WPAN_PAGE,
+ .is_cli_option = TRUE,
+ .property_alias = "page",
+ .prompt = N_("Page (<default|0-31>)"),
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, \
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = NM_SETTING_WPAN_PAGE_DEFAULT,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_WPAN_CHANNEL,
+ .is_cli_option = TRUE,
+ .property_alias = "channel",
+ .prompt = N_("Channel (<default|0-26>)"),
+ .property_type = &_pt_gobject_int,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, \
+ .value_infos = INT_VALUE_INFOS (
+ {
+ .value.i64 = NM_SETTING_WPAN_CHANNEL_DEFAULT,
+ .nick = "default",
+ },
+ ),
+ ),
+ ),
+ NULL
+};
+
+/*****************************************************************************/
+
+static void
+_setting_init_fcn_adsl (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ /* Initialize a protocol */
+ g_object_set (NM_SETTING_ADSL (setting),
+ NM_SETTING_ADSL_PROTOCOL, NM_SETTING_ADSL_PROTOCOL_PPPOE,
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_cdma (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ /* Initialize 'number' so that 'cdma' is valid */
+ g_object_set (NM_SETTING_CDMA (setting),
+ NM_SETTING_CDMA_NUMBER, "#777",
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_gsm (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ /* Initialize 'apn' so that 'gsm' is valid */
+ g_object_set (NM_SETTING_GSM (setting),
+ NM_SETTING_GSM_APN, "internet",
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_infiniband (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ /* Initialize 'transport-mode' so that 'infiniband' is valid */
+ g_object_set (NM_SETTING_INFINIBAND (setting),
+ NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram",
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_ip4_config (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ g_object_set (NM_SETTING_IP_CONFIG (setting),
+ NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_ip6_config (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ g_object_set (NM_SETTING_IP_CONFIG (setting),
+ NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_olpc_mesh (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ g_object_set (NM_SETTING_OLPC_MESH (setting),
+ NM_SETTING_OLPC_MESH_CHANNEL, 1,
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_proxy (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ g_object_set (NM_SETTING_PROXY (setting),
+ NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_NONE,
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_tun (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ g_object_set (NM_SETTING_TUN (setting),
+ NM_SETTING_TUN_MODE, NM_SETTING_TUN_MODE_TUN,
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_vlan (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ g_object_set (setting,
+ NM_SETTING_VLAN_ID, 1,
+ NULL);
+ }
+}
+
+static void
+_setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN)
+{
+ if (init_type == NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI) {
+ /* For Wi-Fi set mode to "infrastructure". Even though mode == NULL
+ * is regarded as "infrastructure", explicit value makes no doubts.
+ */
+ g_object_set (NM_SETTING_WIRELESS (setting),
+ NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA,
+ NULL);
+ }
+}
+
+/*****************************************************************************/
+
+#define SETTING_PRETTY_NAME_6LOWPAN N_("6LOWPAN settings")
+#define SETTING_PRETTY_NAME_802_1X N_("802-1x settings")
+#define SETTING_PRETTY_NAME_ADSL N_("ADSL connection")
+#define SETTING_PRETTY_NAME_BLUETOOTH N_("bluetooth connection")
+#define SETTING_PRETTY_NAME_BOND N_("Bond device")
+#define SETTING_PRETTY_NAME_BRIDGE N_("Bridge device")
+#define SETTING_PRETTY_NAME_BRIDGE_PORT N_("Bridge port")
+#define SETTING_PRETTY_NAME_CDMA N_("CDMA mobile broadband connection")
+#define SETTING_PRETTY_NAME_CONNECTION N_("General settings")
+#define SETTING_PRETTY_NAME_DCB N_("DCB settings")
+#define SETTING_PRETTY_NAME_DUMMY N_("Dummy settings")
+#define SETTING_PRETTY_NAME_ETHTOOL N_("Ethtool settings")
+#define SETTING_PRETTY_NAME_GENERIC N_("Generic settings")
+#define SETTING_PRETTY_NAME_GSM N_("GSM mobile broadband connection")
+#define SETTING_PRETTY_NAME_HOSTNAME N_("Hostname settings")
+#define SETTING_PRETTY_NAME_INFINIBAND N_("InfiniBand connection")
+#define SETTING_PRETTY_NAME_IP4_CONFIG N_("IPv4 protocol")
+#define SETTING_PRETTY_NAME_IP6_CONFIG N_("IPv6 protocol")
+#define SETTING_PRETTY_NAME_IP_TUNNEL N_("IP-tunnel settings")
+#define SETTING_PRETTY_NAME_MACSEC N_("MACsec connection")
+#define SETTING_PRETTY_NAME_MACVLAN N_("macvlan connection")
+#define SETTING_PRETTY_NAME_MATCH N_("Match")
+#define SETTING_PRETTY_NAME_OLPC_MESH N_("OLPC Mesh connection")
+#define SETTING_PRETTY_NAME_OVS_BRIDGE N_("Open vSwitch bridge settings")
+#define SETTING_PRETTY_NAME_OVS_DPDK N_("Open vSwitch DPDK interface settings")
+#define SETTING_PRETTY_NAME_OVS_EXTERNAL_IDS N_("OVS External IDs")
+#define SETTING_PRETTY_NAME_OVS_INTERFACE N_("Open vSwitch interface settings")
+#define SETTING_PRETTY_NAME_OVS_PATCH N_("Open vSwitch patch interface settings")
+#define SETTING_PRETTY_NAME_OVS_PORT N_("Open vSwitch port settings")
+#define SETTING_PRETTY_NAME_PPP N_("PPP settings")
+#define SETTING_PRETTY_NAME_PPPOE N_("PPPoE")
+#define SETTING_PRETTY_NAME_PROXY N_("Proxy")
+#define SETTING_PRETTY_NAME_SERIAL N_("Serial settings")
+#define SETTING_PRETTY_NAME_SRIOV N_("SR-IOV settings")
+#define SETTING_PRETTY_NAME_TC_CONFIG N_("Traffic controls")
+#define SETTING_PRETTY_NAME_TEAM N_("Team device")
+#define SETTING_PRETTY_NAME_TEAM_PORT N_("Team port")
+#define SETTING_PRETTY_NAME_TUN N_("Tun device")
+#define SETTING_PRETTY_NAME_USER N_("User settings")
+#define SETTING_PRETTY_NAME_VETH N_("Veth connection")
+#define SETTING_PRETTY_NAME_VLAN N_("VLAN connection")
+#define SETTING_PRETTY_NAME_VPN N_("VPN connection")
+#define SETTING_PRETTY_NAME_VRF N_("VRF connection")
+#define SETTING_PRETTY_NAME_VXLAN N_("VXLAN connection")
+#define SETTING_PRETTY_NAME_WIFI_P2P N_("Wi-Fi P2P connection")
+#define SETTING_PRETTY_NAME_WIMAX N_("WiMAX connection")
+#define SETTING_PRETTY_NAME_WIRED N_("Wired Ethernet")
+#define SETTING_PRETTY_NAME_WIREGUARD N_("WireGuard VPN settings")
+#define SETTING_PRETTY_NAME_WIRELESS N_("Wi-Fi connection")
+#define SETTING_PRETTY_NAME_WIRELESS_SECURITY N_("Wi-Fi security settings")
+#define SETTING_PRETTY_NAME_WPAN N_("WPAN settings")
+
+#define NM_META_SETTING_VALID_PARTS(...) \
+ ((const NMMetaSettingValidPartItem *const[]) { __VA_ARGS__ NULL })
+
+#define NM_META_SETTING_VALID_PART_ITEM(type, mand) \
+ (&((const NMMetaSettingValidPartItem) { \
+ .setting_info = &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_##type], \
+ .mandatory = mand, \
+ }))
+
+const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
+#define SETTING_INFO_EMPTY(type, ...) \
+ [NM_META_SETTING_TYPE_##type] = { \
+ .meta_type = &nm_meta_type_setting_info_editor, \
+ .general = &nm_meta_setting_infos[NM_META_SETTING_TYPE_##type], \
+ .pretty_name = SETTING_PRETTY_NAME_##type, \
+ __VA_ARGS__ \
+ }
+#define SETTING_INFO(type, ...) \
+ [NM_META_SETTING_TYPE_##type] = { \
+ .meta_type = &nm_meta_type_setting_info_editor, \
+ .general = &nm_meta_setting_infos[NM_META_SETTING_TYPE_##type], \
+ .properties = property_infos_##type, \
+ .properties_num = G_N_ELEMENTS (property_infos_##type) - 1, \
+ .pretty_name = SETTING_PRETTY_NAME_##type, \
+ __VA_ARGS__ \
+ }
+ SETTING_INFO (6LOWPAN,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (6LOWPAN, TRUE),
+ ),
+ ),
+ SETTING_INFO (802_1X),
+ SETTING_INFO (ADSL,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (ADSL, TRUE),
+ ),
+ .setting_init_fcn = _setting_init_fcn_adsl,
+ ),
+ SETTING_INFO (BLUETOOTH,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (BLUETOOTH, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (BRIDGE, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (GSM, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (CDMA, FALSE),
+ ),
+ ),
+ SETTING_INFO (BOND,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (BOND, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (BRIDGE,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (BRIDGE, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (BRIDGE_PORT),
+ SETTING_INFO (CDMA,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (CDMA, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (SERIAL, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE),
+ ),
+ .setting_init_fcn = _setting_init_fcn_cdma,
+ ),
+ SETTING_INFO (CONNECTION),
+ SETTING_INFO (DCB),
+ SETTING_INFO (ETHTOOL),
+ SETTING_INFO_EMPTY (DUMMY,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (DUMMY, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO_EMPTY (GENERIC,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (GENERIC, TRUE),
+ ),
+ ),
+ SETTING_INFO (GSM,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (GSM, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (SERIAL, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE),
+ ),
+ .setting_init_fcn = _setting_init_fcn_gsm,
+ ),
+ SETTING_INFO (HOSTNAME),
+ SETTING_INFO (INFINIBAND,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (INFINIBAND, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (SRIOV, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ .setting_init_fcn = _setting_init_fcn_infiniband,
+ ),
+ SETTING_INFO (IP4_CONFIG,
+ .setting_init_fcn = _setting_init_fcn_ip4_config,
+ ),
+ SETTING_INFO (IP6_CONFIG,
+ .setting_init_fcn = _setting_init_fcn_ip6_config,
+ ),
+ SETTING_INFO (IP_TUNNEL,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (IP_TUNNEL, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (MACSEC,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (MACSEC, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (MACVLAN,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (MACVLAN, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (MATCH),
+ SETTING_INFO (OLPC_MESH,
+ .alias = "olpc-mesh",
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (OLPC_MESH, TRUE),
+ ),
+ .setting_init_fcn = _setting_init_fcn_olpc_mesh,
+ ),
+ SETTING_INFO (OVS_BRIDGE,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (OVS_BRIDGE, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ ),
+ ),
+ SETTING_INFO (OVS_DPDK,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (OVS_DPDK, TRUE),
+ ),
+ ),
+ SETTING_INFO_EMPTY (OVS_EXTERNAL_IDS),
+ SETTING_INFO (OVS_INTERFACE,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (OVS_INTERFACE, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (OVS_DPDK, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (OVS_PATCH, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (IP4_CONFIG, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (IP6_CONFIG, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (OVS_PATCH,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (OVS_PATCH, TRUE),
+ ),
+ ),
+ SETTING_INFO (OVS_PORT,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (OVS_PORT, TRUE),
+ ),
+ ),
+ SETTING_INFO (PPPOE,
+ /* PPPoE is a base connection type from historical reasons.
+ * See libnm-core/nm-setting.c:_nm_setting_is_base_type()
+ */
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (PPPOE, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (PPP),
+ SETTING_INFO (PROXY,
+ .setting_init_fcn = _setting_init_fcn_proxy,
+ ),
+ SETTING_INFO (SERIAL),
+ SETTING_INFO (SRIOV),
+ SETTING_INFO (TC_CONFIG),
+ SETTING_INFO (TEAM,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (TEAM, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (TEAM_PORT),
+ SETTING_INFO (TUN,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (TUN, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ .setting_init_fcn = _setting_init_fcn_tun,
+ ),
+ SETTING_INFO_EMPTY (USER),
+ SETTING_INFO (VETH,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (VETH, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (VLAN,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (VLAN, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ .setting_init_fcn = _setting_init_fcn_vlan,
+ ),
+ SETTING_INFO (VPN,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (VPN, TRUE),
+ ),
+ ),
+ SETTING_INFO (VRF,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (VRF, TRUE),
+ ),
+ ),
+
+ SETTING_INFO (VXLAN,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (VXLAN, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (WIFI_P2P,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIFI_P2P, TRUE),
+ ),
+ ),
+ SETTING_INFO (WIMAX,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIMAX, TRUE),
+ ),
+ ),
+ SETTING_INFO (WIRED,
+ .alias = "ethernet",
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (DCB, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (SRIOV, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ ),
+ SETTING_INFO (WIREGUARD,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIREGUARD, TRUE),
+ ),
+ ),
+ SETTING_INFO (WIRELESS,
+ .alias = "wifi",
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRELESS, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRELESS_SECURITY, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
+ ),
+ .setting_init_fcn = _setting_init_fcn_wireless,
+ ),
+ SETTING_INFO (WIRELESS_SECURITY,
+ .alias = "wifi-sec",
+ ),
+ SETTING_INFO (WPAN,
+ .valid_parts = NM_META_SETTING_VALID_PARTS (
+ NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WPAN, TRUE),
+ ),
+ ),
+};
+
+/* clang-format on */
+
+/*****************************************************************************/
+
+const NMMetaSettingValidPartItem *const nm_meta_setting_info_valid_parts_default[] = {
+ NM_META_SETTING_VALID_PART_ITEM(CONNECTION, TRUE),
+ NULL};
+
+/*****************************************************************************/
+
+static const NMMetaSettingValidPartItem *const valid_settings_noslave[] = {
+ NM_META_SETTING_VALID_PART_ITEM(MATCH, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM(IP4_CONFIG, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM(IP6_CONFIG, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM(HOSTNAME, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM(TC_CONFIG, FALSE),
+ NM_META_SETTING_VALID_PART_ITEM(PROXY, FALSE),
+ NULL,
+};
+
+static const NMMetaSettingValidPartItem *const valid_settings_slave_bridge[] = {
+ NM_META_SETTING_VALID_PART_ITEM(BRIDGE_PORT, TRUE),
+ NULL,
+};
+
+static const NMMetaSettingValidPartItem *const valid_settings_slave_ovs_bridge[] = {
+ NM_META_SETTING_VALID_PART_ITEM(OVS_PORT, FALSE),
+ NULL,
+};
+
+static const NMMetaSettingValidPartItem *const valid_settings_slave_ovs_port[] = {
+ NM_META_SETTING_VALID_PART_ITEM(OVS_INTERFACE, FALSE),
+ NULL,
+};
+
+static const NMMetaSettingValidPartItem *const valid_settings_slave_team[] = {
+ NM_META_SETTING_VALID_PART_ITEM(TEAM_PORT, TRUE),
+ NULL,
+};
+
+const NMMetaSettingValidPartItem *const *
+nm_meta_setting_info_valid_parts_for_slave_type(const char *slave_type, const char **out_slave_name)
+{
+ if (!slave_type) {
+ NM_SET_OUT(out_slave_name, NULL);
+ return valid_settings_noslave;
+ }
+ if (nm_streq(slave_type, NM_SETTING_BOND_SETTING_NAME)) {
+ NM_SET_OUT(out_slave_name, "bond-slave");
+ return NM_PTRARRAY_EMPTY(const NMMetaSettingValidPartItem *);
+ }
+ if (nm_streq(slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) {
+ NM_SET_OUT(out_slave_name, "bridge-slave");
+ return valid_settings_slave_bridge;
+ }
+ if (nm_streq(slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) {
+ NM_SET_OUT(out_slave_name, "ovs-slave");
+ return valid_settings_slave_ovs_bridge;
+ }
+ if (nm_streq(slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) {
+ NM_SET_OUT(out_slave_name, "ovs-slave");
+ return valid_settings_slave_ovs_port;
+ }
+ if (nm_streq(slave_type, NM_SETTING_TEAM_SETTING_NAME)) {
+ NM_SET_OUT(out_slave_name, "team-slave");
+ return valid_settings_slave_team;
+ }
+ if (nm_streq(slave_type, NM_SETTING_VRF_SETTING_NAME)) {
+ NM_SET_OUT(out_slave_name, "vrf-slave");
+ return valid_settings_noslave;
+ }
+ return NULL;
+}
+
+/*****************************************************************************/
+
+static const char *
+_meta_type_setting_info_editor_get_name(const NMMetaAbstractInfo *abstract_info,
+ gboolean for_header)
+{
+ if (for_header)
+ return N_("name");
+ return ((const NMMetaSettingInfoEditor *) abstract_info)->general->setting_name;
+}
+
+static const char *
+_meta_type_property_info_get_name(const NMMetaAbstractInfo *abstract_info, gboolean for_header)
+{
+ return ((const NMMetaPropertyInfo *) abstract_info)->property_name;
+}
+
+static gconstpointer
+_meta_type_setting_info_editor_get_fcn(const NMMetaAbstractInfo * abstract_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ gpointer target,
+ gpointer target_data,
+ NMMetaAccessorGetType get_type,
+ NMMetaAccessorGetFlags get_flags,
+ NMMetaAccessorGetOutFlags *out_flags,
+ gboolean * out_is_default,
+ gpointer * out_to_free)
+{
+ const NMMetaSettingInfoEditor *info = (const NMMetaSettingInfoEditor *) abstract_info;
+
+ nm_assert(!out_to_free || !*out_to_free);
+ nm_assert(out_flags && !*out_flags);
+ nm_assert(!target_data);
+
+ if (!NM_IN_SET(get_type, NM_META_ACCESSOR_GET_TYPE_PARSABLE, NM_META_ACCESSOR_GET_TYPE_PRETTY))
+ return NULL;
+
+ nm_assert(out_to_free);
+
+ return info->general->setting_name;
+}
+
+static gconstpointer
+_meta_type_property_info_get_fcn(const NMMetaAbstractInfo * abstract_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ gpointer target,
+ gpointer target_data,
+ NMMetaAccessorGetType get_type,
+ NMMetaAccessorGetFlags get_flags,
+ NMMetaAccessorGetOutFlags *out_flags,
+ gboolean * out_is_default,
+ gpointer * out_to_free)
+{
+ const NMMetaPropertyInfo *info = (const NMMetaPropertyInfo *) abstract_info;
+ gboolean is_default_local = FALSE;
+ gconstpointer r;
+
+ nm_assert(!out_to_free || !*out_to_free);
+ nm_assert(out_flags && !*out_flags);
+
+ if (!NM_IN_SET(get_type, NM_META_ACCESSOR_GET_TYPE_PARSABLE, NM_META_ACCESSOR_GET_TYPE_PRETTY))
+ return NULL;
+
+ nm_assert(out_to_free);
+
+ if (info->is_secret && !NM_FLAGS_HAS(get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) {
+ NM_SET_OUT(out_is_default, TRUE);
+ return _get_text_hidden(get_type);
+ }
+
+ if (info->hide_if_default && !out_is_default)
+ out_is_default = &is_default_local;
+
+ r = info->property_type->get_fcn(info,
+ environment,
+ environment_user_data,
+ target,
+ get_type,
+ get_flags,
+ out_flags,
+ out_is_default,
+ out_to_free);
+
+ if (info->hide_if_default && *out_is_default)
+ *out_flags |= NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE;
+
+ return r;
+}
+
+static const NMMetaAbstractInfo *const *
+_meta_type_setting_info_editor_get_nested(const NMMetaAbstractInfo *abstract_info,
+ guint * out_len,
+ gpointer * out_to_free)
+{
+ const NMMetaSettingInfoEditor *info;
+
+ info = (const NMMetaSettingInfoEditor *) abstract_info;
+
+ NM_SET_OUT(out_len, info->properties_num);
+ return (const NMMetaAbstractInfo *const *) info->properties;
+}
+
+static const NMMetaAbstractInfo *const *
+_meta_type_property_info_get_nested(const NMMetaAbstractInfo *abstract_info,
+ guint * out_len,
+ gpointer * out_to_free)
+{
+ NM_SET_OUT(out_len, 0);
+ return NULL;
+}
+
+static const char *const *
+_meta_type_property_info_complete_fcn(const NMMetaAbstractInfo * abstract_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ const NMMetaOperationContext *operation_context,
+ const char * text,
+ gboolean * out_complete_filename,
+ char *** out_to_free)
+{
+ const NMMetaPropertyInfo *info = (const NMMetaPropertyInfo *) abstract_info;
+
+ nm_assert(out_to_free && !*out_to_free);
+
+ if (info->property_type->complete_fcn) {
+ return info->property_type->complete_fcn(info,
+ environment,
+ environment_user_data,
+ operation_context,
+ text,
+ out_complete_filename,
+ out_to_free);
+ }
+
+ if (info->property_type->values_fcn) {
+ return info->property_type->values_fcn(info, out_to_free);
+ }
+
+ if (info->property_typ_data && info->property_typ_data->values_static)
+ return info->property_typ_data->values_static;
+
+ return NULL;
+}
+
+const NMMetaType nm_meta_type_setting_info_editor = {
+ .type_name = "setting_info_editor",
+ .get_name = _meta_type_setting_info_editor_get_name,
+ .get_nested = _meta_type_setting_info_editor_get_nested,
+ .get_fcn = _meta_type_setting_info_editor_get_fcn,
+};
+
+const NMMetaType nm_meta_type_property_info = {
+ .type_name = "property_info",
+ .get_name = _meta_type_property_info_get_name,
+ .get_nested = _meta_type_property_info_get_nested,
+ .get_fcn = _meta_type_property_info_get_fcn,
+ .complete_fcn = _meta_type_property_info_complete_fcn,
+};
+
+const NMMetaType nm_meta_type_nested_property_info = {
+ .type_name = "nested_property_info",
+};
diff --git a/src/libnmc-setting/nm-meta-setting-desc.h b/src/libnmc-setting/nm-meta-setting-desc.h
new file mode 100644
index 0000000000..29416dcbf8
--- /dev/null
+++ b/src/libnmc-setting/nm-meta-setting-desc.h
@@ -0,0 +1,541 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2010 - 2018 Red Hat, Inc.
+ */
+
+#ifndef __NM_META_SETTING_DESC_H__
+#define __NM_META_SETTING_DESC_H__
+
+#include "libnm-glib-aux/nm-obj.h"
+#include "nm-meta-setting-base.h"
+#include "libnm-base/nm-ethtool-base.h"
+
+struct _NMDevice;
+
+#define NM_META_TEXT_HIDDEN N_("<hidden>")
+
+#define NM_META_TEXT_PROMPT_ADSL_PROTO N_("Protocol")
+#define NM_META_TEXT_PROMPT_ADSL_PROTO_CHOICES \
+ "(" NM_SETTING_ADSL_PROTOCOL_PPPOA "/" NM_SETTING_ADSL_PROTOCOL_PPPOE \
+ "/" NM_SETTING_ADSL_PROTOCOL_IPOATM ")"
+
+#define NM_META_TEXT_PROMPT_ADSL_ENCAP N_("ADSL encapsulation")
+#define NM_META_TEXT_PROMPT_ADSL_ENCAP_CHOICES \
+ "(" NM_SETTING_ADSL_ENCAPSULATION_VCMUX "/" NM_SETTING_ADSL_ENCAPSULATION_LLC ") [none]"
+
+#define NM_META_TEXT_PROMPT_CON_TYPE N_("Connection type")
+#define NM_META_TEXT_PROMPT_IFNAME N_("Interface name [*]")
+#define NM_META_TEXT_PROMPT_VPN_TYPE N_("VPN type")
+#define NM_META_TEXT_PROMPT_MASTER N_("Master")
+
+#define NM_META_TEXT_PROMPT_IB_MODE N_("Transport mode")
+#define NM_META_TEXT_WORD_DATAGRAM "datagram"
+#define NM_META_TEXT_WORD_CONNECTED "connected"
+#define NM_META_TEXT_PROMPT_IB_MODE_CHOICES \
+ "(" NM_META_TEXT_WORD_DATAGRAM "/" NM_META_TEXT_WORD_CONNECTED \
+ ") [" NM_META_TEXT_WORD_DATAGRAM "]"
+
+#define NM_META_TEXT_PROMPT_BT_TYPE N_("Bluetooth type")
+#define NM_META_TEXT_WORD_PANU "panu"
+#define NM_META_TEXT_WORD_NAP "nap"
+#define NM_META_TEXT_WORD_DUN_GSM "dun-gsm"
+#define NM_META_TEXT_WORD_DUN_CDMA "dun-cdma"
+#define NM_META_TEXT_PROMPT_BT_TYPE_CHOICES \
+ "(" NM_META_TEXT_WORD_PANU "/" NM_META_TEXT_WORD_NAP "/" NM_META_TEXT_WORD_DUN_GSM \
+ "/" NM_META_TEXT_WORD_DUN_CDMA ") [" NM_META_TEXT_WORD_PANU "]"
+
+#define NM_META_TEXT_PROMPT_BOND_MODE N_("Bonding mode")
+
+#define NM_META_TEXT_PROMPT_BOND_MON_MODE N_("Bonding monitoring mode")
+#define NM_META_TEXT_WORD_MIIMON "miimon"
+#define NM_META_TEXT_WORD_ARP "arp"
+#define NM_META_TEXT_PROMPT_BOND_MON_MODE_CHOICES \
+ "(" NM_META_TEXT_WORD_MIIMON "/" NM_META_TEXT_WORD_ARP ") [" NM_META_TEXT_WORD_MIIMON "]"
+
+#define NM_META_TEXT_PROMPT_WIFI_MODE N_("Wi-Fi mode")
+#define NM_META_TEXT_WORD_INFRA "infrastructure"
+#define NM_META_TEXT_WORD_AP "ap"
+#define NM_META_TEXT_WORD_ADHOC "adhoc"
+#define NM_META_TEXT_WORD_MESH "mesh"
+#define NM_META_TEXT_PROMPT_WIFI_MODE_CHOICES \
+ "(" NM_META_TEXT_WORD_INFRA "/" NM_META_TEXT_WORD_AP "/" NM_META_TEXT_WORD_ADHOC \
+ "/" NM_META_TEXT_WORD_MESH ") [" NM_META_TEXT_WORD_INFRA "]"
+
+#define NM_META_TEXT_PROMPT_TUN_MODE N_("Tun mode")
+#define NM_META_TEXT_WORD_TUN "tun"
+#define NM_META_TEXT_WORD_TAP "tap"
+#define NM_META_TEXT_PROMPT_TUN_MODE_CHOICES \
+ "(" NM_META_TEXT_WORD_TUN "/" NM_META_TEXT_WORD_TAP ") [" NM_META_TEXT_WORD_TUN "]"
+
+#define NM_META_TEXT_PROMPT_IP_TUNNEL_MODE N_("IP Tunnel mode")
+
+#define NM_META_TEXT_PROMPT_MACVLAN_MODE N_("MACVLAN mode")
+
+#define NM_META_TEXT_PROMPT_MACSEC_MODE N_("MACsec mode")
+#define NM_META_TEXT_WORD_PSK "psk"
+#define NM_META_TEXT_WORD_EAP "eap"
+#define NM_META_TEXT_PROMPT_MACSEC_MODE_CHOICES \
+ "(" NM_META_TEXT_WORD_PSK "/" NM_META_TEXT_WORD_EAP ")"
+
+#define NM_META_TEXT_PROMPT_PROXY_METHOD N_("Proxy method")
+#define NM_META_TEXT_WORD_NONE "none"
+#define NM_META_TEXT_WORD_AUTO "auto"
+#define NM_META_TEXT_PROMPT_PROXY_METHOD_CHOICES \
+ "(" NM_META_TEXT_WORD_NONE "/" NM_META_TEXT_WORD_AUTO ") [" NM_META_TEXT_WORD_NONE "]"
+
+typedef enum {
+ NM_META_COLOR_NONE = 0,
+ NM_META_COLOR_CONNECTION_ACTIVATED,
+ NM_META_COLOR_CONNECTION_ACTIVATING,
+ NM_META_COLOR_CONNECTION_DISCONNECTING,
+ NM_META_COLOR_CONNECTION_INVISIBLE,
+ NM_META_COLOR_CONNECTION_EXTERNAL,
+ NM_META_COLOR_CONNECTION_UNKNOWN,
+ NM_META_COLOR_CONNECTIVITY_FULL,
+ NM_META_COLOR_CONNECTIVITY_LIMITED,
+ NM_META_COLOR_CONNECTIVITY_NONE,
+ NM_META_COLOR_CONNECTIVITY_PORTAL,
+ NM_META_COLOR_CONNECTIVITY_UNKNOWN,
+ NM_META_COLOR_DEVICE_ACTIVATED,
+ NM_META_COLOR_DEVICE_ACTIVATING,
+ NM_META_COLOR_DEVICE_DISCONNECTED,
+ NM_META_COLOR_DEVICE_FIRMWARE_MISSING,
+ NM_META_COLOR_DEVICE_PLUGIN_MISSING,
+ NM_META_COLOR_DEVICE_UNAVAILABLE,
+ NM_META_COLOR_DEVICE_DISABLED,
+ NM_META_COLOR_DEVICE_EXTERNAL,
+ NM_META_COLOR_DEVICE_UNKNOWN,
+ NM_META_COLOR_MANAGER_RUNNING,
+ NM_META_COLOR_MANAGER_STARTING,
+ NM_META_COLOR_MANAGER_STOPPED,
+ NM_META_COLOR_PERMISSION_AUTH,
+ NM_META_COLOR_PERMISSION_NO,
+ NM_META_COLOR_PERMISSION_UNKNOWN,
+ NM_META_COLOR_PERMISSION_YES,
+ NM_META_COLOR_PROMPT,
+ NM_META_COLOR_STATE_ASLEEP,
+ NM_META_COLOR_STATE_CONNECTED_GLOBAL,
+ NM_META_COLOR_STATE_CONNECTED_LOCAL,
+ NM_META_COLOR_STATE_CONNECTED_SITE,
+ NM_META_COLOR_STATE_CONNECTING,
+ NM_META_COLOR_STATE_DISCONNECTED,
+ NM_META_COLOR_STATE_DISCONNECTING,
+ NM_META_COLOR_STATE_UNKNOWN,
+ NM_META_COLOR_WIFI_SIGNAL_EXCELLENT,
+ NM_META_COLOR_WIFI_SIGNAL_FAIR,
+ NM_META_COLOR_WIFI_SIGNAL_GOOD,
+ NM_META_COLOR_WIFI_SIGNAL_POOR,
+ NM_META_COLOR_WIFI_SIGNAL_UNKNOWN,
+ NM_META_COLOR_DISABLED,
+ NM_META_COLOR_ENABLED,
+ _NM_META_COLOR_NUM
+} NMMetaColor;
+
+typedef enum {
+ NM_META_ACCESSOR_MODIFIER_SET,
+ NM_META_ACCESSOR_MODIFIER_ADD,
+ NM_META_ACCESSOR_MODIFIER_DEL,
+} NMMetaAccessorModifier;
+
+typedef enum {
+ NM_META_ACCESSOR_GET_TYPE_PRETTY,
+ NM_META_ACCESSOR_GET_TYPE_PARSABLE,
+ NM_META_ACCESSOR_GET_TYPE_COLOR,
+} NMMetaAccessorGetType;
+
+typedef enum {
+ NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT,
+ NM_META_ACCESSOR_SETTING_INIT_TYPE_CLI,
+} NMMetaAccessorSettingInitType;
+
+typedef enum {
+ NM_META_ACCESSOR_GET_FLAGS_NONE = 0,
+ NM_META_ACCESSOR_GET_FLAGS_ACCEPT_STRV = (1LL << 0),
+ NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS = (1LL << 1),
+} NMMetaAccessorGetFlags;
+
+typedef enum {
+ NM_META_ACCESSOR_GET_OUT_FLAGS_NONE = 0,
+ NM_META_ACCESSOR_GET_OUT_FLAGS_STRV = (1LL << 0),
+
+ /* the property allows to be hidden, if and only if, it's value is set to the
+ * default. This should only be set by new properties, to preserve behavior
+ * of old properties, which were always printed. */
+ NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE = (1LL << 1),
+} NMMetaAccessorGetOutFlags;
+
+typedef enum {
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC = (1LL << 0),
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_NUMERIC_HEX = (1LL << 1),
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT = (1LL << 2),
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT_L10N = (1LL << 3),
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC = (1LL << 4),
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_NUMERIC_HEX = (1LL << 5),
+ NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT = (1LL << 6),
+} NMMetaPropertyTypFlags;
+
+typedef enum {
+ NM_META_PROPERTY_TYPE_MAC_MODE_DEFAULT,
+ NM_META_PROPERTY_TYPE_MAC_MODE_CLONED,
+ NM_META_PROPERTY_TYPE_MAC_MODE_INFINIBAND,
+ NM_META_PROPERTY_TYPE_MAC_MODE_WPAN,
+} NMMetaPropertyTypeMacMode;
+
+typedef struct _NMMetaEnvironment NMMetaEnvironment;
+typedef struct _NMMetaType NMMetaType;
+typedef struct _NMMetaAbstractInfo NMMetaAbstractInfo;
+typedef struct _NMMetaSettingInfoEditor NMMetaSettingInfoEditor;
+typedef struct _NMMetaPropertyInfo NMMetaPropertyInfo;
+typedef struct _NMMetaPropertyType NMMetaPropertyType;
+typedef struct _NMMetaPropertyTypData NMMetaPropertyTypData;
+typedef struct _NMMetaOperationContext NMMetaOperationContext;
+typedef struct _NMMetaNestedPropertyInfo NMMetaNestedPropertyInfo;
+typedef struct _NMMetaPropertyTypDataNested NMMetaPropertyTypDataNested;
+
+/* this gives some context information for virtual functions.
+ * This command actually violates layering, and should be considered
+ * a hack. In the future, try to replace its use. */
+struct _NMMetaOperationContext {
+ NMConnection *connection;
+};
+
+struct _NMMetaPropertyType {
+ /* should return a translated string */
+ const char *(*describe_fcn)(const NMMetaPropertyInfo *property_info, char **out_to_free);
+
+ gconstpointer (*get_fcn)(const NMMetaPropertyInfo * property_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ NMSetting * setting,
+ NMMetaAccessorGetType get_type,
+ NMMetaAccessorGetFlags get_flags,
+ NMMetaAccessorGetOutFlags *out_flags,
+ gboolean * out_is_default,
+ gpointer * out_to_free);
+ gboolean (*set_fcn)(const NMMetaPropertyInfo *property_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ NMSetting * setting,
+ NMMetaAccessorModifier modifier,
+ const char * value,
+ GError ** error);
+
+ const char *const *(*values_fcn)(const NMMetaPropertyInfo *property_info, char ***out_to_free);
+
+ const char *const *(*complete_fcn)(const NMMetaPropertyInfo * property_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ const NMMetaOperationContext *operation_context,
+ const char * text,
+ gboolean * out_complete_filename,
+ char *** out_to_free);
+
+ /* Whether set_fcn() supports the '-' modifier. That is, whether the property
+ * is a list type. */
+ bool set_supports_remove : 1;
+};
+
+struct _NMUtilsEnumValueInfo;
+
+typedef union {
+ gint64 i64;
+ guint64 u64;
+} NMMetaSignUnsignInt64;
+
+typedef struct {
+ const char * nick;
+ NMMetaSignUnsignInt64 value;
+} NMMetaUtilsIntValueInfo;
+
+struct _NMMetaPropertyTypData {
+ union {
+ struct {
+ GType (*get_gtype)(void);
+ int min;
+ int max;
+ const struct _NMUtilsEnumValueInfo *value_infos_get; /* nicks for get function */
+ const struct _NMUtilsEnumValueInfo *value_infos; /* nicks for set function */
+ void (*pre_set_notify)(const NMMetaPropertyInfo *property_info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ NMSetting * setting,
+ int value);
+ } gobject_enum;
+ struct {
+ NMMetaSignUnsignInt64 min;
+ NMMetaSignUnsignInt64 max;
+ guint base;
+ const NMMetaUtilsIntValueInfo *value_infos;
+ } gobject_int;
+ struct {
+ const char *(*validate_fcn)(const char *value, char **out_to_free, GError **error);
+ bool handle_emptyunset : 1;
+ } gobject_string;
+ struct {
+ bool legacy_format : 1;
+ } gobject_bytes;
+ struct {
+ guint32 (*get_num_fcn_u32)(NMSetting *setting);
+ guint (*get_num_fcn_u)(NMSetting *setting);
+ void (*clear_all_fcn)(NMSetting *setting);
+
+ /* some multilist properties distinguish between an empty list and
+ * and unset. If this function pointer is set, certain behaviors come
+ * into action to handle that. */
+ void (*clear_emptyunset_fcn)(NMSetting *setting,
+ gboolean is_set /* or else set default */);
+
+ gboolean (*add_fcn)(NMSetting *setting, const char *item);
+ void (*add2_fcn)(NMSetting *setting, const char *item);
+ const char *(*validate_fcn)(const char *item, GError **error);
+ const char *(*validate2_fcn)(NMSetting *setting, const char *item, GError **error);
+ void (*remove_by_idx_fcn_u32)(NMSetting *setting, guint32 idx);
+ void (*remove_by_idx_fcn_u)(NMSetting *setting, guint idx);
+ void (*remove_by_idx_fcn_s)(NMSetting *setting, int idx);
+ gboolean (*remove_by_value_fcn)(NMSetting *setting, const char *item);
+ bool strsplit_plain : 1;
+ bool strsplit_with_spaces : 1;
+ } multilist;
+ struct {
+ guint (*get_num_fcn)(NMSetting *setting);
+ void (*obj_to_str_fcn)(NMMetaAccessorGetType get_type,
+ NMSetting * setting,
+ guint idx,
+ GString * str);
+ gboolean (*set_fcn)(NMSetting * setting,
+ gboolean do_add /* or else remove. */,
+ const char *value,
+ GError ** error);
+ void (*clear_all_fcn)(NMSetting *setting);
+ void (*remove_by_idx_fcn_u)(NMSetting *setting, guint idx);
+ void (*remove_by_idx_fcn_s)(NMSetting *setting, int idx);
+ bool delimit_pretty_with_semicolon : 1;
+ bool strsplit_plain : 1;
+ } objlist;
+ struct {
+ gboolean (*set_fcn)(NMSetting * setting,
+ const char *option,
+ const char *value,
+ GError ** error);
+ bool no_empty_value : 1;
+ } optionlist;
+ struct {
+ guint32 (*get_fcn)(NMSetting *setting);
+ } mtu;
+ struct {
+ NMSetting8021xSchemeType scheme_type;
+ } cert_8021x;
+ struct {
+ NMMetaPropertyTypeMacMode mode;
+ } mac;
+ struct {
+ guint (*get_fcn)(NMSettingDcb *setting, guint user_priority);
+ void (*set_fcn)(NMSettingDcb *setting, guint id, guint value);
+ guint max;
+ guint other;
+ bool is_percent : 1;
+ } dcb;
+ struct {
+ gboolean (*get_fcn)(NMSettingDcb *s_dcb, guint priority);
+ void (*set_fcn)(NMSettingDcb *setting, guint user_priority, gboolean enabled);
+ bool with_flow_control_flags : 1;
+ } dcb_bool;
+ struct {
+ NMEthtoolID ethtool_id;
+ } ethtool;
+ } subtype;
+ gboolean (*is_default_fcn)(NMSetting *setting);
+ const char *const * values_static;
+ const NMMetaPropertyTypDataNested *nested;
+ NMMetaPropertyTypFlags typ_flags;
+};
+
+typedef enum {
+ NM_META_PROPERTY_INF_FLAG_NONE = 0x00,
+ NM_META_PROPERTY_INF_FLAG_REQD = 0x01, /* Don't ask to ask. */
+ NM_META_PROPERTY_INF_FLAG_DONT_ASK = 0x02, /* Don't ask interactively by default */
+ NM_META_PROPERTY_INF_FLAG_MULTI = 0x04, /* Ask multiple times, do an append instead of set. */
+} NMMetaPropertyInfFlags;
+
+enum {
+ _NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE = 0,
+ _NM_META_PROPERTY_TYPE_CONNECTION_TYPE = 3,
+};
+
+#define nm_meta_property_info_connection_type \
+ (nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_CONNECTION] \
+ .properties[_NM_META_PROPERTY_TYPE_CONNECTION_TYPE])
+#define nm_meta_property_info_vpn_service_type \
+ (nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_VPN] \
+ .properties[_NM_META_PROPERTY_TYPE_VPN_SERVICE_TYPE])
+
+struct _NMMetaPropertyInfo {
+ union {
+ NMObjBaseInst parent;
+ const NMMetaType *meta_type;
+ };
+
+ const NMMetaSettingInfoEditor *setting_info;
+
+ const char *property_name;
+
+ const char *property_alias;
+
+ NMMetaPropertyInfFlags inf_flags;
+ bool is_secret : 1;
+
+ bool is_cli_option : 1;
+ bool hide_if_default : 1;
+
+ const char *prompt;
+
+ const char *def_hint;
+
+ const char *describe_doc;
+
+ /* a non-translated but translatable static description (marked with N_()). */
+ const char *describe_message;
+
+ const NMMetaPropertyType * property_type;
+ const NMMetaPropertyTypData *property_typ_data;
+};
+
+typedef struct _NMMetaSettingValidPartItem {
+ const NMMetaSettingInfoEditor *setting_info;
+ bool mandatory;
+} NMMetaSettingValidPartItem;
+
+struct _NMMetaSettingInfoEditor {
+ union {
+ NMObjBaseInst parent;
+ const NMMetaType *meta_type;
+ };
+ const NMMetaSettingInfo * general;
+ const char * alias;
+ const char * pretty_name;
+ const NMMetaPropertyInfo *const *properties;
+ guint properties_num;
+
+ /* a NMConnection has a main type (connection.type), which is a
+ * main NMSetting instance. Depending on the type, a connection
+ * may have a list of other allowed settings.
+ *
+ * For example, a connection of type "vlan" may have settings
+ * of type "connection", "vlan", and "wired".
+ *
+ * Some setting types a not a main type (NMSettingProxy). They
+ * don't have valid_settings but are usually referenced by other
+ * settings to be valid for them. */
+ const NMMetaSettingValidPartItem *const *valid_parts;
+
+ void (*setting_init_fcn)(const NMMetaSettingInfoEditor *setting_info,
+ NMSetting * setting,
+ NMMetaAccessorSettingInitType init_type);
+};
+
+struct _NMMetaType {
+ NMObjBaseClass parent;
+ const char * type_name;
+ const char *(*get_name)(const NMMetaAbstractInfo *abstract_info, gboolean for_header);
+ const NMMetaAbstractInfo *const *(*get_nested)(const NMMetaAbstractInfo *abstract_info,
+ guint * out_len,
+ gpointer * out_to_free);
+ gconstpointer (*get_fcn)(const NMMetaAbstractInfo * info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ gpointer target,
+ gpointer target_data,
+ NMMetaAccessorGetType get_type,
+ NMMetaAccessorGetFlags get_flags,
+ NMMetaAccessorGetOutFlags *out_flags,
+ gboolean * out_is_default,
+ gpointer * out_to_free);
+ const char *const *(*complete_fcn)(const NMMetaAbstractInfo * info,
+ const NMMetaEnvironment * environment,
+ gpointer environment_user_data,
+ const NMMetaOperationContext *operation_context,
+ const char * text,
+ gboolean * out_complete_filename,
+ char *** out_to_free);
+};
+
+struct _NMMetaAbstractInfo {
+ union {
+ NMObjBaseInst parent;
+ const NMMetaType *meta_type;
+ };
+};
+
+extern const NMMetaType nm_meta_type_setting_info_editor;
+extern const NMMetaType nm_meta_type_property_info;
+
+extern const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[_NM_META_SETTING_TYPE_NUM];
+
+extern const NMMetaSettingValidPartItem *const nm_meta_setting_info_valid_parts_default[];
+
+const NMMetaSettingValidPartItem *const *
+nm_meta_setting_info_valid_parts_for_slave_type(const char * slave_type,
+ const char **out_slave_name);
+
+/*****************************************************************************/
+
+typedef enum {
+ NM_META_ENV_WARN_LEVEL_INFO,
+ NM_META_ENV_WARN_LEVEL_WARN,
+} NMMetaEnvWarnLevel;
+
+/* the settings-meta data is supposed to be independent of an actual client
+ * implementation. Hence, there is a need for hooks to the meta-data.
+ * The meta-data handlers may call back to the environment with certain
+ * actions. */
+struct _NMMetaEnvironment {
+ void (*warn_fcn)(
+ const NMMetaEnvironment *environment,
+ gpointer environment_user_data,
+ NMMetaEnvWarnLevel warn_level,
+ const char *
+ fmt_l10n, /* the untranslated format string, but it is marked for translation using N_(). */
+ va_list ap);
+
+ struct _NMDevice *const *(*get_nm_devices)(const NMMetaEnvironment *environment,
+ gpointer environment_user_data,
+ guint * out_len);
+
+ struct _NMRemoteConnection *const *(*get_nm_connections)(const NMMetaEnvironment *environment,
+ gpointer environment_user_data,
+ guint * out_len);
+};
+
+/*****************************************************************************/
+
+/* NMSettingBond is special in that it has nested properties.
+ * We will add API to proper handle such types (Bond, VPN, User),
+ * but for now just expose the type info directly. */
+
+extern const NMMetaType nm_meta_type_nested_property_info;
+
+struct _NMMetaNestedPropertyInfo {
+ union {
+ const NMMetaType * meta_type;
+ NMMetaPropertyInfo base;
+ };
+ const NMMetaPropertyInfo *parent_info;
+};
+
+struct _NMMetaPropertyTypDataNested {
+ const NMMetaNestedPropertyInfo *nested;
+ guint nested_len;
+};
+
+extern const NMMetaPropertyTypDataNested nm_meta_property_typ_data_bond;
+
+/*****************************************************************************/
+
+gboolean _nm_meta_setting_bond_add_option(NMSetting * setting,
+ const char *name,
+ const char *value,
+ GError ** error);
+
+/*****************************************************************************/
+
+#endif /* __NM_META_SETTING_DESC_H__ */
diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in
new file mode 100644
index 0000000000..425eb9a6ac
--- /dev/null
+++ b/src/libnmc-setting/settings-docs.h.in
@@ -0,0 +1,423 @@
+/* Generated file. Do not edit. */
+
+#define DESCRIBE_DOC_NM_SETTING_6LOWPAN_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this 6LowPAN interface should be created.")
+#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_CHANNEL N_("Channel on which the mesh network to join is located.")
+#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS N_("Anycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request.")
+#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_SSID N_("SSID of the mesh network to join.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_AP_ISOLATION N_("Configures AP isolation, which prevents communication between wireless devices connected to this AP. This property can be set to a value different from NM_TERNARY_DEFAULT (-1) only when the interface is configured in AP mode. If set to NM_TERNARY_TRUE (1), devices are not able to communicate with each other. This increases security because it protects devices against attacks from other clients in the network. At the same time, it prevents devices to access resources on the same wireless networks as file shares, printers, etc. If set to NM_TERNARY_FALSE (0), devices can talk to each other. When set to NM_TERNARY_DEFAULT (-1), the global default is used; in case the global default is unspecified it is assumed to be NM_TERNARY_FALSE (0).")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_BAND N_("802.11 frequency band of the network. One of \"a\" for 5GHz 802.11a or \"bg\" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network to the specific band, i.e. if \"a\" is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible. This setting depends on specific driver capability and may not work with all drivers.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_BSSID N_("If specified, directs the device to only associate with the given access point. This capability is highly driver dependent and not supported by all devices. Note: this property does not control the BSSID used when creating an Ad-Hoc network and is unlikely to in the future.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_CHANNEL N_("Wireless channel to use for the Wi-Fi connection. The device will only join (or create for Ad-Hoc networks) a Wi-Fi network on the specified channel. Because channel numbers overlap between bands, this property also requires the \"band\" property to be set.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS N_("If specified, request that the device use this MAC address instead. This is known as MAC cloning or spoofing. Beside explicitly specifying a MAC address, the special values \"preserve\", \"permanent\", \"random\" and \"stable\" are supported. \"preserve\" means not to touch the MAC address on activation. \"permanent\" means to use the permanent hardware address of the device. \"random\" creates a random MAC address on each connect. \"stable\" creates a hashed MAC address based on connection.stable-id and a machine dependent key. If unspecified, the value can be overwritten via global defaults, see manual of NetworkManager.conf. If still unspecified, it defaults to \"preserve\" (older versions of NetworkManager may use a different default value). On D-Bus, this field is expressed as \"assigned-mac-address\" or the deprecated \"cloned-mac-address\".")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_GENERATE_MAC_ADDRESS_MASK N_("With \"cloned-mac-address\" setting \"random\" or \"stable\", by default all bits of the MAC address are scrambled and a locally-administered, unicast MAC address is created. This property allows to specify that certain bits are fixed. Note that the least significant bit of the first MAC address will always be unset to create a unicast MAC address. If the property is NULL, it is eligible to be overwritten by a default connection setting. If the value is still NULL or an empty string, the default is to create a locally-administered, unicast MAC address. If the value contains one MAC address, this address is used as mask. The set bits of the mask are to be filled with the current MAC address of the device, while the unset bits are subject to randomization. Setting \"FE:FF:FF:00:00:00\" means to preserve the OUI of the current MAC address and only randomize the lower 3 bytes using the \"random\" or \"stable\" algorithm. If the value contains one additional MAC address after the mask, this address is used instead of the current MAC address to fill the bits that shall not be randomized. For example, a value of \"FE:FF:FF:00:00:00 68:F7:28:00:00:00\" will set the OUI of the MAC address to 68:F7:28, while the lower bits are randomized. A value of \"02:00:00:00:00:00 00:00:00:00:00:00\" will create a fully scrambled globally-administered, burned-in MAC address. If the value contains more than one additional MAC addresses, one of them is chosen randomly. For example, \"02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00\" will create a fully scrambled MAC address, randomly locally or globally administered.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_HIDDEN N_("If TRUE, indicates that the network is a non-broadcasting network that hides its SSID. This works both in infrastructure and AP mode. In infrastructure mode, various workarounds are used for a more reliable discovery of hidden networks, such as probe-scanning the SSID. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution. In AP mode, the created network does not broadcast its SSID. Note that marking the network as hidden may be a privacy issue for you (in infrastructure mode) or client stations (in AP mode), as the explicit probe-scans are distinctly recognizable on the air.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_MAC_ADDRESS N_("If specified, this connection will only apply to the Wi-Fi device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST N_("A list of permanent MAC addresses of Wi-Fi devices to which this connection should never apply. Each MAC address should be given in the standard hex-digits-and-colons notation (eg \"00:11:22:33:44:55\").")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION N_("One of NM_SETTING_MAC_RANDOMIZATION_DEFAULT (0) (never randomize unless the user has set a global default to randomize and the supplicant supports randomization), NM_SETTING_MAC_RANDOMIZATION_NEVER (1) (never randomize the MAC address), or NM_SETTING_MAC_RANDOMIZATION_ALWAYS (2) (always randomize the MAC address). This property is deprecated for 'cloned-mac-address'. Deprecated: 1")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_MODE N_("Wi-Fi network mode; one of \"infrastructure\", \"mesh\", \"adhoc\" or \"ap\". If blank, infrastructure is assumed.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_POWERSAVE N_("One of NM_SETTING_WIRELESS_POWERSAVE_DISABLE (2) (disable Wi-Fi power saving), NM_SETTING_WIRELESS_POWERSAVE_ENABLE (3) (enable Wi-Fi power saving), NM_SETTING_WIRELESS_POWERSAVE_IGNORE (1) (don't touch currently configure setting) or NM_SETTING_WIRELESS_POWERSAVE_DEFAULT (0) (use the globally configured value). All other values are reserved.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_RATE N_("If non-zero, directs the device to only use the specified bitrate for communication with the access point. Units are in Kb/s, ie 5500 = 5.5 Mbit/s. This property is highly driver dependent and not all devices support setting a static bitrate.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SEEN_BSSIDS N_("A list of BSSIDs (each BSSID formatted as a MAC address like \"00:11:22:33:44:55\") that have been detected as part of the Wi-Fi network. NetworkManager internally tracks previously seen BSSIDs. The property is only meant for reading and reflects the BSSID list of NetworkManager. The changes you make to this property will not be preserved.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SSID N_("SSID of the Wi-Fi network. Must be specified.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_TX_POWER N_("If non-zero, directs the device to use the specified transmit power. Units are dBm. This property is highly driver dependent and not all devices support setting a static transmit power.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_WAKE_ON_WLAN N_("The NMSettingWirelessWakeOnWLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY (0x2), NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT (0x4), NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC (0x8), NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE (0x10), NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST (0x20), NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE (0x40), NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE (0x80), NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP (0x100) or the special values NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT (0x1) (to use global settings) and NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE (0x8000) (to disable management of Wake-on-LAN in NetworkManager).")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_AUTH_ALG N_("When WEP is used (ie, key-mgmt = \"none\" or \"ieee8021x\") indicate the 802.11 authentication algorithm required by the AP here. One of \"open\" for Open System, \"shared\" for Shared Key, or \"leap\" for Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\") the \"leap-username\" and \"leap-password\" properties must be specified.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_FILS N_("Indicates whether Fast Initial Link Setup (802.11ai) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE (1) (disable FILS), NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL (2) (enable FILS if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED (3) (enable FILS and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) and no global default is set, FILS will be optionally enabled.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_GROUP N_("A list of group/broadcast encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of \"wep40\", \"wep104\", \"tkip\", or \"ccmp\".")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_KEY_MGMT N_("Key management used for the connection. One of \"none\" (WEP), \"ieee8021x\" (Dynamic WEP), \"wpa-psk\" (infrastructure WPA-PSK), \"sae\" (SAE), \"owe\" (Opportunistic Wireless Encryption), \"wpa-eap\" (WPA-Enterprise) or \"wpa-eap-suite-b-192\" (WPA3-Enterprise Suite B). This property must be set for any Wi-Fi connection that uses security.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD N_("The login password for legacy LEAP connections (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\").")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS N_("Flags indicating how to handle the \"leap-password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME N_("The login username for legacy LEAP connections (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\").")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PAIRWISE N_("A list of pairwise encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of \"tkip\" or \"ccmp\".")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PMF N_("Indicates whether Protected Management Frames (802.11w) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE (1) (disable PMF), NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL (2) (enable PMF if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED (3) (enable PMF and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT (0) and no global default is set, PMF will be optionally enabled.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PROTO N_("List of strings specifying the allowed WPA protocol versions to use. Each element may be one \"wpa\" (allow WPA) or \"rsn\" (allow WPA2/RSN). If not specified, both WPA and RSN connections are allowed.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PSK N_("Pre-Shared-Key for WPA networks. For WPA-PSK, it's either an ASCII passphrase of 8 to 63 characters that is (as specified in the 802.11i standard) hashed to derive the actual key, or the key in form of 64 hexadecimal character. The WPA3-Personal networks use a passphrase of any length for SAE authentication.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS N_("Flags indicating how to handle the \"psk\" property.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS N_("Flags indicating how to handle the \"wep-key0\", \"wep-key1\", \"wep-key2\", and \"wep-key3\" properties.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE N_("Controls the interpretation of WEP keys. Allowed values are NM_WEP_KEY_TYPE_KEY (1), in which case the key is either a 10- or 26-character hexadecimal string, or a 5- or 13-character ASCII password; or NM_WEP_KEY_TYPE_PASSPHRASE (2), in which case the passphrase is provided as a string and will be hashed using the de-facto MD5 method to derive the actual WEP key.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 N_("Index 0 WEP key. This is the WEP key used in most networks. See the \"wep-key-type\" property for a description of how this key is interpreted.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 N_("Index 1 WEP key. This WEP index is not used by most networks. See the \"wep-key-type\" property for a description of how this key is interpreted.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WEP_KEY2 N_("Index 2 WEP key. This WEP index is not used by most networks. See the \"wep-key-type\" property for a description of how this key is interpreted.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 N_("Index 3 WEP key. This WEP index is not used by most networks. See the \"wep-key-type\" property for a description of how this key is interpreted.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX N_("When static WEP is used (ie, key-mgmt = \"none\") and a non-default WEP key index is used by the AP, put that WEP key index here. Valid values are 0 (default key) through 3. Note that some consumer access points (like the Linksys WRT54G) number the keys 1 - 4.")
+#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WPS_METHOD N_("Flags indicating which mode of WPS is to be used if any. There's little point in changing the default setting as NetworkManager will automatically determine whether it's feasible to start WPS enrollment from the Access Point capabilities. WPS can be disabled by setting this property to a value of 1.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_ALTSUBJECT_MATCHES N_("List of strings to be matched against the altSubjectName of the certificate presented by the authentication server. If the list is empty, no verification of the server certificate's altSubjectName is performed.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_ANONYMOUS_IDENTITY N_("Anonymous identity string for EAP authentication methods. Used as the unencrypted identity with EAP types that support different tunneled identity like EAP-TTLS.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_AUTH_TIMEOUT N_("A timeout for the authentication. Zero means the global default; if the global default is not set, the authentication timeout is 25 seconds.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_CA_CERT N_("Contains the CA certificate if used by the EAP method specified in the \"eap\" property. Certificate data is specified using a \"scheme\"; three are currently supported: blob, path and pkcs#11 URL. When using the blob scheme this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. Note that enabling NMSetting8021x:system-ca-certs will override this setting to use the built-in path, if the built-in path is not a directory.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_CA_CERT_PASSWORD N_("The password used to access the CA certificate stored in \"ca-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_CA_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"ca-cert-password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_CA_PATH N_("UTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the \"ca-cert\" property. If NMSetting8021x:system-ca-certs is enabled and the built-in CA path is an existing directory, then this setting is ignored.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT N_("Contains the client certificate if used by the EAP method specified in the \"eap\" property. Certificate data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT_PASSWORD N_("The password used to access the client certificate stored in \"client-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"client-cert-password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_DOMAIN_MATCH N_("Constraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a \";\" delimited list.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a \";\" delimited list.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_EAP N_("The allowed EAP method to be used when authenticating to the network with 802.1x. Valid methods are: \"leap\", \"md5\", \"tls\", \"peap\", \"ttls\", \"pwd\", and \"fast\". Each method requires different configuration using the properties of this setting; refer to wpa_supplicant documentation for the allowed combinations.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_IDENTITY N_("Identity string for EAP authentication methods. Often the user's user or login name.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_OPTIONAL N_("Whether the 802.1X authentication is optional. If TRUE, the activation will continue even after a timeout or an authentication failure. Setting the property to TRUE is currently allowed only for Ethernet connections. If set to FALSE, the activation can continue only after a successful authentication.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PAC_FILE N_("UTF-8 encoded file path containing PAC for EAP-FAST.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PASSWORD N_("UTF-8 encoded password used for EAP authentication methods. If both the \"password\" property and the \"password-raw\" property are specified, \"password\" is preferred.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PASSWORD_FLAGS N_("Flags indicating how to handle the \"password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PASSWORD_RAW N_("Password used for EAP authentication methods, given as a byte array to allow passwords in other encodings than UTF-8 to be used. If both the \"password\" property and the \"password-raw\" property are specified, \"password\" is preferred.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PASSWORD_RAW_FLAGS N_("Flags indicating how to handle the \"password-raw\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_AUTH_FLAGS N_("Specifies authentication flags to use in \"phase 1\" outer authentication using NMSetting8021xAuthFlags options. The individual TLS versions can be explicitly disabled. If a certain TLS disable flag is not set, it is up to the supplicant to allow or forbid it. The TLS options map to tls_disable_tlsv1_x settings. See the wpa_supplicant documentation for more details.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING N_("Enables or disables in-line provisioning of EAP-FAST credentials when FAST is specified as the EAP method in the \"eap\" property. Recognized values are \"0\" (disabled), \"1\" (allow unauthenticated provisioning), \"2\" (allow authenticated provisioning), and \"3\" (allow both authenticated and unauthenticated provisioning). See the wpa_supplicant documentation for more details.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_PEAPLABEL N_("Forces use of the new PEAP label during key derivation. Some RADIUS servers may require forcing the new PEAP label to interoperate with PEAPv1. Set to \"1\" to force use of the new PEAP label. See the wpa_supplicant documentation for more details.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_PEAPVER N_("Forces which PEAP version is used when PEAP is set as the EAP method in the \"eap\" property. When unset, the version reported by the server will be used. Sometimes when using older RADIUS servers, it is necessary to force the client to use a particular PEAP version. To do so, this property may be set to \"0\" or \"1\" to force that specific PEAP version.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES N_("List of strings to be matched against the altSubjectName of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If the list is empty, no verification of the server certificate's altSubjectName is performed.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_AUTH N_("Specifies the allowed \"phase 2\" inner authentication method when an EAP method that uses an inner TLS tunnel is specified in the \"eap\" property. For TTLS this property selects one of the supported non-EAP inner methods: \"pap\", \"chap\", \"mschap\", \"mschapv2\" while \"phase2-autheap\" selects an EAP inner method. For PEAP this selects an inner EAP method, one of: \"gtc\", \"otp\", \"md5\" and \"tls\". Each \"phase 2\" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details. Both \"phase2-auth\" and \"phase2-autheap\" cannot be specified.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_AUTHEAP N_("Specifies the allowed \"phase 2\" inner EAP-based authentication method when TTLS is specified in the \"eap\" property. Recognized EAP-based \"phase 2\" methods are \"md5\", \"mschapv2\", \"otp\", \"gtc\", and \"tls\". Each \"phase 2\" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CA_CERT N_("Contains the \"phase 2\" CA certificate if used by the EAP method specified in the \"phase2-auth\" or \"phase2-autheap\" properties. Certificate data is specified using a \"scheme\"; three are currently supported: blob, path and pkcs#11 URL. When using the blob scheme this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. Note that enabling NMSetting8021x:system-ca-certs will override this setting to use the built-in path, if the built-in path is not a directory.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD N_("The password used to access the \"phase2\" CA certificate stored in \"phase2-ca-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-ca-cert-password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CA_PATH N_("UTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the \"phase2-ca-cert\" property. If NMSetting8021x:system-ca-certs is enabled and the built-in CA path is an existing directory, then this setting is ignored.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT N_("Contains the \"phase 2\" client certificate if used by the EAP method specified in the \"phase2-auth\" or \"phase2-autheap\" properties. Certificate data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD N_("The password used to access the \"phase2\" client certificate stored in \"phase2-client-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-client-cert-password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH N_("Constraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a \";\" delimited list.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a \";\" delimited list.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY N_("Contains the \"phase 2\" inner private key when the \"phase2-auth\" or \"phase2-autheap\" property is set to \"tls\". Key data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the \"phase2-private-key-password\" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte, and as with the blob scheme the \"phase2-private-key-password\" property must be set to the password used to decode the PKCS#12 private key and certificate.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD N_("The password used to decrypt the \"phase 2\" private key specified in the \"phase2-private-key\" property when the private key either uses the path scheme, or is a PKCS#12 format key.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-private-key-password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH N_("Substring to be matched against the subject of the certificate presented by the authentication server during the inner \"phase 2\" authentication. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:phase2-domain-suffix-match.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PIN N_("PIN used for EAP authentication methods.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PIN_FLAGS N_("Flags indicating how to handle the \"pin\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PRIVATE_KEY N_("Contains the private key when the \"eap\" property is set to \"tls\". Key data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the \"private-key-password\" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte, and as with the blob scheme the \"private-key-password\" property must be set to the password used to decode the PKCS#12 private key and certificate. WARNING: \"private-key\" is not a \"secret\" property, and thus unencrypted private key data using the BLOB scheme may be readable by unprivileged users. Private keys should always be encrypted with a private key password to prevent unauthorized access to unencrypted private key data.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD N_("The password used to decrypt the private key specified in the \"private-key\" property when the private key either uses the path scheme, or if the private key is a PKCS#12 format key.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS N_("Flags indicating how to handle the \"private-key-password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_SUBJECT_MATCH N_("Substring to be matched against the subject of the certificate presented by the authentication server. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:domain-suffix-match.")
+#define DESCRIBE_DOC_NM_SETTING_802_1X_SYSTEM_CA_CERTS N_("When TRUE, overrides the \"ca-path\" and \"phase2-ca-path\" properties using the system CA directory specified at configure time with the --system-ca-path switch. The certificates in this directory are added to the verification chain in addition to any certificates specified by the \"ca-cert\" and \"phase2-ca-cert\" properties. If the path provided with --system-ca-path is rather a file name (bundle of trusted CA certificates), it overrides \"ca-cert\" and \"phase2-ca-cert\" properties instead (sets ca_cert/ca_cert2 options for wpa_supplicant).")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_AUTO_NEGOTIATE N_("When TRUE, enforce auto-negotiation of speed and duplex mode. If \"speed\" and \"duplex\" properties are both specified, only that single mode will be advertised and accepted during the link auto-negotiation process: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabits modes, as in these cases link negotiation is mandatory. When FALSE, \"speed\" and \"duplex\" properties should be both set or link configuration will be skipped.")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_CLONED_MAC_ADDRESS N_("If specified, request that the device use this MAC address instead. This is known as MAC cloning or spoofing. Beside explicitly specifying a MAC address, the special values \"preserve\", \"permanent\", \"random\" and \"stable\" are supported. \"preserve\" means not to touch the MAC address on activation. \"permanent\" means to use the permanent hardware address if the device has one (otherwise this is treated as \"preserve\"). \"random\" creates a random MAC address on each connect. \"stable\" creates a hashed MAC address based on connection.stable-id and a machine dependent key. If unspecified, the value can be overwritten via global defaults, see manual of NetworkManager.conf. If still unspecified, it defaults to \"preserve\" (older versions of NetworkManager may use a different default value). On D-Bus, this field is expressed as \"assigned-mac-address\" or the deprecated \"cloned-mac-address\".")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_DUPLEX N_("When a value is set, either \"half\" or \"full\", configures the device to use the specified duplex mode. If \"auto-negotiate\" is \"yes\" the specified duplex mode will be the only one advertised during link negotiation: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabits modes, as in these cases link negotiation is mandatory. If the value is unset (the default), the link configuration will be either skipped (if \"auto-negotiate\" is \"no\", the default) or will be auto-negotiated (if \"auto-negotiate\" is \"yes\") and the local device will advertise all the supported duplex modes. Must be set together with the \"speed\" property if specified. Before specifying a duplex mode be sure your device supports it.")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK N_("With \"cloned-mac-address\" setting \"random\" or \"stable\", by default all bits of the MAC address are scrambled and a locally-administered, unicast MAC address is created. This property allows to specify that certain bits are fixed. Note that the least significant bit of the first MAC address will always be unset to create a unicast MAC address. If the property is NULL, it is eligible to be overwritten by a default connection setting. If the value is still NULL or an empty string, the default is to create a locally-administered, unicast MAC address. If the value contains one MAC address, this address is used as mask. The set bits of the mask are to be filled with the current MAC address of the device, while the unset bits are subject to randomization. Setting \"FE:FF:FF:00:00:00\" means to preserve the OUI of the current MAC address and only randomize the lower 3 bytes using the \"random\" or \"stable\" algorithm. If the value contains one additional MAC address after the mask, this address is used instead of the current MAC address to fill the bits that shall not be randomized. For example, a value of \"FE:FF:FF:00:00:00 68:F7:28:00:00:00\" will set the OUI of the MAC address to 68:F7:28, while the lower bits are randomized. A value of \"02:00:00:00:00:00 00:00:00:00:00:00\" will create a fully scrambled globally-administered, burned-in MAC address. If the value contains more than one additional MAC addresses, one of them is chosen randomly. For example, \"02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00\" will create a fully scrambled MAC address, randomly locally or globally administered.")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_MAC_ADDRESS N_("If specified, this connection will only apply to the Ethernet device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST N_("If specified, this connection will never apply to the Ethernet device whose permanent MAC address matches an address in the list. Each MAC address is in the standard hex-digits-and-colons notation (00:11:22:33:44:55).")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames.")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_PORT N_("Specific port type to use if the device supports multiple attachment methods. One of \"tp\" (Twisted Pair), \"aui\" (Attachment Unit Interface), \"bnc\" (Thin Ethernet) or \"mii\" (Media Independent Interface). If the device supports only one port type, this setting is ignored.")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_S390_NETTYPE N_("s390 network device type; one of \"qeth\", \"lcs\", or \"ctc\", representing the different types of virtual network devices available on s390 systems.")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_S390_OPTIONS N_("Dictionary of key/value pairs of s390-specific device options. Both keys and values must be strings. Allowed keys include \"portno\", \"layer2\", \"portname\", \"protocol\", among others. Key names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_S390_SUBCHANNELS N_("Identifies specific subchannels that this network device uses for communication with z/VM or s390 host. Like the \"mac-address\" property for non-z/VM devices, this property can be used to ensure this connection only applies to the network device that uses these subchannels. The list should contain exactly 3 strings, and each string may only be composed of hexadecimal characters and the period (.) character.")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_SPEED N_("When a value greater than 0 is set, configures the device to use the specified speed. If \"auto-negotiate\" is \"yes\" the specified speed will be the only one advertised during link negotiation: this works only for BASE-T 802.3 specifications and is useful for enforcing gigabit speeds, as in this case link negotiation is mandatory. If the value is unset (0, the default), the link configuration will be either skipped (if \"auto-negotiate\" is \"no\", the default) or will be auto-negotiated (if \"auto-negotiate\" is \"yes\") and the local device will advertise all the supported speeds. In Mbit/s, ie 100 == 100Mbit/s. Must be set together with the \"duplex\" property when non-zero. Before specifying a speed value be sure your device supports it.")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_WAKE_ON_LAN N_("The NMSettingWiredWakeOnLan options to enable. Not all devices support all options. May be any combination of NM_SETTING_WIRED_WAKE_ON_LAN_PHY (0x2), NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST (0x4), NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST (0x8), NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST (0x10), NM_SETTING_WIRED_WAKE_ON_LAN_ARP (0x20), NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC (0x40) or the special values NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT (0x1) (to use global settings) and NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE (0x8000) (to disable management of Wake-on-LAN in NetworkManager).")
+#define DESCRIBE_DOC_NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD N_("If specified, the password used with magic-packet-based Wake-on-LAN, represented as an Ethernet MAC address. If NULL, no password will be required.")
+#define DESCRIBE_DOC_NM_SETTING_ADSL_ENCAPSULATION N_("Encapsulation of ADSL connection. Can be \"vcmux\" or \"llc\".")
+#define DESCRIBE_DOC_NM_SETTING_ADSL_PASSWORD N_("Password used to authenticate with the ADSL service.")
+#define DESCRIBE_DOC_NM_SETTING_ADSL_PASSWORD_FLAGS N_("Flags indicating how to handle the \"password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_ADSL_PROTOCOL N_("ADSL connection protocol. Can be \"pppoa\", \"pppoe\" or \"ipoatm\".")
+#define DESCRIBE_DOC_NM_SETTING_ADSL_USERNAME N_("Username used to authenticate with the ADSL service.")
+#define DESCRIBE_DOC_NM_SETTING_ADSL_VCI N_("VCI of ADSL connection")
+#define DESCRIBE_DOC_NM_SETTING_ADSL_VPI N_("VPI of ADSL connection")
+#define DESCRIBE_DOC_NM_SETTING_BLUETOOTH_BDADDR N_("The Bluetooth address of the device.")
+#define DESCRIBE_DOC_NM_SETTING_BLUETOOTH_TYPE N_("Either \"dun\" for Dial-Up Networking connections or \"panu\" for Personal Area Networking connections to devices supporting the NAP profile.")
+#define DESCRIBE_DOC_NM_SETTING_BOND_OPTIONS N_("Dictionary of key/value pairs of bonding options. Both keys and values must be strings. Option names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_AGEING_TIME N_("The Ethernet MAC address aging time, in seconds.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_FORWARD_DELAY N_("The Spanning Tree Protocol (STP) forwarding delay, in seconds.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_GROUP_ADDRESS N_("If specified, The MAC address of the multicast group this bridge uses for STP. The address must be a link-local address in standard Ethernet MAC address format, ie an address of the form 01:80:C2:00:00:0X, with X in [0, 4..F]. If not specified the default value is 01:80:C2:00:00:00.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_GROUP_FORWARD_MASK N_("A mask of group addresses to forward. Usually, group addresses in the range from 01:80:C2:00:00:00 to 01:80:C2:00:00:0F are not forwarded according to standards. This property is a mask of 16 bits, each corresponding to a group address in that range that must be forwarded. The mask can't have bits 0, 1 or 2 set because they are used for STP, MAC pause frames and LACP.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_HELLO_TIME N_("The Spanning Tree Protocol (STP) hello time, in seconds.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MAC_ADDRESS N_("If specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. If this field is left unspecified, the \"ethernet.cloned-mac-address\" is referred instead to generate the initial MAC address. Note that setting \"ethernet.cloned-mac-address\" anyway overwrites the MAC address of the bridge later while activating the bridge. Hence, this property is deprecated. Deprecated: 1")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MAX_AGE N_("The Spanning Tree Protocol (STP) maximum message age, in seconds.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_HASH_MAX N_("Set maximum size of multicast hash table (value must be a power of 2).")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT N_("Set the number of queries the bridge will send before stopping forwarding a multicast group after a \"leave\" message has been received.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL N_("Set interval (in deciseconds) between queries to find remaining members of a group, after a \"leave\" message is received.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL N_("Set delay (in deciseconds) after which the bridge will leave a group, if no membership reports for this group are received.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERIER N_("Enable or disable sending of multicast queries by the bridge. If not specified the option is disabled.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL N_("If no queries are seen after this delay (in deciseconds) has passed, the bridge will start to send its own queries.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL N_("Interval (in deciseconds) between queries sent by the bridge after the end of the startup phase.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL N_("Set the Max Response Time/Max Response Delay (in deciseconds) for IGMP/MLD queries sent by the bridge.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR N_("If enabled the bridge's own IP address is used as the source address for IGMP queries otherwise the default of 0.0.0.0 is used.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_ROUTER N_("Sets bridge's multicast router. Multicast-snooping must be enabled for this option to work. Supported values are: 'auto', 'disabled', 'enabled' to which kernel assigns the numbers 1, 0, and 2, respectively. If not specified the default value is 'auto' (1).")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_SNOOPING N_("Controls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT N_("Set the number of IGMP queries to send during startup phase.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL N_("Sets the time (in deciseconds) between queries sent out at startup to determine membership information.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PRIORITY N_("Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are \"better\"; the lowest priority bridge will be elected the root bridge.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_STP N_("Controls whether Spanning Tree Protocol (STP) is enabled for this bridge.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID N_("The default PVID for the ports of the bridge, that is the VLAN id assigned to incoming untagged frames.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_FILTERING N_("Control whether VLAN filtering is enabled on the bridge.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_PROTOCOL N_("If specified, the protocol used for VLAN filtering. Supported values are: '802.1Q', '802.1ad'. If not specified the default value is '802.1Q'.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_STATS_ENABLED N_("Controls whether per-VLAN stats accounting is enabled.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLANS N_("Array of bridge VLAN objects. In addition to the VLANs specified here, the bridge will also have the default-pvid VLAN configured by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... where $vid is either a single id between 1 and 4094 or a range, represented as a couple of ids separated by a dash.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE N_("Enables or disables \"hairpin mode\" for the port, which allows frames to be sent back out through the port the frame was received on.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_PATH_COST N_("The Spanning Tree Protocol (STP) port cost for destinations via this port.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_PRIORITY N_("The Spanning Tree Protocol (STP) priority of this bridge port.")
+#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_VLANS N_("Array of bridge VLAN objects. In addition to the VLANs specified here, the port will also have the default-pvid VLAN configured on the bridge by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... where $vid is either a single id between 1 and 4094 or a range, represented as a couple of ids separated by a dash.")
+#define DESCRIBE_DOC_NM_SETTING_CDMA_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.")
+#define DESCRIBE_DOC_NM_SETTING_CDMA_NUMBER N_("The number to dial to establish the connection to the CDMA-based mobile broadband network, if any. If not specified, the default number (#777) is used when required.")
+#define DESCRIBE_DOC_NM_SETTING_CDMA_PASSWORD N_("The password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here.")
+#define DESCRIBE_DOC_NM_SETTING_CDMA_PASSWORD_FLAGS N_("Flags indicating how to handle the \"password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_CDMA_USERNAME N_("The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTH_RETRIES N_("The number of retries for the authentication. Zero means to try indefinitely; -1 means to use a global default. If the global default is not set, the authentication retries for 3 times before failing the connection. Currently, this only applies to 802-1x authentication.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT N_("Whether or not the connection should be automatically connected by NetworkManager when the resources for the connection are available. TRUE to automatically activate the connection, FALSE to require manual intervention to activate the connection. Note that autoconnect is not implemented for VPN profiles. See \"secondaries\" as an alternative to automatically connect VPN profiles.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY N_("The autoconnect priority. If the connection is set to autoconnect, connections with higher priority will be preferred. Defaults to 0. The higher number means higher priority.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES N_("The number of times a connection should be tried when autoactivating before giving up. Zero means forever, -1 means the global default (4 times if not overridden). Setting this to 1 means to try activation only once before blocking autoconnect. Note that after a timeout, NetworkManager will try to autoconnect again.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES N_("Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The properties \"autoconnect\", \"autoconnect-priority\" and \"autoconnect-retries\" are unrelated to this setting. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT N_("If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_ID N_("A human readable unique identifier for the connection, like \"Work Wi-Fi\" or \"T-Mobile 3G\".")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_INTERFACE_NAME N_("The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_LLDP N_("Whether LLDP is enabled for the connection.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_LLMNR N_("Whether Link-Local Multicast Name Resolution (LLMNR) is enabled for the connection. LLMNR is a protocol based on the Domain Name System (DNS) packet format that allows both IPv4 and IPv6 hosts to perform name resolution for hosts on the same local link. The permitted values are: \"yes\" (2) register hostname and resolving for the connection, \"no\" (0) disable LLMNR for the interface, \"resolve\" (1) do not register hostname but allow resolving of LLMNR host names If unspecified, \"default\" ultimately depends on the DNS plugin (which for systemd-resolved currently means \"yes\"). This feature requires a plugin which supports LLMNR. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MASTER N_("Interface name of the master device or UUID of the master connection.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MDNS N_("Whether mDNS is enabled for the connection. The permitted values are: \"yes\" (2) register hostname and resolving for the connection, \"no\" (0) disable mDNS for the interface, \"resolve\" (1) do not register hostname but allow resolving of mDNS host names and \"default\" (-1) to allow lookup of a global default in NetworkManager.conf. If unspecified, \"default\" ultimately depends on the DNS plugin (which for systemd-resolved currently means \"no\"). This feature requires a plugin which supports mDNS. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_METERED N_("Whether the connection is metered. When updating this property on a currently activated connection, the change takes effect immediately.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MUD_URL N_("If configured, set to a Manufacturer Usage Description (MUD) URL that points to manufacturer-recommended network policies for IoT devices. It is transmitted as a DHCPv4 or DHCPv6 option. The value must be a valid URL starting with \"https://\". The special value \"none\" is allowed to indicate that no MUD URL is used. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the ultimate default is \"none\".")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_MULTI_CONNECT N_("Specifies whether the profile can be active multiple times at a particular moment. The value is of type NMConnectionMultiConnect.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_PERMISSIONS N_("An array of strings defining what access a given user has to this connection. If this is NULL or empty, all users are allowed to access this connection; otherwise users are allowed if and only if they are in this list. When this is not empty, the connection can be active only when one of the specified users is logged into an active session. Each entry is of the form \"[type]:[id]:[reserved]\"; for example, \"user:dcbw:blah\". At this time only the \"user\" [type] is allowed. Any other values are ignored and reserved for future use. [id] is the username that this permission refers to, which may not contain the \":\" character. Any [reserved] information present must be ignored and is reserved for future use. All of [type], [id], and [reserved] must be valid UTF-8.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_READ_ONLY N_("FALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_SECONDARIES N_("List of connection UUIDs that should be activated when the base connection itself is activated. Currently, only VPN connections are supported.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_SLAVE_TYPE N_("Setting name of the device type of this slave's master connection (eg, \"bond\"), or NULL if this connection is not a slave.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_STABLE_ID N_("This represents the identity of the connection used for various purposes. It allows to configure multiple profiles to share the identity. Also, the stable-id can contain placeholders that are substituted dynamically and deterministically depending on the context. The stable-id is used for generating IPv6 stable private addresses with ipv6.addr-gen-mode=stable-privacy. It is also used to seed the generated cloned MAC address for ethernet.cloned-mac-address=stable and wifi.cloned-mac-address=stable. It is also used as DHCP client identifier with ipv4.dhcp-client-id=stable and to derive the DHCP DUID with ipv6.dhcp-duid=stable-[llt,ll,uuid]. Note that depending on the context where it is used, other parameters are also seeded into the generation algorithm. For example, a per-host key is commonly also included, so that different systems end up generating different IDs. Or with ipv6.addr-gen-mode=stable-privacy, also the device's name is included, so that different interfaces yield different addresses. The per-host key is the identity of your machine and stored in /var/lib/NetworkManager/secret-key. The '$' character is treated special to perform dynamic substitutions at runtime. Currently, supported are \"${CONNECTION}\", \"${DEVICE}\", \"${MAC}\", \"${BOOT}\", \"${RANDOM}\". These effectively create unique IDs per-connection, per-device, per-boot, or every time. Note that \"${DEVICE}\" corresponds to the interface name of the device and \"${MAC}\" is the permanent MAC address of the device. Any unrecognized patterns following '$' are treated verbatim, however are reserved for future use. You are thus advised to avoid '$' or escape it as \"$$\". For example, set it to \"${CONNECTION}-${BOOT}-${DEVICE}\" to create a unique id for this connection that changes with every reboot and differs depending on the interface where the profile activates. If the value is unset, a global connection default is consulted. If the value is still unset, the default is similar to \"${CONNECTION}\" and uses a unique, fixed ID for the connection.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_TIMESTAMP N_("The time, in seconds since the Unix Epoch, that the connection was last _successfully_ fully activated. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp. The property is only meant for reading (changes to this property will not be preserved).")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_TYPE N_("Base type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, \"802-3-ethernet\" or \"802-11-wireless\" or \"bluetooth\", etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, \"vpn\" or \"bridge\", etc).")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_UUID N_("A universally unique identifier for the connection, for example generated with libuuid. It should be assigned when the connection is created, and never changed as long as the connection still applies to the same network. For example, it should not be changed when the \"id\" property or NMSettingIP4Config changes, but might need to be re-created when the Wi-Fi SSID, mobile broadband network provider, or \"type\" property changes. The UUID must be in the format \"2815492f-7e56-435e-b2e9-246bd7cdc664\" (ie, contains only hexadecimal characters and \"-\").")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT N_("Timeout in milliseconds to wait for device at startup. During boot, devices may take a while to be detected by the driver. This property will cause to delay NetworkManager-wait-online.service and nm-online to give the device a chance to appear. This works by waiting for the given timeout until a compatible device for the profile is available and managed. The value 0 means no wait time. The default value is -1, which currently has the same meaning as no wait time.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_ZONE N_("The trust level of a the connection. Free form case-insensitive string (for example \"Home\", \"Work\", \"Public\"). NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall. When updating this property on a currently activated connection, the change takes effect immediately.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_APP_FCOE_FLAGS N_("Specifies the NMSettingDcbFlags for the DCB FCoE application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).")
+#define DESCRIBE_DOC_NM_SETTING_DCB_APP_FCOE_MODE N_("The FCoE controller mode; either \"fabric\" (default) or \"vn2vn\".")
+#define DESCRIBE_DOC_NM_SETTING_DCB_APP_FCOE_PRIORITY N_("The highest User Priority (0 - 7) which FCoE frames should use, or -1 for default priority. Only used when the \"app-fcoe-flags\" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_APP_FIP_FLAGS N_("Specifies the NMSettingDcbFlags for the DCB FIP application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).")
+#define DESCRIBE_DOC_NM_SETTING_DCB_APP_FIP_PRIORITY N_("The highest User Priority (0 - 7) which FIP frames should use, or -1 for default priority. Only used when the \"app-fip-flags\" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_APP_ISCSI_FLAGS N_("Specifies the NMSettingDcbFlags for the DCB iSCSI application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).")
+#define DESCRIBE_DOC_NM_SETTING_DCB_APP_ISCSI_PRIORITY N_("The highest User Priority (0 - 7) which iSCSI frames should use, or -1 for default priority. Only used when the \"app-iscsi-flags\" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_BANDWIDTH N_("An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the percentage of bandwidth of the priority's assigned group that the priority may use. The sum of all percentages for priorities which belong to the same group must total 100 percents.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_FLOW_CONTROL N_("An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the corresponding priority should transmit priority pause.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS N_("Specifies the NMSettingDcbFlags for DCB Priority Flow Control (PFC). Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).")
+#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH N_("An array of 8 uint values, where the array index corresponds to the Priority Group ID (0 - 7) and the value indicates the percentage of link bandwidth allocated to that group. Allowed values are 0 - 100, and the sum of all values must total 100 percents.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_GROUP_FLAGS N_("Specifies the NMSettingDcbFlags for DCB Priority Groups. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4).")
+#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_GROUP_ID N_("An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the Priority Group ID. Allowed Priority Group ID values are 0 - 7 or 15 for the unrestricted group.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH N_("An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the priority may use all of the bandwidth allocated to its assigned group.")
+#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS N_("An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the traffic class (0 - 7) to which the priority is mapped.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_APN N_("The GPRS Access Point Name specifying the APN used when establishing a data session with the GSM-based network. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider-specific walled-garden, so it is important to use the correct APN for the user's mobile broadband plan. The APN may only be composed of the characters a-z, 0-9, ., and - per GSM 03.60 Section 14.9.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_AUTO_CONFIG N_("When TRUE, the settings such as APN, username, or password will default to values that match the network the modem will register to in the Mobile Broadband Provider database.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_DEVICE_ID N_("The device unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will only apply to the specified device.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_HOME_ONLY N_("When TRUE, only connections to the home network will be allowed. Connections to roaming networks will not be made.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_NETWORK_ID N_("The Network ID (GSM LAI format, ie MCC-MNC) to force specific network registration. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_NUMBER N_("Legacy setting that used to help establishing PPP data sessions for GSM-based modems. Deprecated: 1")
+#define DESCRIBE_DOC_NM_SETTING_GSM_PASSWORD N_("The password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_PASSWORD_FLAGS N_("Flags indicating how to handle the \"password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_PIN N_("If the SIM is locked with a PIN it must be unlocked before any other operations are requested. Specify the PIN here to allow operation of the device.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_PIN_FLAGS N_("Flags indicating how to handle the \"pin\" property.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_SIM_ID N_("The SIM card unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will apply to any device also allowed by \"device-id\" which contains a SIM card matching the given identifier.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_SIM_OPERATOR_ID N_("A MCC/MNC string like \"310260\" or \"21601\" identifying the specific mobile network operator which this connection applies to. If given, the connection will apply to any device also allowed by \"device-id\" and \"sim-id\" which contains a SIM card provisioned by the given operator.")
+#define DESCRIBE_DOC_NM_SETTING_GSM_USERNAME N_("The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.")
+#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DHCP N_("Whether the system hostname can be determined from DHCP on this connection. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).")
+#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP N_("Whether the system hostname can be determined from reverse DNS lookup of addresses on this device. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).")
+#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT N_("If set to NM_TERNARY_TRUE (1), NetworkManager attempts to get the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this device only when the device has the default route for the given address family (IPv4/IPv6). If set to NM_TERNARY_FALSE (0), the hostname can be set from this device even if it doesn't have the default route. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_FALSE (0).")
+#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_PRIORITY N_("The relative priority of this connection to determine the system hostname. A lower numerical value is better (higher priority). A connection with higher priority is considered before connections with lower priority. If the value is zero, it can be overridden by a global value from NetworkManager configuration. If the property doesn't have a value in the global configuration, the value is assumed to be 100. Negative values have the special effect of excluding other connections with a greater numerical priority value; so in presence of at least one negative priority, only connections with the lowest priority value will be used to determine the hostname.")
+#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MAC_ADDRESS N_("If specified, this connection will only apply to the IPoIB device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).")
+#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.")
+#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_P_KEY N_("The InfiniBand P_Key to use for this device. A value of -1 means to use the default P_Key (aka \"the P_Key at index 0\"). Otherwise, it is a 16-bit unsigned integer, whose high bit is set if it is a \"full membership\" P_Key.")
+#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_PARENT N_("The interface name of the parent device of this device. Normally NULL, but if the \"p_key\" property is set, then you must specify the base device by setting either this property or \"mac-address\".")
+#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_TRANSPORT_MODE N_("The IP-over-InfiniBand transport mode. Either \"datagram\" or \"connected\".")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT N_("How many additional levels of encapsulation are permitted to be prepended to packets. This property applies only to IPv6 tunnels.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_FLAGS N_("Tunnel flags. Currently, the following values are supported: NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT (0x1), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS (0x2), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL (0x4), NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV (0x8), NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY (0x10), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK (0x20). They are valid only for IPv6 tunnels.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_FLOW_LABEL N_("The flow label to assign to tunnel packets. This property applies only to IPv6 tunnels.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_INPUT_KEY N_("The key used for tunnel input packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_LOCAL N_("The local endpoint of the tunnel; the value can be empty, otherwise it must contain an IPv4 or IPv6 address.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_MODE N_("The tunneling mode, for example NM_IP_TUNNEL_MODE_IPIP (1) or NM_IP_TUNNEL_MODE_GRE (2).")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_OUTPUT_KEY N_("The key used for tunnel output packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_PARENT N_("If given, specifies the parent interface name or parent connection UUID the new device will be bound to so that tunneled packets will only be routed via that interface.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY N_("Whether to enable Path MTU Discovery on this tunnel.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_REMOTE N_("The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 address.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_TOS N_("The type of service (IPv4) or traffic class (IPv6) field to be set on tunneled packets.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_TTL N_("The TTL to assign to tunneled packets. 0 is a special value meaning that packets inherit the TTL value.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES N_("A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\".")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DAD_TIMEOUT N_("Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID N_("A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values \"mac\" and \"perm-mac\" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value \"ipv6-duid\" uses the DUID from \"ipv6.dhcp-duid\" property as an RFC4361-compliant client identifier. As IAID it uses \"ipv4.dhcp-iaid\" and falls back to \"ipv6.dhcp-iaid\" if unset. The special value \"duid\" generates a RFC4361-compliant client identifier based on \"ipv4.dhcp-iaid\" and uses a DUID generated by hashing /etc/machine-id. The special value \"stable\" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the \"${DEVICE}\" or \"${MAC}\" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_FQDN N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-hostname\" are mutually exclusive and cannot be set at the same time.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-fqdn\" are mutually exclusive and cannot be set at the same time.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME_FLAGS N_("Flags for the DHCP hostname and FQDN. Currently, this property only includes flags to control the FQDN flags set in the DHCP FQDN option. Supported FQDN flags are NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) and NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE (0x4). When no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is set, the DHCP FQDN option will contain no flag. Otherwise, if no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is not set, the standard FQDN flags are set in the request: NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) for IPv4 and NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1) for IPv6. When this property is set to the default value NM_DHCP_HOSTNAME_FLAG_NONE (0x0), a global default is looked up in NetworkManager configuration. If that value is unset or also NM_DHCP_HOSTNAME_FLAG_NONE (0x0), then the standard FQDN flags described above are sent in the DHCP requests.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_IAID N_("A string containing the \"Identity Association Identifier\" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among \"mac\", \"perm-mac\", \"ifname\" and \"stable\". When set to \"mac\" (or \"perm-mac\"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to \"ifname\", the IAID is computed by hashing the interface name. The special value \"stable\" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be \"ifname\". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_REJECT_SERVERS N_("Array of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. \"192.168.122.0/24\"). This property is currently not implemented for DHCPv6.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER N_("The Vendor Class Identifier DHCP option (60). Special characters in the data string may be escaped using C-style escapes, nevertheless this property cannot contain nul bytes. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the DHCP option is not sent to the server. Since 1.28")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS N_("Array of IP addresses of DNS servers.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled. When using a caching DNS plugin (dnsmasq or systemd-resolved in NetworkManager.conf) then \"edns0\" and \"trust-ad\" are automatically added.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the \"rotate\" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with \"never-default\" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured name servers and search domains are ignored and only name servers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_MAY_FAIL N_("If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_METHOD N_("IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support \"disabled\", \"auto\", \"manual\", and \"link-local\". See the subclass-specific documentation for other values. In general, for the \"auto\" method, properties such as \"dns\" and \"routes\" specify information that is added on to the information returned from automatic configuration. The \"ignore-auto-routes\" and \"ignore-auto-dns\" properties modify this behavior. For methods that imply no upstream network, such as \"shared\" or \"link-local\", these properties must be empty. For IPv4 method \"shared\", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen. Note that the shared method must be configured on the interface which shares the internet to a subnet, not on the uplink which is shared.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_NEVER_DEFAULT N_("If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_METRIC N_("The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_TABLE N_("Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTES N_("A list of IPv4 destination addresses, prefix length, optional IPv4 next hop addresses, optional route metric, optional attribute. The valid syntax is: \"ip[/prefix] [next-hop] [metric] [attribute=val]...[,ip[/prefix]...]\". For example \"192.0.2.0/24 10.1.1.1 77, 198.51.100.0/24\".")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE N_("Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are: NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 (0) or NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY (1). If the property is set to EUI64, the addresses will be generated using the interface tokens derived from hardware address. This makes the host part of the address to stay constant, making it possible to track host's presence when it changes networks. The address changes when the interface hardware is replaced. The value of stable-privacy enables use of cryptographically secure hash of a secret host-specific key along with the connection's stable-id and the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address stable when the network interface hardware is replaced. On D-Bus, the absence of an addr-gen-mode setting equals enabling stable-privacy. For keyfile plugin, the absence of the setting on disk means EUI64 so that the property doesn't change on upgrade from older versions. Note that this setting is distinct from the Privacy Extensions as configured by \"ip6-privacy\" property and it does not affect the temporary addresses configured with this option.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDRESSES N_("Array of IP addresses.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DAD_TIMEOUT N_("Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_DUID N_("A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp client to identify itself to DHCPv6 servers (RFC 3315). The DUID is carried in the Client Identifier option. If the property is a hex string ('aa:bb:cc') it is interpreted as a binary DUID and filled as an opaque value in the Client Identifier option. The special value \"lease\" will retrieve the DUID previously used from the lease file belonging to the connection. If no DUID is found and \"dhclient\" is the configured dhcp client, the DUID is searched in the system-wide dhclient lease file. If still no DUID is found, or another dhcp client is used, a global and permanent DUID-UUID (RFC 6355) will be generated based on the machine-id. The special values \"llt\" and \"ll\" will generate a DUID of type LLT or LL (see RFC 3315) based on the current MAC address of the device. In order to try providing a stable DUID-LLT, the time field will contain a constant timestamp that is used globally (for all profiles) and persisted to disk. The special values \"stable-llt\", \"stable-ll\" and \"stable-uuid\" will generate a DUID of the corresponding type, derived from the connection's stable-id and a per-host unique key. You may want to include the \"${DEVICE}\" or \"${MAC}\" specifier in the stable-id, in case this profile gets activated on multiple devices. So, the link-layer address of \"stable-ll\" and \"stable-llt\" will be a generated address derived from the stable id. The DUID-LLT time value in the \"stable-llt\" option will be picked among a static timespan of three years (the upper bound of the interval is the same constant timestamp used in \"llt\"). When the property is unset, the global value provided for \"ipv6.dhcp-duid\" is used. If no global value is provided, the default \"lease\" value is assumed.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-fqdn\" are mutually exclusive and cannot be set at the same time.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME_FLAGS N_("Flags for the DHCP hostname and FQDN. Currently, this property only includes flags to control the FQDN flags set in the DHCP FQDN option. Supported FQDN flags are NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) and NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE (0x4). When no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is set, the DHCP FQDN option will contain no flag. Otherwise, if no FQDN flag is set and NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS (0x8) is not set, the standard FQDN flags are set in the request: NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1), NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED (0x2) for IPv4 and NM_DHCP_HOSTNAME_FLAG_FQDN_SERV_UPDATE (0x1) for IPv6. When this property is set to the default value NM_DHCP_HOSTNAME_FLAG_NONE (0x0), a global default is looked up in NetworkManager configuration. If that value is unset or also NM_DHCP_HOSTNAME_FLAG_NONE (0x0), then the standard FQDN flags described above are sent in the DHCP requests.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_IAID N_("A string containing the \"Identity Association Identifier\" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among \"mac\", \"perm-mac\", \"ifname\" and \"stable\". When set to \"mac\" (or \"perm-mac\"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to \"ifname\", the IAID is computed by hashing the interface name. The special value \"stable\" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be \"ifname\". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_REJECT_SERVERS N_("Array of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. \"192.168.122.0/24\"). This property is currently not implemented for DHCPv6.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS N_("Array of IP addresses of DNS servers.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled. When using a caching DNS plugin (dnsmasq or systemd-resolved in NetworkManager.conf) then \"edns0\" and \"trust-ad\" are automatically added.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the \"rotate\" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with \"never-default\" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured name servers and search domains are ignored and only name servers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IP6_PRIVACY N_("Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to \"-1\" (unknown) means fallback to global configuration \"ipv6.ip6-privacy\". If also global configuration is unspecified or set to \"-1\", fallback to read \"/proc/sys/net/ipv6/conf/default/use_tempaddr\". Note that this setting is distinct from the Stable Privacy addresses that can be enabled with the \"addr-gen-mode\" property's \"stable-privacy\" setting as another way of avoiding host tracking with IPv6 addresses.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_MAY_FAIL N_("If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_METHOD N_("IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support \"disabled\", \"auto\", \"manual\", and \"link-local\". See the subclass-specific documentation for other values. In general, for the \"auto\" method, properties such as \"dns\" and \"routes\" specify information that is added on to the information returned from automatic configuration. The \"ignore-auto-routes\" and \"ignore-auto-dns\" properties modify this behavior. For methods that imply no upstream network, such as \"shared\" or \"link-local\", these properties must be empty. For IPv4 method \"shared\", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen. Note that the shared method must be configured on the interface which shares the internet to a subnet, not on the uplink which is shared.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_NEVER_DEFAULT N_("If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_RA_TIMEOUT N_("A timeout for waiting Router Advertisements in seconds. If zero (the default), a globally configured default is used. If still unspecified, the timeout depends on the sysctl settings of the device. Set to 2147483647 (MAXINT32) for infinity.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_METRIC N_("The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_TABLE N_("Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTES N_("Array of IP routes.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_TOKEN N_("Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_ENCRYPT N_("Whether the transmitted traffic must be encrypted.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_MKA_CAK N_("The pre-shared CAK (Connectivity Association Key) for MACsec Key Agreement.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_MKA_CAK_FLAGS N_("Flags indicating how to handle the \"mka-cak\" property.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_MKA_CKN N_("The pre-shared CKN (Connectivity-association Key Name) for MACsec Key Agreement.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_MODE N_("Specifies how the CAK (Connectivity Association Key) for MKA (MACsec Key Agreement) is obtained.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this MACSEC interface should be created. If this property is not specified, the connection must contain an \"802-3-ethernet\" setting with a \"mac-address\" property.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_PORT N_("The port component of the SCI (Secure Channel Identifier), between 1 and 65534.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_SEND_SCI N_("Specifies whether the SCI (Secure Channel Identifier) is included in every packet.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_VALIDATION N_("Specifies the validation mode for incoming frames.")
+#define DESCRIBE_DOC_NM_SETTING_MACVLAN_MODE N_("The macvlan mode, which specifies the communication mechanism between multiple macvlans on the same lower device.")
+#define DESCRIBE_DOC_NM_SETTING_MACVLAN_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this MAC-VLAN interface should be created. If this property is not specified, the connection must contain an \"802-3-ethernet\" setting with a \"mac-address\" property.")
+#define DESCRIBE_DOC_NM_SETTING_MACVLAN_PROMISCUOUS N_("Whether the interface should be put in promiscuous mode.")
+#define DESCRIBE_DOC_NM_SETTING_MACVLAN_TAP N_("Whether the interface should be a MACVTAP.")
+#define DESCRIBE_DOC_NM_SETTING_MATCH_DRIVER N_("A list of driver names to match. Each element is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.")
+#define DESCRIBE_DOC_NM_SETTING_MATCH_INTERFACE_NAME N_("A list of interface names to match. Each element is a shell wildcard pattern. An element can be prefixed with a pipe symbol (|) or an ampersand (&). The former means that the element is optional and the latter means that it is mandatory. If there are any optional elements, than the match evaluates to true if at least one of the optional element matches (logical OR). If there are any mandatory elements, then they all must match (logical AND). By default, an element is optional. This means that an element \"foo\" behaves the same as \"|foo\". An element can also be inverted with exclamation mark (!) between the pipe symbol (or the ampersand) and before the pattern. Note that \"!foo\" is a shortcut for the mandatory match \"&!foo\". Finally, a backslash can be used at the beginning of the element (after the optional special characters) to escape the start of the pattern. For example, \"&\\!a\" is an mandatory match for literally \"!a\".")
+#define DESCRIBE_DOC_NM_SETTING_MATCH_KERNEL_COMMAND_LINE N_("A list of kernel command line arguments to match. This may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset). The argument must either be a single word, or an assignment (i.e. two words, separated \"=\"). In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.")
+#define DESCRIBE_DOC_NM_SETTING_MATCH_PATH N_("A list of paths to match against the ID_PATH udev property of devices. ID_PATH represents the topological persistent path of a device. It typically contains a subsystem string (pci, usb, platform, etc.) and a subsystem-specific identifier. For PCI devices the path has the form \"pci-$domain:$bus:$device.$function\", where each variable is an hexadecimal value; for example \"pci-0000:0a:00.0\". The path of a device can be obtained with \"udevadm info /sys/class/net/$dev | grep ID_PATH=\" or by looking at the \"path\" property exported by NetworkManager (\"nmcli -f general.path device show $dev\"). Each element of the list is a shell wildcard pattern. See NMSettingMatch:interface-name for how special characters '|', '&', '!' and '\\' are used for optional and mandatory matches and inverting the pattern.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_DATAPATH_TYPE N_("The data path type. One of \"system\", \"netdev\" or empty.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_FAIL_MODE N_("The bridge failure mode. One of \"secure\", \"standalone\" or empty.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE N_("Enable or disable multicast snooping.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_RSTP_ENABLE N_("Enable or disable RSTP.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_STP_ENABLE N_("Enable or disable STP.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_DPDK_DEVARGS N_("Open vSwitch DPDK device arguments.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_EXTERNAL_IDS_DATA N_("A dictionary of key/value pairs with exernal-ids for OVS.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_INTERFACE_TYPE N_("The interface type. Either \"internal\", \"system\", \"patch\", \"dpdk\", or empty.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_PATCH_PEER N_("Specifies the name of the interface for the other side of the patch. The patch on the other side must also set this interface as peer.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_BOND_DOWNDELAY N_("The time port must be inactive in order to be considered down.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_BOND_MODE N_("Bonding mode. One of \"active-backup\", \"balance-slb\", or \"balance-tcp\".")
+#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_BOND_UPDELAY N_("The time port must be active before it starts forwarding traffic.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_LACP N_("LACP mode. One of \"active\", \"off\", or \"passive\".")
+#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_TAG N_("The VLAN tag in the range 0-4095.")
+#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_VLAN_MODE N_("The VLAN mode. One of \"access\", \"native-tagged\", \"native-untagged\", \"trunk\" or unset.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_BAUD N_("If non-zero, instruct pppd to set the serial port to the specified baudrate. This value should normally be left as 0 to automatically choose the speed.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_CRTSCTS N_("If TRUE, specify that pppd should set the serial port to use hardware flow control with RTS and CTS signals. This value should normally be set to FALSE.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_LCP_ECHO_FAILURE N_("If non-zero, instruct pppd to presume the connection to the peer has failed if the specified number of LCP echo-requests go unanswered by the peer. The \"lcp-echo-interval\" property must also be set to a non-zero value if this property is used.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_LCP_ECHO_INTERVAL N_("If non-zero, instruct pppd to send an LCP echo-request frame to the peer every n seconds (where n is the specified value). Note that some PPP peers will respond to echo requests and some will not, and it is not possible to autodetect this.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_MPPE_STATEFUL N_("If TRUE, stateful MPPE is used. See pppd documentation for more information on stateful MPPE.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_MRU N_("If non-zero, instruct pppd to request that the peer send packets no larger than the specified size. If non-zero, the MRU should be between 128 and 16384.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_MTU N_("If non-zero, instruct pppd to send packets no larger than the specified size.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_NO_VJ_COMP N_("If TRUE, Van Jacobsen TCP header compression will not be requested.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_NOAUTH N_("If TRUE, do not require the other side (usually the PPP server) to authenticate itself to the client. If FALSE, require authentication from the remote side. In almost all cases, this should be TRUE.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_NOBSDCOMP N_("If TRUE, BSD compression will not be requested.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_NODEFLATE N_("If TRUE, \"deflate\" compression will not be requested.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_REFUSE_CHAP N_("If TRUE, the CHAP authentication method will not be used.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_REFUSE_EAP N_("If TRUE, the EAP authentication method will not be used.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_REFUSE_MSCHAP N_("If TRUE, the MSCHAP authentication method will not be used.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_REFUSE_MSCHAPV2 N_("If TRUE, the MSCHAPv2 authentication method will not be used.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_REFUSE_PAP N_("If TRUE, the PAP authentication method will not be used.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_REQUIRE_MPPE N_("If TRUE, MPPE (Microsoft Point-to-Point Encryption) will be required for the PPP session. If either 64-bit or 128-bit MPPE is not available the session will fail. Note that MPPE is not used on mobile broadband connections.")
+#define DESCRIBE_DOC_NM_SETTING_PPP_REQUIRE_MPPE_128 N_("If TRUE, 128-bit MPPE (Microsoft Point-to-Point Encryption) will be required for the PPP session, and the \"require-mppe\" property must also be set to TRUE. If 128-bit MPPE is not available the session will fail.")
+#define DESCRIBE_DOC_NM_SETTING_PPPOE_PARENT N_("If given, specifies the parent interface name on which this PPPoE connection should be created. If this property is not specified, the connection is activated on the interface specified in \"interface-name\" of NMSettingConnection.")
+#define DESCRIBE_DOC_NM_SETTING_PPPOE_PASSWORD N_("Password used to authenticate with the PPPoE service.")
+#define DESCRIBE_DOC_NM_SETTING_PPPOE_PASSWORD_FLAGS N_("Flags indicating how to handle the \"password\" property.")
+#define DESCRIBE_DOC_NM_SETTING_PPPOE_SERVICE N_("If specified, instruct PPPoE to only initiate sessions with access concentrators that provide the specified service. For most providers, this should be left blank. It is only required if there are multiple access concentrators or a specific service is known to be required.")
+#define DESCRIBE_DOC_NM_SETTING_PPPOE_USERNAME N_("Username used to authenticate with the PPPoE service.")
+#define DESCRIBE_DOC_NM_SETTING_PROXY_BROWSER_ONLY N_("Whether the proxy configuration is for browser only.")
+#define DESCRIBE_DOC_NM_SETTING_PROXY_METHOD N_("Method for proxy configuration, Default is NM_SETTING_PROXY_METHOD_NONE (0)")
+#define DESCRIBE_DOC_NM_SETTING_PROXY_PAC_SCRIPT N_("PAC script for the connection.")
+#define DESCRIBE_DOC_NM_SETTING_PROXY_PAC_URL N_("PAC URL for obtaining PAC file.")
+#define DESCRIBE_DOC_NM_SETTING_SERIAL_BAUD N_("Speed to use for communication over the serial port. Note that this value usually has no effect for mobile broadband modems as they generally ignore speed settings and use the highest available speed.")
+#define DESCRIBE_DOC_NM_SETTING_SERIAL_BITS N_("Byte-width of the serial communication. The 8 in \"8n1\" for example.")
+#define DESCRIBE_DOC_NM_SETTING_SERIAL_PARITY N_("Parity setting of the serial port.")
+#define DESCRIBE_DOC_NM_SETTING_SERIAL_SEND_DELAY N_("Time to delay between each byte sent to the modem, in microseconds.")
+#define DESCRIBE_DOC_NM_SETTING_SERIAL_STOPBITS N_("Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in \"8n1\" for example.")
+#define DESCRIBE_DOC_NM_SETTING_SRIOV_AUTOPROBE_DRIVERS N_("Whether to autoprobe virtual functions by a compatible driver. If set to NM_TERNARY_TRUE (1), the kernel will try to bind VFs to a compatible driver and if this succeeds a new network interface will be instantiated for each VF. If set to NM_TERNARY_FALSE (0), VFs will not be claimed and no network interfaces will be created for them. When set to NM_TERNARY_DEFAULT (-1), the global default is used; in case the global default is unspecified it is assumed to be NM_TERNARY_TRUE (1).")
+#define DESCRIBE_DOC_NM_SETTING_SRIOV_TOTAL_VFS N_("The total number of virtual functions to create. Note that when the sriov setting is present NetworkManager enforces the number of virtual functions on the interface (also when it is zero) during activation and resets it upon deactivation. To prevent any changes to SR-IOV parameters don't add a sriov setting to the connection.")
+#define DESCRIBE_DOC_NM_SETTING_SRIOV_VFS N_("Array of virtual function descriptors. Each VF descriptor is a dictionary mapping attribute names to GVariant values. The 'index' entry is mandatory for each VF. When represented as string a VF is in the form: \"INDEX [ATTR=VALUE[ ATTR=VALUE]...]\". for example: \"2 mac=00:11:22:33:44:55 spoof-check=true\". Multiple VFs can be specified using a comma as separator. Currently, the following attributes are supported: mac, spoof-check, trust, min-tx-rate, max-tx-rate, vlans. The \"vlans\" attribute is represented as a semicolon-separated list of VLAN descriptors, where each descriptor has the form \"ID[.PRIORITY[.PROTO]]\". PROTO can be either 'q' for 802.1Q (the default) or 'ad' for 802.1ad.")
+#define DESCRIBE_DOC_NM_SETTING_TC_CONFIG_QDISCS N_("Array of TC queueing disciplines.")
+#define DESCRIBE_DOC_NM_SETTING_TC_CONFIG_TFILTERS N_("Array of TC traffic filters.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_CONFIG N_("The JSON configuration for the team network interface. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_LINK_WATCHERS N_("Link watchers configuration for the connection: each link watcher is defined by a dictionary, whose keys depend upon the selected link watcher. Available link watchers are 'ethtool', 'nsna_ping' and 'arp_ping' and it is specified in the dictionary with the key 'name'. Available keys are: ethtool: 'delay-up', 'delay-down', 'init-wait'; nsna_ping: 'init-wait', 'interval', 'missed-max', 'target-host'; arp_ping: all the ones in nsna_ping and 'source-host', 'validate-active', 'validate-inactive', 'send-always'. See teamd.conf man for more details.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_MCAST_REJOIN_COUNT N_("Corresponds to the teamd mcast_rejoin.count.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL N_("Corresponds to the teamd mcast_rejoin.interval.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_NOTIFY_PEERS_COUNT N_("Corresponds to the teamd notify_peers.count.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL N_("Corresponds to the teamd notify_peers.interval.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER N_("Corresponds to the teamd runner.name. Permitted values are: \"roundrobin\", \"broadcast\", \"activebackup\", \"loadbalance\", \"lacp\", \"random\".")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_ACTIVE N_("Corresponds to the teamd runner.active.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY N_("Corresponds to the teamd runner.agg_select_policy.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_FAST_RATE N_("Corresponds to the teamd runner.fast_rate.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_HWADDR_POLICY N_("Corresponds to the teamd runner.hwaddr_policy.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_MIN_PORTS N_("Corresponds to the teamd runner.min_ports.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_SYS_PRIO N_("Corresponds to the teamd runner.sys_prio.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER N_("Corresponds to the teamd runner.tx_balancer.name.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL N_("Corresponds to the teamd runner.tx_balancer.interval.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_HASH N_("Corresponds to the teamd runner.tx_hash.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_CONFIG N_("The JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LACP_KEY N_("Corresponds to the teamd ports.PORTIFNAME.lacp_key.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LACP_PRIO N_("Corresponds to the teamd ports.PORTIFNAME.lacp_prio.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LINK_WATCHERS N_("Link watchers configuration for the connection: each link watcher is defined by a dictionary, whose keys depend upon the selected link watcher. Available link watchers are 'ethtool', 'nsna_ping' and 'arp_ping' and it is specified in the dictionary with the key 'name'. Available keys are: ethtool: 'delay-up', 'delay-down', 'init-wait'; nsna_ping: 'init-wait', 'interval', 'missed-max', 'target-host'; arp_ping: all the ones in nsna_ping and 'source-host', 'validate-active', 'validate-inactive', 'send-always'. See teamd.conf man for more details.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_PRIO N_("Corresponds to the teamd ports.PORTIFNAME.prio.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_QUEUE_ID N_("Corresponds to the teamd ports.PORTIFNAME.queue_id. When set to -1 means the parameter is skipped from the json config.")
+#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_STICKY N_("Corresponds to the teamd ports.PORTIFNAME.sticky.")
+#define DESCRIBE_DOC_NM_SETTING_TUN_GROUP N_("The group ID which will own the device. If set to NULL everyone will be able to use the device.")
+#define DESCRIBE_DOC_NM_SETTING_TUN_MODE N_("The operating mode of the virtual device. Allowed values are NM_SETTING_TUN_MODE_TUN (1) to create a layer 3 device and NM_SETTING_TUN_MODE_TAP (2) to create an Ethernet-like layer 2 one.")
+#define DESCRIBE_DOC_NM_SETTING_TUN_MULTI_QUEUE N_("If the property is set to TRUE, the interface will support multiple file descriptors (queues) to parallelize packet sending or receiving. Otherwise, the interface will only support a single queue.")
+#define DESCRIBE_DOC_NM_SETTING_TUN_OWNER N_("The user ID which will own the device. If set to NULL everyone will be able to use the device.")
+#define DESCRIBE_DOC_NM_SETTING_TUN_PI N_("If TRUE the interface will prepend a 4 byte header describing the physical interface to the packets.")
+#define DESCRIBE_DOC_NM_SETTING_TUN_VNET_HDR N_("If TRUE the IFF_VNET_HDR the tunnel packets will include a virtio network header.")
+#define DESCRIBE_DOC_NM_SETTING_USER_DATA N_("A dictionary of key/value pairs with user data. This data is ignored by NetworkManager and can be used at the users discretion. The keys only support a strict ascii format, but the values can be arbitrary UTF8 strings up to a certain length.")
+#define DESCRIBE_DOC_NM_SETTING_VETH_PEER N_("This property specifies the peer interface name of the veth. This property is mandatory.")
+#define DESCRIBE_DOC_NM_SETTING_VLAN_EGRESS_PRIORITY_MAP N_("For outgoing packets, a list of mappings from Linux SKB priorities to 802.1p priorities. The mapping is given in the format \"from:to\" where both \"from\" and \"to\" are unsigned integers, ie \"7:3\".")
+#define DESCRIBE_DOC_NM_SETTING_VLAN_FLAGS N_("One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state). NM_VLAN_FLAG_MVRP (0x8) (use of the MVRP protocol). The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, but it used to be 0. To preserve backward compatibility, the default-value in the D-Bus API continues to be 0 and a missing property on D-Bus is still considered as 0.")
+#define DESCRIBE_DOC_NM_SETTING_VLAN_ID N_("The VLAN identifier that the interface created by this connection should be assigned. The valid range is from 0 to 4094, without the reserved id 4095.")
+#define DESCRIBE_DOC_NM_SETTING_VLAN_INGRESS_PRIORITY_MAP N_("For incoming packets, a list of mappings from 802.1p priorities to Linux SKB priorities. The mapping is given in the format \"from:to\" where both \"from\" and \"to\" are unsigned integers, ie \"7:3\".")
+#define DESCRIBE_DOC_NM_SETTING_VLAN_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this VLAN interface should be created. If this property is not specified, the connection must contain an \"802-3-ethernet\" setting with a \"mac-address\" property.")
+#define DESCRIBE_DOC_NM_SETTING_VPN_DATA N_("Dictionary of key/value pairs of VPN plugin specific data. Both keys and values must be strings.")
+#define DESCRIBE_DOC_NM_SETTING_VPN_PERSISTENT N_("If the VPN service supports persistence, and this property is TRUE, the VPN will attempt to stay connected across link changes and outages, until explicitly disconnected.")
+#define DESCRIBE_DOC_NM_SETTING_VPN_SECRETS N_("Dictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys. Both keys and values must be strings.")
+#define DESCRIBE_DOC_NM_SETTING_VPN_SERVICE_TYPE N_("D-Bus service name of the VPN plugin that this setting uses to connect to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc plugin.")
+#define DESCRIBE_DOC_NM_SETTING_VPN_TIMEOUT N_("Timeout for the VPN service to establish the connection. Some services may take quite a long time to connect. Value of 0 means a default timeout, which is 60 seconds (unless overridden by vpn.timeout in configuration file). Values greater than zero mean timeout in seconds.")
+#define DESCRIBE_DOC_NM_SETTING_VPN_USER_NAME N_("If the VPN connection requires a user name for authentication, that name should be provided here. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection.")
+#define DESCRIBE_DOC_NM_SETTING_VRF_TABLE N_("The routing table for this VRF.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_AGEING N_("Specifies the lifetime in seconds of FDB entries learnt by the kernel.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_DESTINATION_PORT N_("Specifies the UDP destination port to communicate to the remote VXLAN tunnel endpoint.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_ID N_("Specifies the VXLAN Network Identifier (or VXLAN Segment Identifier) to use.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_L2_MISS N_("Specifies whether netlink LL ADDR miss notifications are generated.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_L3_MISS N_("Specifies whether netlink IP ADDR miss notifications are generated.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_LEARNING N_("Specifies whether unknown source link layer addresses and IP addresses are entered into the VXLAN device forwarding database.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_LIMIT N_("Specifies the maximum number of FDB entries. A value of zero means that the kernel will store unlimited entries.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_LOCAL N_("If given, specifies the source IP address to use in outgoing packets.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_PARENT N_("If given, specifies the parent interface name or parent connection UUID.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_PROXY N_("Specifies whether ARP proxy is turned on.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_REMOTE N_("Specifies the unicast destination IP address to use in outgoing packets when the destination link layer address is not known in the VXLAN device forwarding database, or the multicast IP address to join.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_RSC N_("Specifies whether route short circuit is turned on.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_SOURCE_PORT_MAX N_("Specifies the maximum UDP source port to communicate to the remote VXLAN tunnel endpoint.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_SOURCE_PORT_MIN N_("Specifies the minimum UDP source port to communicate to the remote VXLAN tunnel endpoint.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_TOS N_("Specifies the TOS value to use in outgoing packets.")
+#define DESCRIBE_DOC_NM_SETTING_VXLAN_TTL N_("Specifies the time-to-live value to use in outgoing packets.")
+#define DESCRIBE_DOC_NM_SETTING_WIFI_P2P_PEER N_("The P2P device that should be connected to. Currently, this is the only way to create or join a group.")
+#define DESCRIBE_DOC_NM_SETTING_WIFI_P2P_WFD_IES N_("The Wi-Fi Display (WFD) Information Elements (IEs) to set. Wi-Fi Display requires a protocol specific information element to be set in certain Wi-Fi frames. These can be specified here for the purpose of establishing a connection. This setting is only useful when implementing a Wi-Fi Display client.")
+#define DESCRIBE_DOC_NM_SETTING_WIFI_P2P_WPS_METHOD N_("Flags indicating which mode of WPS is to be used. There's little point in changing the default setting as NetworkManager will automatically determine the best method to use.")
+#define DESCRIBE_DOC_NM_SETTING_WIMAX_MAC_ADDRESS N_("If specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing). Deprecated: 1")
+#define DESCRIBE_DOC_NM_SETTING_WIMAX_NETWORK_NAME N_("Network Service Provider (NSP) name of the WiMAX network this connection should use. Deprecated: 1")
+#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_FWMARK N_("The use of fwmark is optional and is by default off. Setting it to 0 disables it. Otherwise, it is a 32-bit fwmark for outgoing packets. Note that \"ip4-auto-default-route\" or \"ip6-auto-default-route\" enabled, implies to automatically choose a fwmark.")
+#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE N_("Whether to enable special handling of the IPv4 default route. If enabled, the IPv4 default route from wireguard.peer-routes will be placed to a dedicated routing-table and two policy routing rules will be added. The fwmark number is also used as routing-table for the default-route, and if fwmark is zero, an unused fwmark/table is chosen automatically. This corresponds to what wg-quick does with Table=auto and what WireGuard calls \"Improved Rule-based Routing\". Note that for this automatism to work, you usually don't want to set ipv4.gateway, because that will result in a conflicting default route. Leaving this at the default will enable this option automatically if ipv4.never-default is not set and there are any peers that use a default-route as allowed-ips.")
+#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE N_("Like ip4-auto-default-route, but for the IPv6 default route.")
+#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_LISTEN_PORT N_("The listen-port. If listen-port is not specified, the port will be chosen randomly when the interface comes up.")
+#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments. If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes at the time of activation.")
+#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PEER_ROUTES N_("Whether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. Usually you want this automatism enabled. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively. Note that if the peer's AllowedIPs is \"0.0.0.0/0\" or \"::/0\" and the profile's ipv4.never-default or ipv6.never-default setting is enabled, the peer route for this peer won't be added automatically.")
+#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY N_("The 256 bit private-key in base64 encoding.")
+#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS N_("Flags indicating how to handle the \"private-key\" property.")
+#define DESCRIBE_DOC_NM_SETTING_WPAN_CHANNEL N_("IEEE 802.15.4 channel. A positive integer or -1, meaning \"do not set, use whatever the device is already set to\".")
+#define DESCRIBE_DOC_NM_SETTING_WPAN_MAC_ADDRESS N_("If specified, this connection will only apply to the IEEE 802.15.4 (WPAN) MAC layer device whose permanent MAC address matches.")
+#define DESCRIBE_DOC_NM_SETTING_WPAN_PAGE N_("IEEE 802.15.4 channel page. A positive integer or -1, meaning \"do not set, use whatever the device is already set to\".")
+#define DESCRIBE_DOC_NM_SETTING_WPAN_PAN_ID N_("IEEE 802.15.4 Personal Area Network (PAN) identifier.")
+#define DESCRIBE_DOC_NM_SETTING_WPAN_SHORT_ADDRESS N_("Short IEEE 802.15.4 address to be used within a restricted environment.")
diff --git a/src/libnmc-setting/settings-docs.xsl b/src/libnmc-setting/settings-docs.xsl
new file mode 100644
index 0000000000..0d08a0c898
--- /dev/null
+++ b/src/libnmc-setting/settings-docs.xsl
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output
+ method="text"
+ doctype-public="-//OASIS//DTD DocBook XML V4.3//EN"
+ doctype-system="http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+ />
+
+ <xsl:template match="nm-setting-docs">/* Generated file. Do not edit. */
+
+<xsl:apply-templates select="setting" mode="properties"><xsl:sort select="@name"/></xsl:apply-templates>
+ </xsl:template>
+
+
+ <xsl:template match="setting" mode="properties">
+<xsl:apply-templates select="property">
+ <xsl:sort select="@name"/>
+ <xsl:with-param name="setting_name_upper" select="@name_upper"/>
+</xsl:apply-templates>
+
+</xsl:template>
+
+ <xsl:template match="property">
+ <xsl:param name="setting_name_upper" />
+ <xsl:variable name="docs">
+ <xsl:call-template name="escape_quotes">
+ <xsl:with-param name="string" select="@description"/>
+ </xsl:call-template>
+ </xsl:variable>#define DESCRIBE_DOC_NM_SETTING_<xsl:value-of select="$setting_name_upper"/>_<xsl:value-of select="@name_upper"/> N_("<xsl:value-of select="$docs"/>")
+</xsl:template>
+
+ <xsl:template match="setting" mode="settings">
+ { "<xsl:value-of select="@name"/>", setting_<xsl:value-of select="translate(@name,'-','_')"/>, <xsl:value-of select="count(./property)"/> },</xsl:template>
+
+ <xsl:template name="escape_quotes">
+ <xsl:param name="string" />
+ <xsl:choose>
+ <xsl:when test="contains($string, '&quot;')">
+ <xsl:value-of select="substring-before($string, '&quot;')" />\&quot;<xsl:call-template name="escape_quotes"><xsl:with-param name="string" select="substring-after($string, '&quot;')" /></xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$string" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/libnmc-setting/tests/meson.build b/src/libnmc-setting/tests/meson.build
new file mode 100644
index 0000000000..6c71f286b3
--- /dev/null
+++ b/src/libnmc-setting/tests/meson.build
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+exe = executable(
+ 'test-libnmc-setting',
+ 'test-libnmc-setting.c',
+ dependencies: [
+ libnm_dep,
+ glib_dep,
+ ],
+ link_with: [
+ libnmc_setting,
+ libnmc_base,
+ libnm_core_aux_extern,
+ libnm_core_aux_intern,
+ libnm_base,
+ libnm_glib_aux,
+ libnm_std_aux,
+ libc_siphash,
+ ],
+)
+
+test(
+ 'src/libnmc-setting/tests/test-libnmc-setting',
+ test_script,
+ args: test_args + [exe.full_path()],
+)
diff --git a/src/libnmc-setting/tests/test-libnmc-setting.c b/src/libnmc-setting/tests/test-libnmc-setting.c
new file mode 100644
index 0000000000..fe196ad014
--- /dev/null
+++ b/src/libnmc-setting/tests/test-libnmc-setting.c
@@ -0,0 +1,366 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2017 Red Hat, Inc.
+ */
+
+#include "libnm-client-aux-extern/nm-default-client.h"
+
+#include "libnmc-setting/nm-meta-setting-access.h"
+#include "libnmc-base/nm-vpn-helpers.h"
+#include "libnmc-base/nm-client-utils.h"
+
+#include "libnm-glib-aux/nm-test-utils.h"
+
+/*****************************************************************************/
+
+static void
+test_client_meta_check(void)
+{
+ const NMMetaSettingInfoEditor *const *infos_p;
+ NMMetaSettingType m;
+ guint p;
+
+ G_STATIC_ASSERT(G_STRUCT_OFFSET(NMMetaAbstractInfo, meta_type)
+ == G_STRUCT_OFFSET(NMMetaSettingInfoEditor, meta_type));
+ G_STATIC_ASSERT(G_STRUCT_OFFSET(NMMetaAbstractInfo, meta_type)
+ == G_STRUCT_OFFSET(NMMetaPropertyInfo, meta_type));
+
+ for (m = 0; m < _NM_META_SETTING_TYPE_NUM; m++) {
+ const NMMetaSettingInfo *info = &nm_meta_setting_infos[m];
+ GType gtype;
+
+ g_assert(info);
+ g_assert(info->meta_type == m);
+ g_assert(info->setting_name);
+ g_assert(info->get_setting_gtype);
+
+ gtype = info->get_setting_gtype();
+ g_assert(gtype != NM_TYPE_SETTING);
+
+ {
+ nm_auto_unref_gtypeclass GTypeClass *gclass = g_type_class_ref(gtype);
+
+ g_assert(G_TYPE_CHECK_CLASS_TYPE(gclass, gtype));
+ }
+ {
+ gs_unref_object NMSetting *setting = g_object_new(gtype, NULL);
+
+ g_assert(NM_IS_SETTING(setting));
+ g_assert(G_TYPE_CHECK_INSTANCE_TYPE(setting, gtype));
+ g_assert_cmpstr(nm_setting_get_name(setting), ==, info->setting_name);
+ }
+ }
+
+ for (m = 0; m < _NM_META_SETTING_TYPE_NUM; m++) {
+ const NMMetaSettingInfoEditor *info = &nm_meta_setting_infos_editor[m];
+ GType gtype;
+ NMSettingPriority base_priority;
+ gboolean is_base_type;
+
+ g_assert(info);
+ g_assert(info->meta_type == &nm_meta_type_setting_info_editor);
+ g_assert(info->general);
+ g_assert(info->general == &nm_meta_setting_infos[m]);
+
+ g_assert_cmpstr(info->general->setting_name,
+ ==,
+ info->meta_type->get_name((const NMMetaAbstractInfo *) info, FALSE));
+ g_assert_cmpstr("name",
+ ==,
+ info->meta_type->get_name((const NMMetaAbstractInfo *) info, TRUE));
+
+ g_assert(info->properties_num == NM_PTRARRAY_LEN(info->properties));
+
+ if (info->properties_num) {
+ gs_unref_hashtable GHashTable *property_names =
+ g_hash_table_new(nm_str_hash, g_str_equal);
+
+ g_assert(info->properties);
+ for (p = 0; p < info->properties_num; p++) {
+ const NMMetaPropertyInfo *pi = info->properties[p];
+
+ g_assert(pi);
+ g_assert(pi->meta_type == &nm_meta_type_property_info);
+ g_assert(pi->setting_info == info);
+ g_assert(pi->property_name);
+
+ g_assert(g_hash_table_add(property_names, (gpointer) pi->property_name));
+
+ g_assert_cmpstr(pi->property_name,
+ ==,
+ pi->meta_type->get_name((const NMMetaAbstractInfo *) pi, FALSE));
+ g_assert_cmpstr(pi->property_name,
+ ==,
+ pi->meta_type->get_name((const NMMetaAbstractInfo *) pi, TRUE));
+
+ g_assert(pi->property_type);
+ g_assert(pi->property_type->get_fcn);
+ }
+ g_assert(!info->properties[info->properties_num]);
+ } else
+ g_assert(!info->properties);
+
+ gtype = info->general->get_setting_gtype();
+ base_priority = _nm_setting_type_get_base_type_priority(gtype);
+ is_base_type = (base_priority != NM_SETTING_PRIORITY_INVALID);
+ g_assert((!!info->valid_parts) == is_base_type);
+
+ if (info->valid_parts) {
+ gsize i, l;
+ gs_unref_hashtable GHashTable *dup = g_hash_table_new(nm_direct_hash, NULL);
+
+ l = NM_PTRARRAY_LEN(info->valid_parts);
+ g_assert(l >= 2);
+
+ for (i = 0; info->valid_parts[i]; i++) {
+ g_assert(info->valid_parts[i]->setting_info);
+ g_assert(g_hash_table_add(dup, (gpointer) info->valid_parts[i]->setting_info));
+
+ if (i == 0) {
+ g_assert(info->valid_parts[i]->setting_info
+ == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_CONNECTION]);
+ g_assert(info->valid_parts[i]->mandatory);
+ }
+ if (i == 1) {
+ g_assert(info->valid_parts[i]->setting_info
+ == &nm_meta_setting_infos_editor[m]);
+ g_assert(info->valid_parts[i]->mandatory);
+ }
+ }
+ g_assert(i == l);
+ }
+ }
+
+ for (m = 0; m < _NM_META_SETTING_TYPE_NUM; m++) {
+ const NMMetaSettingInfoEditor *info = &nm_meta_setting_infos_editor[m];
+
+ g_assert(nm_meta_setting_info_editor_find_by_name(info->general->setting_name, FALSE)
+ == info);
+ g_assert(nm_meta_setting_info_editor_find_by_gtype(info->general->get_setting_gtype())
+ == info);
+
+ for (p = 0; p < info->properties_num; p++) {
+ const NMMetaPropertyInfo *pi = info->properties[p];
+
+ g_assert(nm_meta_setting_info_editor_get_property_info(info, pi->property_name) == pi);
+ g_assert(
+ nm_meta_property_info_find_by_name(info->general->setting_name, pi->property_name)
+ == pi);
+ }
+ }
+
+ infos_p = nm_meta_setting_infos_editor_p();
+ g_assert(infos_p);
+ for (m = 0; m < _NM_META_SETTING_TYPE_NUM; m++)
+ g_assert(infos_p[m] == &nm_meta_setting_infos_editor[m]);
+ g_assert(!infos_p[m]);
+}
+
+/*****************************************************************************/
+
+static void
+test_client_import_wireguard_test0(void)
+{
+ gs_unref_object NMConnection *connection;
+ NMSettingWireGuard * s_wg;
+ NMSettingIPConfig * s_ip4;
+ NMSettingIPConfig * s_ip6;
+ NMWireGuardPeer * peer;
+ gs_free_error GError *error = NULL;
+
+ connection =
+ nm_vpn_wireguard_import(NM_BUILD_SRCDIR "/src/libnmc-setting/tests/wg-test0.conf", &error);
+
+ g_assert_no_error(error);
+
+ g_assert_cmpstr(nm_connection_get_id(connection), ==, "wg-test0");
+ g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, "wg-test0");
+ g_assert_cmpstr(nm_connection_get_connection_type(connection),
+ ==,
+ NM_SETTING_WIREGUARD_SETTING_NAME);
+
+ s_wg = NM_SETTING_WIREGUARD(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIREGUARD));
+
+ g_assert_cmpint(nm_setting_wireguard_get_listen_port(s_wg), ==, 51820);
+ g_assert_cmpstr(nm_setting_wireguard_get_private_key(s_wg),
+ ==,
+ "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=");
+
+ g_assert_cmpint(nm_setting_wireguard_get_peers_len(s_wg), ==, 3);
+
+ peer = nm_setting_wireguard_get_peer(s_wg, 0);
+ g_assert_cmpstr(nm_wireguard_peer_get_public_key(peer),
+ ==,
+ "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=");
+ g_assert_cmpstr(nm_wireguard_peer_get_endpoint(peer), ==, "192.95.5.67:1234");
+ g_assert_cmpint(nm_wireguard_peer_get_allowed_ips_len(peer), ==, 2);
+ g_assert_cmpstr(nm_wireguard_peer_get_allowed_ip(peer, 0, NULL), ==, "10.192.122.3/32");
+ g_assert_cmpstr(nm_wireguard_peer_get_allowed_ip(peer, 1, NULL), ==, "10.192.124.1/24");
+
+ peer = nm_setting_wireguard_get_peer(s_wg, 1);
+ g_assert_cmpstr(nm_wireguard_peer_get_public_key(peer),
+ ==,
+ "TrMvSoP4jYQlY6RIzBgbssQqY3vxI2Pi+y71lOWWXX0=");
+ g_assert_cmpstr(nm_wireguard_peer_get_endpoint(peer), ==, "[2607:5300:60:6b0::c05f:543]:2468");
+ g_assert_cmpint(nm_wireguard_peer_get_allowed_ips_len(peer), ==, 2);
+ g_assert_cmpstr(nm_wireguard_peer_get_allowed_ip(peer, 0, NULL), ==, "10.192.122.4/32");
+ g_assert_cmpstr(nm_wireguard_peer_get_allowed_ip(peer, 1, NULL), ==, "192.168.0.0/16");
+
+ peer = nm_setting_wireguard_get_peer(s_wg, 2);
+ g_assert_cmpstr(nm_wireguard_peer_get_public_key(peer),
+ ==,
+ "gN65BkIKy1eCE9pP1wdc8ROUtkHLF2PfAqYdyYBz6EA=");
+ g_assert_cmpstr(nm_wireguard_peer_get_endpoint(peer), ==, "test.wireguard.com:18981");
+ g_assert_cmpint(nm_wireguard_peer_get_allowed_ips_len(peer), ==, 1);
+ g_assert_cmpstr(nm_wireguard_peer_get_allowed_ip(peer, 0, NULL), ==, "10.10.10.230/32");
+
+ s_ip4 = nm_connection_get_setting_ip4_config(connection);
+ s_ip6 = nm_connection_get_setting_ip6_config(connection);
+
+ g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1);
+ g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 0);
+
+ g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip4), ==, 1);
+ g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip6), ==, 0);
+
+ g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip4, 0), ==, "~");
+}
+
+static void
+test_client_import_wireguard_test1(void)
+{
+ gs_free_error GError *error = NULL;
+
+ nm_vpn_wireguard_import(NM_BUILD_SRCDIR "/src/libnmc-setting/tests/wg-test1.conf", &error);
+ g_assert_error(error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
+ g_assert(g_str_has_prefix(error->message, "invalid secret 'PrivateKey'"));
+ g_assert(g_str_has_suffix(error->message, "wg-test1.conf:2"));
+}
+
+static void
+test_client_import_wireguard_test2(void)
+{
+ gs_free_error GError *error = NULL;
+
+ nm_vpn_wireguard_import(NM_BUILD_SRCDIR "/src/libnmc-setting/tests/wg-test2.conf", &error);
+
+ g_assert_error(error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
+ g_assert(g_str_has_prefix(error->message, "unrecognized line at"));
+ g_assert(g_str_has_suffix(error->message, "wg-test2.conf:5"));
+}
+
+static void
+test_client_import_wireguard_test3(void)
+{
+ gs_free_error GError *error = NULL;
+
+ nm_vpn_wireguard_import(NM_BUILD_SRCDIR "/src/libnmc-setting/tests/wg-test3.conf", &error);
+ g_assert_error(error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT);
+ g_assert(g_str_has_prefix(error->message, "invalid value for 'ListenPort'"));
+ g_assert(g_str_has_suffix(error->message, "wg-test3.conf:3"));
+}
+
+static void
+test_client_import_wireguard_missing(void)
+{
+ gs_free_error GError *error = NULL;
+
+ nm_vpn_wireguard_import(NM_BUILD_SRCDIR "/src/libnmc-setting/tests/wg-missing.conf", &error);
+ g_assert_error(error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
+}
+
+/*****************************************************************************/
+
+#define _do_test_parse_passwd_file(contents, success, exp_error_line, ...) \
+ G_STMT_START \
+ { \
+ static const NMUtilsNamedValue _values[] = {__VA_ARGS__}; \
+ gs_free char * _contents = g_strndup(contents, NM_STRLEN(contents)); \
+ gs_unref_hashtable GHashTable *_secrets = NULL; \
+ gs_free_error GError *_local = NULL; \
+ gssize _error_line; \
+ GError ** _p_local = nmtst_get_rand_bool() ? &_local : NULL; \
+ gssize * _p_error_line = nmtst_get_rand_bool() ? &_error_line : NULL; \
+ gboolean _success = !!(success); \
+ gssize _exp_error_line = (exp_error_line); \
+ int _i; \
+ \
+ g_assert(_success || (G_N_ELEMENTS(_values) == 0)); \
+ \
+ _secrets = nmc_utils_parse_passwd_file(_contents, _p_error_line, _p_local); \
+ \
+ g_assert(_success == (!!_secrets)); \
+ if (!_success) { \
+ if (_p_error_line) \
+ g_assert_cmpint(_exp_error_line, ==, *_p_error_line); \
+ if (_p_local) \
+ g_assert(_local); \
+ } else { \
+ if (_p_error_line) \
+ g_assert_cmpint(-1, ==, *_p_error_line); \
+ g_assert(!_local); \
+ \
+ for (_i = 0; _i < (int) G_N_ELEMENTS(_values); _i++) { \
+ const NMUtilsNamedValue *_n = &_values[_i]; \
+ const char * _v; \
+ \
+ _v = g_hash_table_lookup(_secrets, _n->name); \
+ if (!_v) \
+ g_error("cannot find key \"%s\"", _n->name); \
+ g_assert_cmpstr(_v, ==, _n->value_str); \
+ } \
+ \
+ g_assert_cmpint(g_hash_table_size(_secrets), ==, G_N_ELEMENTS(_values)); \
+ } \
+ } \
+ G_STMT_END
+
+#define _do_test_parse_passwd_file_bad(contents, exp_error_line) \
+ _do_test_parse_passwd_file(contents, FALSE, exp_error_line)
+#define _do_test_parse_passwd_file_good(contents, ...) \
+ _do_test_parse_passwd_file(contents, TRUE, -1, __VA_ARGS__)
+
+static void
+test_nmc_utils_parse_passwd_file(void)
+{
+ _do_test_parse_passwd_file_good("");
+ _do_test_parse_passwd_file_bad("x", 1);
+ _do_test_parse_passwd_file_bad("\r\rx", 3);
+ _do_test_parse_passwd_file_good(
+ "wifi.psk=abc",
+ NM_UTILS_NAMED_VALUE_INIT("802-11-wireless-security.psk", "abc"));
+ _do_test_parse_passwd_file_good(
+ "wifi.psk:ABC\r"
+ "wifi-sec.psk = abc ",
+ NM_UTILS_NAMED_VALUE_INIT("802-11-wireless-security.psk", "abc"));
+ _do_test_parse_passwd_file_good(
+ "wifi.psk: abc\r"
+ "wifi-sec.psk2 = d\\145f\r\n"
+ " wifi.psk3 = e\\ \n"
+ " #wifi-sec.psk2 = \r\n"
+ " wifi-sec.psk4:",
+ NM_UTILS_NAMED_VALUE_INIT("802-11-wireless-security.psk", "abc"),
+ NM_UTILS_NAMED_VALUE_INIT("802-11-wireless-security.psk2", "def"),
+ NM_UTILS_NAMED_VALUE_INIT("802-11-wireless-security.psk3", "e "),
+ NM_UTILS_NAMED_VALUE_INIT("802-11-wireless-security.psk4", ""));
+}
+
+/*****************************************************************************/
+
+NMTST_DEFINE();
+
+int
+main(int argc, char **argv)
+{
+ nmtst_init(&argc, &argv, TRUE);
+
+ g_test_add_func("/client/meta/check", test_client_meta_check);
+ g_test_add_func("/client/import/wireguard/test0", test_client_import_wireguard_test0);
+ g_test_add_func("/client/import/wireguard/test1", test_client_import_wireguard_test1);
+ g_test_add_func("/client/import/wireguard/test2", test_client_import_wireguard_test2);
+ g_test_add_func("/client/import/wireguard/test3", test_client_import_wireguard_test3);
+ g_test_add_func("/client/import/wireguard/missing", test_client_import_wireguard_missing);
+ g_test_add_func("/client/test_nmc_utils_parse_passwd_file", test_nmc_utils_parse_passwd_file);
+
+ return g_test_run();
+}
diff --git a/src/libnmc-setting/tests/wg-test0.conf b/src/libnmc-setting/tests/wg-test0.conf
new file mode 100644
index 0000000000..28af4a0003
--- /dev/null
+++ b/src/libnmc-setting/tests/wg-test0.conf
@@ -0,0 +1,20 @@
+[Interface]
+PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
+ListenPort = 51820
+Address = 10.10.10.5/32
+DNS = 10.10.10.1
+
+[Peer]
+PublicKey = xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
+Endpoint = 192.95.5.67:1234
+AllowedIPs = 10.192.122.3/32, 10.192.124.1/24
+
+[Peer]
+PublicKey = TrMvSoP4jYQlY6RIzBgbssQqY3vxI2Pi+y71lOWWXX0=
+Endpoint = [2607:5300:60:6b0::c05f:543]:2468
+AllowedIPs = 10.192.122.4/32, 192.168.0.0/16
+
+[Peer]
+PublicKey = gN65BkIKy1eCE9pP1wdc8ROUtkHLF2PfAqYdyYBz6EA=
+Endpoint = test.wireguard.com:18981
+AllowedIPs = 10.10.10.230/32
diff --git a/src/libnmc-setting/tests/wg-test1.conf b/src/libnmc-setting/tests/wg-test1.conf
new file mode 100644
index 0000000000..ceb267acba
--- /dev/null
+++ b/src/libnmc-setting/tests/wg-test1.conf
@@ -0,0 +1,3 @@
+[Interface]
+PrivateKey = bad
+ListenPort = 51820
diff --git a/src/libnmc-setting/tests/wg-test2.conf b/src/libnmc-setting/tests/wg-test2.conf
new file mode 100644
index 0000000000..f691c2af65
--- /dev/null
+++ b/src/libnmc-setting/tests/wg-test2.conf
@@ -0,0 +1,8 @@
+[Interface]
+PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
+ListenPort = 51820
+
+[Beer]
+PublicKey = xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
+Endpoint = 192.95.5.67:1234
+AllowedIPs = 10.192.122.3/32, 10.192.124.1/24
diff --git a/src/libnmc-setting/tests/wg-test3.conf b/src/libnmc-setting/tests/wg-test3.conf
new file mode 100644
index 0000000000..9956e4004d
--- /dev/null
+++ b/src/libnmc-setting/tests/wg-test3.conf
@@ -0,0 +1,3 @@
+[Interface]
+PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
+ListenPort = 666666666