mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-11 07:30:16 +01:00
cli: add macvlan support
This commit is contained in:
parent
4d0192e661
commit
c3e6e25239
4 changed files with 280 additions and 2 deletions
|
|
@ -119,6 +119,7 @@ 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[];
|
||||
extern NmcOutputField nmc_fields_setting_macvlan[];
|
||||
|
||||
/* Available settings for 'connection show <con>' - profile part */
|
||||
static NmcOutputField nmc_fields_settings_names[] = {
|
||||
|
|
@ -149,6 +150,7 @@ static NmcOutputField nmc_fields_settings_names[] = {
|
|||
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 */
|
||||
SETTING_FIELD (NM_SETTING_MACVLAN_SETTING_NAME, nmc_fields_setting_macvlan + 1), /* 27 */
|
||||
{NULL, NULL, 0, NULL, NULL, FALSE, FALSE, 0}
|
||||
};
|
||||
#define NMC_FIELDS_SETTINGS_NAMES_ALL_X NM_SETTING_CONNECTION_SETTING_NAME","\
|
||||
|
|
@ -176,7 +178,8 @@ static NmcOutputField nmc_fields_settings_names[] = {
|
|||
NM_SETTING_TEAM_PORT_SETTING_NAME"," \
|
||||
NM_SETTING_DCB_SETTING_NAME"," \
|
||||
NM_SETTING_TUN_SETTING_NAME"," \
|
||||
NM_SETTING_IP_TUNNEL_SETTING_NAME
|
||||
NM_SETTING_IP_TUNNEL_SETTING_NAME"," \
|
||||
NM_SETTING_MACVLAN_SETTING_NAME
|
||||
#define NMC_FIELDS_SETTINGS_NAMES_ALL NMC_FIELDS_SETTINGS_NAMES_ALL_X
|
||||
|
||||
/* Active connection data */
|
||||
|
|
@ -423,6 +426,9 @@ usage_connection_add (void)
|
|||
" [pi yes|no]\n"
|
||||
" [vnet-hdr yes|no]\n"
|
||||
" [multi-queue yes|no]\n\n"
|
||||
" macvlan: dev <parent device (connection UUID, ifname, or MAC)>\n"
|
||||
" mode vepa|bridge|private|passthru|source\n"
|
||||
" [tap yes|no]\n\n"
|
||||
" SLAVE_OPTIONS:\n"
|
||||
" bridge: [priority <0-63>]\n"
|
||||
" [path-cost <1-65535>]\n"
|
||||
|
|
@ -2811,6 +2817,15 @@ static const NameItem nmc_ip_tunnel_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[] = {
|
||||
{ NM_SETTING_GENERIC_SETTING_NAME, NULL, nmc_generic_settings },
|
||||
|
|
@ -2834,6 +2849,7 @@ static const NameItem nmc_valid_connection_types[] = {
|
|||
{ "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 },
|
||||
{ NM_SETTING_MACVLAN_SETTING_NAME, NULL, nmc_macvlan_settings },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
@ -4206,6 +4222,33 @@ do_questionnaire_adsl (gboolean echo, char **password, char **encapsulation)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_questionnaire_macvlan (char **tap)
|
||||
{
|
||||
gboolean once_more;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Ask for optional 'bridge-slave' arguments. */
|
||||
if (!want_provide_opt_args (_("macvlan"), 1))
|
||||
return;
|
||||
|
||||
if (!*tap) {
|
||||
gboolean tap_bool;
|
||||
do {
|
||||
*tap = nmc_readline (_("Tap %s"), prompt_yes_no (FALSE, ":"));
|
||||
*tap = *tap ? *tap : g_strdup ("yes");
|
||||
normalize_yes_no (tap);
|
||||
once_more = !nmc_string_to_bool (*tap, &tap_bool, &error);
|
||||
if (once_more) {
|
||||
g_print (_("Error: 'tap': %s.\n"), error->message);
|
||||
g_clear_error (&error);
|
||||
g_free (*tap);
|
||||
}
|
||||
} while (once_more);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
split_address (char* str, char **ip, char **rest)
|
||||
{
|
||||
|
|
@ -4676,6 +4719,7 @@ complete_connection_by_type (NMConnection *connection,
|
|||
NMSettingAdsl *s_adsl;
|
||||
NMSettingTun *s_tun;
|
||||
NMSettingIPTunnel *s_ip_tunnel;
|
||||
NMSettingMacvlan *s_macvlan;
|
||||
const char *slave_type;
|
||||
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
|
@ -5783,6 +5827,99 @@ 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;
|
||||
const char *tap_c = NULL;
|
||||
char *tap = NULL;
|
||||
NMSettingMacvlanMode mode_enum;
|
||||
gboolean valid_mac = FALSE;
|
||||
gboolean tap_bool = FALSE;
|
||||
nmc_arg_t exp_args[] = { {"dev", TRUE, &parent, !ask},
|
||||
{"mode", TRUE, &mode, !ask},
|
||||
{"tap", TRUE, &tap_c, FALSE},
|
||||
{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 ( !(valid_mac = nm_utils_hwaddr_valid (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;
|
||||
}
|
||||
|
||||
/* Also ask for all optional arguments if '--ask' is specified. */
|
||||
tap = g_strdup (tap_c);
|
||||
if (ask)
|
||||
do_questionnaire_macvlan (&tap);
|
||||
|
||||
if (tap) {
|
||||
GError *tmp_err = NULL;
|
||||
if (!nmc_string_to_bool (tap, &tap_bool, &tmp_err)) {
|
||||
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
|
||||
_("Error: 'tap': %s."), tmp_err->message);
|
||||
g_clear_error (&tmp_err);
|
||||
goto cleanup_macvlan;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (valid_mac) {
|
||||
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, parent, NULL);
|
||||
}
|
||||
|
||||
/* Set 'macvlan' properties */
|
||||
if (!valid_mac)
|
||||
g_object_set (s_macvlan, NM_SETTING_MACVLAN_PARENT, parent, NULL);
|
||||
g_object_set (s_macvlan, NM_SETTING_MACVLAN_MODE, mode_enum, NULL);
|
||||
g_object_set (s_macvlan, NM_SETTING_MACVLAN_TAP, tap_bool, NULL);
|
||||
|
||||
success = TRUE;
|
||||
cleanup_macvlan:
|
||||
g_free (parent_ask);
|
||||
g_free (mode_ask);
|
||||
g_free (tap);
|
||||
|
||||
if (!success)
|
||||
return FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -412,7 +412,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 ip-tunnel"
|
||||
_nmcli_list "ethernet wifi wimax gsm cdma infiniband bluetooth vpn olpc-mesh vlan bond bridge team pppoe adsl tun ip-tunnel macvlan"
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -748,6 +748,22 @@ NmcOutputField nmc_fields_setting_ip_tunnel[] = {
|
|||
NM_SETTING_IP_TUNNEL_FLOW_LABEL
|
||||
#define NMC_FIELDS_SETTING_IP_TUNNEL_COMMON NMC_FIELDS_SETTING_IP_TUNNEL_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 */
|
||||
SETTING_FIELD (NM_SETTING_MACVLAN_PROMISCUOUS), /* 3 */
|
||||
SETTING_FIELD (NM_SETTING_MACVLAN_TAP), /* 4 */
|
||||
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
||||
};
|
||||
#define NMC_FIELDS_SETTING_MACVLAN_ALL "name"","\
|
||||
NM_SETTING_MACVLAN_PARENT","\
|
||||
NM_SETTING_MACVLAN_MODE","\
|
||||
NM_SETTING_MACVLAN_PROMISCUOUS","\
|
||||
NM_SETTING_MACVLAN_TAP
|
||||
#define NMC_FIELDS_SETTING_MACVLAN_COMMON NMC_FIELDS_SETTING_MACVLAN_ALL
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static char *
|
||||
wep_key_type_to_string (NMWepKeyType type)
|
||||
|
|
@ -1866,6 +1882,61 @@ 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)
|
||||
DEFINE_GETTER (nmc_property_macvlan_get_promiscuous, NM_SETTING_MACVLAN_PROMISCUOUS)
|
||||
DEFINE_GETTER (nmc_property_macvlan_get_tap, NM_SETTING_MACVLAN_TAP)
|
||||
|
||||
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(),
|
||||
NM_SETTING_MACVLAN_MODE_UNKNOWN + 1,
|
||||
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
|
||||
|
|
@ -7231,6 +7302,36 @@ 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);
|
||||
nmc_add_prop_funcs (GLUE (MACVLAN, PROMISCUOUS),
|
||||
nmc_property_macvlan_get_promiscuous,
|
||||
nmc_property_set_bool,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
nmc_add_prop_funcs (GLUE (MACVLAN, TAP),
|
||||
nmc_property_macvlan_get_tap,
|
||||
nmc_property_set_bool,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -8447,6 +8548,35 @@ setting_ip_tunnel_details (NMSetting *setting, NmCli *nmc, const char *one_prop
|
|||
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));
|
||||
set_val_str (arr, 3, nmc_property_macvlan_get_promiscuous (setting, NMC_PROPERTY_GET_PRETTY));
|
||||
set_val_str (arr, 4, nmc_property_macvlan_get_tap (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);
|
||||
|
|
@ -8480,6 +8610,7 @@ static const SettingDetails detail_printers[] = {
|
|||
{ 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 },
|
||||
{ NM_SETTING_MACVLAN_SETTING_NAME, setting_macvlan_details },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -684,6 +684,16 @@ The value can be prefixed with \fBifname/\fP, \fBuuid/\fP or \fBid/\fP to disamb
|
|||
.RE
|
||||
.RS
|
||||
.TP
|
||||
.B macvlan:
|
||||
.IP "\fIdev <parent device (connection UUID, ifname, or MAC)>\fP" 42
|
||||
\(en parent device this MACVLAN is on
|
||||
.IP "\fImode vepa|bridge|private|passthru|source\fP" 42
|
||||
\(en MACVLAN mode, which specifies the communication mechanism between multiple MACVLANs on the same lower device
|
||||
.IP "\fI[tap yes|no]\fP" 42
|
||||
\(en controls the device type. If set to 'yes' a MACVTAP will be created (default: no)
|
||||
.RE
|
||||
.RS
|
||||
.TP
|
||||
.B SLAVE_OPTIONS:
|
||||
.RE
|
||||
.RS
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue