diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-09-01 15:14:03 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-12-01 17:39:41 +0100 |
commit | b614a5ec6174bd6dce1ea9593160dd7164fdbd57 (patch) | |
tree | ac8aa7645829b925ca5ae343d04e5e4bec59e9e8 | |
parent | ae8c7a8967c6f91aeeea75a37cd3d14bf0edb67d (diff) | |
download | NetworkManager-b614a5ec6174bd6dce1ea9593160dd7164fdbd57.tar.gz |
cli: add support for IP tunnel settings
-rw-r--r-- | clients/cli/connections.c | 130 | ||||
-rw-r--r-- | clients/cli/nmcli-completion | 2 | ||||
-rw-r--r-- | clients/cli/settings.c | 195 |
3 files changed, 325 insertions, 2 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index bb07552f9c..659815a2f6 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -116,6 +116,7 @@ extern NmcOutputField nmc_fields_setting_team[]; extern NmcOutputField nmc_fields_setting_team_port[]; extern NmcOutputField nmc_fields_setting_dcb[]; extern NmcOutputField nmc_fields_setting_tun[]; +extern NmcOutputField nmc_fields_setting_ip_tunnel[]; /* Available settings for 'connection show <con>' - profile part */ static NmcOutputField nmc_fields_settings_names[] = { @@ -145,6 +146,7 @@ static NmcOutputField nmc_fields_settings_names[] = { SETTING_FIELD (NM_SETTING_TEAM_PORT_SETTING_NAME, nmc_fields_setting_team_port + 1), /* 23 */ SETTING_FIELD (NM_SETTING_DCB_SETTING_NAME, nmc_fields_setting_dcb + 1), /* 24 */ SETTING_FIELD (NM_SETTING_TUN_SETTING_NAME, nmc_fields_setting_tun + 1), /* 25 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_SETTING_NAME, nmc_fields_setting_ip_tunnel + 1), /* 26 */ {NULL, NULL, 0, NULL, NULL, FALSE, FALSE, 0} }; #define NMC_FIELDS_SETTINGS_NAMES_ALL_X NM_SETTING_CONNECTION_SETTING_NAME","\ @@ -171,7 +173,8 @@ static NmcOutputField nmc_fields_settings_names[] = { NM_SETTING_TEAM_SETTING_NAME","\ NM_SETTING_TEAM_PORT_SETTING_NAME"," \ NM_SETTING_DCB_SETTING_NAME"," \ - NM_SETTING_TUN_SETTING_NAME + NM_SETTING_TUN_SETTING_NAME"," \ + NM_SETTING_IP_TUNNEL_SETTING_NAME #define NMC_FIELDS_SETTINGS_NAMES_ALL NMC_FIELDS_SETTINGS_NAMES_ALL_X /* Active connection data */ @@ -2757,6 +2760,14 @@ static const NameItem nmc_tun_settings [] = { { 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 } +}; + /* Available connection types */ static const NameItem nmc_valid_connection_types[] = { { NM_SETTING_GENERIC_SETTING_NAME, NULL, nmc_generic_settings }, @@ -2779,6 +2790,7 @@ static const NameItem nmc_valid_connection_types[] = { { "team-slave", NULL, nmc_team_slave_settings }, { "bridge-slave", NULL, nmc_bridge_slave_settings }, { NM_SETTING_TUN_SETTING_NAME, NULL, nmc_tun_settings }, + { NM_SETTING_IP_TUNNEL_SETTING_NAME, NULL, nmc_ip_tunnel_settings }, { NULL, NULL, NULL } }; @@ -4383,6 +4395,31 @@ do_questionnaire_tun (char **user, char **group, } } +static void +do_questionnaire_ip_tunnel (char **local) +{ + gboolean once_more; + + /* Ask for optional 'ip-tunnel' arguments. */ + if (!want_provide_opt_args (_("IP Tunnel"), 1)) + return; + + if (!*local) { + do { + *local = nmc_readline (_("Local endpoint [none]: ")); + if (!*local) + break; + once_more = !nm_utils_ipaddr_valid (AF_INET, *local) + && !nm_utils_ipaddr_valid (AF_INET6, *local); + if (once_more) { + g_print (_("Error: 'local': '%s' is not valid; must be an IP address\n"), + *local); + g_free (*local); + } + } while (once_more); + } +} + static gboolean read_connection_properties (NMConnection *connection, int argc, @@ -4594,6 +4631,7 @@ complete_connection_by_type (NMConnection *connection, NMSettingOlpcMesh *s_olpc_mesh; NMSettingAdsl *s_adsl; NMSettingTun *s_tun; + NMSettingIPTunnel *s_ip_tunnel; const char *slave_type; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -5813,6 +5851,96 @@ cleanup_tun: g_free (multi_queue); if (!success) return FALSE; + + } else if (!strcmp (con_type, NM_SETTING_IP_TUNNEL_SETTING_NAME)) { + /* Build up the settings required for 'ip-tunnel' */ + const char *mode_c = NULL, *local_c = NULL, *remote_c = NULL; + char *mode_ask = NULL, *remote_ask = NULL, *local = NULL; + gboolean success = FALSE; + NMIPTunnelMode mode_enum; + nmc_arg_t exp_args[] = { {"mode", TRUE, &mode_c, !ask}, + {"local", TRUE, &local_c, FALSE}, + {"remote", TRUE, &remote_c, !ask}, + {NULL} }; + + if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) + return FALSE; + + if (!mode_c && ask) + mode_c = mode_ask = nmc_readline (_("Tunnel mode: ")); + if (!mode_c) { + g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: 'mode' is required.")); + goto cleanup_tunnel; + } + + if (!remote_c && ask) + remote_c = remote_ask = nmc_readline (_("Remote endpoint: ")); + if (!remote_c) { + g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: 'remote' is required.")); + goto cleanup_tunnel; + } + + if (!nm_utils_enum_from_str (nm_ip_tunnel_mode_get_type (), + mode_c, (int *) &mode_enum, NULL)) { + gs_free const char **values = NULL; + gs_free char *values_str = NULL; + + values = nm_utils_enum_get_values (nm_ip_tunnel_mode_get_type (), + NM_IP_TUNNEL_MODE_UKNOWN + 1, + G_MAXINT); + values_str = g_strjoinv (",", (char **) values); + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: 'mode': '%s' is not valid, use one of %s"), + mode_c, values_str); + goto cleanup_tunnel; + } + + if ( !nm_utils_ipaddr_valid (AF_INET, remote_c) + && !nm_utils_ipaddr_valid (AF_INET6, remote_c)) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: 'remote': '%s' is not valid; must be an IP address"), + remote_c); + goto cleanup_tunnel; + } + + local = g_strdup (local_c); + if (ask) + do_questionnaire_ip_tunnel (&local); + + if ( local + && !nm_utils_ipaddr_valid (AF_INET, local) + && !nm_utils_ipaddr_valid (AF_INET6, local)) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("Error: 'local': '%s' is not valid; must be an IP address"), + local); + goto cleanup_tunnel; + } + + /* Add 'tunnel' setting */ + s_ip_tunnel = (NMSettingIPTunnel *) nm_setting_ip_tunnel_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip_tunnel)); + + /* Set 'tunnel' properties */ + g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_MODE, mode_enum, NULL); + g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_REMOTE, remote_c, NULL); + if (local) + g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_LOCAL, local, NULL); + + /* Set default values for IPv6 tunnels */ + if (nm_utils_ipaddr_valid (AF_INET6, remote_c)) { + g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_TOS, 64, NULL); + g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT, 4, NULL); + } + + success = TRUE; +cleanup_tunnel: + g_free (remote_ask); + g_free (mode_ask); + if (!success) + return FALSE; + } else if (!strcmp (con_type, NM_SETTING_GENERIC_SETTING_NAME)) { /* Add 'generic' setting */ s_generic = (NMSettingGeneric *) nm_setting_generic_new (); diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion index 1827551b0c..2424fc6d7c 100644 --- a/clients/cli/nmcli-completion +++ b/clients/cli/nmcli-completion @@ -401,7 +401,7 @@ _nmcli_compl_ARGS() # user friendly. Only complete them, if the current word already starts with an "8". _nmcli_list "802-3-ethernet 802-11-wireless 802-11-olpc-mesh" else - _nmcli_list "ethernet wifi wimax gsm cdma infiniband bluetooth vpn olpc-mesh vlan bond bridge team pppoe adsl tun" + _nmcli_list "ethernet wifi wimax gsm cdma infiniband bluetooth vpn olpc-mesh vlan bond bridge team pppoe adsl tun ip-tunnel" fi return 0 fi diff --git a/clients/cli/settings.c b/clients/cli/settings.c index bf2cadc707..3e8c10f4c2 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -718,6 +718,36 @@ NmcOutputField nmc_fields_setting_tun[] = { NM_SETTING_TUN_MULTI_QUEUE #define NMC_FIELDS_SETTING_TUN_COMMON NMC_FIELDS_SETTING_TUN_ALL +/* Available fields for NM_SETTING_IP_TUNNEL_SETTING_NAME */ +NmcOutputField nmc_fields_setting_ip_tunnel[] = { + SETTING_FIELD ("name"), /* 0 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_MODE), /* 1 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_PARENT), /* 2 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_LOCAL), /* 3 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_REMOTE), /* 4 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_TTL), /* 5 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_TOS), /* 6 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY), /* 7 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_INPUT_KEY), /* 8 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_OUTPUT_KEY), /* 9 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT), /* 10 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_FLOW_LABEL), /* 11 */ + {NULL, NULL, 0, NULL, FALSE, FALSE, 0} +}; +#define NMC_FIELDS_SETTING_IP_TUNNEL_ALL "name"","\ + NM_SETTING_IP_TUNNEL_MODE","\ + NM_SETTING_IP_TUNNEL_PARENT","\ + NM_SETTING_IP_TUNNEL_LOCAL","\ + NM_SETTING_IP_TUNNEL_REMOTE","\ + NM_SETTING_IP_TUNNEL_TTL","\ + NM_SETTING_IP_TUNNEL_TOS","\ + NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY","\ + NM_SETTING_IP_TUNNEL_INPUT_KEY","\ + NM_SETTING_IP_TUNNEL_OUTPUT_KEY","\ + NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT","\ + NM_SETTING_IP_TUNNEL_FLOW_LABEL +#define NMC_FIELDS_SETTING_IP_TUNNEL_COMMON NMC_FIELDS_SETTING_IP_TUNNEL_ALL + /*----------------------------------------------------------------------------*/ static char * wep_key_type_to_string (NMWepKeyType type) @@ -1310,6 +1340,17 @@ DEFINE_GETTER (nmc_property_tun_get_pi, NM_SETTING_TUN_PI); DEFINE_GETTER (nmc_property_tun_get_vnet_hdr, NM_SETTING_TUN_VNET_HDR); DEFINE_GETTER (nmc_property_tun_get_multi_queue, NM_SETTING_TUN_MULTI_QUEUE); +DEFINE_GETTER (nmc_property_ip_tunnel_get_parent, NM_SETTING_IP_TUNNEL_PARENT); +DEFINE_GETTER (nmc_property_ip_tunnel_get_local, NM_SETTING_IP_TUNNEL_LOCAL); +DEFINE_GETTER (nmc_property_ip_tunnel_get_remote, NM_SETTING_IP_TUNNEL_REMOTE); +DEFINE_GETTER (nmc_property_ip_tunnel_get_ttl, NM_SETTING_IP_TUNNEL_TTL); +DEFINE_GETTER (nmc_property_ip_tunnel_get_tos, NM_SETTING_IP_TUNNEL_TOS); +DEFINE_GETTER (nmc_property_ip_tunnel_get_path_mtu_discovery, NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY); +DEFINE_GETTER (nmc_property_ip_tunnel_get_input_key, NM_SETTING_IP_TUNNEL_INPUT_KEY); +DEFINE_GETTER (nmc_property_ip_tunnel_get_output_key, NM_SETTING_IP_TUNNEL_OUTPUT_KEY); +DEFINE_GETTER (nmc_property_ip_tunnel_get_encapsulation_limit, NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT); +DEFINE_GETTER (nmc_property_ip_tunnel_get_flow_label, NM_SETTING_IP_TUNNEL_FLOW_LABEL); + static char * nmc_property_ib_get_mtu (NMSetting *setting, NmcPropertyGetType get_type) { @@ -1665,6 +1706,44 @@ nmc_property_wired_set_wake_on_lan (NMSetting *setting, const char *prop, return TRUE; } +static char * +nmc_property_ip_tunnel_get_mode (NMSetting *setting, NmcPropertyGetType get_type) +{ + NMSettingIPTunnel *s_ip_tunnel = NM_SETTING_IP_TUNNEL (setting); + NMIPTunnelMode mode; + + mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel); + return nm_utils_enum_to_str (nm_ip_tunnel_mode_get_type (), mode); +} + +static gboolean +nmc_property_ip_tunnel_set_mode (NMSetting *setting, const char *prop, + const char *val, GError **error) +{ + NMIPTunnelMode mode; + gboolean ret; + + ret = nm_utils_enum_from_str (nm_ip_tunnel_mode_get_type(), val, + (int *) &mode, NULL); + + if (!ret) { + gs_free const char **values = NULL; + gs_free char *values_str = NULL; + + values = nm_utils_enum_get_values (nm_ip_tunnel_mode_get_type (), + NM_IP_TUNNEL_MODE_UKNOWN + 1, + G_MAXINT); + values_str = g_strjoinv (",", (char **) values); + g_set_error (error, 1, 0, _("invalid mode '%s', use one of %s"), + val, values_str); + + return FALSE; + } + + g_object_set (setting, prop, mode, NULL); + return TRUE; +} + /* --- NM_SETTING_WIRELESS_SETTING_NAME property get functions --- */ DEFINE_GETTER (nmc_property_wireless_get_mode, NM_SETTING_WIRELESS_MODE) DEFINE_GETTER (nmc_property_wireless_get_band, NM_SETTING_WIRELESS_BAND) @@ -7073,6 +7152,85 @@ nmc_properties_init (void) NULL, NULL, NULL); + + /* Add editable properties for NM_SETTING_IP_TUNNEL_SETTING_NAME */ + nmc_add_prop_funcs (GLUE (IP_TUNNEL, MODE), + nmc_property_ip_tunnel_get_mode, + nmc_property_ip_tunnel_set_mode, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, PARENT), + nmc_property_ip_tunnel_get_parent, + nmc_property_set_string, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, LOCAL), + nmc_property_ip_tunnel_get_local, + nmc_property_set_string, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, REMOTE), + nmc_property_ip_tunnel_get_remote, + nmc_property_set_string, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, TTL), + nmc_property_ip_tunnel_get_ttl, + nmc_property_set_uint, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, TOS), + nmc_property_ip_tunnel_get_tos, + nmc_property_set_uint, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, PATH_MTU_DISCOVERY), + nmc_property_ip_tunnel_get_path_mtu_discovery, + nmc_property_set_bool, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, INPUT_KEY), + nmc_property_ip_tunnel_get_input_key, + nmc_property_set_string, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, OUTPUT_KEY), + nmc_property_ip_tunnel_get_output_key, + nmc_property_set_string, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, ENCAPSULATION_LIMIT), + nmc_property_ip_tunnel_get_encapsulation_limit, + nmc_property_set_uint, + NULL, + NULL, + NULL, + NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, FLOW_LABEL), + nmc_property_ip_tunnel_get_flow_label, + nmc_property_set_uint, + NULL, + NULL, + NULL, + NULL); } void @@ -8253,6 +8411,42 @@ setting_tun_details (NMSetting *setting, NmCli *nmc, const char *one_prop, gboo return TRUE; } +static gboolean +setting_ip_tunnel_details (NMSetting *setting, NmCli *nmc, const char *one_prop, gboolean secrets) +{ + NMSettingIPTunnel *s_ip_tunnel = NM_SETTING_IP_TUNNEL (setting); + NmcOutputField *tmpl, *arr; + size_t tmpl_len; + + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (s_ip_tunnel), FALSE); + + tmpl = nmc_fields_setting_ip_tunnel; + tmpl_len = sizeof (nmc_fields_setting_ip_tunnel); + nmc->print_fields.indices = parse_output_fields (one_prop ? one_prop : NMC_FIELDS_SETTING_IP_TUNNEL_ALL, + tmpl, FALSE, NULL, NULL); + arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); + g_ptr_array_add (nmc->output_data, arr); + + arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); + set_val_str (arr, 0, g_strdup (nm_setting_get_name (setting))); + set_val_str (arr, 1, nmc_property_ip_tunnel_get_mode (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 2, nmc_property_ip_tunnel_get_parent (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 3, nmc_property_ip_tunnel_get_local (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 4, nmc_property_ip_tunnel_get_remote (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 5, nmc_property_ip_tunnel_get_ttl (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 6, nmc_property_ip_tunnel_get_tos (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 7, nmc_property_ip_tunnel_get_path_mtu_discovery (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 8, nmc_property_ip_tunnel_get_input_key (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 9, nmc_property_ip_tunnel_get_output_key (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 10, nmc_property_ip_tunnel_get_encapsulation_limit (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 11, nmc_property_ip_tunnel_get_flow_label (setting, NMC_PROPERTY_GET_PRETTY)); + g_ptr_array_add (nmc->output_data, arr); + + print_data (nmc); /* Print all data */ + + return TRUE; +} + typedef struct { const char *sname; gboolean (*func) (NMSetting *setting, NmCli *nmc, const char *one_prop, gboolean secrets); @@ -8285,6 +8479,7 @@ static const SettingDetails detail_printers[] = { { NM_SETTING_TEAM_PORT_SETTING_NAME, setting_team_port_details }, { NM_SETTING_DCB_SETTING_NAME, setting_dcb_details }, { NM_SETTING_TUN_SETTING_NAME, setting_tun_details }, + { NM_SETTING_IP_TUNNEL_SETTING_NAME, setting_ip_tunnel_details }, { NULL }, }; |