summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-09-18 11:03:17 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-10-02 15:02:30 +0200
commiteb1b67615eb34543054a3448f2c804946a221c88 (patch)
treee39f05aecb6ecf88ae5b586dcc21bbc62466d9e5
parentc9e77cdf26fe8056c6625d0f505d032afb31d9b9 (diff)
downloadNetworkManager-eb1b67615eb34543054a3448f2c804946a221c88.tar.gz
cli: add macvlan support
-rw-r--r--clients/cli/connections.c89
-rw-r--r--clients/cli/settings.c107
2 files changed, 195 insertions, 1 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c
index 2031cdcb3d..59f3d84cdc 100644
--- a/clients/cli/connections.c
+++ b/clients/cli/connections.c
@@ -104,6 +104,7 @@ extern NmcOutputField nmc_fields_setting_bridge_port[];
extern NmcOutputField nmc_fields_setting_team[];
extern NmcOutputField nmc_fields_setting_team_port[];
extern NmcOutputField nmc_fields_setting_dcb[];
+extern NmcOutputField nmc_fields_setting_macvlan[];
/* Available settings for 'connection show <con>' - profile part */
static NmcOutputField nmc_fields_settings_names[] = {
@@ -132,6 +133,7 @@ static NmcOutputField nmc_fields_settings_names[] = {
SETTING_FIELD (NM_SETTING_TEAM_SETTING_NAME, nmc_fields_setting_team + 1), /* 22 */
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_MACVLAN_SETTING_NAME, nmc_fields_setting_macvlan + 1), /* 25 */
{NULL, NULL, 0, NULL, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTINGS_NAMES_ALL_X NM_SETTING_CONNECTION_SETTING_NAME","\
@@ -157,7 +159,8 @@ static NmcOutputField nmc_fields_settings_names[] = {
NM_SETTING_BRIDGE_PORT_SETTING_NAME","\
NM_SETTING_TEAM_SETTING_NAME","\
NM_SETTING_TEAM_PORT_SETTING_NAME"," \
- NM_SETTING_DCB_SETTING_NAME
+ NM_SETTING_DCB_SETTING_NAME"," \
+ NM_SETTING_MACVLAN_SETTING_NAME
#define NMC_FIELDS_SETTINGS_NAMES_ALL NMC_FIELDS_SETTINGS_NAMES_ALL_X
/* Active connection data */
@@ -2714,6 +2717,14 @@ static const NameItem nmc_bridge_slave_settings [] = {
{ NULL, NULL, NULL, FALSE }
};
+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 }
+};
/* Available connection types */
static const NameItem nmc_valid_connection_types[] = {
@@ -2736,6 +2747,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 },
+ { NM_SETTING_MACVLAN_SETTING_NAME, NULL, nmc_macvlan_settings },
{ NULL, NULL, NULL }
};
@@ -4444,6 +4456,7 @@ complete_connection_by_type (NMConnection *connection,
NMSettingVpn *s_vpn;
NMSettingOlpcMesh *s_olpc_mesh;
NMSettingAdsl *s_adsl;
+ NMSettingMacvlan *s_macvlan;
const char *slave_type;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -5553,6 +5566,80 @@ cleanup_adsl:
g_free (password);
g_free (protocol_ask);
g_free (encapsulation);
+
+ if (!success)
+ return FALSE;
+
+ } else if (!strcmp (con_type, NM_SETTING_MACVLAN_SETTING_NAME)) {
+ /* Build up the settings required for 'macvlan' */
+ gboolean success = FALSE;
+ const char *parent = NULL;
+ char *parent_ask = NULL;
+ const char *mode = NULL;
+ char *mode_ask = NULL;
+ GByteArray *addr_array = NULL;
+ NMSettingMacvlanMode mode_enum;
+ nmc_arg_t exp_args[] = { {"dev", TRUE, &parent, !ask},
+ {"mode", TRUE, &mode, !ask},
+ {NULL} };
+
+ if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error))
+ return FALSE;
+
+ if (!parent && ask)
+ parent = parent_ask = nmc_readline (_("MACVLAN parent device or connection UUID: "));
+ if (!parent) {
+ g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
+ _("Error: 'dev' is required."));
+ return FALSE;
+ }
+
+ if ( !(addr_array = nm_utils_hwaddr_atoba (parent, ETH_ALEN))
+ && !nm_utils_is_uuid (parent)
+ && !nm_utils_iface_valid_name (parent)) {
+ g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
+ _("Error: 'dev': '%s' is neither UUID, interface name, nor MAC."),
+ parent);
+ goto cleanup_macvlan;
+ }
+
+ if (!mode && ask)
+ mode = mode_ask = nmc_readline (_("MACVLAN mode: "));
+ if (!mode) {
+ g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
+ _("Error: 'mode' is required."));
+ return FALSE;
+ }
+
+ if (!nm_utils_enum_from_str (nm_setting_macvlan_mode_get_type(), mode, (int *) &mode_enum, NULL)) {
+ g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
+ _("Error: 'mode' is not valid."));
+ return FALSE;
+ }
+
+ /* Add 'macvlan' setting */
+ s_macvlan = (NMSettingMacvlan *) nm_setting_macvlan_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_macvlan));
+
+ /* Add 'wired' setting if necessary */
+ if (addr_array) {
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+ g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, addr_array, NULL);
+ }
+
+ /* Set 'macvlan' properties */
+ if (!addr_array)
+ g_object_set (s_macvlan, NM_SETTING_MACVLAN_PARENT, parent, NULL);
+ g_object_set (s_macvlan, NM_SETTING_MACVLAN_MODE, mode_enum, NULL);
+
+ success = TRUE;
+cleanup_macvlan:
+ if (addr_array)
+ g_byte_array_free (addr_array, TRUE);
+ g_free (parent_ask);
+ g_free (mode_ask);
+
if (!success)
return FALSE;
diff --git a/clients/cli/settings.c b/clients/cli/settings.c
index b4d635b52e..3d79c9c633 100644
--- a/clients/cli/settings.c
+++ b/clients/cli/settings.c
@@ -682,6 +682,18 @@ NmcOutputField nmc_fields_setting_dcb[] = {
NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS
#define NMC_FIELDS_SETTING_DCB_COMMON NMC_FIELDS_SETTING_DCB_ALL
+/* Available fields for NM_SETTING_MACVLAN_SETTING_NAME */
+NmcOutputField nmc_fields_setting_macvlan[] = {
+ SETTING_FIELD ("name"), /* 0 */
+ SETTING_FIELD (NM_SETTING_MACVLAN_PARENT), /* 1 */
+ SETTING_FIELD (NM_SETTING_MACVLAN_MODE), /* 2 */
+ {NULL, NULL, 0, NULL, FALSE, FALSE, 0}
+};
+#define NMC_FIELDS_SETTING_MACVLAN_ALL "name"","\
+ NM_SETTING_MACVLAN_PARENT","\
+ NM_SETTING_MACVLAN_MODE
+#define NMC_FIELDS_SETTING_MACVLAN_COMMON NMC_FIELDS_SETTING_MACVLAN_ALL
+
/*----------------------------------------------------------------------------*/
static char *
@@ -1718,6 +1730,57 @@ nmc_property_wifi_sec_get_wep_key_type (NMSetting *setting, NmcPropertyGetType g
return wep_key_type_to_string (nm_setting_wireless_security_get_wep_key_type (s_wireless_sec));
}
+/* --- NM_SETTING_MACVLAN_SETTING_NAME property get functions --- */
+DEFINE_GETTER (nmc_property_macvlan_get_parent, NM_SETTING_MACVLAN_PARENT)
+
+static char *
+nmc_property_macvlan_get_mode (NMSetting *setting, NmcPropertyGetType get_type)
+{
+ NMSettingMacvlan *s_macvlan = NM_SETTING_MACVLAN (setting);
+ NMSettingMacvlanMode mode;
+ char *tmp, *str;
+
+ mode = nm_setting_macvlan_get_mode (s_macvlan);
+ tmp = nm_utils_enum_to_str (nm_setting_macvlan_mode_get_type (), mode);
+
+ if (get_type == NMC_PROPERTY_GET_PARSABLE)
+ str = g_strdup (tmp ? tmp : "");
+ else
+ str = g_strdup_printf ("%d (%s)", mode, tmp ? tmp : "");
+ g_free (tmp);
+
+ return str;
+}
+
+static gboolean
+nmc_property_macvlan_set_mode (NMSetting *setting, const char *prop,
+ const char *val, GError **error)
+{
+ NMSettingMacvlanMode mode;
+ gs_free const char **options = NULL;
+ gs_free char *options_str = NULL;
+ long int t;
+ gboolean ret;
+
+ if (nmc_string_to_int_base (val, 0, TRUE, 0, _NM_SETTING_MACVLAN_MODE_NUM - 1, &t))
+ mode = (NMSettingMacvlanMode) t;
+ else {
+ ret = nm_utils_enum_from_str (nm_setting_macvlan_mode_get_type (), val,
+ (int *) &mode, NULL);
+
+ if (!ret) {
+ options = nm_utils_enum_get_values (nm_setting_macvlan_mode_get_type(), 0, G_MAXINT);
+ options_str = g_strjoinv (", ", (char **) options);
+ g_set_error (error, 1, 0, _("invalid option '%s', use one of %s"),
+ val, options_str);
+ return FALSE;
+ }
+ }
+
+ g_object_set (setting, prop, (guint) mode, NULL);
+ return TRUE;
+}
+
/*----------------------------------------------------------------------------*/
static void
@@ -6696,6 +6759,22 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
+
+ /* Add editable properties for NM_SETTING_MACVLAN_SETTING_NAME */
+ nmc_add_prop_funcs (GLUE (MACVLAN, PARENT),
+ nmc_property_macvlan_get_parent,
+ nmc_property_set_string,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ nmc_add_prop_funcs (GLUE (MACVLAN, MODE),
+ nmc_property_macvlan_get_mode,
+ nmc_property_macvlan_set_mode,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
void
@@ -7837,6 +7916,33 @@ setting_dcb_details (NMSetting *setting, NmCli *nmc, const char *one_prop, gboo
return TRUE;
}
+static gboolean
+setting_macvlan_details (NMSetting *setting, NmCli *nmc, const char *one_prop, gboolean secrets)
+{
+ NMSettingMacvlan *s_macvlan = NM_SETTING_MACVLAN (setting);
+ NmcOutputField *tmpl, *arr;
+ size_t tmpl_len;
+
+ g_return_val_if_fail (NM_IS_SETTING_MACVLAN (s_macvlan), FALSE);
+
+ tmpl = nmc_fields_setting_macvlan;
+ tmpl_len = sizeof (nmc_fields_setting_macvlan);
+ nmc->print_fields.indices = parse_output_fields (one_prop ? one_prop : NMC_FIELDS_SETTING_MACVLAN_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_macvlan_get_parent (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 2, nmc_property_macvlan_get_mode (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);
@@ -7868,6 +7974,7 @@ static const SettingDetails detail_printers[] = {
{ NM_SETTING_TEAM_SETTING_NAME, setting_team_details },
{ NM_SETTING_TEAM_PORT_SETTING_NAME, setting_team_port_details },
{ NM_SETTING_DCB_SETTING_NAME, setting_dcb_details },
+ { NM_SETTING_MACVLAN_SETTING_NAME, setting_macvlan_details },
{ NULL },
};