From a54ac63bbf9b2c71026ac9028a8ffaf186cf3c82 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sun, 28 Jun 2020 18:58:14 +0200 Subject: New upstream version 1.25.90 --- clients/cli/connections.c | 316 +++---- clients/cli/connections.h | 2 +- clients/cli/devices.c | 53 +- clients/cli/devices.h | 2 +- clients/cli/general.c | 30 +- clients/cli/generate-docs-nm-settings-nmcli.c | 64 ++ clients/cli/generate-docs-nm-settings-nmcli.xml | 1102 +++++++++++++++++++++++ clients/cli/meson.build | 44 +- clients/cli/nmcli.c | 4 + clients/cli/utils.h | 1 + 10 files changed, 1380 insertions(+), 238 deletions(-) create mode 100644 clients/cli/generate-docs-nm-settings-nmcli.c create mode 100644 clients/cli/generate-docs-nm-settings-nmcli.xml (limited to 'clients/cli') diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 0e4a95e6..44e34d56 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -490,9 +490,7 @@ _metagen_con_show_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) const char *s; char *s_mut; - NMC_HANDLE_COLOR ( ac - ? nmc_active_connection_state_to_color (nm_active_connection_get_state (ac)) - : NM_META_COLOR_CONNECTION_UNKNOWN); + NMC_HANDLE_COLOR (nmc_active_connection_state_to_color (ac)); if (c) s_con = nm_connection_get_setting_connection (c); @@ -541,6 +539,8 @@ _metagen_con_show_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) if (info->info_type == NMC_GENERIC_INFO_TYPE_CON_SHOW_TIMESTAMP) return (*out_to_free = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp)); else { + struct tm localtime_result; + if (!timestamp) { if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) return _("never"); @@ -548,7 +548,7 @@ _metagen_con_show_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) } timestamp_real = timestamp; s_mut = g_malloc0 (128); - strftime (s_mut, 64, "%c", localtime (×tamp_real)); + strftime (s_mut, 127, "%c", localtime_r (×tamp_real, &localtime_result)); return (*out_to_free = s_mut); } } @@ -1425,8 +1425,18 @@ nmc_connection_profile_details (NMConnection *connection, NmCli *nmc) } NMMetaColor -nmc_active_connection_state_to_color (NMActiveConnectionState state) +nmc_active_connection_state_to_color (NMActiveConnection *ac) { + NMActiveConnectionState state; + + if (!ac) + return NM_META_COLOR_CONNECTION_UNKNOWN; + + if (NM_FLAGS_HAS (nm_active_connection_get_state_flags (ac), NM_ACTIVATION_STATE_FLAG_EXTERNAL)) + return NM_META_COLOR_CONNECTION_EXTERNAL; + + state = nm_active_connection_get_state (ac); + if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING) return NM_META_COLOR_CONNECTION_ACTIVATING; else if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) @@ -1449,7 +1459,9 @@ nmc_active_connection_details (NMActiveConnection *acon, NmCli *nmc) gboolean was_output = FALSE; if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) { + /* pass */ } else if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -2074,6 +2086,7 @@ do_connections_show (const NMCCommand *cmd, NmCli *nmc, int argc, const char *co if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) fields_str = NMC_FIELDS_CON_SHOW_COMMON; else if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -2600,7 +2613,7 @@ progress_active_connection_cb (gpointer user_data) } str = device - ? gettext (nmc_device_state_to_string (nm_device_get_state (device))) + ? gettext (nmc_device_state_to_string_with_external (device)) : active_connection_state_to_string (ac_state); nmc_terminal_show_progress (str); @@ -2689,91 +2702,6 @@ activate_connection_cb (GObject *client, GAsyncResult *result, gpointer user_dat } } -/** - * parse_passwords: - * @passwd_file: file with passwords to parse - * @error: location to store error, or %NULL - * - * Parse passwords given in @passwd_file and insert them into a hash table. - * Example of @passwd_file contents: - * wifi.psk:tajne heslo - * 802-1x.password:krakonos - * 802-11-wireless-security:leap-password:my leap password - * - * Returns: hash table with parsed passwords, or %NULL on an error - */ -static GHashTable * -parse_passwords (const char *passwd_file, GError **error) -{ - gs_unref_hashtable GHashTable *pwds_hash = NULL; - gs_free char *contents = NULL; - gsize len = 0; - GError *local_err = NULL; - gs_free const char **strv = NULL; - const char *const*iter; - char *pwd_spec, *pwd, *prop; - const char *setting; - - pwds_hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); - - if (!passwd_file) - return g_steal_pointer (&pwds_hash); - - if (!g_file_get_contents (passwd_file, &contents, &len, &local_err)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("failed to read passwd-file '%s': %s"), - passwd_file, local_err->message); - g_error_free (local_err); - return NULL; - } - - strv = nm_utils_strsplit_set (contents, "\r\n"); - for (iter = strv; strv && *iter; iter++) { - gs_free char *iter_s = g_strdup (*iter); - - pwd = strchr (iter_s, ':'); - if (!pwd) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("missing colon in 'password' entry '%s'"), *iter); - return NULL; - } - *(pwd++) = '\0'; - - prop = strchr (iter_s, '.'); - if (!prop) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("missing dot in 'password' entry '%s'"), *iter); - return NULL; - } - *(prop++) = '\0'; - - setting = iter_s; - while (g_ascii_isspace (*setting)) - setting++; - /* Accept wifi-sec or wifi instead of cumbersome '802-11-wireless-security' */ - if (!strcmp (setting, "wifi-sec") || !strcmp (setting, "wifi")) - setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; - if (nm_setting_lookup_type (setting) == G_TYPE_INVALID) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid setting name in 'password' entry '%s'"), setting); - return NULL; - } - - if ( nm_streq (setting, "vpn") - && g_str_has_prefix (prop, "secret.")) { - /* in 1.12.0, we wrongly required the VPN secrets to be named - * "vpn.secret". It should be "vpn.secrets". Work around it - * (rh#1628833). */ - pwd_spec = g_strdup_printf ("vpn.secrets.%s", &prop[NM_STRLEN ("secret.")]); - } else - pwd_spec = g_strdup_printf ("%s.%s", setting, prop); - - g_hash_table_insert (pwds_hash, pwd_spec, g_strdup (pwd)); - } - - return g_steal_pointer (&pwds_hash); -} - static gboolean nmc_activate_connection (NmCli *nmc, NMConnection *connection, @@ -2822,9 +2750,27 @@ nmc_activate_connection (NmCli *nmc, } /* Parse passwords given in passwords file */ - pwds_hash = parse_passwords (pwds, error); - if (!pwds_hash) - return FALSE; + { + gs_free_error GError *local = NULL; + gssize error_line; + + pwds_hash = nmc_utils_read_passwd_file (pwds, &error_line, &local); + if (!pwds_hash) { + if (error_line >= 0) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("invalid passwd-file '%s' at line %zd: %s"), + pwds, + error_line, + local->message); + } else { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("invalid passwd-file '%s': %s"), + pwds, + local->message); + } + return FALSE; + } + } if (nmc->pwds_hash) g_hash_table_destroy (nmc->pwds_hash); @@ -3506,10 +3452,10 @@ static const char * check_valid_name_toplevel (const char *val, const char **slave_type, GError **error) { gs_unref_ptrarray GPtrArray *tmp_arr = NULL; + const NMMetaSettingInfoEditor *setting_info; + gs_free_error GError *tmp_err = NULL; const char *str; - GError *tmp_err = NULL; int i; - const NMMetaSettingInfoEditor *setting_info; NM_SET_OUT (slave_type, NULL); @@ -3530,14 +3476,13 @@ check_valid_name_toplevel (const char *val, const char **slave_type, GError **er str = nmc_string_is_valid (val, (const char **) tmp_arr->pdata, &tmp_err); if (!str) { if (tmp_err->code == 1) - g_propagate_error (error, tmp_err); + g_propagate_error (error, g_steal_pointer (&tmp_err)); else { /* We want to handle aliases, so construct own error message */ - char *err_str = get_valid_options_string_toplevel (); + gs_free char *err_str = NULL; + err_str = get_valid_options_string_toplevel (); g_set_error (error, 1, 0, _("'%s' not among [%s]"), val, err_str); - g_free (err_str); - g_clear_error (&tmp_err); } return NULL; } @@ -3731,15 +3676,12 @@ is_setting_valid (NMConnection *connection, const NMMetaSettingValidPartItem *co static char * is_property_valid (NMSetting *setting, const char *property, GError **error) { - char **valid_props = NULL; + gs_strfreev char **valid_props = NULL; const char *prop_name; - char *ret; valid_props = nmc_setting_get_valid_properties (setting); prop_name = nmc_string_is_valid (property, (const char **) valid_props, error); - ret = g_strdup (prop_name); - g_strfreev (valid_props); - return ret; + return g_strdup (prop_name); } static char * @@ -6034,19 +5976,23 @@ extract_setting_and_property (const char *prompt, const char *line, } static void -get_setting_and_property (const char *prompt, const char *line, - NMSetting **setting_out, char**property_out) +get_setting_and_property (const char *prompt, + const char *line, + NMSetting **setting_out, + char **property_out) { const NMMetaSettingValidPartItem *const*valid_settings_main; const NMMetaSettingValidPartItem *const*valid_settings_slave; - const char *setting_name; - NMSetting *setting = NULL; - char *property = NULL; - char *sett = NULL, *prop = NULL; + gs_unref_object NMSetting *setting = NULL; + gs_free char *property = NULL; NMSettingConnection *s_con; + gs_free char *sett = NULL; + gs_free char *prop = NULL; const char *s_type = NULL; + const char *setting_name; extract_setting_and_property (prompt, line, &sett, &prop); + if (sett) { /* Is this too much (and useless?) effort for an unlikely case? */ s_con = nm_connection_get_setting_connection (nmc_tab_completion.connection); @@ -6056,23 +6002,22 @@ get_setting_and_property (const char *prompt, const char *line, valid_settings_main = get_valid_settings_array (nmc_tab_completion.con_type); valid_settings_slave = nm_meta_setting_info_valid_parts_for_slave_type (s_type, NULL); - setting_name = check_valid_name (sett, valid_settings_main, - valid_settings_slave, NULL); + setting_name = check_valid_name (sett, + valid_settings_main, + valid_settings_slave, + NULL); setting = nm_meta_setting_info_editor_new_setting (nm_meta_setting_info_editor_find_by_name (setting_name, FALSE), NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT); } else - setting = nmc_tab_completion.setting ? g_object_ref (nmc_tab_completion.setting) : NULL; + setting = nm_g_object_ref (nmc_tab_completion.setting); if (setting && prop) property = is_property_valid (setting, prop, NULL); else property = g_strdup (nmc_tab_completion.property); - *setting_out = setting; - *property_out = property; - - g_free (sett); - g_free (prop); + *setting_out = g_steal_pointer (&setting); + *property_out = g_steal_pointer (&property); } static gboolean @@ -6082,7 +6027,7 @@ _get_and_check_property (const char *prompt, const char **array_multi, gboolean *multi) { - char *prop; + gs_free char *prop = NULL; gboolean found = FALSE; extract_setting_and_property (prompt, line, NULL, &prop); @@ -6091,7 +6036,6 @@ _get_and_check_property (const char *prompt, found = !!nmc_string_is_valid (prop, array, NULL); if (array_multi && multi) *multi = !!nmc_string_is_valid (prop, array_multi, NULL); - g_free (prop); } return found; } @@ -6169,33 +6113,26 @@ should_complete_property_values (const char *prompt, const char *line, gboolean static gboolean _setting_property_is_boolean (NMSetting *setting, const char *property_name) { - GParamSpec *pspec; + const GParamSpec *pspec; - g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); - g_return_val_if_fail (property_name, FALSE); + nm_assert (NM_IS_SETTING (setting)); + nm_assert (property_name); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); - if (pspec && pspec->value_type == G_TYPE_BOOLEAN) - return TRUE; - return FALSE; + return pspec + && pspec->value_type == G_TYPE_BOOLEAN; } static gboolean should_complete_boolean (const char *prompt, const char *line) { - NMSetting *setting; - char *property; - gboolean is_boolean = FALSE; + gs_unref_object NMSetting *setting = NULL; + gs_free char *property = NULL; get_setting_and_property (prompt, line, &setting, &property); - if (setting && property) - is_boolean = _setting_property_is_boolean (setting, property); - - if (setting) - g_object_unref (setting); - g_free (property); - - return is_boolean; + return setting + && property + && _setting_property_is_boolean (setting, property); } static char * @@ -6222,11 +6159,11 @@ extern int rl_complete_with_tilde_expansion; static char ** nmcli_editor_tab_completion (const char *text, int start, int end) { - char **match_array = NULL; - const char *line = rl_line_buffer; rl_compentry_func_t *generator_func = NULL; - char *prompt_tmp; - char *word = NULL; + const char *line = rl_line_buffer; + gs_free char *prompt_tmp = NULL; + gs_free char *word = NULL; + char **match_array = NULL; size_t n1; int num; @@ -6280,7 +6217,7 @@ nmcli_editor_tab_completion (const char *text, int start, int end) rl_completion_append_character = '.'; } else generator_func = gen_property_names; - } else if (num >= 3) { + } else { if (num == 3 && should_complete_files (NULL, line)) rl_attempted_completion_over = 0; else if (should_complete_vpn_uuids (NULL, line)) { @@ -6350,8 +6287,6 @@ nmcli_editor_tab_completion (const char *text, int start, int end) if (generator_func) match_array = rl_completion_matches (text, generator_func); - g_free (prompt_tmp); - g_free (word); return match_array; } @@ -6391,49 +6326,44 @@ load_history_cmds (const char *uuid) static void save_history_cmds (const char *uuid) { - HIST_ENTRY **hist = NULL; - GKeyFile *kf; - char *filename; - size_t i; - char *key; - char *data; - gsize len = 0; - GError *err = NULL; + gs_unref_keyfile GKeyFile *kf = NULL; + gs_free_error GError *error = NULL; + gs_free char *filename = NULL; + gs_free char *data = NULL; + HIST_ENTRY **hist; + gsize len; + gsize i; hist = history_list (); - if (hist) { - filename = g_build_filename (g_get_home_dir (), NMCLI_EDITOR_HISTORY, NULL); - kf = g_key_file_new (); - if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_KEEP_COMMENTS, &err)) { - if ( !g_error_matches (err, G_FILE_ERROR, G_FILE_ERROR_NOENT) - && !g_error_matches (err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { - g_print ("Warning: %s parse error: %s\n", filename, err->message); - g_key_file_free (kf); - g_free (filename); - g_clear_error (&err); - return; - } - g_clear_error (&err); - } + if (!hist) + return; - /* Remove previous history group and save new history entries */ - g_key_file_remove_group (kf, uuid, NULL); - for (i = 0; hist[i]; i++) - { - key = g_strdup_printf ("%zd", i); - g_key_file_set_string (kf, uuid, key, hist[i]->line); - g_free (key); - } + filename = g_build_filename (g_get_home_dir (), NMCLI_EDITOR_HISTORY, NULL); + + kf = g_key_file_new (); - /* Write history to file */ - data = g_key_file_to_data (kf, &len, NULL); - if (data) { - g_file_set_contents (filename, data, len, NULL); - g_free (data); + if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_KEEP_COMMENTS, &error)) { + if ( !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) + && !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { + g_print ("Warning: %s parse error: %s\n", filename, error->message); + return; } - g_key_file_free (kf); - g_free (filename); + g_clear_error (&error); + } + + /* Remove previous history group and save new history entries */ + g_key_file_remove_group (kf, uuid, NULL); + for (i = 0; hist[i]; i++) { + char key[100]; + + nm_sprintf_buf (key, "%zd", i); + g_key_file_set_string (kf, uuid, key, hist[i]->line); } + + /* Write history to file */ + data = g_key_file_to_data (kf, &len, NULL); + if (data) + g_file_set_contents (filename, data, len, NULL); } /*****************************************************************************/ @@ -6890,7 +6820,7 @@ progress_activation_editor_cb (gpointer user_data) ac_state = nm_active_connection_get_state (ac); dev_state = nm_device_get_state (device); - nmc_terminal_show_progress (gettext (nmc_device_state_to_string (dev_state))); + nmc_terminal_show_progress (gettext (nmc_device_state_to_string_with_external (device))); if ( ac_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED || dev_state == NM_DEVICE_STATE_ACTIVATED) { @@ -7181,9 +7111,10 @@ property_edit_submenu (NmCli *nmc, else g_print (_("Unknown command argument: '%s'\n"), cmd_property_arg); } else { - char *prop_val = nmc_setting_get_property (curr_setting, prop_name, NULL); + gs_free char *prop_val = NULL; + + prop_val = nmc_setting_get_property (curr_setting, prop_name, NULL); g_print ("%s: %s\n", prop_name, prop_val); - g_free (prop_val); } break; @@ -7265,7 +7196,7 @@ ask_check_setting (const NmcConfig *nmc_config, const NMMetaSettingValidPartItem *const*valid_settings_slave, const char *valid_settings_str) { - char *setting_name_user; + gs_free char *setting_name_user = NULL; const char *setting_name; GError *err = NULL; @@ -7285,7 +7216,6 @@ ask_check_setting (const NmcConfig *nmc_config, g_print (_("Error: invalid setting name; %s\n"), err->message); g_clear_error (&err); } - g_free (setting_name_user); return setting_name; } @@ -7295,9 +7225,9 @@ ask_check_property (const NmcConfig *nmc_config, const char **valid_props, const char *valid_props_str) { - char *prop_name_user; + gs_free_error GError *tmp_err = NULL; + gs_free char *prop_name_user = NULL; const char *prop_name; - GError *tmp_err = NULL; if (!arg) { g_print (_("Available properties: %s\n"), valid_props_str); @@ -7307,11 +7237,10 @@ ask_check_property (const NmcConfig *nmc_config, } else prop_name_user = g_strdup (arg); - if (!(prop_name = nmc_string_is_valid (prop_name_user, valid_props, &tmp_err))) { + prop_name = nmc_string_is_valid (prop_name_user, valid_props, &tmp_err); + if (!prop_name) g_print (_("Error: property %s\n"), tmp_err->message); - g_clear_error (&tmp_err); - } - g_free (prop_name_user); + return prop_name; } @@ -7325,6 +7254,7 @@ update_connection_timestamp (NMConnection *src, NMConnection *dst) s_con_dst = nm_connection_get_setting_connection (dst); if (s_con_src && s_con_dst) { guint64 timestamp = nm_setting_connection_get_timestamp (s_con_src); + g_object_set (s_con_dst, NM_SETTING_CONNECTION_TIMESTAMP, timestamp, NULL); } } diff --git a/clients/cli/connections.h b/clients/cli/connections.h index 79359a1f..31b024d7 100644 --- a/clients/cli/connections.h +++ b/clients/cli/connections.h @@ -18,7 +18,7 @@ nmc_process_connection_properties (NmCli *nmc, gboolean allow_remove_setting, GError **error); -NMMetaColor nmc_active_connection_state_to_color (NMActiveConnectionState state); +NMMetaColor nmc_active_connection_state_to_color (NMActiveConnection *ac); int nmc_active_connection_cmp (NMActiveConnection *ac_a, NMActiveConnection *ac_b); diff --git a/clients/cli/devices.c b/clients/cli/devices.c index d5224b93..e83d3472 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -53,7 +53,7 @@ ap_wpa_rsn_flags_to_string (NM80211ApSecurityFlags flags, NMMetaAccessorGetType flags_str[i++] = "802.1X"; if (flags & NM_802_11_AP_SEC_KEY_MGMT_SAE) flags_str[i++] = "sae"; - if (flags & NM_802_11_AP_SEC_KEY_MGMT_OWE) + if (NM_FLAGS_ANY (flags, NM_802_11_AP_SEC_KEY_MGMT_OWE |NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) flags_str[i++] = "owe"; /* Make sure you grow flags_str when adding items here. */ @@ -92,7 +92,7 @@ _metagen_device_status_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) NMDevice *d = target; NMActiveConnection *ac; - NMC_HANDLE_COLOR (nmc_device_state_to_color (nm_device_get_state (d))); + NMC_HANDLE_COLOR (nmc_device_state_to_color (d)); switch (info->info_type) { case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_DEVICE: @@ -100,7 +100,7 @@ _metagen_device_status_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_TYPE: return nm_device_get_type_description (d); case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_STATE: - return nmc_meta_generic_get_str_i18n (nmc_device_state_to_string (nm_device_get_state (d)), + return nmc_meta_generic_get_str_i18n (nmc_device_state_to_string_with_external (d), get_type); case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_IP4_CONNECTIVITY: return nmc_meta_generic_get_str_i18n (nm_connectivity_to_string (nm_device_get_connectivity (d, AF_INET)), @@ -147,7 +147,6 @@ _metagen_device_detail_general_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) { NMDevice *d = target; NMActiveConnection *ac; - NMDeviceState state; NMDeviceStateReason state_reason; NMConnectivityState connectivity; const char *s; @@ -180,10 +179,9 @@ _metagen_device_detail_general_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_MTU: return (*out_to_free = g_strdup_printf ("%u", (guint) nm_device_get_mtu (d))); case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_STATE: - state = nm_device_get_state (d); return (*out_to_free = nmc_meta_generic_get_enum_with_detail (NMC_META_GENERIC_GET_ENUM_TYPE_PARENTHESES, - state, - nmc_device_state_to_string (state), + nm_device_get_state (d), + nmc_device_state_to_string_with_external (d), get_type)); case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_REASON: state_reason = nm_device_get_state_reason (d); @@ -205,6 +203,8 @@ _metagen_device_detail_general_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) get_type)); case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_UDI: return nm_device_get_udi (d); + case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_PATH: + return nm_device_get_path (d); case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP_IFACE: return nm_device_get_ip_iface (d); case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IS_SOFTWARE: @@ -257,6 +257,7 @@ const NmcMetaGenericInfo *const metagen_device_detail_general[_NMC_GENERIC_INFO_ _METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP4_CONNECTIVITY, "IP4-CONNECTIVITY"), _METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP6_CONNECTIVITY, "IP6-CONNECTIVITY"), _METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_UDI, "UDI"), + _METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_PATH, "PATH"), _METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP_IFACE, "IP-IFACE"), _METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IS_SOFTWARE, "IS-SOFTWARE"), _METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_NM_MANAGED, "NM-MANAGED"), @@ -1214,7 +1215,7 @@ fill_output_access_point (gpointer data, gpointer user_data) if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE) { g_string_append (security_str, "WPA3 "); } - if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE) { + if (NM_FLAGS_ANY (rsn_flags, NM_802_11_AP_SEC_KEY_MGMT_OWE | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) { g_string_append (security_str, "OWE "); } if ( (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) @@ -1437,6 +1438,7 @@ show_device_info (NMDevice *device, NmCli *nmc) if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) fields_str = NMC_FIELDS_DEV_SHOW_SECTIONS_COMMON; else if (g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -1715,8 +1717,20 @@ show_device_info (NMDevice *device, NmCli *nmc) } NMMetaColor -nmc_device_state_to_color (NMDeviceState state) +nmc_device_state_to_color (NMDevice *device) { + NMDeviceState state; + NMActiveConnection *ac; + + if (!device) + return NM_META_COLOR_DEVICE_UNKNOWN; + + ac = nm_device_get_active_connection (device); + if ( ac + && NM_FLAGS_HAS (nm_active_connection_get_state_flags (ac), NM_ACTIVATION_STATE_FLAG_EXTERNAL)) + return NM_META_COLOR_CONNECTION_EXTERNAL; + + state = nm_device_get_state (device); if (state <= NM_DEVICE_STATE_UNAVAILABLE) return NM_META_COLOR_DEVICE_UNAVAILABLE; else if (state == NM_DEVICE_STATE_DISCONNECTED) @@ -1750,6 +1764,7 @@ do_devices_status (const NMCCommand *cmd, NmCli *nmc, int argc, const char *cons if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) fields_str = "DEVICE,TYPE,STATE,CONNECTION"; else if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -1835,7 +1850,7 @@ progress_cb (gpointer user_data) { NMDevice *device = (NMDevice *) user_data; - nmc_terminal_show_progress (device ? gettext (nmc_device_state_to_string (nm_device_get_state (device))) : ""); + nmc_terminal_show_progress (device ? gettext (nmc_device_state_to_string_with_external (device)) : ""); return TRUE; } @@ -2606,17 +2621,15 @@ do_device_set (const NMCCommand *cmd, NmCli *nmc, int argc, const char *const*ar static void device_state (NMDevice *device, GParamSpec *pspec, NmCli *nmc) { - NMDeviceState state = nm_device_get_state (device); + gs_free char *str = NULL; NMMetaColor color; - char *str; - color = nmc_device_state_to_color (state); + color = nmc_device_state_to_color (device); str = nmc_colorize (&nmc->nmc_config, color, "%s: %s\n", nm_device_get_iface (device), - gettext (nmc_device_state_to_string (state))); + gettext (nmc_device_state_to_string_with_external (device))); g_print ("%s", str); - g_free (str); } static void @@ -3150,6 +3163,7 @@ do_device_wifi_list (const NMCCommand *cmd, NmCli *nmc, int argc, const char *co if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) fields_str = NMC_FIELDS_DEV_WIFI_LIST_COMMON; else if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -3687,8 +3701,12 @@ do_device_wifi_connect (const NMCCommand *cmd, NmCli *nmc, int argc, const char /* Set password for WEP or WPA-PSK. */ if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) - || (ap_wpa_flags != NM_802_11_AP_SEC_NONE && !(ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE)) - || (ap_rsn_flags != NM_802_11_AP_SEC_NONE && !(ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE))) { + || ( ap_wpa_flags != NM_802_11_AP_SEC_NONE + && !NM_FLAGS_ANY (ap_wpa_flags, NM_802_11_AP_SEC_KEY_MGMT_OWE | + NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) + || ( ap_rsn_flags != NM_802_11_AP_SEC_NONE + && !NM_FLAGS_ANY (ap_rsn_flags, NM_802_11_AP_SEC_KEY_MGMT_OWE | + NM_802_11_AP_SEC_KEY_MGMT_OWE_TM))) { const char *con_password = NULL; NMSettingWirelessSecurity *s_wsec = NULL; @@ -4655,6 +4673,7 @@ do_device_lldp_list (const NMCCommand *cmd, NmCli *nmc, int argc, const char *co if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) fields_str = NMC_FIELDS_DEV_LLDP_LIST_COMMON; else if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; diff --git a/clients/cli/devices.h b/clients/cli/devices.h index 8b7aa901..b5d646b5 100644 --- a/clients/cli/devices.h +++ b/clients/cli/devices.h @@ -16,7 +16,7 @@ void monitor_devices (NmCli *nmc); NMDevice ** nmc_get_devices_sorted (NMClient *client); -NMMetaColor nmc_device_state_to_color (NMDeviceState state); +NMMetaColor nmc_device_state_to_color (NMDevice *device); extern const NmcMetaGenericInfo *const metagen_device_status[]; extern const NmcMetaGenericInfo *const metagen_device_detail_general[]; diff --git a/clients/cli/general.c b/clients/cli/general.c index 747203bb..a771e1d5 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -545,7 +545,9 @@ print_permissions (void *user_data) } if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) { + /* pass */ } else if (g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -694,7 +696,9 @@ show_general_logging (NmCli *nmc) }; if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) { + /* pass */ } else if (g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -1404,15 +1408,12 @@ nmc_command_func_overview (const NMCCommand *cmd, NmCli *nmc, int argc, const ch /* The VPN connections don't have devices (yet?). */ p = nm_client_get_active_connections (nmc->client); for (i = 0; i < p->len; i++) { - NMActiveConnectionState state; - ac = p->pdata[i]; if (!nm_active_connection_get_vpn (ac)) continue; - state = nm_active_connection_get_state (ac); - color = nmc_active_connection_state_to_color (state); + color = nmc_active_connection_state_to_color (ac); tmp = nmc_colorize (&nmc->nmc_config, color, _("%s VPN connection"), nm_active_connection_get_id (ac)); g_print ("%s\n", tmp); @@ -1424,33 +1425,32 @@ nmc_command_func_overview (const NMCCommand *cmd, NmCli *nmc, int argc, const ch devices = nmc_get_devices_sorted (nmc->client); for (i = 0; devices[i]; i++) { - NMDeviceState state; + NMDevice *device = devices[i]; - ac = nm_device_get_active_connection (devices[i]); + ac = nm_device_get_active_connection (device); - state = nm_device_get_state (devices[i]); - color = nmc_device_state_to_color (state); + color = nmc_device_state_to_color (device); if (ac) { /* TRANSLATORS: prints header line for activated device in plain `nmcli` overview output as * ": to " */ tmp = nmc_colorize (&nmc->nmc_config, color, C_("nmcli-overview", "%s: %s to %s"), - nm_device_get_iface (devices[i]), - gettext (nmc_device_state_to_string (state)), + nm_device_get_iface (device), + gettext (nmc_device_state_to_string_with_external (device)), nm_active_connection_get_id (ac)); } else { /* TRANSLATORS: prints header line for not active device in plain `nmcli` overview output as * ": " */ tmp = nmc_colorize (&nmc->nmc_config, color, C_("nmcli-overview", "%s: %s"), - nm_device_get_iface (devices[i]), - gettext (nmc_device_state_to_string (state))); + nm_device_get_iface (device), + gettext (nmc_device_state_to_string_with_external (device))); } g_print ("%s\n", tmp); g_free (tmp); - if (nm_device_get_description (devices[i]) && strcmp (nm_device_get_description (devices[i]), "")) - g_print ("\t\"%s\"\n", nm_device_get_description (devices[i])); + if (nm_device_get_description (device) && strcmp (nm_device_get_description (device), "")) + g_print ("\t\"%s\"\n", nm_device_get_description (device)); - device_overview (nmc, devices[i]); + device_overview (nmc, device); if (ac) ac_overview (nmc, ac); g_print ("\n"); diff --git a/clients/cli/generate-docs-nm-settings-nmcli.c b/clients/cli/generate-docs-nm-settings-nmcli.c new file mode 100644 index 00000000..caf941d7 --- /dev/null +++ b/clients/cli/generate-docs-nm-settings-nmcli.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: LGPL-2.1+ + +#include "nm-default.h" + +#include "nm-meta-setting-desc.h" + +#define INDENT 4 + +static char * +_xml_escape_attribute (const char *value) +{ + gs_free char *s = NULL; + + s = g_markup_escape_text (value, -1); + return g_strdup_printf ("\"%s\"", s); +} + +static const char * +_indent_level (guint num_spaces) +{ + static const char spaces[] = " "; + + nm_assert (num_spaces < G_N_ELEMENTS (spaces)); + return &spaces[G_N_ELEMENTS (spaces) - num_spaces - 1]; +} + +int +main (int argc, char *argv[]) +{ + int i_sett_infos; + int i_property; + + g_print ("\n"); + for (i_sett_infos = 0; i_sett_infos < G_N_ELEMENTS (nm_meta_setting_infos_editor); i_sett_infos++) { + const NMMetaSettingInfoEditor *sett_info = &nm_meta_setting_infos_editor[i_sett_infos]; + gs_free char *tmp_s1 = NULL; + gs_free char *tmp_s2 = NULL; + + g_print ("%sgeneral->setting_name)); + if (sett_info->alias) + g_print ("\n%salias=%s", _indent_level (INDENT + 9), tmp_s2 = _xml_escape_attribute (sett_info->alias)); + g_print (" >\n"); + + for (i_property = 0; i_property < sett_info->properties_num; i_property++) { + const NMMetaPropertyInfo *prop_info = sett_info->properties[i_property]; + gs_free char *tmp2 = NULL; + gs_free char *tmp3 = NULL; + gs_free char *tmp4 = NULL; + + g_print ("%sproperty_name)); + if (prop_info->property_alias) + g_print ("\n%salias=%s", _indent_level (2*INDENT + 10), tmp3 = _xml_escape_attribute (prop_info->property_alias)); + if (prop_info->describe_doc) + g_print ("\n%sdescription=%s", _indent_level (2*INDENT + 10), tmp4 = _xml_escape_attribute (prop_info->describe_doc)); + g_print (" />\n"); + } + + g_print ("%s\n", _indent_level (INDENT)); + } + g_print ("\n"); + return 0; +} diff --git a/clients/cli/generate-docs-nm-settings-nmcli.xml b/clients/cli/generate-docs-nm-settings-nmcli.xml new file mode 100644 index 00000000..860a0fd4 --- /dev/null +++ b/clients/cli/generate-docs-nm-settings-nmcli.xml @@ -0,0 +1,1102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clients/cli/meson.build b/clients/cli/meson.build index 8dd05aff..517deffa 100644 --- a/clients/cli/meson.build +++ b/clients/cli/meson.build @@ -1,6 +1,6 @@ # SPDX-License-Identifier: LGPL-2.1+ -name = 'nmcli' +if enable_nmcli # FIXME: nmcli-completion should be renamed to nmcli install_data( @@ -8,15 +8,8 @@ install_data( install_dir: join_paths(nm_datadir, 'bash-completion', 'completions'), ) -deps = [ - libnmc_base_dep, - libnmc_dep, - readline_dep, - libnm_libnm_aux_dep, -] - executable( - name, + 'nmcli', files( 'agent.c', 'common.c', @@ -28,9 +21,38 @@ executable( 'settings.c', 'utils.c', ), - dependencies: deps, - c_args: clients_c_flags + ['-DG_LOG_DOMAIN="@0@"'.format(name)], + dependencies: [ + libnmc_base_dep, + libnmc_dep, + readline_dep, + libnm_libnm_aux_dep, + ], + c_args: clients_c_flags + ['-DG_LOG_DOMAIN="@0@"'.format('nmcli')], link_args: ldflags_linker_script_binary, link_depends: linker_script_binary, install: true, ) + +endif + +generate_docs_nm_settings_nmcli = executable( + 'generate-docs-nm-settings-nmcli', + files( + 'generate-docs-nm-settings-nmcli.c', + ), + dependencies: [ + libnmc_base_dep, + libnmc_dep, + libnm_libnm_aux_dep, + ], + c_args: clients_c_flags + ['-DG_LOG_DOMAIN="@0@"'.format('nmcli')], + link_args: ldflags_linker_script_binary, + link_depends: linker_script_binary, +) + +generate_docs_nm_settings_nmcli_xml = custom_target( + 'generate-docs-nm-settings-nmcli.xml', + output: 'generate-docs-nm-settings-nmcli.xml', + command: [ generate_docs_nm_settings_nmcli ], + capture: true, +) diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index e23212eb..0ae4a4de 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -38,6 +38,7 @@ [NM_META_COLOR_CONNECTION_ACTIVATING] = "33", \ [NM_META_COLOR_CONNECTION_DISCONNECTING] = "31", \ [NM_META_COLOR_CONNECTION_INVISIBLE] = "2", \ + [NM_META_COLOR_CONNECTION_EXTERNAL] = "32;2", \ [NM_META_COLOR_CONNECTIVITY_FULL] = "32", \ [NM_META_COLOR_CONNECTIVITY_LIMITED] = "33", \ [NM_META_COLOR_CONNECTIVITY_NONE] = "31", \ @@ -49,6 +50,7 @@ [NM_META_COLOR_DEVICE_PLUGIN_MISSING] = "31", \ [NM_META_COLOR_DEVICE_UNAVAILABLE] = "2", \ [NM_META_COLOR_DEVICE_DISABLED] = "31", \ + [NM_META_COLOR_DEVICE_EXTERNAL] = "32;2", \ [NM_META_COLOR_MANAGER_RUNNING] = "32", \ [NM_META_COLOR_MANAGER_STARTING] = "33", \ [NM_META_COLOR_MANAGER_STOPPED] = "31", \ @@ -550,6 +552,7 @@ parse_color_scheme (char *palette_buffer, [NM_META_COLOR_CONNECTION_ACTIVATING] = "connection-activating", [NM_META_COLOR_CONNECTION_DISCONNECTING] = "connection-disconnecting", [NM_META_COLOR_CONNECTION_INVISIBLE] = "connection-invisible", + [NM_META_COLOR_CONNECTION_EXTERNAL] = "connection-external", [NM_META_COLOR_CONNECTION_UNKNOWN] = "connection-unknown", [NM_META_COLOR_CONNECTIVITY_FULL] = "connectivity-full", [NM_META_COLOR_CONNECTIVITY_LIMITED] = "connectivity-limited", @@ -563,6 +566,7 @@ parse_color_scheme (char *palette_buffer, [NM_META_COLOR_DEVICE_PLUGIN_MISSING] = "device-plugin-missing", [NM_META_COLOR_DEVICE_UNAVAILABLE] = "device-unavailable", [NM_META_COLOR_DEVICE_DISABLED] = "device-disabled", + [NM_META_COLOR_DEVICE_EXTERNAL] = "device-external", [NM_META_COLOR_DEVICE_UNKNOWN] = "device-unknown", [NM_META_COLOR_MANAGER_RUNNING] = "manager-running", [NM_META_COLOR_MANAGER_STARTING] = "manager-starting", diff --git a/clients/cli/utils.h b/clients/cli/utils.h index 76f5bae0..d7ad738f 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -179,6 +179,7 @@ typedef enum { NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP4_CONNECTIVITY, NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP6_CONNECTIVITY, NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_UDI, + NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_PATH, NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP_IFACE, NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IS_SOFTWARE, NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_NM_MANAGED, -- cgit 1.3.0-6-gf8a5 From 10ae7d8cd706062742d0cdb1803d49909aef9e06 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Mon, 29 Jun 2020 22:15:58 +0200 Subject: New upstream version 1.25.91 --- clients/cli/devices.c | 1 - clients/cli/generate-docs-nm-settings-nmcli.xml | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'clients/cli') diff --git a/clients/cli/devices.c b/clients/cli/devices.c index e83d3472..27f72e77 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -4192,7 +4192,6 @@ do_device_wifi_hotspot (const NMCCommand *cmd, NmCli *nmc, int argc, const char g_return_if_fail (s_wsec); if (!set_wireless_security_for_hotspot (s_wsec, wifi_mode, caps, password, show_password, &error)) { - g_object_unref (connection); g_string_printf (nmc->return_text, _("Error: Invalid 'password': %s."), error->message); g_clear_error (&error); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; diff --git a/clients/cli/generate-docs-nm-settings-nmcli.xml b/clients/cli/generate-docs-nm-settings-nmcli.xml index 860a0fd4..9a3316a3 100644 --- a/clients/cli/generate-docs-nm-settings-nmcli.xml +++ b/clients/cli/generate-docs-nm-settings-nmcli.xml @@ -754,13 +754,13 @@ + description="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"." /> + description="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." /> + description="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." /> + description="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." />