diff options
Diffstat (limited to 'clients/common/nm-meta-setting-desc.c')
| -rw-r--r-- | clients/common/nm-meta-setting-desc.c | 690 |
1 files changed, 339 insertions, 351 deletions
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 698ded86..c1a5c2a7 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -28,6 +28,7 @@ #include "nm-glib-aux/nm-enum-utils.h" #include "nm-glib-aux/nm-secret-utils.h" #include "nm-libnm-core-intern/nm-libnm-core-utils.h" +#include "nm-libnm-core-aux/nm-libnm-core-aux.h" #include "nm-vpn-helpers.h" #include "nm-client-utils.h" @@ -76,6 +77,25 @@ _gtype_property_get_gtype (GType gtype, const char *property_name) /*****************************************************************************/ +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, @@ -188,7 +208,7 @@ _value_strsplit (const char *value, gsize len; /* FIXME: some modes should support backslash escaping. - * In particular, to distingish from _value_str_as_index_list(), which + * In particular, to distinguish from _value_str_as_index_list(), which * does not accept '\\'. */ /* note that all modes remove empty tokens (",", "a,,b", ",,"). */ @@ -432,158 +452,7 @@ _parse_ip_route (int family, return route; } -static char * -_dump_team_link_watcher (NMTeamLinkWatcher *watcher) -{ - const char *name; - NMTeamLinkWatcherArpPingFlags flags; - GString *w_dump; - - if (!watcher) - return NULL; - - w_dump = g_string_new (NULL); - name = nm_team_link_watcher_get_name (watcher); - g_string_append_printf (w_dump, "name=%s", name); - -#define DUMP_WATCHER_INT(str, watcher, name, key) \ - G_STMT_START { \ - int _val = nm_team_link_watcher_get_##key (watcher); \ - \ - if (_val) \ - g_string_append_printf (str, " %s=%d", name, _val); \ - } G_STMT_END; - - if (nm_streq (name, NM_TEAM_LINK_WATCHER_ETHTOOL)) { - DUMP_WATCHER_INT (w_dump, watcher, "delay-up", delay_up); - DUMP_WATCHER_INT (w_dump, watcher, "delay-down", delay_down); - return g_string_free (w_dump, FALSE); - } - /* NM_TEAM_LINK_WATCHER_NSNA_PING and NM_TEAM_LINK_WATCHER_ARP_PING */ - DUMP_WATCHER_INT (w_dump, watcher, "init-wait", init_wait); - DUMP_WATCHER_INT (w_dump, watcher, "interval", interval); - DUMP_WATCHER_INT (w_dump, watcher, "missed-max", missed_max); - g_string_append_printf (w_dump, " target-host=%s", - nm_team_link_watcher_get_target_host (watcher)); - - if (nm_streq (name, NM_TEAM_LINK_WATCHER_NSNA_PING)) - return g_string_free (w_dump, FALSE); - - DUMP_WATCHER_INT (w_dump, watcher, "vlanid", vlanid); -#undef DUMP_WATCHER_INT - g_string_append_printf (w_dump, " source-host=%s", - nm_team_link_watcher_get_source_host (watcher)); - flags = nm_team_link_watcher_get_flags (watcher); - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE) - g_string_append_printf (w_dump, " validate-active=true"); - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE) - g_string_append_printf (w_dump, " validate-inactive=true"); - if (flags & NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS) - g_string_append_printf (w_dump, "send-always=true"); - - return g_string_free (w_dump, FALSE); -} - -static NMTeamLinkWatcher * -_parse_team_link_watcher (const char *str, - GError **error) -{ - gs_free const char **watcherv = NULL; - gs_free char *str_clean_free = NULL; - const char *str_clean; - guint i; - gs_free const char *name = NULL; - int val1 = 0, val2 = 0, val3 = 3, val4 = -1; - gs_free const char *target_host = NULL; - gs_free const char *source_host = NULL; - NMTeamLinkWatcherArpPingFlags flags = 0; - - nm_assert (str); - nm_assert (!error || !*error); - - str_clean = nm_strstrip_avoid_copy_a (300, str, &str_clean_free); - watcherv = nm_utils_strsplit_set (str_clean, " \t"); - if (!watcherv) { - g_set_error (error, 1, 0, "'%s' is not valid", str); - return NULL; - } - - for (i = 0; watcherv[i]; i++) { - gs_free const char **pair = NULL; - - pair = nm_utils_strsplit_set (watcherv[i], "="); - if (!pair) { - g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i], - "properties should be specified as 'key=value'"); - return NULL; - } - if (!pair[1]) { - g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i], - "missing key value"); - return NULL; - } - if (pair[2]) { - g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i], - "properties should be specified as 'key=value'"); - return NULL; - } - - if (nm_streq (pair[0], "name")) - name = g_strdup (pair[1]); - else if ( nm_streq (pair[0], "delay-up") - || nm_streq (pair[0], "init-wait")) - val1 = _nm_utils_ascii_str_to_int64 (pair[1], 10, 0, G_MAXINT32, -1); - else if ( nm_streq (pair[0], "delay-down") - || nm_streq (pair[0], "interval")) - val2 = _nm_utils_ascii_str_to_int64 (pair[1], 10, 0, G_MAXINT32, -1); - else if (nm_streq (pair[0], "missed-max")) - val3 = _nm_utils_ascii_str_to_int64 (pair[1], 10, 0, G_MAXINT32, -1); - else if (nm_streq (pair[0], "vlanid")) - val4 = _nm_utils_ascii_str_to_int64 (pair[1], 10, -1, 4094, -2); - else if (nm_streq (pair[0], "target-host")) - target_host = g_strdup (pair[1]); - else if (nm_streq (pair[0], "source-host")) - source_host = g_strdup (pair[1]); - else if (nm_streq (pair[0], "validate-active")) { - if (nm_streq (pair[1], "true")) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE; - } else if (nm_streq (pair[0], "validate-inactive")) { - if (nm_streq (pair[1], "true")) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE; - } else if (nm_streq (pair[0], "send-always")) { - if (nm_streq (pair[1], "true")) - flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS; - } else { - g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i], - "unknown key"); - return NULL; - } - - if ((val1 < 0) || (val2 < 0) || (val3 < 0)) { - g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i], - "value is not a valid number [0, MAXINT]"); - return NULL; - } - if (val4 < -1) { - g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i], - "value is not a valid number [-1, 4094]"); - return NULL; - } - } - - if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_ETHTOOL)) - return nm_team_link_watcher_new_ethtool (val1, val2, error); - else if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_NSNA_PING)) - return nm_team_link_watcher_new_nsna_ping (val1, val2, val3, target_host, error); - else if (nm_streq0 (name, NM_TEAM_LINK_WATCHER_ARP_PING)) - return nm_team_link_watcher_new_arp_ping2 (val1, val2, val3, val4, target_host, source_host, flags, error); - - if (!name) - g_set_error (error, 1, 0, "link watcher name missing"); - else - g_set_error (error, 1, 0, "unknown link watcher name: '%s'", name); - return NULL; -} +/*****************************************************************************/ /* Max priority values from libnm-core/nm-setting-vlan.c */ #define MAX_SKB_PRIO G_MAXUINT32 @@ -685,7 +554,6 @@ nmc_team_check_config (const char *config, char **out_config, GError **error) _TEAM_CONFIG_TYPE_FILE, _TEAM_CONFIG_TYPE_JSON, } desired_type = _TEAM_CONFIG_TYPE_GUESS; - const char *filename = NULL; size_t c_len = 0; gs_free char *config_clone = NULL; @@ -719,22 +587,10 @@ nmc_team_check_config (const char *config, char **out_config, GError **error) config); return FALSE; } - filename = config; config = config_clone = g_steal_pointer (&contents); } } - if (!nm_utils_is_json_object (config, NULL)) { - if (filename) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' does not contain a valid team configuration"), filename); - } else { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, - _("team configuration must be a JSON object")); - } - return FALSE; - } - *out_config = (config == config_clone) ? g_steal_pointer (&config_clone) : g_strdup (config); @@ -788,7 +644,7 @@ _env_warn_fcn (const NMMetaEnvironment *environment, 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, char ***out_to_free + 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 @@ -849,9 +705,21 @@ _SET_FCN_DO_REMOVE (char modifier, const char *value) #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) { @@ -894,7 +762,7 @@ _gobject_property_reset (NMSetting *setting, g_value_init (&v, pspec->value_type); if (reset_default) - g_param_value_defaults (pspec, &v); + g_param_value_set_default (pspec, &v); g_object_set_property (G_OBJECT (setting), prop_name, &v); return TRUE; } @@ -905,73 +773,167 @@ _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; +} + +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 (); - NM_SET_OUT (out_is_default, _gobject_property_is_default (setting, property_info->property_name)); - if ( property_info->property_typ_data - && property_info->property_typ_data->is_default_fcn - && property_info->property_typ_data->is_default_fcn (setting)) { - if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) - return _("(default)"); - return ""; - } + 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 convertion 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 (glib_handles_str_transform) + RETURN_STR_TEMPORARY (g_value_get_string (&val)); + if (gtype_prop == G_TYPE_BOOLEAN) { gboolean b; - g_value_init (&val, gtype_prop); - g_object_get_property (G_OBJECT (setting), property_info->property_name, &val); 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; - } else { - char *str; + } - /* Note that we register certain transform functions in nmc_value_transforms_register(). - * This makes G_TYPE_STRV working. - * - * FIXME: that is particularly ugly because it's non-obvious which code relies - * on nmc_value_transforms_register(). Also, nmc_value_transforms_register() is - * in clients/cli, while we are here in clients/common. */ - g_value_init (&val, G_TYPE_STRING); - g_object_get_property (G_OBJECT (setting), property_info->property_name, &val); - cstr = g_value_get_string (&val); - - if ( property_info->property_typ_data - && property_info->property_typ_data->is_default_fcn) { - if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) { - str = cstr - ? g_strdup_printf ("\"%s\"", cstr) - : g_strdup (""); - } else - str = g_strdup (cstr && cstr[0] ? cstr : " "); - } else - str = cstr ? g_strdup (cstr) : NULL; + 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)); + /* special hack for handling properties that can be empty and unset + * (see multilist.clear_emptyunset_fcn). */ + if (handle_emptyunset) { + char *str = NULL; + + cstr = _coerce_str_emptyunset (get_type, is_default, NULL, &str); + if (str) + RETURN_STR_TO_FREE (str); + RETURN_STR_TEMPORARY (cstr); + } + + 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; + + 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++) { + if (str->len > 0) + g_string_append_c (str, ','); + g_string_append_printf (str, + "%s=%s", + keys[i], + (const char *) g_hash_table_lookup (strdict, keys[i])); + } + 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, out_is_default, out_to_free); + return _get_fcn_gobject_impl (property_info, setting, get_type, FALSE, out_is_default, out_to_free); } static gconstpointer @@ -1063,7 +1025,7 @@ _get_fcn_gobject_mtu (ARGS_GET_FCN) 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, out_is_default, out_to_free); + 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) { @@ -1195,7 +1157,7 @@ _get_fcn_gobject_enum (ARGS_GET_FCN) 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_FORMAT, v) + ? g_strdup_printf ("0x%"G_GINT64_MODIFIER"x", v) : g_strdup_printf ("%"G_GINT64_FORMAT, v); RETURN_STR_TO_FREE (g_steal_pointer (&s)); } @@ -1213,7 +1175,7 @@ _get_fcn_gobject_enum (ARGS_GET_FCN) 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_FORMAT, v); + nm_sprintf_buf (s_numeric, "0x%"G_GINT64_MODIFIER"x", v); else nm_sprintf_buf (s_numeric, "%"G_GINT64_FORMAT, v); @@ -1723,23 +1685,6 @@ wep_key_type_to_string (NMWepKeyType type) } 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 char * vlan_flags_to_string (guint32 flags, NMMetaAccessorGetType get_type) { GString *flag_str; @@ -1839,19 +1784,41 @@ _multilist_do_validate (const NMMetaPropertyInfo *property_info, 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)) { - 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); - } + 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 @@ -1884,6 +1851,11 @@ _set_fcn_multilist (ARGS_SET_FCN) } } + 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 @@ -1906,11 +1878,13 @@ _set_fcn_multilist (ARGS_SET_FCN) } nstrv = j; - if (_SET_FCN_DO_SET_ALL (modifier, value)) { - if (property_info->property_typ_data->subtype.multilist.clear_all_fcn) - property_info->property_typ_data->subtype.multilist.clear_all_fcn (setting); - else - _gobject_property_reset (setting, property_info->property_name, FALSE); + 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++) { @@ -2229,8 +2203,7 @@ _get_fcn_cert_8021x (ARGS_GET_FCN) switch (vtable->scheme_func (s_8021X)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: - if ( vtable->is_secret - && !NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS)) + 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; @@ -2268,16 +2241,25 @@ _set_fcn_cert_8021x (ARGS_SET_FCN) vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x.scheme_type]; if (vtable->is_secret) { - gs_free char *path = NULL; nm_auto_free_secret char *password_free = NULL; - char *password; - - path = g_strdup (value); - password = path + strcspn (path, " \t"); - if (password[0] != '\0') { - password[0] = '\0'; - while (nm_utils_is_separator (password[0])) - password++; + 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; @@ -2298,19 +2280,24 @@ _set_fcn_cert_8021x (ARGS_SET_FCN) } } -static gconstpointer -_get_fcn_gobject_bytes (ARGS_GET_FCN) +static const char *const* +_complete_fcn_cert_8021x (ARGS_COMPLETE_FCN) { - gs_unref_bytes GBytes *bytes = NULL; - char *str; + const NMSetting8021xSchemeVtable *vtable; - RETURN_UNSUPPORTED_GET_TYPE (); + vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x.scheme_type]; - g_object_get (setting, property_info->property_name, &bytes, NULL); + if (vtable->is_secret) { + gs_free const char **strv = NULL; - str = bytes_to_string (bytes); - NM_SET_OUT (out_is_default, !str || !str[0]); - RETURN_STR_TO_FREE (str); + 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 @@ -2479,8 +2466,9 @@ _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 + 1); + result = g_new (char *, _NM_META_SETTING_TYPE_NUM * 2 + G_N_ELEMENTS (slave_types) + 1); text_len = text ? strlen (text) : 0; @@ -2500,6 +2488,12 @@ _complete_fcn_connection_type (ARGS_COMPLETE_FCN) 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 { @@ -3362,8 +3356,7 @@ _objlist_set_fcn_ip_config_routes (NMSetting *setting, static gboolean _is_default_func_ip_config_dns_options (NMSetting *setting) { - return nm_setting_ip_config_has_dns_options (NM_SETTING_IP_CONFIG (setting)) - && !nm_setting_ip_config_get_num_dns_options (NM_SETTING_IP_CONFIG (setting)); + return !nm_setting_ip_config_has_dns_options (NM_SETTING_IP_CONFIG (setting)); } static void @@ -3405,7 +3398,7 @@ _objlist_set_fcn_ip_config_routing_rules (NMSetting *setting, return FALSE; /* also for @do_add, we first always search whether such a rule already exist - * and remove the first occurance. + * 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). @@ -3687,85 +3680,6 @@ _validate_fcn_team_config (const char *value, char **out_to_free, GError **error } static void -_multilist_clear_all_fcn_team_runner_tx_hash (NMSetting *setting) -{ - /* Workaround libnm bug (confirmed against version 1.16.0). - * We need to both clear the GObject property and call the libnm API. - * - * This workaround was added in nmcli as [1]. This needs fixing in libnm. - * - * Without this, CI test "team_abs_set_runner_tx_hash" fails. - * Try (without the following workaround): */ -#if 0 - $ (nmcli connection delete team0 ; :); \ - nmcli connection add type team con-name team0 ifname team0 autoconnect no \ - team.runner lacp && \ - echo ">>> FIRST:" && \ - PAGER= nmcli -o connection show team0 && \ - nmcli connection modify team0 team.runner-tx-hash l3 && \ - echo ">>> AFTER:" && \ - PAGER= nmcli -o connection show team0 -#endif - /* See also: - * - * - https://github.com/NetworkManager/NetworkManager/pull/318 - * - https://bugzilla.redhat.com/show_bug.cgi?id=1691619 - * - * [1] https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=350dbb55abf3a80267c398e6f64c2cee4645475a - */ - - /* it appears, we don't really need _gobject_property_reset(). Just to be sure - * also call it. */ - _gobject_property_reset (setting, NM_SETTING_TEAM_RUNNER_TX_HASH, FALSE); - while (nm_setting_team_get_num_runner_tx_hash (NM_SETTING_TEAM (setting))) - nm_setting_team_remove_runner_tx_hash (NM_SETTING_TEAM (setting), 0); -} - -static void -_objlist_clear_all_fcn_team_link_watchers (NMSetting *setting) -{ - /* the same workaround as _multilist_clear_all_fcn_team_runner_tx_hash() above. - * - * Reproduce with: */ -#if 0 - $ (nmcli connection delete team0 ; :); \ - nmcli connection add type team con-name team0 ifname team0 autoconnect no \ - team.link-watchers 'name=arp_ping source-host=172.16.1.1 target-host=172.16.1.254, name=ethtool delay-up=3' && \ - echo ">>> FIRST:" && \ - PAGER= nmcli -o connection show team0 && \ - nmcli connection modify team0 team.link-watchers 'name=ethtool delay-up=4' && \ - echo ">>> AFTER:" && \ - PAGER= nmcli -o connection show team0 - - (nmcli connection delete team0-slave ; :); \ - nmcli connection add type ethernet con-name team0-slave master team0 slave-type team ifname eth0 autoconnect no \ - team-port.link-watchers 'name=arp_ping source-host=172.16.1.1 target-host=172.16.1.254, name=ethtool delay-up=3' && \ - echo ">>> FIRST:" && \ - PAGER= nmcli -o connection show team0-slave && \ - nmcli connection modify team0-slave team.link-watchers 'name=ethtool delay-up=4' && \ - echo ">>> AFTER:" && \ - PAGER= nmcli -o connection show team0-slave -#endif - /* See also: - * - * - https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=72bf38cad6ca6033d0117bf67b0e726001922d8f - * - https://github.com/NetworkManager/NetworkManager/pull/318 - * - https://bugzilla.redhat.com/show_bug.cgi?id=1691619 - */ - - /* In this case, it appears both GObject reset and nm_setting_team*_clear_link_watchers() - * work (on their own). So, we might not need the workaround. - * Just to be sure, as something is not right with libnm here. */ - if (NM_IS_SETTING_TEAM (setting)) { - _gobject_property_reset (setting, NM_SETTING_TEAM_LINK_WATCHERS, FALSE); - nm_setting_team_clear_link_watchers (NM_SETTING_TEAM (setting)); - } else { - _gobject_property_reset (setting, NM_SETTING_TEAM_PORT_LINK_WATCHERS, FALSE); - nm_setting_team_port_clear_link_watchers (NM_SETTING_TEAM_PORT (setting)); - } -} - -static void _objlist_obj_to_str_fcn_team_link_watchers (NMMetaAccessorGetType get_type, NMSetting *setting, guint idx, @@ -3779,9 +3693,9 @@ _objlist_obj_to_str_fcn_team_link_watchers (NMMetaAccessorGetType get_type, else watcher = nm_setting_team_port_get_link_watcher (NM_SETTING_TEAM_PORT (setting), idx); - s = _dump_team_link_watcher (watcher); + s = nm_utils_team_link_watcher_to_string (watcher); if (s) - g_string_append (str, s); + nm_utils_escaped_tokens_escape_gstr (s, ESCAPED_TOKENS_DELIMITERS, str); } static gboolean @@ -3792,7 +3706,7 @@ _objlist_set_fcn_team_link_watchers (NMSetting *setting, { nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher = NULL; - watcher = _parse_team_link_watcher (value, error); + watcher = nm_utils_team_link_watcher_from_string (value, error); if (!watcher) return FALSE; if (NM_IS_SETTING_TEAM (setting)) { @@ -4412,7 +4326,7 @@ static const NMMetaPropertyType _pt_gobject_mtu = { }; static const NMMetaPropertyType _pt_gobject_bytes = { - .get_fcn = _get_fcn_gobject_bytes, + .get_fcn = _get_fcn_gobject, .set_fcn = _set_fcn_gobject_bytes, }; @@ -4457,6 +4371,7 @@ static const NMMetaPropertyType _pt_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 = { @@ -4466,7 +4381,7 @@ static const NMMetaPropertyType _pt_ethtool = { }; static const NMMetaPropertyType _pt_multilist = { - .get_fcn = _get_fcn_gobject, + .get_fcn = _get_fcn_multilist, .set_fcn = _set_fcn_multilist, .set_supports_remove = TRUE, }; @@ -4485,6 +4400,7 @@ static const NMMetaPropertyType _pt_objlist = { #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) @@ -5270,6 +5186,9 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = { ), ), ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, + .property_type = &_pt_gobject_int, + ), NULL }; @@ -5595,6 +5514,7 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { .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, @@ -5761,7 +5681,8 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { 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_SHARED, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED), ), ), PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS, @@ -5807,6 +5728,7 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { .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, @@ -6201,6 +6123,21 @@ static const NMMetaPropertyInfo *const property_infos_OVS_BRIDGE[] = { 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 }; @@ -6210,7 +6147,7 @@ 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", "patch"), + .values_static = NM_MAKE_STRV ("internal", "system", "patch", "dpdk"), ), ), NULL @@ -6524,6 +6461,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .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", }, @@ -6535,6 +6476,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .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", }, @@ -6546,6 +6491,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .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", }, @@ -6557,6 +6506,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .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", }, @@ -6587,7 +6540,6 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .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), - .clear_all_fcn = _multilist_clear_all_fcn_team_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), @@ -6608,6 +6560,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .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", }, @@ -6625,6 +6581,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .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", }, @@ -6636,7 +6596,11 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, .value_infos = INT_VALUE_INFOS ( { - .value.i64 = 0, + .value.i64 = -1, + .nick = "unset", + }, + { + .value.i64 = 1, .nick = "default", }, ), @@ -6658,11 +6622,9 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .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), - .clear_all_fcn = _objlist_clear_all_fcn_team_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), - .strsplit_plain = TRUE, ), ), ), @@ -6687,7 +6649,11 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = { .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, .value_infos = INT_VALUE_INFOS ( { - .value.i64 = NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT, + .value.i64 = -1, + .nick = "unset", + }, + { + .value.i64 = 0, .nick = "default", }, ), @@ -6699,6 +6665,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = { .value_infos = INT_VALUE_INFOS ( { .value.i64 = 0, + .nick = "unset", + }, + { + .value.i64 = 0, .nick = "default", }, ), @@ -6712,6 +6682,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = { .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", }, @@ -6723,6 +6697,10 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = { .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", }, @@ -6735,11 +6713,9 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = { .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), - .clear_all_fcn = _objlist_clear_all_fcn_team_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), - .strsplit_plain = TRUE, ), ), ), @@ -7161,6 +7137,12 @@ static const NMMetaPropertyInfo *const property_infos_WIREGUARD[] = { 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 }; @@ -7186,7 +7168,8 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS[] = { .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_AP, + NM_SETTING_WIRELESS_MODE_MESH), ), ), PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_BAND, @@ -7657,6 +7640,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN) #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_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") @@ -7837,10 +7821,12 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (OVS_BRIDGE, TRUE), ), ), + SETTING_INFO (OVS_DPDK), 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), @@ -8150,6 +8136,7 @@ _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, 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; @@ -8162,6 +8149,7 @@ _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info, environment_user_data, operation_context, text, + out_complete_filename, out_to_free); } |