diff options
Diffstat (limited to 'clients/cli')
| -rw-r--r-- | clients/cli/connections.c | 688 | ||||
| -rw-r--r-- | clients/cli/nmcli-completion | 2 | ||||
| -rw-r--r-- | clients/cli/settings-docs.c | 12 | ||||
| -rw-r--r-- | clients/cli/settings.c | 118 |
4 files changed, 467 insertions, 353 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index d263154d..129a5298 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -1641,13 +1641,13 @@ do_connections_show (NmCli *nmc, gboolean active_only, gboolean show_secrets, invisibles = get_invisible_active_connections (nmc); for (i = 0; i < invisibles->len; i++) fill_output_connection_for_invisible (invisibles->pdata[i], nmc); - g_ptr_array_free (invisibles, FALSE); + g_ptr_array_free (invisibles, TRUE); /* Sort the connections and fill the output data */ sorted_cons = sort_connections (nmc->connections, nmc, order); for (i = 0; i < sorted_cons->len; i++) fill_output_connection (sorted_cons->pdata[i], nmc, active_only); - g_ptr_array_free (sorted_cons, FALSE); + g_ptr_array_free (sorted_cons, TRUE); print_data (nmc); /* Print all data */ } else { @@ -2302,7 +2302,7 @@ nmc_activate_connection (NmCli *nmc, /* Virtual connection may not have their interfaces created yet */ if (!device_found && !nm_connection_is_virtual (connection)) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_CON_ACTIVATION, - "%s", local && local->message ? local->message : _("unknown error")); + "%s", local->message); g_clear_error (&local); return FALSE; } @@ -2450,8 +2450,8 @@ do_connection_up (NmCli *nmc, int argc, char **argv) if (!nmc_activate_connection (nmc, connection, ifname, ap, nsp, pwds, activate_connection_cb, &error)) { g_string_printf (nmc->return_text, _("Error: %s."), - error ? error->message : _("unknown error")); - nmc->return_value = error ? error->code : NMC_RESULT_ERROR_CON_ACTIVATION; + error->message); + nmc->return_value = error->code; g_clear_error (&error); nmc->should_wait--; goto error; @@ -2653,8 +2653,6 @@ typedef struct NameItem { static const NameItem nmc_generic_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2662,8 +2660,6 @@ static const NameItem nmc_ethernet_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NM_SETTING_DCB_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2671,8 +2667,6 @@ static const NameItem nmc_ethernet_settings [] = { static const NameItem nmc_infiniband_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2681,16 +2675,12 @@ static const NameItem nmc_wifi_settings [] = { { NM_SETTING_WIRELESS_SETTING_NAME, "wifi", NULL, TRUE }, { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-sec", NULL, FALSE }, { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_wimax_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIMAX_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2699,8 +2689,6 @@ static const NameItem nmc_gsm_settings [] = { { NM_SETTING_GSM_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2709,24 +2697,18 @@ static const NameItem nmc_cdma_settings [] = { { NM_SETTING_CDMA_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_bluetooth_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_BLUETOOTH_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_adsl_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_ADSL_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2739,24 +2721,18 @@ static const NameItem nmc_pppoe_settings [] = { { NM_SETTING_PPPOE_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_olpc_mesh_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_OLPC_MESH_SETTING_NAME, "olpc-mesh", NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_vpn_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_VPN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2764,8 +2740,6 @@ static const NameItem nmc_vlan_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, { NM_SETTING_VLAN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2773,8 +2747,6 @@ static const NameItem nmc_bond_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_BOND_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2782,8 +2754,6 @@ static const NameItem nmc_team_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_TEAM_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2791,31 +2761,26 @@ static const NameItem nmc_bridge_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_BRIDGE_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_bond_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_team_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, { NM_SETTING_TEAM_PORT_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_bridge_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, + { NULL, NULL, NULL, FALSE } +}; + +static const NameItem nmc_no_slave_settings [] = { + { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2823,16 +2788,12 @@ static const NameItem nmc_tun_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_TUN_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; static const NameItem nmc_ip_tunnel_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_IP_TUNNEL_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2840,8 +2801,6 @@ static const NameItem nmc_macvlan_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, { NM_SETTING_MACVLAN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2849,8 +2808,6 @@ static const NameItem nmc_vxlan_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_VXLAN_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } }; @@ -2875,6 +2832,7 @@ static const NameItem nmc_valid_connection_types[] = { { "bond-slave", NULL, nmc_bond_slave_settings }, { "team-slave", NULL, nmc_team_slave_settings }, { "bridge-slave", NULL, nmc_bridge_slave_settings }, + { "no-slave", NULL, nmc_no_slave_settings }, { NM_SETTING_TUN_SETTING_NAME, NULL, nmc_tun_settings }, { NM_SETTING_IP_TUNNEL_SETTING_NAME, NULL, nmc_ip_tunnel_settings }, { NM_SETTING_MACVLAN_SETTING_NAME, NULL, nmc_macvlan_settings }, @@ -2907,32 +2865,53 @@ get_name_alias (const char *name, const NameItem array[]) } /* - * Construct a string with names and aliases from the array formatted as: + * Construct a string with names and aliases from the arrays formatted as: * "name (alias), name, name (alias), name, name" * * Returns: string; the caller is responsible for freeing it. */ static char * -get_valid_options_string (const NameItem array[]) +get_valid_options_string (const NameItem *array, const NameItem *array_slv) { - const NameItem *iter = &array[0]; + const NameItem *iter = array; GString *str; + int i; str = g_string_sized_new (150); - while (iter && iter->name) { - if (str->len) - g_string_append (str, ", "); - if (iter->alias) - g_string_append_printf (str, "%s (%s)", iter->name, iter->alias); - else - g_string_append (str, iter->name); - iter++; + + for (i = 0; i < 2; i++, iter = array_slv) { + while (iter && iter->name) { + if (str->len) + g_string_append (str, ", "); + if (iter->alias) + g_string_append_printf (str, "%s (%s)", iter->name, iter->alias); + else + g_string_append (str, iter->name); + iter++; + } } return g_string_free (str, FALSE); } +static const NameItem * +get_valid_settings_array (const char *con_type) +{ + guint i, num; + + if (!con_type) + return NULL; + + num = G_N_ELEMENTS (nmc_valid_connection_types); + for (i = 0; i < num; i++) { + if (nm_streq0 (con_type, nmc_valid_connection_types[i].name)) + return nmc_valid_connection_types[i].settings; + } + return NULL; +} + /* - * Check if 'val' is valid string in either array->name or array->alias. + * Check if 'val' is valid string in either array->name or array->alias for + * both array parameters (array & array_slv). * It accepts shorter string provided they are not ambiguous. * 'val' == NULL doesn't hurt. * @@ -2940,21 +2919,27 @@ get_valid_options_string (const NameItem array[]) * The returned string must not be freed. */ static const char * -check_valid_name (const char *val, const NameItem array[], GError **error) +check_valid_name (const char *val, const NameItem *array, const NameItem *array_slv, GError **error) { const NameItem *iter; - GPtrArray *tmp_arr; + gs_unref_ptrarray GPtrArray *tmp_arr = NULL; const char *str; GError *tmp_err = NULL; + int i; + + g_return_val_if_fail (val, NULL); + g_return_val_if_fail (array, NULL); /* Create a temporary array that can be used in nmc_string_is_valid() */ - tmp_arr = g_ptr_array_sized_new (30); - iter = &array[0]; - while (iter && iter->name) { - g_ptr_array_add (tmp_arr, (gpointer) iter->name); - if (iter->alias) - g_ptr_array_add (tmp_arr, (gpointer) iter->alias); - iter++; + tmp_arr = g_ptr_array_sized_new (32); + iter = array; + for (i = 0; i < 2; i++, iter = array_slv) { + while (iter && iter->name) { + g_ptr_array_add (tmp_arr, (gpointer) iter->name); + if (iter->alias) + g_ptr_array_add (tmp_arr, (gpointer) iter->alias); + iter++; + } } g_ptr_array_add (tmp_arr, (gpointer) NULL); @@ -2965,48 +2950,33 @@ check_valid_name (const char *val, const NameItem array[], GError **error) g_propagate_error (error, tmp_err); else { /* We want to handle aliases, so construct own error message */ - char *err_str = get_valid_options_string (array); + char *err_str = get_valid_options_string (array, array_slv); + g_set_error (error, 1, 0, _("'%s' not among [%s]"), - val ? val : "", err_str); + val, err_str); g_free (err_str); g_clear_error (&tmp_err); } - g_ptr_array_free (tmp_arr, TRUE); return NULL; } /* Return a pointer to the found string in passed 'array' */ - iter = &array[0]; - while (iter && iter->name) { - if ( (iter->name && g_strcmp0 (iter->name, str) == 0) - || (iter->alias && g_strcmp0 (iter->alias, str) == 0)) { - g_ptr_array_free (tmp_arr, TRUE); - return iter->name; + iter = array; + for (i = 0; i < 2; i++, iter = array_slv) { + while (iter && iter->name) { + if ( nm_streq (iter->name, str) + || nm_streq0 (iter->alias, str)) { + return iter->name; + } + iter++; } - iter++; } + /* We should not really come here */ - g_ptr_array_free (tmp_arr, TRUE); g_set_error (error, 1, 0, _("Unknown error")); return NULL; } -static const NameItem * -get_valid_settings_array (const char *con_type) -{ - guint i, num; - - if (!con_type) - return NULL; - - num = G_N_ELEMENTS (nmc_valid_connection_types); - for (i = 0; i < num; i++) { - if (!g_strcmp0 (con_type, nmc_valid_connection_types[i].name)) - return nmc_valid_connection_types[i].settings; - } - return NULL; -} - static gboolean is_setting_mandatory (NMConnection *connection, NMSetting *setting) { @@ -3014,6 +2984,8 @@ is_setting_mandatory (NMConnection *connection, NMSetting *setting) const char *c_type; const NameItem *item; const char *name; + const char *s_type; + char *slv_type; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -3027,6 +2999,18 @@ is_setting_mandatory (NMConnection *connection, NMSetting *setting) return item->mandatory; item++; } + + /* Let's give a try to parameters related to slave type */ + s_type = nm_setting_connection_get_slave_type (s_con); + slv_type = g_strdup_printf ("%s-slave", s_type ? s_type : "no"); + item = get_valid_settings_array (slv_type); + g_free (slv_type); + while (item && item->name) { + if (!strcmp (name, item->name)) + return item->mandatory; + item++; + } + return FALSE; } @@ -4482,11 +4466,11 @@ do_questionnaire_ip (NMConnection *connection) } static NMSetting * -is_setting_valid (NMConnection *connection, const NameItem *valid_settings, char *setting) +is_setting_valid (NMConnection *connection, const NameItem *valid_settings_main, const NameItem *valid_settings_slave, char *setting) { const char *setting_name; - if (!(setting_name = check_valid_name (setting, valid_settings, NULL))) + if (!(setting_name = check_valid_name (setting, valid_settings_main, valid_settings_slave, NULL))) return NULL; return nm_connection_get_setting_by_name (connection, setting_name); } @@ -4639,6 +4623,7 @@ read_connection_properties (NMConnection *connection, const char *s_dot_p; const char *value; char **strv = NULL; + char *slv_type = NULL; const char *setting_name; gboolean append = FALSE; gboolean remove = FALSE; @@ -4647,6 +4632,16 @@ read_connection_properties (NMConnection *connection, s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); + + /* First check if we have a slave-type, as this would mean we will not + * have ip properties but possibly others, slave-type specific. + */ + con_type = nm_setting_connection_get_slave_type (s_con); + if (!con_type) + con_type = "no"; + + slv_type = g_strdup_printf ("%s-slave", con_type); + con_type = nm_setting_connection_get_connection_type (s_con); /* Go through arguments and set properties */ @@ -4687,7 +4682,8 @@ read_connection_properties (NMConnection *connection, goto finish; } - setting_name = check_valid_name (strv[0], get_valid_settings_array (con_type), &local); + setting_name = check_valid_name (strv[0], get_valid_settings_array (con_type), + get_valid_settings_array (slv_type), &local); if (!setting_name) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("Error: invalid or not allowed setting '%s': %s."), @@ -4759,6 +4755,7 @@ read_connection_properties (NMConnection *connection, finish: if (strv) g_strfreev (strv); + g_free (slv_type); return success; } @@ -4802,6 +4799,7 @@ complete_slave (NMSettingConnection *s_con, /* Change properties in 'connection' setting */ g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, checked_master, + NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, NULL); g_free (master_ask); @@ -4842,7 +4840,6 @@ complete_connection_by_type (NMConnection *connection, NMSettingIPTunnel *s_ip_tunnel; NMSettingMacvlan *s_macvlan; NMSettingVxlan *s_vxlan; - const char *slave_type; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -5545,12 +5542,24 @@ cleanup_bond: return FALSE; } else if (!strcmp (con_type, "bond-slave")) { + /* Slave types without any specific settings ('bond-slave') */ + const char *master = NULL; + const char *type = NULL; + nmc_arg_t exp_args[] = { {"master", TRUE, &master, FALSE}, + {"type", TRUE, &type, FALSE}, + {NULL} }; + + /* Set global variables for use in TAB completion */ + nmc_tab_completion.con_type = NM_SETTING_BOND_SETTING_NAME; + + if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) + return FALSE; + + if (!complete_slave (s_con, all_connections, NM_SETTING_BOND_SETTING_NAME, master, type, ask, error)) + return FALSE; /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, - NULL); + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); /* Add ethernet setting */ s_wired = (NMSettingWired *) nm_setting_wired_new (); @@ -5605,12 +5614,55 @@ cleanup_team: return FALSE; } else if (!strcmp (con_type, "team-slave")) { + /* Build up the settings required for 'team-slave' */ + gboolean success = FALSE; + const char *master = NULL; + char *master_ask = NULL; + const char *type = NULL; + const char *config_c = NULL; + char *config = NULL; + char *json = NULL; + nmc_arg_t exp_args[] = { {"master", TRUE, &master, FALSE}, + {"type", TRUE, &type, FALSE}, + {"config", TRUE, &config_c, FALSE}, + {NULL} }; + + /* Set global variables for use in TAB completion */ + nmc_tab_completion.con_type = NM_SETTING_TEAM_SETTING_NAME; + + if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) + return FALSE; + + if (!complete_slave (s_con, all_connections, NM_SETTING_TEAM_SETTING_NAME, master, type, ask, error)) + return FALSE; + + /* Also ask for all optional arguments if '--ask' is specified. */ + config = g_strdup (config_c); + if (ask) + do_questionnaire_team_slave (&config); + + /* Add 'team-port' setting */ + s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new (); + nm_connection_add_setting (connection, NM_SETTING (s_team_port)); + + if (!nmc_team_check_config (config, &json, error)) { + g_prefix_error (error, _("Error: ")); + goto cleanup_team_slave; + } + + /* Set team-port options */ + g_object_set (s_team_port, NM_SETTING_TEAM_PORT_CONFIG, json, NULL); + + success = TRUE; +cleanup_team_slave: + g_free (master_ask); + g_free (config); + g_free (json); + if (!success) + return FALSE; /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, - NULL); + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); /* Add ethernet setting */ s_wired = (NMSettingWired *) nm_setting_wired_new (); @@ -5755,12 +5807,83 @@ cleanup_bridge: return FALSE; } else if (!strcmp (con_type, "bridge-slave")) { + /* Build up the settings required for 'bridge-slave' */ + gboolean success = FALSE; + const char *master = NULL; + char *master_ask = NULL; + const char *type = NULL; + const char *priority_c = NULL; + char *priority = NULL; + const char *path_cost_c = NULL; + char *path_cost = NULL; + const char *hairpin_c = NULL; + char *hairpin = NULL; + unsigned long prio_int, path_cost_int; + gboolean hairpin_bool; + nmc_arg_t exp_args[] = { {"master", TRUE, &master, FALSE}, + {"type", TRUE, &type, FALSE}, + {"priority", TRUE, &priority_c, FALSE}, + {"path-cost", TRUE, &path_cost_c, FALSE}, + {"hairpin", TRUE, &hairpin_c, FALSE}, + {NULL} }; + + /* Set global variables for use in TAB completion */ + nmc_tab_completion.con_type = NM_SETTING_BRIDGE_SETTING_NAME; + + if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) + return FALSE; + + if (!complete_slave (s_con, all_connections, NM_SETTING_BRIDGE_SETTING_NAME, master, type, ask, error)) + return FALSE; + + /* Add 'bridge-port' setting */ + /* Must be done *before* bridge_prop_string_to_uint() so that the type is known */ + s_bridge_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); + nm_connection_add_setting (connection, NM_SETTING (s_bridge_port)); + + /* Also ask for all optional arguments if '--ask' is specified. */ + priority = g_strdup (priority_c); + path_cost = g_strdup (path_cost_c); + hairpin = g_strdup (hairpin_c); + if (ask) + do_questionnaire_bridge_slave (&priority, &path_cost, &hairpin); + + if (priority) + if (!bridge_prop_string_to_uint (priority, "priority", NM_TYPE_SETTING_BRIDGE_PORT, + NM_SETTING_BRIDGE_PORT_PRIORITY, &prio_int, error)) + goto cleanup_bridge_slave; + if (path_cost) + if (!bridge_prop_string_to_uint (path_cost, "path-cost", NM_TYPE_SETTING_BRIDGE_PORT, + NM_SETTING_BRIDGE_PORT_PATH_COST, &path_cost_int, error)) + goto cleanup_bridge_slave; + if (hairpin) { + GError *tmp_err = NULL; + if (!nmc_string_to_bool (hairpin, &hairpin_bool, &tmp_err)) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: 'hairpin': %s."), tmp_err->message); + g_clear_error (&tmp_err); + goto cleanup_bridge_slave; + } + } + + if (priority) + g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_PRIORITY, prio_int, NULL); + if (path_cost) + g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_PATH_COST, path_cost_int, NULL); + if (hairpin) + g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, hairpin_bool, NULL); + + success = TRUE; +cleanup_bridge_slave: + g_free (master_ask); + g_free (priority); + g_free (path_cost); + g_free (hairpin); + if (!success) + return FALSE; /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, - NULL); + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); /* Add ethernet setting */ s_wired = (NMSettingWired *) nm_setting_wired_new (); @@ -6064,7 +6187,7 @@ cleanup_macvlan: {"pi", TRUE, &pi_c, FALSE}, {"vnet-hdr", TRUE, &vnet_hdr_c, FALSE}, {"multi-queue", TRUE, &multi_queue_c, FALSE}, - {NULL} }; + {NULL} }; if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) return FALSE; @@ -6416,145 +6539,7 @@ cleanup_vxlan: return FALSE; } - slave_type = nm_setting_connection_get_slave_type (s_con); - if (slave_type) { - - /* Set global variables for use in TAB completion */ - nmc_tab_completion.con_type = (char *)slave_type; - - if (!strcmp (slave_type, NM_SETTING_TEAM_SETTING_NAME)) { - /* Build up the settings required for 'team-slave' */ - gboolean success = FALSE; - const char *master = NULL; - char *master_ask = NULL; - const char *type = NULL; - const char *config_c = NULL; - char *config = NULL; - char *json = NULL; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, FALSE}, - {"type", TRUE, &type, FALSE}, - {"config", TRUE, &config_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!complete_slave (s_con, all_connections, slave_type, master, type, ask, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - config = g_strdup (config_c); - if (ask) - do_questionnaire_team_slave (&config); - - /* Add 'team-port' setting */ - s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team_port)); - - if (!nmc_team_check_config (config, &json, error)) { - g_prefix_error (error, _("Error: ")); - goto cleanup_team_slave; - } - - /* Set team-port options */ - g_object_set (s_team_port, NM_SETTING_TEAM_PORT_CONFIG, json, NULL); - - success = TRUE; -cleanup_team_slave: - g_free (master_ask); - g_free (config); - g_free (json); - if (!success) - return FALSE; - - } else if (!strcmp (slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) { - /* Build up the settings required for 'bridge-slave' */ - gboolean success = FALSE; - const char *master = NULL; - char *master_ask = NULL; - const char *type = NULL; - const char *priority_c = NULL; - char *priority = NULL; - const char *path_cost_c = NULL; - char *path_cost = NULL; - const char *hairpin_c = NULL; - char *hairpin = NULL; - unsigned long prio_int, path_cost_int; - gboolean hairpin_bool; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, FALSE}, - {"type", TRUE, &type, FALSE}, - {"priority", TRUE, &priority_c, FALSE}, - {"path-cost", TRUE, &path_cost_c, FALSE}, - {"hairpin", TRUE, &hairpin_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!complete_slave (s_con, all_connections, slave_type, master, type, ask, error)) - return FALSE; - - /* Add 'bridge-port' setting */ - /* Must be done *before* bridge_prop_string_to_uint() so that the type is known */ - s_bridge_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bridge_port)); - - /* Also ask for all optional arguments if '--ask' is specified. */ - priority = g_strdup (priority_c); - path_cost = g_strdup (path_cost_c); - hairpin = g_strdup (hairpin_c); - if (ask) - do_questionnaire_bridge_slave (&priority, &path_cost, &hairpin); - - if (priority) - if (!bridge_prop_string_to_uint (priority, "priority", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PRIORITY, &prio_int, error)) - goto cleanup_bridge_slave; - if (path_cost) - if (!bridge_prop_string_to_uint (path_cost, "path-cost", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PATH_COST, &path_cost_int, error)) - goto cleanup_bridge_slave; - if (hairpin) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (hairpin, &hairpin_bool, &tmp_err)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'hairpin': %s."), tmp_err->message); - g_clear_error (&tmp_err); - goto cleanup_bridge_slave; - } - } - - if (priority) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_PRIORITY, prio_int, NULL); - if (path_cost) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_PATH_COST, path_cost_int, NULL); - if (hairpin) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, hairpin_bool, NULL); - - success = TRUE; -cleanup_bridge_slave: - g_free (master_ask); - g_free (priority); - g_free (path_cost); - g_free (hairpin); - if (!success) - return FALSE; - } else { - /* Slave types without any specific settings ('bond-slave') */ - const char *master = NULL; - const char *type = NULL; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, FALSE}, - {"type", TRUE, &type, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!complete_slave (s_con, all_connections, slave_type, master, type, ask, error)) - return FALSE; - } - - } else { + if (!nm_setting_connection_get_slave_type (s_con)) { /* Read and add IP configuration */ NMIPAddress *ip4addr = NULL, *ip6addr = NULL; const char *ip4 = NULL, *gw4 = NULL, *ip6 = NULL, *gw6 = NULL; @@ -6649,7 +6634,7 @@ cleanup_bridge_slave: if (argc) { /* Set extra connection properties. */ nmc_arg_t exp_args[] = { {"--", FALSE, NULL, TRUE}, - {NULL} }; + {NULL} }; if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) return FALSE; @@ -6954,7 +6939,7 @@ do_connection_add (NmCli *nmc, int argc, char **argv) } if (!type && nmc->ask) { - char *types_tmp = get_valid_options_string (nmc_valid_connection_types); + char *types_tmp = get_valid_options_string (nmc_valid_connection_types, NULL); g_print ("Valid types: [%s]\n", types_tmp); type = type_ask = nmc_readline (PROMPT_CON_TYPE); g_free (types_tmp); @@ -6967,7 +6952,7 @@ do_connection_add (NmCli *nmc, int argc, char **argv) if (type_ask) type = g_strstrip (type_ask); - if (!(setting_name = check_valid_name (type, nmc_valid_connection_types, &error))) { + if (!(setting_name = check_valid_name (type, nmc_valid_connection_types, NULL, &error))) { g_string_printf (nmc->return_text, _("Error: invalid connection type; %s."), error->message); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; @@ -7250,18 +7235,48 @@ gen_connection_types (const char *text, int state) static char * gen_setting_names (const char *text, int state) { - static int list_idx, len; + static int list_idx, len, is_slv; const char *s_name, *a_name; const NameItem *valid_settings_arr; + NMSettingConnection *s_con; + const char *s_type = NULL; + char *slv_type; if (!state) { list_idx = 0; len = strlen (text); + is_slv = 0; } - valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); - if (!valid_settings_arr) - return NULL; + if (!is_slv) { + valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); + if (!valid_settings_arr) + return NULL; + while (valid_settings_arr[list_idx].name) { + a_name = valid_settings_arr[list_idx].alias; + s_name = valid_settings_arr[list_idx].name; + list_idx++; + if (len == 0 && a_name) + return g_strdup_printf ("%s (%s)", s_name, a_name); + if (a_name && !strncmp (text, a_name, len)) + return g_strdup (a_name); + if (s_name && !strncmp (text, s_name, len)) + return g_strdup (s_name); + } + + /* Let's give a try to parameters related to slave type */ + list_idx = 0; + is_slv = 1; + } + + /* is_slv */ + s_con = nm_connection_get_setting_connection (nmc_tab_completion.connection); + if (s_con) + s_type = nm_setting_connection_get_slave_type (s_con); + slv_type = g_strdup_printf ("%s-slave", s_type ? s_type : "no"); + valid_settings_arr = get_valid_settings_array (slv_type); + g_free (slv_type); + while (valid_settings_arr[list_idx].name) { a_name = valid_settings_arr[list_idx].alias; s_name = valid_settings_arr[list_idx].name; @@ -7273,6 +7288,7 @@ gen_setting_names (const char *text, int state) if (s_name && !strncmp (text, s_name, len)) return g_strdup (s_name); } + return NULL; } @@ -7285,8 +7301,10 @@ gen_property_names (const char *text, int state) const char *line = rl_line_buffer; const char *setting_name; char **strv = NULL; - const NameItem *valid_settings_arr; + const NameItem *valid_settings_main; + const NameItem *valid_settings_slave; const char *p1; + const char *slv_type; /* Try to get the setting from 'line' - setting_name.property */ p1 = strchr (line, '.'); @@ -7296,8 +7314,23 @@ gen_property_names (const char *text, int state) strv = g_strsplit (p1+1, ".", 2); - valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); - setting_name = check_valid_name (strv[0], valid_settings_arr, NULL); + valid_settings_main = get_valid_settings_array (nmc_tab_completion.con_type); + + /* Support autocompletion of slave-connection parameters + * guessing the slave type from the setting name already + * typed (or autocompleted) */ + if (nm_streq0 (strv[0], NM_SETTING_TEAM_PORT_SETTING_NAME)) + slv_type = "team-slave"; + else if (nm_streq0 (strv[0], NM_SETTING_BRIDGE_PORT_SETTING_NAME)) + slv_type = "bridge-slave"; + else + slv_type = "no-slave"; + valid_settings_slave = get_valid_settings_array (slv_type); + + setting_name = check_valid_name (strv[0], + valid_settings_main, + valid_settings_slave, + NULL); setting = nmc_setting_new_for_name (setting_name); } else { /* Else take the current setting, if any */ @@ -7575,16 +7608,30 @@ static void get_setting_and_property (const char *prompt, const char *line, NMSetting **setting_out, char**property_out) { - const NameItem *valid_settings_arr; + const NameItem *valid_settings_main; + const NameItem *valid_settings_slave; const char *setting_name; NMSetting *setting = NULL; char *property = NULL; char *sett = NULL, *prop = NULL; + NMSettingConnection *s_con; + const char *s_type = NULL; + char *slv_type; extract_setting_and_property (prompt, line, &sett, &prop); if (sett) { - valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); - setting_name = check_valid_name (sett, valid_settings_arr, NULL); + /* Is this too much (and useless?) effort for an unlikely case? */ + s_con = nm_connection_get_setting_connection (nmc_tab_completion.connection); + if (s_con) + s_type = nm_setting_connection_get_slave_type (s_con); + slv_type = g_strdup_printf ("%s-slave", s_type ? s_type : "no"); + + valid_settings_main = get_valid_settings_array (nmc_tab_completion.con_type); + valid_settings_slave = get_valid_settings_array (slv_type); + g_free (slv_type); + + setting_name = check_valid_name (sett, valid_settings_main, + valid_settings_slave, NULL); setting = nmc_setting_new_for_name (setting_name); } else setting = nmc_tab_completion.setting ? g_object_ref (nmc_tab_completion.setting) : NULL; @@ -7898,7 +7945,7 @@ load_history_cmds (const char *uuid) 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 (err->code == G_KEY_FILE_ERROR_PARSE) + if (g_error_matches (err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE)) g_print ("Warning: %s parse error: %s\n", filename, err->message); g_key_file_free (kf); g_free (filename); @@ -7933,8 +7980,8 @@ save_history_cmds (const char *uuid) 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 ( err->code != G_FILE_ERROR_NOENT - && err->code != G_KEY_FILE_ERROR_NOT_FOUND) { + 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); @@ -8786,13 +8833,13 @@ split_editor_main_cmd_args (const char *str, char **setting, char **property, ch } static NMSetting * -create_setting_by_name (const char *name, const NameItem *valid_settings) +create_setting_by_name (const char *name, const NameItem *valid_settings_main, const NameItem *valid_settings_slave) { const char *setting_name; NMSetting *setting = NULL; /* Get a valid setting name */ - setting_name = check_valid_name (name, valid_settings, NULL); + setting_name = check_valid_name (name, valid_settings_main, valid_settings_slave, NULL); if (setting_name) { setting = nmc_setting_new_for_name (setting_name); @@ -8805,7 +8852,8 @@ create_setting_by_name (const char *name, const NameItem *valid_settings) static const char * ask_check_setting (const char *arg, - const NameItem *valid_settings_arr, + const NameItem *valid_settings_main, + const NameItem *valid_settings_slave, const char *valid_settings_str) { char *setting_name_user; @@ -8821,7 +8869,10 @@ ask_check_setting (const char *arg, if (setting_name_user) g_strstrip (setting_name_user); - if (!(setting_name = check_valid_name (setting_name_user, valid_settings_arr, &err))) { + if (!(setting_name = check_valid_name (setting_name_user, + valid_settings_main, + valid_settings_slave, + &err))) { g_print (_("Error: invalid setting name; %s\n"), err->message); g_clear_error (&err); } @@ -8946,6 +8997,7 @@ menu_switch_to_level1 (NmCli *nmc, static gboolean editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_type) { + NMSettingConnection *s_con; NMRemoteConnection *rem_con; NMRemoteConnection *con_tmp; GWeakRef weak = { { NULL } }; @@ -8956,16 +9008,27 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t char *cmd_arg = NULL; char *cmd_arg_s, *cmd_arg_p, *cmd_arg_v; const char *BASE_PROMPT = "nmcli> "; - const NameItem *valid_settings_arr = NULL; + const NameItem *valid_settings_main = NULL; + const NameItem *valid_settings_slave = NULL; char *valid_settings_str = NULL; + const char *s_type = NULL; + char *slv_type; AddConnectionInfo *info = NULL; gboolean dirty; gboolean temp_changes; GError *err1 = NULL; NmcEditorMenuContext menu_ctx; - valid_settings_arr = get_valid_settings_array (connection_type); - valid_settings_str = get_valid_options_string (valid_settings_arr); + s_con = nm_connection_get_setting_connection (connection); + if (s_con) + s_type = nm_setting_connection_get_slave_type (s_con); + slv_type = g_strdup_printf ("%s-slave", s_type ? s_type : "no"); + + valid_settings_main = get_valid_settings_array (connection_type); + valid_settings_slave = get_valid_settings_array (slv_type); + g_free (slv_type); + + valid_settings_str = get_valid_options_string (valid_settings_main, valid_settings_slave); g_print (_("You may edit the following settings: %s\n"), valid_settings_str); menu_ctx.level = 0; @@ -9047,9 +9110,9 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t if (cmd_arg_s) { /* setting provided as "setting.property" */ - ss = is_setting_valid (connection, valid_settings_arr, cmd_arg_s); + ss = is_setting_valid (connection, valid_settings_main, valid_settings_slave, cmd_arg_s); if (!ss) { - ss = create_setting_by_name (cmd_arg_s, valid_settings_arr); + ss = create_setting_by_name (cmd_arg_s, valid_settings_main, valid_settings_slave); if (!ss) { g_print (_("Error: invalid setting argument '%s'; valid are [%s]\n"), cmd_arg_s, valid_settings_str); @@ -9110,7 +9173,10 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t NMSetting *setting; const char *user_arg = cmd_arg_s ? cmd_arg_s : cmd_arg_p; - setting_name = ask_check_setting (user_arg, valid_settings_arr, valid_settings_str); + setting_name = ask_check_setting (user_arg, + valid_settings_main, + valid_settings_slave, + valid_settings_str); if (!setting_name) break; @@ -9185,10 +9251,17 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t descr_all = !cmd_arg_s && !menu_ctx.curr_setting; user_s = descr_all ? cmd_arg_p : cmd_arg_s ? cmd_arg_s : NULL; if (user_s) { - ss = is_setting_valid (connection, valid_settings_arr, user_s); + ss = is_setting_valid (connection, + valid_settings_main, + valid_settings_slave, + user_s); if (!ss) { - if (check_valid_name (user_s, valid_settings_arr, NULL)) - g_print (_("Setting '%s' is not present in the connection.\n"), user_s); + if (check_valid_name (user_s, + valid_settings_main, + valid_settings_slave, + NULL)) + g_print (_("Setting '%s' is not present in the connection.\n"), + user_s); else g_print (_("Error: invalid setting argument '%s'; valid are [%s]\n"), user_s, valid_settings_str); @@ -9218,7 +9291,10 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t } else { /* If the string is not a property, try it as a setting */ NMSetting *s_tmp; - s_tmp = is_setting_valid (connection, valid_settings_arr, cmd_arg_p); + s_tmp = is_setting_valid (connection, + valid_settings_main, + valid_settings_slave, + cmd_arg_p); if (s_tmp) { /* Remove setting from the connection */ connection_remove_setting (connection, s_tmp); @@ -9266,9 +9342,14 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t descr_all = !cmd_arg_s && !menu_ctx.curr_setting; user_s = descr_all ? cmd_arg_p : cmd_arg_s ? cmd_arg_s : NULL; if (user_s) { - ss = is_setting_valid (connection, valid_settings_arr, user_s); + ss = is_setting_valid (connection, + valid_settings_main, + valid_settings_slave, + user_s); if (!ss) { - ss = create_setting_by_name (user_s, valid_settings_arr); + ss = create_setting_by_name (user_s, + valid_settings_main, + valid_settings_slave); if (!ss) { g_print (_("Error: invalid setting argument '%s'; valid are [%s]\n"), user_s, valid_settings_str); @@ -9291,7 +9372,10 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t } else { /* If the string is not a property, try it as a setting */ NMSetting *s_tmp; - s_tmp = is_setting_valid (connection, valid_settings_arr, cmd_arg_p); + s_tmp = is_setting_valid (connection, + valid_settings_main, + valid_settings_slave, + cmd_arg_p); if (s_tmp) print_setting_description (s_tmp); else @@ -9322,7 +9406,10 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t user_s = whole_setting ? cmd_arg_p : cmd_arg_s ? cmd_arg_s : NULL; if (user_s) { const char *s_name; - s_name = check_valid_name (user_s, valid_settings_arr, NULL); + s_name = check_valid_name (user_s, + valid_settings_main, + valid_settings_slave, + NULL); if (!s_name) { g_print (_("Error: unknown setting: '%s'\n"), user_s); break; @@ -9349,7 +9436,10 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t } else { /* If the string is not a property, try it as a setting */ NMSetting *s_tmp; - s_tmp = is_setting_valid (connection, valid_settings_arr, cmd_arg_p); + s_tmp = is_setting_valid (connection, + valid_settings_main, + valid_settings_slave, + cmd_arg_p); if (s_tmp) { /* Print the whole setting */ editor_show_setting (s_tmp, nmc); @@ -9928,8 +10018,8 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) editor_init_existing_connection (connection); } else { /* New connection */ - connection_type = check_valid_name (type, nmc_valid_connection_types, &err1); - tmp_str = get_valid_options_string (nmc_valid_connection_types); + connection_type = check_valid_name (type, nmc_valid_connection_types, NULL, &err1); + tmp_str = get_valid_options_string (nmc_valid_connection_types, NULL); while (!connection_type) { if (!type) @@ -9940,7 +10030,7 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) type_ask = nmc_readline (EDITOR_PROMPT_CON_TYPE); type = type_ask = type_ask ? g_strstrip (type_ask) : NULL; - connection_type = check_valid_name (type_ask, nmc_valid_connection_types, &err1); + connection_type = check_valid_name (type_ask, nmc_valid_connection_types, NULL, &err1); g_free (type_ask); } g_free (tmp_str); @@ -10724,7 +10814,7 @@ do_connection_export (NmCli *nmc, int argc, char **argv) if (!nm_vpn_editor_plugin_export (plugin, path, connection, &error)) { g_string_printf (nmc->return_text, _("Error: failed to export '%s': %s."), - nm_connection_get_id (connection), error ? error->message : "(unknown)"); + nm_connection_get_id (connection), error->message); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto finish; } @@ -11021,8 +11111,6 @@ do_connections (NmCli *nmc, int argc, char **argv) g_thread_unref (editor_thread); } else if (matches(*argv, "delete") == 0) { nmc->return_value = do_connection_delete (nmc, argc-1, argv+1); - } else if (matches(*argv, "monitor") == 0) { - nmc->return_value = do_connection_monitor (nmc, argc-1, argv+1); } else if (matches(*argv, "reload") == 0) { nmc->return_value = do_connection_reload (nmc, argc-1, argv+1); } else if (matches(*argv, "load") == 0) { @@ -11056,6 +11144,8 @@ do_connections (NmCli *nmc, int argc, char **argv) nmc->return_value = do_connection_import (nmc, temporary, argc, argv); } else if (matches(*argv, "export") == 0) { nmc->return_value = do_connection_export (nmc, argc-1, argv+1); + } else if (matches(*argv, "monitor") == 0) { + nmc->return_value = do_connection_monitor (nmc, argc-1, argv+1); } else { usage (); g_string_printf (nmc->return_text, _("Error: '%s' is not valid 'connection' command."), *argv); diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion index f8c0298e..7f79180f 100644 --- a/clients/cli/nmcli-completion +++ b/clients/cli/nmcli-completion @@ -1325,7 +1325,7 @@ _nmcli() ;; de|del|dele|delet|delete| \ - m|mo|mon|moni|monit|monito|monitor) + mon|moni|monit|monito|monitor) if [[ ${#words[@]} -eq 3 ]]; then _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" elif [[ ${#words[@]} -gt 3 ]]; then diff --git a/clients/cli/settings-docs.c b/clients/cli/settings-docs.c index 10db2328..0f882c9b 100644 --- a/clients/cli/settings-docs.c +++ b/clients/cli/settings-docs.c @@ -58,6 +58,7 @@ NmcPropertyDesc setting_802_1x[] = { { "ca-cert", "Contains the CA 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. 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." }, { "ca-path", "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." }, { "client-cert", "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." }, + { "domain-suffix-match", "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." }, { "eap", "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." }, { "identity", "Identity string for EAP authentication methods. Often the user's user or login name." }, { "name", "The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\"." }, @@ -75,16 +76,17 @@ NmcPropertyDesc setting_802_1x[] = { { "phase2-ca-cert", "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\"; 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." }, { "phase2-ca-path", "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." }, { "phase2-client-cert", "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." }, + { "phase2-domain-suffix-match", "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." }, { "phase2-private-key", "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 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." }, { "phase2-private-key-password", "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." }, { "phase2-private-key-password-flags", "Flags indicating how to handle the \"phase2-private-key-password\" property." }, - { "phase2-subject-match", "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." }, + { "phase2-subject-match", "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." }, { "pin", "PIN used for EAP authentication methods." }, { "pin-flags", "Flags indicating how to handle the \"pin\" property." }, { "private-key", "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 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." }, { "private-key-password", "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." }, { "private-key-password-flags", "Flags indicating how to handle the \"private-key-password\" property." }, - { "subject-match", "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." }, + { "subject-match", "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." }, { "system-ca-certs", "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)." }, }; @@ -254,7 +256,7 @@ NmcPropertyDesc setting_ipv4[] = { { "ignore-auto-dns", "When \"method\" is set to \"auto\" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used." }, { "ignore-auto-routes", "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." }, { "may-fail", "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." }, - { "method", "IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support \"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." }, + { "method", "IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support \"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." }, { "name", "The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\"." }, { "never-default", "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." }, { "route-metric", "The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is choosen 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." }, @@ -276,7 +278,7 @@ NmcPropertyDesc setting_ipv6[] = { { "ignore-auto-routes", "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." }, { "ip6-privacy", "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." }, { "may-fail", "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." }, - { "method", "IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support \"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." }, + { "method", "IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support \"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." }, { "name", "The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\"." }, { "never-default", "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." }, { "route-metric", "The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is choosen 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." }, @@ -407,7 +409,7 @@ NmcSettingDesc all_settings[] = { { "802-11-olpc-mesh", setting_802_11_olpc_mesh, 4 }, { "802-11-wireless", setting_802_11_wireless, 16 }, { "802-11-wireless-security", setting_802_11_wireless_security, 18 }, - { "802-1x", setting_802_1x, 33 }, + { "802-1x", setting_802_1x, 35 }, { "802-3-ethernet", setting_802_3_ethernet, 14 }, { "adsl", setting_adsl, 8 }, { "bluetooth", setting_bluetooth, 3 }, diff --git a/clients/cli/settings.c b/clients/cli/settings.c index 9e0cf08e..3fb841a1 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -123,30 +123,32 @@ NmcOutputField nmc_fields_setting_8021X[] = { SETTING_FIELD (NM_SETTING_802_1X_CA_PATH), /* 6 */ SETTING_FIELD (NM_SETTING_802_1X_SUBJECT_MATCH), /* 7 */ SETTING_FIELD (NM_SETTING_802_1X_ALTSUBJECT_MATCHES), /* 8 */ - SETTING_FIELD (NM_SETTING_802_1X_CLIENT_CERT), /* 9 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPVER), /* 10 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPLABEL), /* 11 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING), /* 12 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH), /* 13 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP), /* 14 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT), /* 15 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH), /* 16 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH), /* 17 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES), /* 18 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT), /* 19 */ - SETTING_FIELD (NM_SETTING_802_1X_PASSWORD), /* 20 */ - SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_FLAGS), /* 21 */ - SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_RAW), /* 22 */ - SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS), /* 23 */ - SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY), /* 24 */ - SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD), /* 25 */ - SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS), /* 26 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY), /* 27 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD), /* 28 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS), /* 29 */ - SETTING_FIELD (NM_SETTING_802_1X_PIN), /* 30 */ - SETTING_FIELD (NM_SETTING_802_1X_PIN_FLAGS), /* 31 */ - SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS), /* 32 */ + SETTING_FIELD (NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH), /* 9 */ + SETTING_FIELD (NM_SETTING_802_1X_CLIENT_CERT), /* 10 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPVER), /* 11 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPLABEL), /* 12 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING), /* 13 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH), /* 14 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP), /* 15 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT), /* 16 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH), /* 17 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH), /* 18 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES), /* 19 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH), /* 20 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT), /* 21 */ + SETTING_FIELD (NM_SETTING_802_1X_PASSWORD), /* 22 */ + SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_FLAGS), /* 23 */ + SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_RAW), /* 24 */ + SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS), /* 25 */ + SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY), /* 26 */ + SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD), /* 27 */ + SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS), /* 28 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY), /* 29 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD), /* 30 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS), /* 31 */ + SETTING_FIELD (NM_SETTING_802_1X_PIN), /* 32 */ + SETTING_FIELD (NM_SETTING_802_1X_PIN_FLAGS), /* 33 */ + SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS), /* 34 */ {NULL, NULL, 0, NULL, FALSE, FALSE, 0} }; #define NMC_FIELDS_SETTING_802_1X_ALL "name"","\ @@ -158,6 +160,7 @@ NmcOutputField nmc_fields_setting_8021X[] = { NM_SETTING_802_1X_CA_PATH","\ NM_SETTING_802_1X_SUBJECT_MATCH","\ NM_SETTING_802_1X_ALTSUBJECT_MATCHES","\ + NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH","\ NM_SETTING_802_1X_CLIENT_CERT","\ NM_SETTING_802_1X_PHASE1_PEAPVER","\ NM_SETTING_802_1X_PHASE1_PEAPLABEL","\ @@ -168,6 +171,7 @@ NmcOutputField nmc_fields_setting_8021X[] = { NM_SETTING_802_1X_PHASE2_CA_PATH","\ NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH","\ NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES","\ + NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH","\ NM_SETTING_802_1X_PHASE2_CLIENT_CERT","\ NM_SETTING_802_1X_PASSWORD","\ NM_SETTING_802_1X_PASSWORD_FLAGS","\ @@ -999,6 +1003,7 @@ DEFINE_GETTER (nmc_property_802_1X_get_pac_file, NM_SETTING_802_1X_PAC_FILE) DEFINE_GETTER (nmc_property_802_1X_get_ca_path, NM_SETTING_802_1X_CA_PATH) DEFINE_GETTER (nmc_property_802_1X_get_subject_match, NM_SETTING_802_1X_SUBJECT_MATCH) DEFINE_GETTER (nmc_property_802_1X_get_altsubject_matches, NM_SETTING_802_1X_ALTSUBJECT_MATCHES) +DEFINE_GETTER (nmc_property_802_1X_get_domain_suffix_match, NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH) DEFINE_GETTER (nmc_property_802_1X_get_phase1_peapver, NM_SETTING_802_1X_PHASE1_PEAPVER) DEFINE_GETTER (nmc_property_802_1X_get_phase1_peaplabel, NM_SETTING_802_1X_PHASE1_PEAPLABEL) DEFINE_GETTER (nmc_property_802_1X_get_phase1_fast_provisioning, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING) @@ -1007,6 +1012,7 @@ DEFINE_GETTER (nmc_property_802_1X_get_phase2_autheap, NM_SETTING_802_1X_PHASE2_ DEFINE_GETTER (nmc_property_802_1X_get_phase2_ca_path, NM_SETTING_802_1X_PHASE2_CA_PATH) DEFINE_GETTER (nmc_property_802_1X_get_phase2_subject_match, NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH) DEFINE_GETTER (nmc_property_802_1X_get_phase2_altsubject_matches, NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES) +DEFINE_GETTER (nmc_property_802_1X_get_phase2_domain_suffix_match, NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH) DEFINE_GETTER (nmc_property_802_1X_get_password, NM_SETTING_802_1X_PASSWORD) DEFINE_SECRET_FLAGS_GETTER (nmc_property_802_1X_get_password_flags, NM_SETTING_802_1X_PASSWORD_FLAGS) DEFINE_SECRET_FLAGS_GETTER (nmc_property_802_1X_get_password_raw_flags, NM_SETTING_802_1X_PASSWORD_RAW_FLAGS) @@ -5673,6 +5679,13 @@ nmc_properties_init (void) NULL, NULL, NULL); + nmc_add_prop_funcs (GLUE (802_1X, DOMAIN_SUFFIX_MATCH), + nmc_property_802_1X_get_domain_suffix_match, + nmc_property_set_string, + NULL, + NULL, + NULL, + NULL); nmc_add_prop_funcs (GLUE (802_1X, CLIENT_CERT), nmc_property_802_1X_get_client_cert, nmc_property_802_1X_set_client_cert, @@ -5743,6 +5756,13 @@ nmc_properties_init (void) NULL, NULL, NULL); + nmc_add_prop_funcs (GLUE (802_1X, PHASE2_DOMAIN_SUFFIX_MATCH), + nmc_property_802_1X_get_phase2_domain_suffix_match, + nmc_property_set_string, + NULL, + NULL, + NULL, + NULL); nmc_add_prop_funcs (GLUE (802_1X, PHASE2_CLIENT_CERT), nmc_property_802_1X_get_phase2_client_cert, nmc_property_802_1X_set_phase2_client_cert, @@ -7956,30 +7976,32 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc, const char *one_prop, g set_val_str (arr, 6, nmc_property_802_1X_get_ca_path (setting, NMC_PROPERTY_GET_PRETTY)); set_val_str (arr, 7, nmc_property_802_1X_get_subject_match (setting, NMC_PROPERTY_GET_PRETTY)); set_val_str (arr, 8, nmc_property_802_1X_get_altsubject_matches (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 9, nmc_property_802_1X_get_client_cert (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 10, nmc_property_802_1X_get_phase1_peapver (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 11, nmc_property_802_1X_get_phase1_peaplabel (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 12, nmc_property_802_1X_get_phase1_fast_provisioning (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 13, nmc_property_802_1X_get_phase2_auth (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 14, nmc_property_802_1X_get_phase2_autheap (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 15, nmc_property_802_1X_get_phase2_ca_cert (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 16, nmc_property_802_1X_get_phase2_ca_path (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 17, nmc_property_802_1X_get_phase2_subject_match (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 18, nmc_property_802_1X_get_phase2_altsubject_matches (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 19, nmc_property_802_1X_get_phase2_client_cert (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 20, GET_SECRET (secrets, setting, nmc_property_802_1X_get_password)); - set_val_str (arr, 21, nmc_property_802_1X_get_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 22, GET_SECRET (secrets, setting, nmc_property_802_1X_get_password_raw)); - set_val_str (arr, 23, nmc_property_802_1X_get_password_raw_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 24, nmc_property_802_1X_get_private_key (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 25, GET_SECRET (secrets, setting, nmc_property_802_1X_get_private_key_password)); - set_val_str (arr, 26, nmc_property_802_1X_get_private_key_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 27, nmc_property_802_1X_get_phase2_private_key (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 28, GET_SECRET (secrets, setting, nmc_property_802_1X_get_phase2_private_key_password)); - set_val_str (arr, 29, nmc_property_802_1X_get_phase2_private_key_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 30, GET_SECRET (secrets, setting, nmc_property_802_1X_get_pin)); - set_val_str (arr, 31, nmc_property_802_1X_get_pin_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 32, nmc_property_802_1X_get_system_ca_certs (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 9, nmc_property_802_1X_get_domain_suffix_match (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 10, nmc_property_802_1X_get_client_cert (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 11, nmc_property_802_1X_get_phase1_peapver (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 12, nmc_property_802_1X_get_phase1_peaplabel (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 13, nmc_property_802_1X_get_phase1_fast_provisioning (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 14, nmc_property_802_1X_get_phase2_auth (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 15, nmc_property_802_1X_get_phase2_autheap (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 16, nmc_property_802_1X_get_phase2_ca_cert (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 17, nmc_property_802_1X_get_phase2_ca_path (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 18, nmc_property_802_1X_get_phase2_subject_match (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 19, nmc_property_802_1X_get_phase2_altsubject_matches (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 20, nmc_property_802_1X_get_phase2_domain_suffix_match (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 21, nmc_property_802_1X_get_phase2_client_cert (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 22, GET_SECRET (secrets, setting, nmc_property_802_1X_get_password)); + set_val_str (arr, 23, nmc_property_802_1X_get_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 24, GET_SECRET (secrets, setting, nmc_property_802_1X_get_password_raw)); + set_val_str (arr, 25, nmc_property_802_1X_get_password_raw_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 26, nmc_property_802_1X_get_private_key (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 27, GET_SECRET (secrets, setting, nmc_property_802_1X_get_private_key_password)); + set_val_str (arr, 28, nmc_property_802_1X_get_private_key_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 29, nmc_property_802_1X_get_phase2_private_key (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 30, GET_SECRET (secrets, setting, nmc_property_802_1X_get_phase2_private_key_password)); + set_val_str (arr, 31, nmc_property_802_1X_get_phase2_private_key_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 32, GET_SECRET (secrets, setting, nmc_property_802_1X_get_pin)); + set_val_str (arr, 33, nmc_property_802_1X_get_pin_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 34, nmc_property_802_1X_get_system_ca_certs (setting, NMC_PROPERTY_GET_PRETTY)); g_ptr_array_add (nmc->output_data, arr); print_data (nmc); /* Print all data */ |