mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 03:40:07 +01:00
merge: macvlan and macvtap devices creation support
https://bugzilla.gnome.org/show_bug.cgi?id=755986
This commit is contained in:
commit
e25d144d77
33 changed files with 2012 additions and 59 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 },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@
|
|||
</tp:docstring>
|
||||
</property>
|
||||
|
||||
<property name="Tap" type="b" access="read">
|
||||
<tp:docstring>
|
||||
Whether the device is a macvtap.
|
||||
</tp:docstring>
|
||||
</property>
|
||||
|
||||
<signal name="PropertiesChanged">
|
||||
<arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
|
||||
<tp:docstring>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ libnm_core_headers = \
|
|||
$(core)/nm-setting-ip-tunnel.h \
|
||||
$(core)/nm-setting-ip4-config.h \
|
||||
$(core)/nm-setting-ip6-config.h \
|
||||
$(core)/nm-setting-macvlan.h \
|
||||
$(core)/nm-setting-olpc-mesh.h \
|
||||
$(core)/nm-setting-ppp.h \
|
||||
$(core)/nm-setting-pppoe.h \
|
||||
|
|
@ -86,6 +87,7 @@ libnm_core_sources = \
|
|||
$(core)/nm-setting-ip-tunnel.c \
|
||||
$(core)/nm-setting-ip4-config.c \
|
||||
$(core)/nm-setting-ip6-config.c \
|
||||
$(core)/nm-setting-macvlan.c \
|
||||
$(core)/nm-setting-olpc-mesh.c \
|
||||
$(core)/nm-setting-ppp.c \
|
||||
$(core)/nm-setting-pppoe.c \
|
||||
|
|
|
|||
|
|
@ -1596,7 +1596,8 @@ nm_connection_is_virtual (NMConnection *connection)
|
|||
|| !strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME)
|
||||
|| !strcmp (type, NM_SETTING_VLAN_SETTING_NAME)
|
||||
|| !strcmp (type, NM_SETTING_TUN_SETTING_NAME)
|
||||
|| !strcmp (type, NM_SETTING_IP_TUNNEL_SETTING_NAME))
|
||||
|| !strcmp (type, NM_SETTING_IP_TUNNEL_SETTING_NAME)
|
||||
|| !strcmp (type, NM_SETTING_MACVLAN_SETTING_NAME))
|
||||
return TRUE;
|
||||
|
||||
if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) {
|
||||
|
|
@ -1905,6 +1906,24 @@ nm_connection_get_setting_ip6_config (NMConnection *connection)
|
|||
return (NMSettingIPConfig *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_connection_get_setting_macvlan:
|
||||
* @connection: the #NMConnection
|
||||
*
|
||||
* A shortcut to return any #NMSettingMacvlan the connection might contain.
|
||||
*
|
||||
* Returns: (transfer none): an #NMSettingMacvlan if the connection contains one, otherwise %NULL
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
NMSettingMacvlan *
|
||||
nm_connection_get_setting_macvlan (NMConnection *connection)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||
|
||||
return (NMSettingMacvlan *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MACVLAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_connection_get_setting_olpc_mesh:
|
||||
* @connection: the #NMConnection
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ NM_AVAILABLE_IN_1_2
|
|||
NMSettingIPTunnel * nm_connection_get_setting_ip_tunnel (NMConnection *connection);
|
||||
NMSettingIPConfig * nm_connection_get_setting_ip4_config (NMConnection *connection);
|
||||
NMSettingIPConfig * nm_connection_get_setting_ip6_config (NMConnection *connection);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMSettingMacvlan * nm_connection_get_setting_macvlan (NMConnection *connection);
|
||||
NMSettingOlpcMesh * nm_connection_get_setting_olpc_mesh (NMConnection *connection);
|
||||
NMSettingPpp * nm_connection_get_setting_ppp (NMConnection *connection);
|
||||
NMSettingPppoe * nm_connection_get_setting_pppoe (NMConnection *connection);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "nm-setting-ip-tunnel.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-setting-macvlan.h"
|
||||
#include "nm-setting-olpc-mesh.h"
|
||||
#include "nm-setting-ppp.h"
|
||||
#include "nm-setting-pppoe.h"
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ typedef struct _NMSettingIPConfig NMSettingIPConfig;
|
|||
typedef struct _NMSettingIPTunnel NMSettingIPTunnel;
|
||||
typedef struct _NMSettingIP4Config NMSettingIP4Config;
|
||||
typedef struct _NMSettingIP6Config NMSettingIP6Config;
|
||||
typedef struct _NMSettingMacvlan NMSettingMacvlan;
|
||||
typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh;
|
||||
typedef struct _NMSettingPpp NMSettingPpp;
|
||||
typedef struct _NMSettingPppoe NMSettingPppoe;
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@ typedef enum {
|
|||
* @NM_DEVICE_TYPE_BRIDGE: a bridge master interface
|
||||
* @NM_DEVICE_TYPE_TEAM: a team master interface
|
||||
* @NM_DEVICE_TYPE_TUN: a TUN or TAP interface
|
||||
* @NM_DEVICE_TYPE_IP_TUNNEL: a IP tunnel interface
|
||||
* @NM_DEVICE_TYPE_MACVLAN: a MACVLAN interface
|
||||
*
|
||||
* #NMDeviceType values indicate the type of hardware represented by
|
||||
* an #NMDevice.
|
||||
|
|
@ -174,6 +176,7 @@ typedef enum {
|
|||
NM_DEVICE_TYPE_TEAM = 15,
|
||||
NM_DEVICE_TYPE_TUN = 16,
|
||||
NM_DEVICE_TYPE_IP_TUNNEL = 17,
|
||||
NM_DEVICE_TYPE_MACVLAN = 18,
|
||||
} NMDeviceType;
|
||||
|
||||
/**
|
||||
|
|
|
|||
350
libnm-core/nm-setting-macvlan.c
Normal file
350
libnm-core/nm-setting-macvlan.c
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nm-setting-macvlan.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-private.h"
|
||||
#include "nm-setting-wired.h"
|
||||
#include "nm-connection-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:nm-setting-macvlan
|
||||
* @short_description: Describes connection properties for macvlan interfaces
|
||||
*
|
||||
* The #NMSettingMacvlan object is a #NMSetting subclass that describes properties
|
||||
* necessary for connection to macvlan interfaces.
|
||||
**/
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (NMSettingMacvlan, nm_setting_macvlan, NM_TYPE_SETTING,
|
||||
_nm_register_setting (MACVLAN, 1))
|
||||
NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_MACVLAN)
|
||||
|
||||
#define NM_SETTING_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanPrivate))
|
||||
|
||||
typedef struct {
|
||||
char *parent;
|
||||
NMSettingMacvlanMode mode;
|
||||
gboolean promiscuous;
|
||||
gboolean tap;
|
||||
} NMSettingMacvlanPrivate;
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_PARENT,
|
||||
PROP_MODE,
|
||||
PROP_PROMISCUOUS,
|
||||
PROP_TAP,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
/**
|
||||
* nm_setting_macvlan_new:
|
||||
*
|
||||
* Creates a new #NMSettingMacvlan object with default values.
|
||||
*
|
||||
* Returns: (transfer full): the new empty #NMSettingMacvlan object
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
NMSetting *
|
||||
nm_setting_macvlan_new (void)
|
||||
{
|
||||
return (NMSetting *) g_object_new (NM_TYPE_SETTING_MACVLAN, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_macvlan_get_parent:
|
||||
* @setting: the #NMSettingMacvlan
|
||||
*
|
||||
* Returns: the #NMSettingMacvlan:parent property of the setting
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
const char *
|
||||
nm_setting_macvlan_get_parent (NMSettingMacvlan *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), NULL);
|
||||
return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_macvlan_get_mode:
|
||||
* @setting: the #NMSettingMacvlan
|
||||
*
|
||||
* Returns: the #NMSettingMacvlan:mode property of the setting
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
NMSettingMacvlanMode
|
||||
nm_setting_macvlan_get_mode (NMSettingMacvlan *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), NM_SETTING_MACVLAN_MODE_UNKNOWN);
|
||||
return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_macvlan_get_promiscuous:
|
||||
* @setting: the #NMSettingMacvlan
|
||||
*
|
||||
* Returns: the #NMSettingMacvlan:promiscuous property of the setting
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
gboolean
|
||||
nm_setting_macvlan_get_promiscuous (NMSettingMacvlan *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), FALSE);
|
||||
return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->promiscuous;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_macvlan_get_tap:
|
||||
* @setting: the #NMSettingMacvlan
|
||||
*
|
||||
* Returns: the #NMSettingMacvlan:tap property of the setting
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
gboolean
|
||||
nm_setting_macvlan_get_tap (NMSettingMacvlan *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), FALSE);
|
||||
return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->tap;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
static void
|
||||
nm_setting_macvlan_init (NMSettingMacvlan *setting)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||
{
|
||||
NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
|
||||
if (connection) {
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
} else {
|
||||
s_con = NULL;
|
||||
s_wired = NULL;
|
||||
}
|
||||
|
||||
if (priv->parent) {
|
||||
if ( !nm_utils_is_uuid (priv->parent)
|
||||
&& !nm_utils_iface_valid_name (priv->parent)) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("'%s' is neither an UUID nor an interface name"),
|
||||
priv->parent);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
/* If parent is NULL, the parent must be specified via
|
||||
* NMSettingWired:mac-address.
|
||||
*/
|
||||
if ( connection
|
||||
&& (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_MISSING_PROPERTY,
|
||||
_("property is not specified and neither is '%s:%s'"),
|
||||
NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!priv->promiscuous && priv->mode != NM_SETTING_MACVLAN_MODE_PASSTHRU) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("non promiscuous operation is allowed only in passthru mode'"));
|
||||
g_prefix_error (error, "%s.%s: ",
|
||||
NM_SETTING_MACVLAN_SETTING_NAME,
|
||||
NM_SETTING_MACVLAN_PROMISCUOUS);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object);
|
||||
NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PARENT:
|
||||
g_free (priv->parent);
|
||||
priv->parent = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_MODE:
|
||||
priv->mode = g_value_get_uint (value);
|
||||
break;
|
||||
case PROP_PROMISCUOUS:
|
||||
priv->promiscuous = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_TAP:
|
||||
priv->tap = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object);
|
||||
NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PARENT:
|
||||
g_value_set_string (value, priv->parent);
|
||||
break;
|
||||
case PROP_MODE:
|
||||
g_value_set_uint (value, priv->mode);
|
||||
break;
|
||||
case PROP_PROMISCUOUS:
|
||||
g_value_set_boolean (value, priv->promiscuous);
|
||||
break;
|
||||
case PROP_TAP:
|
||||
g_value_set_boolean (value, priv->tap);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object);
|
||||
NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
|
||||
|
||||
g_free (priv->parent);
|
||||
|
||||
G_OBJECT_CLASS (nm_setting_macvlan_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_macvlan_class_init (NMSettingMacvlanClass *setting_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
|
||||
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
|
||||
|
||||
g_type_class_add_private (setting_class, sizeof (NMSettingMacvlanPrivate));
|
||||
|
||||
/* virtual methods */
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->finalize = finalize;
|
||||
parent_class->verify = verify;
|
||||
|
||||
/* Properties */
|
||||
|
||||
/**
|
||||
* NMSettingMacvlan:parent:
|
||||
*
|
||||
* If given, specifies the parent interface name or parent connection UUID
|
||||
* from which this MAC-VLAN interface should be created. If this property is
|
||||
* not specified, the connection must contain an #NMSettingWired setting
|
||||
* with a #NMSettingWired:mac-address property.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_PARENT,
|
||||
g_param_spec_string (NM_SETTING_MACVLAN_PARENT, "", "",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMSettingMacvlan:mode:
|
||||
*
|
||||
* The macvlan mode, which specifies the communication mechanism between multiple
|
||||
* macvlans on the same lower device.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_MODE,
|
||||
g_param_spec_uint (NM_SETTING_MACVLAN_MODE, "", "",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMSettingMacvlan:promiscuous:
|
||||
*
|
||||
* Whether the interface should be put in promiscuous mode.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_PROMISCUOUS,
|
||||
g_param_spec_boolean (NM_SETTING_MACVLAN_PROMISCUOUS, "", "",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMSettingMacvlan:tap:
|
||||
*
|
||||
* Whether the interface should be a MACVTAP.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_TAP,
|
||||
g_param_spec_boolean (NM_SETTING_MACVLAN_TAP, "", "",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
94
libnm-core/nm-setting-macvlan.h
Normal file
94
libnm-core/nm-setting-macvlan.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_SETTING_MACVLAN_H__
|
||||
#define __NM_SETTING_MACVLAN_H__
|
||||
|
||||
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
|
||||
#error "Only <NetworkManager.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "nm-setting.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_SETTING_MACVLAN (nm_setting_macvlan_get_type ())
|
||||
#define NM_SETTING_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlan))
|
||||
#define NM_SETTING_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_MACVLANCONFIG, NMSettingMacvlanClass))
|
||||
#define NM_IS_SETTING_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_MACVLAN))
|
||||
#define NM_IS_SETTING_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_MACVLAN))
|
||||
#define NM_SETTING_MACVLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanClass))
|
||||
|
||||
#define NM_SETTING_MACVLAN_SETTING_NAME "macvlan"
|
||||
|
||||
#define NM_SETTING_MACVLAN_PARENT "parent"
|
||||
#define NM_SETTING_MACVLAN_MODE "mode"
|
||||
#define NM_SETTING_MACVLAN_PROMISCUOUS "promiscuous"
|
||||
#define NM_SETTING_MACVLAN_TAP "tap"
|
||||
|
||||
struct _NMSettingMacvlan {
|
||||
NMSetting parent;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
NMSettingClass parent;
|
||||
|
||||
/*< private >*/
|
||||
gpointer padding[4];
|
||||
} NMSettingMacvlanClass;
|
||||
|
||||
/**
|
||||
* NMSettingMacvlanMode:
|
||||
* @NM_SETTING_MACVLAN_MODE_UNKNOWN: unknown/unset mode
|
||||
* @NM_SETTING_MACVLAN_MODE_VEPA: Virtual Ethernet Port Aggregator mode
|
||||
* @NM_SETTING_MACVLAN_MODE_BRIDGE: bridge mode
|
||||
* @NM_SETTING_MACVLAN_MODE_PRIVATE: private mode
|
||||
* @NM_SETTING_MACVLAN_MODE_PASSTHRU: passthru mode
|
||||
* @NM_SETTING_MACVLAN_MODE_SOURCE: source mode
|
||||
**/
|
||||
typedef enum {
|
||||
NM_SETTING_MACVLAN_MODE_UNKNOWN = 0,
|
||||
NM_SETTING_MACVLAN_MODE_VEPA = 1,
|
||||
NM_SETTING_MACVLAN_MODE_BRIDGE = 2,
|
||||
NM_SETTING_MACVLAN_MODE_PRIVATE = 3,
|
||||
NM_SETTING_MACVLAN_MODE_PASSTHRU = 4,
|
||||
NM_SETTING_MACVLAN_MODE_SOURCE = 5,
|
||||
_NM_SETTING_MACVLAN_MODE_NUM, /*< skip >*/
|
||||
NM_SETTING_MACVLAN_MODE_LAST = _NM_SETTING_MACVLAN_MODE_NUM - 1, /*< skip >*/
|
||||
} NMSettingMacvlanMode;
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GType nm_setting_macvlan_get_type (void);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMSetting *nm_setting_macvlan_new (void);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char *nm_setting_macvlan_get_parent (NMSettingMacvlan *setting);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMSettingMacvlanMode nm_setting_macvlan_get_mode (NMSettingMacvlan *setting);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_setting_macvlan_get_promiscuous (NMSettingMacvlan *setting);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_setting_macvlan_get_tap (NMSettingMacvlan *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_SETTING_MACVLAN_H__ */
|
||||
|
|
@ -39,6 +39,7 @@ libnminclude_hfiles = \
|
|||
nm-device-generic.h \
|
||||
nm-device-infiniband.h \
|
||||
nm-device-ip-tunnel.h \
|
||||
nm-device-macvlan.h \
|
||||
nm-device-modem.h \
|
||||
nm-device-olpc-mesh.h \
|
||||
nm-device-team.h \
|
||||
|
|
@ -92,6 +93,7 @@ libnm_la_csources = \
|
|||
nm-device-generic.c \
|
||||
nm-device-infiniband.c \
|
||||
nm-device-ip-tunnel.c \
|
||||
nm-device-macvlan.c \
|
||||
nm-device-modem.c \
|
||||
nm-device-olpc-mesh.c \
|
||||
nm-device-team.c \
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#include <nm-setting-ip-tunnel.h>
|
||||
#include <nm-setting-ip4-config.h>
|
||||
#include <nm-setting-ip6-config.h>
|
||||
#include <nm-setting-macvlan.h>
|
||||
#include <nm-setting-olpc-mesh.h>
|
||||
#include <nm-setting-ppp.h>
|
||||
#include <nm-setting-pppoe.h>
|
||||
|
|
|
|||
|
|
@ -859,6 +859,7 @@ libnm_1_2_0 {
|
|||
global:
|
||||
nm_access_point_get_last_seen;
|
||||
nm_connection_get_setting_ip_tunnel;
|
||||
nm_connection_get_setting_macvlan;
|
||||
nm_connection_verify_secrets;
|
||||
nm_device_ethernet_get_s390_subchannels;
|
||||
nm_client_get_all_devices;
|
||||
|
|
@ -876,6 +877,12 @@ global:
|
|||
nm_device_ip_tunnel_get_tos;
|
||||
nm_device_ip_tunnel_get_ttl;
|
||||
nm_device_ip_tunnel_get_type;
|
||||
nm_device_macvlan_get_hw_address;
|
||||
nm_device_macvlan_get_mode;
|
||||
nm_device_macvlan_get_no_promisc;
|
||||
nm_device_macvlan_get_parent;
|
||||
nm_device_macvlan_get_tap;
|
||||
nm_device_macvlan_get_type;
|
||||
nm_device_get_nm_plugin_missing;
|
||||
nm_device_is_real;
|
||||
nm_device_set_managed;
|
||||
|
|
@ -944,6 +951,13 @@ global:
|
|||
nm_setting_tun_new;
|
||||
nm_setting_verify_secrets;
|
||||
nm_setting_vpn_get_timeout;
|
||||
nm_setting_macvlan_get_mode;
|
||||
nm_setting_macvlan_get_parent;
|
||||
nm_setting_macvlan_get_promiscuous;
|
||||
nm_setting_macvlan_get_tap;
|
||||
nm_setting_macvlan_get_type;
|
||||
nm_setting_macvlan_mode_get_type;
|
||||
nm_setting_macvlan_new;
|
||||
nm_setting_wired_get_wake_on_lan;
|
||||
nm_setting_wired_get_wake_on_lan_password;
|
||||
nm_setting_wired_wake_on_lan_get_type;
|
||||
|
|
|
|||
347
libnm/nm-device-macvlan.c
Normal file
347
libnm/nm-device-macvlan.c
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <nm-setting-connection.h>
|
||||
#include <nm-setting-macvlan.h>
|
||||
#include <nm-setting-wired.h>
|
||||
#include <nm-utils.h>
|
||||
|
||||
#include "nm-default.h"
|
||||
#include "nm-device-macvlan.h"
|
||||
#include "nm-device-private.h"
|
||||
#include "nm-object-private.h"
|
||||
|
||||
G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE)
|
||||
|
||||
#define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate))
|
||||
|
||||
typedef struct {
|
||||
NMDevice *parent;
|
||||
char *mode;
|
||||
gboolean no_promisc;
|
||||
gboolean tap;
|
||||
char *hw_address;
|
||||
} NMDeviceMacvlanPrivate;
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_PARENT,
|
||||
PROP_MODE,
|
||||
PROP_NO_PROMISC,
|
||||
PROP_TAP,
|
||||
PROP_HW_ADDRESS,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
/**
|
||||
* nm_device_macvlan_get_parent:
|
||||
* @device: a #NMDeviceMacvlan
|
||||
*
|
||||
* Returns: (transfer none): the device's parent device
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
NMDevice *
|
||||
nm_device_macvlan_get_parent (NMDeviceMacvlan *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE);
|
||||
|
||||
return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_macvlan_get_mode:
|
||||
* @device: a #NMDeviceMacvlan
|
||||
*
|
||||
* Gets the MACVLAN mode of the device.
|
||||
*
|
||||
* Returns: the MACVLAN mode. This is the internal string used by the
|
||||
* device, and must not be modified.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
const char *
|
||||
nm_device_macvlan_get_mode (NMDeviceMacvlan *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), NULL);
|
||||
|
||||
return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_macvlan_get_no_promisc
|
||||
* @device: a #NMDeviceMacvlan
|
||||
*
|
||||
* Gets the no-promiscuous flag of the device.
|
||||
*
|
||||
* Returns: the no-promiscuous flag of the device.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
gboolean
|
||||
nm_device_macvlan_get_no_promisc (NMDeviceMacvlan *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE);
|
||||
|
||||
return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->no_promisc;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_macvlan_get_tap:
|
||||
* @device: a #NMDeviceMacvlan
|
||||
*
|
||||
* Gets the device type (MACVLAN or MACVTAP).
|
||||
*
|
||||
* Returns: %TRUE if the device is a MACVTAP, %FALSE if it is a MACVLAN.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
gboolean
|
||||
nm_device_macvlan_get_tap (NMDeviceMacvlan *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE);
|
||||
|
||||
return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->tap;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_macvlan_get_hw_address:
|
||||
* @device: a #NMDeviceMacvlan
|
||||
*
|
||||
* Gets the hardware (MAC) address of the #NMDeviceMacvlan
|
||||
*
|
||||
* Returns: the hardware address. This is the internal string used by the
|
||||
* device, and must not be modified.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
const char *
|
||||
nm_device_macvlan_get_hw_address (NMDeviceMacvlan *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), NULL);
|
||||
|
||||
return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->hw_address;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device);
|
||||
NMSettingMacvlan *s_macvlan;
|
||||
|
||||
if (!NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->connection_compatible (device, connection, error))
|
||||
return FALSE;
|
||||
|
||||
if (!nm_connection_is_type (connection, NM_SETTING_MACVLAN_SETTING_NAME)) {
|
||||
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
||||
_("The connection was not a MAC-VLAN connection."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s_macvlan = nm_connection_get_setting_macvlan (connection);
|
||||
if (s_macvlan) {
|
||||
if (nm_setting_macvlan_get_tap (s_macvlan) != priv->tap)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_hw_address (NMDevice *device)
|
||||
{
|
||||
return nm_device_macvlan_get_hw_address (NM_DEVICE_MACVLAN (device));
|
||||
}
|
||||
|
||||
static GType
|
||||
get_setting_type (NMDevice *device)
|
||||
{
|
||||
return NM_TYPE_SETTING_MACVLAN;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
static void
|
||||
nm_device_macvlan_init (NMDeviceMacvlan *device)
|
||||
{
|
||||
_nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_MACVLAN);
|
||||
}
|
||||
|
||||
static void
|
||||
init_dbus (NMObject *object)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
|
||||
const NMPropertiesInfo property_info[] = {
|
||||
{ NM_DEVICE_MACVLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
|
||||
{ NM_DEVICE_MACVLAN_MODE, &priv->mode },
|
||||
{ NM_DEVICE_MACVLAN_NO_PROMISC, &priv->no_promisc },
|
||||
{ NM_DEVICE_MACVLAN_TAP, &priv->tap },
|
||||
{ NM_DEVICE_MACVLAN_HW_ADDRESS, &priv->hw_address },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
NM_OBJECT_CLASS (nm_device_macvlan_parent_class)->init_dbus (object);
|
||||
|
||||
_nm_object_register_properties (object,
|
||||
NM_DBUS_INTERFACE_DEVICE_MACVLAN,
|
||||
property_info);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
|
||||
|
||||
g_free (priv->mode);
|
||||
g_free (priv->hw_address);
|
||||
g_clear_object (&priv->parent);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_macvlan_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NMDeviceMacvlan *device = NM_DEVICE_MACVLAN (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PARENT:
|
||||
g_value_set_object (value, nm_device_macvlan_get_parent (device));
|
||||
break;
|
||||
case PROP_MODE:
|
||||
g_value_set_string (value, nm_device_macvlan_get_mode (device));
|
||||
break;
|
||||
case PROP_NO_PROMISC:
|
||||
g_value_set_boolean (value, nm_device_macvlan_get_no_promisc (device));
|
||||
break;
|
||||
case PROP_TAP:
|
||||
g_value_set_boolean (value, nm_device_macvlan_get_tap (device));
|
||||
break;
|
||||
case PROP_HW_ADDRESS:
|
||||
g_value_set_string (value, nm_device_macvlan_get_hw_address (device));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_device_macvlan_class_init (NMDeviceMacvlanClass *gre_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (gre_class);
|
||||
NMObjectClass *nm_object_class = NM_OBJECT_CLASS (gre_class);
|
||||
NMDeviceClass *device_class = NM_DEVICE_CLASS (gre_class);
|
||||
|
||||
g_type_class_add_private (gre_class, sizeof (NMDeviceMacvlanPrivate));
|
||||
|
||||
_nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_MACVLAN);
|
||||
|
||||
/* virtual methods */
|
||||
object_class->finalize = finalize;
|
||||
object_class->get_property = get_property;
|
||||
|
||||
nm_object_class->init_dbus = init_dbus;
|
||||
|
||||
device_class->connection_compatible = connection_compatible;
|
||||
device_class->get_setting_type = get_setting_type;
|
||||
device_class->get_hw_address = get_hw_address;
|
||||
|
||||
/* properties */
|
||||
|
||||
/**
|
||||
* NMDeviceMacvlan:parent:
|
||||
*
|
||||
* The devices's parent device.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_PARENT,
|
||||
g_param_spec_object (NM_DEVICE_MACVLAN_PARENT, "", "",
|
||||
NM_TYPE_DEVICE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDeviceMacvlan:mode:
|
||||
*
|
||||
* The MACVLAN mode.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_MODE,
|
||||
g_param_spec_string (NM_DEVICE_MACVLAN_MODE, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDeviceMacvlan:no-promisc:
|
||||
*
|
||||
* Whether the device has the no-promiscuos flag.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_NO_PROMISC,
|
||||
g_param_spec_boolean (NM_DEVICE_MACVLAN_NO_PROMISC, "", "",
|
||||
FALSE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDeviceMacvlan:tap:
|
||||
*
|
||||
* Whether the device is a MACVTAP.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_TAP,
|
||||
g_param_spec_boolean (NM_DEVICE_MACVLAN_TAP, "", "",
|
||||
FALSE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDeviceMacvlan:hw-address:
|
||||
*
|
||||
* The hardware (MAC) address of the device.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_HW_ADDRESS,
|
||||
g_param_spec_string (NM_DEVICE_MACVLAN_HW_ADDRESS, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
72
libnm/nm-device-macvlan.h
Normal file
72
libnm/nm-device-macvlan.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_DEVICE_MACVLAN_H__
|
||||
#define __NM_DEVICE_MACVLAN_H__
|
||||
|
||||
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION)
|
||||
#error "Only <NetworkManager.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <nm-device.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_DEVICE_MACVLAN (nm_device_macvlan_get_type ())
|
||||
#define NM_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlan))
|
||||
#define NM_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass))
|
||||
#define NM_IS_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MACVLAN))
|
||||
#define NM_IS_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_MACVLAN))
|
||||
#define NM_DEVICE_MACVLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass))
|
||||
|
||||
#define NM_DEVICE_MACVLAN_PARENT "parent"
|
||||
#define NM_DEVICE_MACVLAN_MODE "mode"
|
||||
#define NM_DEVICE_MACVLAN_NO_PROMISC "no-promisc"
|
||||
#define NM_DEVICE_MACVLAN_TAP "tap"
|
||||
#define NM_DEVICE_MACVLAN_HW_ADDRESS "hw-address"
|
||||
|
||||
struct _NMDeviceMacvlan {
|
||||
NMDevice parent;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
NMDeviceClass parent;
|
||||
|
||||
/*< private >*/
|
||||
gpointer padding[4];
|
||||
} NMDeviceMacvlanClass;
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GType nm_device_macvlan_get_type (void);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMDevice * nm_device_macvlan_get_parent (NMDeviceMacvlan *device);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char * nm_device_macvlan_get_mode (NMDeviceMacvlan *device);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_device_macvlan_get_no_promisc (NMDeviceMacvlan *device);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_device_macvlan_get_tap (NMDeviceMacvlan *device);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char * nm_device_macvlan_get_hw_address (NMDeviceMacvlan *device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_DEVICE_MACVLAN_H__ */
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
#include "nm-device-vlan.h"
|
||||
#include "nm-device-generic.h"
|
||||
#include "nm-device-ip-tunnel.h"
|
||||
#include "nm-device-macvlan.h"
|
||||
#include "nm-device.h"
|
||||
#include "nm-device-private.h"
|
||||
#include "nm-dhcp4-config.h"
|
||||
|
|
@ -371,6 +372,8 @@ _nm_device_gtype_from_dtype (NMDeviceType dtype)
|
|||
return NM_TYPE_DEVICE_TUN;
|
||||
case NM_DEVICE_TYPE_IP_TUNNEL:
|
||||
return NM_TYPE_DEVICE_IP_TUNNEL;
|
||||
case NM_DEVICE_TYPE_MACVLAN:
|
||||
return NM_TYPE_DEVICE_MACVLAN;
|
||||
default:
|
||||
g_warning ("Unknown device type %d", dtype);
|
||||
return G_TYPE_INVALID;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ typedef struct _NMDeviceEthernet NMDeviceEthernet;
|
|||
typedef struct _NMDeviceGeneric NMDeviceGeneric;
|
||||
typedef struct _NMDeviceInfiniband NMDeviceInfiniband;
|
||||
typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel;
|
||||
typedef struct _NMDeviceMacvlan NMDeviceMacvlan;
|
||||
typedef struct _NMDeviceModem NMDeviceModem;
|
||||
typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh;
|
||||
typedef struct _NMDeviceTeam NMDeviceTeam;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ libnm-core/nm-setting-ip-config.c
|
|||
libnm-core/nm-setting-ip4-config.c
|
||||
libnm-core/nm-setting-ip6-config.c
|
||||
libnm-core/nm-setting-ip-tunnel.c
|
||||
libnm-core/nm-setting-macvlan.c
|
||||
libnm-core/nm-setting-olpc-mesh.c
|
||||
libnm-core/nm-setting-ppp.c
|
||||
libnm-core/nm-setting-pppoe.c
|
||||
|
|
@ -122,6 +123,7 @@ libnm/nm-device-generic.c
|
|||
libnm/nm-device-tun.c
|
||||
libnm/nm-device-infiniband.c
|
||||
libnm/nm-device-ip-tunnel.c
|
||||
libnm/nm-device-macvlan.c
|
||||
libnm/nm-device-modem.c
|
||||
libnm/nm-device-olpc-mesh.c
|
||||
libnm/nm-device-team.c
|
||||
|
|
@ -152,6 +154,7 @@ src/devices/nm-device-ethernet.c
|
|||
src/devices/nm-device-ethernet-utils.c
|
||||
src/devices/nm-device-infiniband.c
|
||||
src/devices/nm-device-ip-tunnel.c
|
||||
src/devices/nm-device-macvlan.c
|
||||
src/devices/nm-device-tun.c
|
||||
src/devices/nm-device-vlan.c
|
||||
src/devices/team/nm-device-team.c
|
||||
|
|
|
|||
|
|
@ -15,31 +15,40 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
* Copyright 2013 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "nm-default.h"
|
||||
#include "nm-device-macvlan.h"
|
||||
#include "nm-device-private.h"
|
||||
#include "nm-default.h"
|
||||
#include "nm-connection-provider.h"
|
||||
#include "nm-activation-request.h"
|
||||
#include "nm-manager.h"
|
||||
#include "nm-platform.h"
|
||||
#include "nm-device-factory.h"
|
||||
#include "nm-setting-macvlan.h"
|
||||
#include "nm-setting-wired.h"
|
||||
#include "nm-active-connection.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-utils.h"
|
||||
|
||||
#include "nmdbus-device-macvlan.h"
|
||||
|
||||
#include "nm-device-logging.h"
|
||||
_LOG_DECLARE_SELF(NMDeviceMacvlan);
|
||||
|
||||
G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE_GENERIC)
|
||||
G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE)
|
||||
|
||||
#define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate))
|
||||
|
||||
typedef struct {
|
||||
int parent_ifindex;
|
||||
guint parent_state_id;
|
||||
NMDevice *parent;
|
||||
NMPlatformLnkMacvlan props;
|
||||
} NMDeviceMacvlanPrivate;
|
||||
|
||||
|
|
@ -48,14 +57,114 @@ enum {
|
|||
PROP_PARENT,
|
||||
PROP_MODE,
|
||||
PROP_NO_PROMISC,
|
||||
PROP_TAP,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
static int modes[][2] = {
|
||||
{ NM_SETTING_MACVLAN_MODE_VEPA, MACVLAN_MODE_VEPA },
|
||||
{ NM_SETTING_MACVLAN_MODE_BRIDGE, MACVLAN_MODE_BRIDGE },
|
||||
{ NM_SETTING_MACVLAN_MODE_PRIVATE, MACVLAN_MODE_PRIVATE },
|
||||
{ NM_SETTING_MACVLAN_MODE_PASSTHRU, MACVLAN_MODE_PASSTHRU },
|
||||
};
|
||||
|
||||
static int
|
||||
setting_mode_to_platform (int mode)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (modes); i++) {
|
||||
if (modes[i][0] == mode)
|
||||
return modes[i][1];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
platform_mode_to_setting (int mode)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (modes); i++) {
|
||||
if (modes[i][1] == mode)
|
||||
return modes[i][0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *
|
||||
platform_mode_to_string (guint mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case MACVLAN_MODE_PRIVATE:
|
||||
return "private";
|
||||
case MACVLAN_MODE_VEPA:
|
||||
return "vepa";
|
||||
case MACVLAN_MODE_BRIDGE:
|
||||
return "bridge";
|
||||
case MACVLAN_MODE_PASSTHRU:
|
||||
return "passthru";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
static void
|
||||
parent_state_changed (NMDevice *parent,
|
||||
NMDeviceState new_state,
|
||||
NMDeviceState old_state,
|
||||
NMDeviceStateReason reason,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (user_data);
|
||||
|
||||
/* We'll react to our own carrier state notifications. Ignore the parent's. */
|
||||
if (reason == NM_DEVICE_STATE_REASON_CARRIER)
|
||||
return;
|
||||
|
||||
nm_device_set_unmanaged_flags (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent), reason);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_device_macvlan_set_parent (NMDeviceMacvlan *self, NMDevice *parent)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (self);
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
|
||||
if (parent == priv->parent)
|
||||
return;
|
||||
|
||||
if (priv->parent_state_id)
|
||||
nm_clear_g_signal_handler (priv->parent, &priv->parent_state_id);
|
||||
|
||||
g_clear_object (&priv->parent);
|
||||
|
||||
if (parent) {
|
||||
priv->parent = g_object_ref (parent);
|
||||
priv->parent_state_id = g_signal_connect (priv->parent,
|
||||
"state-changed",
|
||||
G_CALLBACK (parent_state_changed),
|
||||
device);
|
||||
|
||||
/* Set parent-dependent unmanaged flag */
|
||||
nm_device_set_unmanaged_flags (device,
|
||||
NM_UNMANAGED_PARENT,
|
||||
!nm_device_get_managed (parent),
|
||||
NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED);
|
||||
}
|
||||
|
||||
/* Recheck availability now that the parent has changed */
|
||||
nm_device_queue_recheck_available (self,
|
||||
NM_DEVICE_STATE_REASON_PARENT_CHANGED,
|
||||
NM_DEVICE_STATE_REASON_PARENT_CHANGED);
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_MACVLAN_PARENT);
|
||||
}
|
||||
|
||||
static void
|
||||
update_properties (NMDevice *device)
|
||||
{
|
||||
|
|
@ -64,18 +173,25 @@ update_properties (NMDevice *device)
|
|||
GObject *object = G_OBJECT (device);
|
||||
const NMPlatformLnkMacvlan *props;
|
||||
const NMPlatformLink *plink;
|
||||
NMDevice *parent = NULL;
|
||||
|
||||
if (priv->props.tap)
|
||||
props = nm_platform_link_get_lnk_macvtap (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink);
|
||||
else
|
||||
props = nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink);
|
||||
|
||||
props = nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink);
|
||||
if (!props) {
|
||||
_LOGW (LOGD_HW, "could not get macvlan properties");
|
||||
_LOGW (LOGD_HW, "could not get %s properties", priv->props.tap ? "macvtap" : "macvlan");
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_freeze_notify (object);
|
||||
|
||||
if (priv->parent_ifindex != plink->parent)
|
||||
g_object_notify (object, NM_DEVICE_MACVLAN_PARENT);
|
||||
if (g_strcmp0 (priv->props.mode, props->mode) != 0)
|
||||
if (priv->parent_ifindex != plink->parent) {
|
||||
parent = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->parent);
|
||||
nm_device_macvlan_set_parent (self, parent);
|
||||
}
|
||||
if (priv->props.mode != props->mode)
|
||||
g_object_notify (object, NM_DEVICE_MACVLAN_MODE);
|
||||
if (priv->props.no_promisc != props->no_promisc)
|
||||
g_object_notify (object, NM_DEVICE_MACVLAN_NO_PROMISC);
|
||||
|
|
@ -93,21 +209,380 @@ link_changed (NMDevice *device, NMPlatformLink *info)
|
|||
update_properties (device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
realize (NMDevice *device, NMPlatformLink *plink, GError **error)
|
||||
{
|
||||
update_properties (device);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
create_and_realize (NMDevice *device,
|
||||
NMConnection *connection,
|
||||
NMDevice *parent,
|
||||
NMPlatformLink *out_plink,
|
||||
GError **error)
|
||||
{
|
||||
const char *iface = nm_device_get_iface (device);
|
||||
NMPlatformError plerr;
|
||||
NMSettingMacvlan *s_macvlan;
|
||||
NMPlatformLnkMacvlan lnk = { };
|
||||
int parent_ifindex;
|
||||
|
||||
s_macvlan = nm_connection_get_setting_macvlan (connection);
|
||||
g_assert (s_macvlan);
|
||||
g_assert (out_plink);
|
||||
|
||||
parent_ifindex = nm_device_get_ifindex (parent);
|
||||
g_warn_if_fail (parent_ifindex > 0);
|
||||
|
||||
lnk.mode = setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan));
|
||||
if (!lnk.mode) {
|
||||
nm_log_info (LOGD_DEVICE, "unsupported MACVLAN mode %u in connection %s",
|
||||
nm_setting_macvlan_get_mode (s_macvlan),
|
||||
nm_connection_get_uuid (connection));
|
||||
return FALSE;
|
||||
}
|
||||
lnk.no_promisc = !nm_setting_macvlan_get_promiscuous (s_macvlan);
|
||||
lnk.tap = nm_setting_macvlan_get_tap (s_macvlan);
|
||||
|
||||
plerr = nm_platform_link_macvlan_add (NM_PLATFORM_GET, iface, parent_ifindex, &lnk, out_plink);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create %s interface '%s' for '%s': %s",
|
||||
lnk.tap ? "macvtap" : "macvlan",
|
||||
iface,
|
||||
nm_connection_get_id (connection),
|
||||
nm_platform_error_to_string (plerr));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
static NMDeviceCapabilities
|
||||
get_generic_capabilities (NMDevice *dev)
|
||||
{
|
||||
/* We assume MACVLAN interfaces always support carrier detect */
|
||||
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bring_up (NMDevice *dev, gboolean *no_firmware)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
guint i = 20;
|
||||
|
||||
while (i-- > 0 && !success) {
|
||||
success = NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->bring_up (dev, no_firmware);
|
||||
g_usleep (50);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
static gboolean
|
||||
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
|
||||
{
|
||||
if (!NM_DEVICE_MACVLAN_GET_PRIVATE (device)->parent)
|
||||
return FALSE;
|
||||
|
||||
return NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->is_available (device, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_new_device_added (NMDevice *device, NMDevice *new_device)
|
||||
{
|
||||
NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device);
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (self);
|
||||
|
||||
if (priv->parent)
|
||||
return;
|
||||
|
||||
if (!nm_device_is_real (device))
|
||||
return;
|
||||
|
||||
update_properties (device);
|
||||
|
||||
if ( priv->parent_ifindex <= 0
|
||||
|| nm_device_get_ifindex (new_device) != priv->parent_ifindex)
|
||||
return;
|
||||
|
||||
priv->parent_ifindex = nm_device_get_ifindex (new_device);
|
||||
nm_device_macvlan_set_parent (self, new_device);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
|
||||
static gboolean
|
||||
match_parent (NMDeviceMacvlan *self, const char *parent)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (self);
|
||||
|
||||
g_return_val_if_fail (parent != NULL, FALSE);
|
||||
|
||||
if (!priv->parent)
|
||||
return FALSE;
|
||||
|
||||
if (nm_utils_is_uuid (parent)) {
|
||||
NMActRequest *parent_req;
|
||||
NMConnection *parent_connection;
|
||||
|
||||
/* If the parent is a UUID, the connection matches if our parent
|
||||
* device has that connection activated.
|
||||
*/
|
||||
|
||||
parent_req = nm_device_get_act_request (priv->parent);
|
||||
if (!parent_req)
|
||||
return FALSE;
|
||||
|
||||
parent_connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (parent_req));
|
||||
if (!parent_connection)
|
||||
return FALSE;
|
||||
|
||||
if (g_strcmp0 (parent, nm_connection_get_uuid (parent_connection)) != 0)
|
||||
return FALSE;
|
||||
} else {
|
||||
/* interface name */
|
||||
if (g_strcmp0 (parent, nm_device_get_ip_iface (priv->parent)) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device);
|
||||
NMSettingWired *s_wired;
|
||||
const char *setting_mac;
|
||||
const char *parent_mac;
|
||||
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
if (!s_wired)
|
||||
return !fail_if_no_hwaddr;
|
||||
|
||||
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||
if (!setting_mac)
|
||||
return !fail_if_no_hwaddr;
|
||||
|
||||
if (!priv->parent)
|
||||
return !fail_if_no_hwaddr;
|
||||
|
||||
parent_mac = nm_device_get_hw_address (priv->parent);
|
||||
|
||||
return nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_connection_compatible (NMDevice *device, NMConnection *connection)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device);
|
||||
NMSettingMacvlan *s_macvlan;
|
||||
const char *parent, *iface = NULL;
|
||||
|
||||
if (!NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->check_connection_compatible (device, connection))
|
||||
return FALSE;
|
||||
|
||||
s_macvlan = nm_connection_get_setting_macvlan (connection);
|
||||
if (!s_macvlan)
|
||||
return FALSE;
|
||||
|
||||
if (nm_setting_macvlan_get_tap (s_macvlan) != priv->props.tap)
|
||||
return FALSE;
|
||||
|
||||
/* Before the device is realized some properties will not be set */
|
||||
if (nm_device_is_real (device)) {
|
||||
|
||||
if (setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan)) != priv->props.mode)
|
||||
return FALSE;
|
||||
|
||||
if (nm_setting_macvlan_get_promiscuous (s_macvlan) == priv->props.no_promisc)
|
||||
return FALSE;
|
||||
|
||||
/* Check parent interface; could be an interface name or a UUID */
|
||||
parent = nm_setting_macvlan_get_parent (s_macvlan);
|
||||
if (parent) {
|
||||
if (!match_parent (NM_DEVICE_MACVLAN (device), parent))
|
||||
return FALSE;
|
||||
} else {
|
||||
/* Parent could be a MAC address in an NMSettingWired */
|
||||
if (!match_hwaddr (device, connection, TRUE))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure the interface name matches */
|
||||
iface = nm_connection_get_interface_name (connection);
|
||||
if (iface) {
|
||||
if (g_strcmp0 (nm_device_get_ip_iface (device), iface) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
complete_connection (NMDevice *device,
|
||||
NMConnection *connection,
|
||||
const char *specific_object,
|
||||
const GSList *existing_connections,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingMacvlan *s_macvlan;
|
||||
|
||||
nm_utils_complete_generic (connection,
|
||||
NM_SETTING_MACVLAN_SETTING_NAME,
|
||||
existing_connections,
|
||||
NULL,
|
||||
_("MACVLAN connection"),
|
||||
NULL,
|
||||
TRUE);
|
||||
|
||||
s_macvlan = nm_connection_get_setting_macvlan (connection);
|
||||
if (!s_macvlan) {
|
||||
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
|
||||
"A 'macvlan' setting is required.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If there's no MACVLAN interface, no parent, and no hardware address in the
|
||||
* settings, then there's not enough information to complete the setting.
|
||||
*/
|
||||
if ( !nm_setting_macvlan_get_parent (s_macvlan)
|
||||
&& !match_hwaddr (device, connection, TRUE)) {
|
||||
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
|
||||
"The 'macvlan' setting had no interface name, parent, or hardware address.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_connection (NMDevice *device, NMConnection *connection)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device);
|
||||
NMSettingMacvlan *s_macvlan = nm_connection_get_setting_macvlan (connection);
|
||||
const char *setting_parent, *new_parent;
|
||||
int new_mode;
|
||||
|
||||
if (!s_macvlan) {
|
||||
s_macvlan = (NMSettingMacvlan *) nm_setting_macvlan_new ();
|
||||
nm_connection_add_setting (connection, (NMSetting *) s_macvlan);
|
||||
}
|
||||
|
||||
new_mode = platform_mode_to_setting (priv->props.mode);
|
||||
if (new_mode != nm_setting_macvlan_get_mode (s_macvlan))
|
||||
g_object_set (s_macvlan, NM_SETTING_MACVLAN_MODE, new_mode, NULL);
|
||||
|
||||
if (priv->props.no_promisc == nm_setting_macvlan_get_promiscuous (s_macvlan))
|
||||
g_object_set (s_macvlan, NM_SETTING_MACVLAN_PROMISCUOUS, !priv->props.no_promisc, NULL);
|
||||
|
||||
|
||||
if (priv->props.tap != nm_setting_macvlan_get_tap (s_macvlan))
|
||||
g_object_set (s_macvlan, NM_SETTING_MACVLAN_TAP, !!priv->props.tap, NULL);
|
||||
|
||||
/* Update parent in the connection; default to parent's interface name */
|
||||
if (priv->parent) {
|
||||
new_parent = nm_device_get_iface (priv->parent);
|
||||
setting_parent = nm_setting_macvlan_get_parent (s_macvlan);
|
||||
if (setting_parent && nm_utils_is_uuid (setting_parent)) {
|
||||
NMConnection *parent_connection;
|
||||
|
||||
/* Don't change a parent specified by UUID if it's still valid */
|
||||
parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), setting_parent);
|
||||
if (parent_connection && nm_device_check_connection_compatible (priv->parent, parent_connection))
|
||||
new_parent = NULL;
|
||||
}
|
||||
if (new_parent)
|
||||
g_object_set (s_macvlan, NM_SETTING_MACVLAN_PARENT, new_parent, NULL);
|
||||
} else
|
||||
g_object_set (s_macvlan, NM_SETTING_MACVLAN_PARENT, NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||
{
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMSettingWired *s_wired;
|
||||
const char *cloned_mac;
|
||||
NMActStageReturn ret;
|
||||
|
||||
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
ret = NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->act_stage1_prepare (dev, reason);
|
||||
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
||||
return ret;
|
||||
|
||||
req = nm_device_get_act_request (dev);
|
||||
g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
connection = nm_act_request_get_applied_connection (req);
|
||||
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
if (s_wired) {
|
||||
/* Set device MAC address if the connection wants to change it */
|
||||
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
|
||||
if (cloned_mac)
|
||||
nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_HW);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingWired *s_wired;
|
||||
guint32 mtu;
|
||||
|
||||
connection = nm_device_get_applied_connection (device);
|
||||
g_assert (connection);
|
||||
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
if (s_wired) {
|
||||
mtu = nm_setting_wired_get_mtu (s_wired);
|
||||
if (mtu)
|
||||
nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_start (NMDevice *device, NMPlatformLink *plink)
|
||||
{
|
||||
NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->setup_start (device, plink);
|
||||
|
||||
update_properties (device);
|
||||
}
|
||||
|
||||
static void
|
||||
deactivate (NMDevice *device)
|
||||
{
|
||||
/* Reset MAC address back to initial address */
|
||||
if (nm_device_get_initial_hw_address (device)) {
|
||||
nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device),
|
||||
"reset", LOGD_DEVICE);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
static void
|
||||
nm_device_macvlan_init (NMDeviceMacvlan *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
constructed (GObject *object)
|
||||
{
|
||||
update_properties (NM_DEVICE (object));
|
||||
|
||||
G_OBJECT_CLASS (nm_device_macvlan_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
|
|
@ -124,17 +599,35 @@ get_property (GObject *object, guint prop_id,
|
|||
nm_utils_g_value_set_object_path (value, parent);
|
||||
break;
|
||||
case PROP_MODE:
|
||||
g_value_set_string (value, priv->props.mode);
|
||||
g_value_set_string (value, platform_mode_to_string (priv->props.mode));
|
||||
break;
|
||||
case PROP_NO_PROMISC:
|
||||
g_value_set_boolean (value, priv->props.no_promisc);
|
||||
break;
|
||||
case PROP_TAP:
|
||||
g_value_set_boolean (value, priv->props.tap);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_TAP:
|
||||
priv->props.tap = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass)
|
||||
{
|
||||
|
|
@ -145,10 +638,24 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass)
|
|||
|
||||
NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP)
|
||||
|
||||
object_class->constructed = constructed;
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
|
||||
device_class->act_stage1_prepare = act_stage1_prepare;
|
||||
device_class->bring_up = bring_up;
|
||||
device_class->check_connection_compatible = check_connection_compatible;
|
||||
device_class->complete_connection = complete_connection;
|
||||
device_class->connection_type = NM_SETTING_MACVLAN_SETTING_NAME;
|
||||
device_class->create_and_realize = create_and_realize;
|
||||
device_class->deactivate = deactivate;
|
||||
device_class->get_generic_capabilities = get_generic_capabilities;
|
||||
device_class->ip4_config_pre_commit = ip4_config_pre_commit;
|
||||
device_class->is_available = is_available;
|
||||
device_class->link_changed = link_changed;
|
||||
device_class->notify_new_device_added = notify_new_device_added;
|
||||
device_class->realize = realize;
|
||||
device_class->setup_start = setup_start;
|
||||
device_class->update_connection = update_connection;
|
||||
|
||||
/* properties */
|
||||
g_object_class_install_property
|
||||
|
|
@ -172,6 +679,14 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass)
|
|||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_TAP,
|
||||
g_param_spec_boolean (NM_DEVICE_MACVLAN_TAP, "", "",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
|
||||
NMDBUS_TYPE_DEVICE_MACVLAN_SKELETON,
|
||||
NULL);
|
||||
|
|
@ -189,18 +704,79 @@ create_device (NMDeviceFactory *factory,
|
|||
NMConnection *connection,
|
||||
gboolean *out_ignore)
|
||||
{
|
||||
g_return_val_if_fail (plink, NULL);
|
||||
NMSettingMacvlan *s_macvlan;
|
||||
NMLinkType link_type;
|
||||
gboolean tap;
|
||||
|
||||
if (connection) {
|
||||
s_macvlan = nm_connection_get_setting_macvlan (connection);
|
||||
g_assert (s_macvlan);
|
||||
tap = nm_setting_macvlan_get_tap (s_macvlan);
|
||||
} else {
|
||||
g_assert (plink);
|
||||
tap = plink->type == NM_LINK_TYPE_MACVTAP;
|
||||
}
|
||||
|
||||
link_type = tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN;
|
||||
|
||||
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACVLAN,
|
||||
NM_DEVICE_IFACE, iface,
|
||||
NM_DEVICE_TYPE_DESC, "Macvlan",
|
||||
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC,
|
||||
NM_DEVICE_LINK_TYPE, plink->type,
|
||||
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_MACVLAN,
|
||||
NM_DEVICE_LINK_TYPE, link_type,
|
||||
NM_DEVICE_MACVLAN_TAP, tap,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
|
||||
{
|
||||
NMSettingMacvlan *s_macvlan;
|
||||
NMSettingWired *s_wired;
|
||||
const char *parent = NULL;
|
||||
|
||||
g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_MACVLAN_SETTING_NAME), NULL);
|
||||
|
||||
s_macvlan = nm_connection_get_setting_macvlan (connection);
|
||||
g_assert (s_macvlan);
|
||||
|
||||
parent = nm_setting_macvlan_get_parent (s_macvlan);
|
||||
if (parent)
|
||||
return parent;
|
||||
|
||||
/* Try the hardware address from the MACVLAN connection's hardware setting */
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
if (s_wired)
|
||||
return nm_setting_wired_get_mac_address (s_wired);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_virtual_iface_name (NMDeviceFactory *factory,
|
||||
NMConnection *connection,
|
||||
const char *parent_iface)
|
||||
{
|
||||
NMSettingMacvlan *s_macvlan;
|
||||
const char *ifname;
|
||||
|
||||
g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_MACVLAN_SETTING_NAME), NULL);
|
||||
|
||||
s_macvlan = nm_connection_get_setting_macvlan (connection);
|
||||
g_assert (s_macvlan);
|
||||
|
||||
if (!parent_iface)
|
||||
return NULL;
|
||||
|
||||
ifname = nm_connection_get_interface_name (connection);
|
||||
return g_strdup (ifname);
|
||||
}
|
||||
|
||||
NM_DEVICE_FACTORY_DEFINE_INTERNAL (MACVLAN, Macvlan, macvlan,
|
||||
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP),
|
||||
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP)
|
||||
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_MACVLAN_SETTING_NAME),
|
||||
factory_iface->create_device = create_device;
|
||||
factory_iface->get_connection_parent = get_connection_parent;
|
||||
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef __NETWORKMANAGER_DEVICE_MACVLAN_H__
|
||||
#define __NETWORKMANAGER_DEVICE_MACVLAN_H__
|
||||
|
||||
#include "nm-device-generic.h"
|
||||
#include "nm-device.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
@ -35,9 +35,10 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_MACVLAN_PARENT "parent"
|
||||
#define NM_DEVICE_MACVLAN_MODE "mode"
|
||||
#define NM_DEVICE_MACVLAN_NO_PROMISC "no-promisc"
|
||||
#define NM_DEVICE_MACVLAN_TAP "tap"
|
||||
|
||||
typedef NMDeviceGeneric NMDeviceMacvlan;
|
||||
typedef NMDeviceGenericClass NMDeviceMacvlanClass;
|
||||
typedef NMDevice NMDeviceMacvlan;
|
||||
typedef NMDeviceClass NMDeviceMacvlanClass;
|
||||
|
||||
GType nm_device_macvlan_get_type (void);
|
||||
|
||||
|
|
|
|||
|
|
@ -781,6 +781,8 @@ nm_device_get_priority (NMDevice *self)
|
|||
return 350;
|
||||
case NM_DEVICE_TYPE_VLAN:
|
||||
return 400;
|
||||
case NM_DEVICE_TYPE_MACVLAN:
|
||||
return 410;
|
||||
case NM_DEVICE_TYPE_BRIDGE:
|
||||
return 425;
|
||||
case NM_DEVICE_TYPE_TUN:
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ typedef enum {
|
|||
NMP_OBJECT_TYPE_LNK_IP6TNL,
|
||||
NMP_OBJECT_TYPE_LNK_IPIP,
|
||||
NMP_OBJECT_TYPE_LNK_MACVLAN,
|
||||
NMP_OBJECT_TYPE_LNK_MACVTAP,
|
||||
NMP_OBJECT_TYPE_LNK_SIT,
|
||||
NMP_OBJECT_TYPE_LNK_VLAN,
|
||||
NMP_OBJECT_TYPE_LNK_VXLAN,
|
||||
|
|
|
|||
|
|
@ -1026,9 +1026,16 @@ _parse_lnk_macvlan (const char *kind, struct nlattr *info_data)
|
|||
struct nlattr *tb[IFLA_MACVLAN_MAX + 1];
|
||||
int err;
|
||||
NMPObject *obj;
|
||||
const char *mode;
|
||||
gboolean tap;
|
||||
|
||||
if (!info_data || g_strcmp0 (kind, "macvlan"))
|
||||
if (!info_data)
|
||||
return NULL;
|
||||
|
||||
if (!g_strcmp0 (kind, "macvlan"))
|
||||
tap = FALSE;
|
||||
else if (!g_strcmp0 (kind, "macvtap"))
|
||||
tap = TRUE;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
err = nla_parse_nested (tb, IFLA_MACVLAN_MAX, info_data, policy);
|
||||
|
|
@ -1038,26 +1045,10 @@ _parse_lnk_macvlan (const char *kind, struct nlattr *info_data)
|
|||
if (!tb[IFLA_MACVLAN_MODE])
|
||||
return NULL;
|
||||
|
||||
switch (nla_get_u32 (tb[IFLA_MACVLAN_MODE])) {
|
||||
case MACVLAN_MODE_PRIVATE:
|
||||
mode = "private";
|
||||
break;
|
||||
case MACVLAN_MODE_VEPA:
|
||||
mode = "vepa";
|
||||
break;
|
||||
case MACVLAN_MODE_BRIDGE:
|
||||
mode = "bridge";
|
||||
break;
|
||||
case MACVLAN_MODE_PASSTHRU:
|
||||
mode = "passthru";
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_MACVLAN, NULL);
|
||||
obj = nmp_object_new (tap ? NMP_OBJECT_TYPE_LNK_MACVTAP : NMP_OBJECT_TYPE_LNK_MACVLAN, NULL);
|
||||
props = &obj->lnk_macvlan;
|
||||
props->mode = mode;
|
||||
props->mode = nla_get_u32 (tb[IFLA_MACVLAN_MODE]);
|
||||
props->tap = tap;
|
||||
|
||||
if (tb[IFLA_MACVLAN_FLAGS])
|
||||
props->no_promisc = NM_FLAGS_HAS (nla_get_u16 (tb[IFLA_MACVLAN_FLAGS]), MACVLAN_FLAG_NOPROMISC);
|
||||
|
|
@ -1493,6 +1484,7 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||
lnk_data = _parse_lnk_ipip (nl_info_kind, nl_info_data);
|
||||
break;
|
||||
case NM_LINK_TYPE_MACVLAN:
|
||||
case NM_LINK_TYPE_MACVTAP:
|
||||
lnk_data = _parse_lnk_macvlan (nl_info_kind, nl_info_data);
|
||||
break;
|
||||
case NM_LINK_TYPE_SIT:
|
||||
|
|
@ -2907,6 +2899,7 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP
|
|||
case NM_LINK_TYPE_IP6TNL:
|
||||
case NM_LINK_TYPE_INFINIBAND:
|
||||
case NM_LINK_TYPE_MACVLAN:
|
||||
case NM_LINK_TYPE_MACVTAP:
|
||||
case NM_LINK_TYPE_SIT:
|
||||
case NM_LINK_TYPE_VLAN:
|
||||
case NM_LINK_TYPE_VXLAN:
|
||||
|
|
@ -4373,6 +4366,55 @@ nla_put_failure:
|
|||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
link_macvlan_add (NMPlatform *platform,
|
||||
const char *name,
|
||||
int parent,
|
||||
NMPlatformLnkMacvlan *props,
|
||||
NMPlatformLink *out_link)
|
||||
{
|
||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
||||
struct nlattr *info;
|
||||
struct nlattr *data;
|
||||
|
||||
_LOGD ("adding %s '%s' parent %u mode %u",
|
||||
props->tap ? "macvtap" : "macvlan",
|
||||
name,
|
||||
parent,
|
||||
props->mode);
|
||||
|
||||
nlmsg = _nl_msg_new_link (RTM_NEWLINK,
|
||||
NLM_F_CREATE,
|
||||
0,
|
||||
name,
|
||||
0,
|
||||
0);
|
||||
if (!nlmsg)
|
||||
return FALSE;
|
||||
|
||||
NLA_PUT_U32 (nlmsg, IFLA_LINK, parent);
|
||||
|
||||
if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, props->tap ? "macvtap" : "macvlan");
|
||||
|
||||
if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U32 (nlmsg, IFLA_MACVLAN_MODE, props->mode);
|
||||
NLA_PUT_U16 (nlmsg, IFLA_MACVLAN_FLAGS, props->no_promisc ? MACVLAN_FLAG_NOPROMISC : 0);
|
||||
|
||||
nla_nest_end (nlmsg, data);
|
||||
nla_nest_end (nlmsg, info);
|
||||
|
||||
return do_add_link_with_lookup (platform,
|
||||
props->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN,
|
||||
name, nlmsg, out_link);
|
||||
nla_put_failure:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
link_sit_add (NMPlatform *platform,
|
||||
const char *name,
|
||||
|
|
@ -5879,6 +5921,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
|||
|
||||
platform_class->link_gre_add = link_gre_add;
|
||||
platform_class->link_ip6tnl_add = link_ip6tnl_add;
|
||||
platform_class->link_macvlan_add = link_macvlan_add;
|
||||
platform_class->link_ipip_add = link_ipip_add;
|
||||
platform_class->link_sit_add = link_sit_add;
|
||||
|
||||
|
|
|
|||
|
|
@ -1447,6 +1447,12 @@ nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatfor
|
|||
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVLAN, out_link);
|
||||
}
|
||||
|
||||
const NMPlatformLnkMacvtap *
|
||||
nm_platform_link_get_lnk_macvtap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
||||
{
|
||||
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVTAP, out_link);
|
||||
}
|
||||
|
||||
const NMPlatformLnkSit *
|
||||
nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
||||
{
|
||||
|
|
@ -1943,6 +1949,47 @@ nm_platform_link_ipip_add (NMPlatform *self,
|
|||
return NM_PLATFORM_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_macvlan_add:
|
||||
* @self: platform instance
|
||||
* @name: name of the new interface
|
||||
* @props: interface properties
|
||||
* @out_link: on success, the link object
|
||||
*
|
||||
* Create a MACVLAN or MACVTAP device.
|
||||
*/
|
||||
NMPlatformError
|
||||
nm_platform_link_macvlan_add (NMPlatform *self,
|
||||
const char *name,
|
||||
int parent,
|
||||
NMPlatformLnkMacvlan *props,
|
||||
NMPlatformLink *out_link)
|
||||
{
|
||||
NMPlatformError plerr;
|
||||
NMLinkType type;
|
||||
|
||||
_CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG);
|
||||
|
||||
g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG);
|
||||
g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
|
||||
|
||||
type = props->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN;
|
||||
|
||||
plerr = _link_add_check_existing (self, name, type, out_link);
|
||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
|
||||
return plerr;
|
||||
|
||||
_LOGD ("adding %s '%s' parent %u mode %u",
|
||||
props->tap ? "macvtap" : "macvlan",
|
||||
name,
|
||||
parent,
|
||||
props->mode);
|
||||
|
||||
if (!klass->link_macvlan_add (self, name, parent, props, out_link))
|
||||
return NM_PLATFORM_ERROR_UNSPECIFIED;
|
||||
return NM_PLATFORM_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_sit_add:
|
||||
* @self: platform instance
|
||||
|
|
@ -3059,10 +3106,9 @@ nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, g
|
|||
return buf;
|
||||
|
||||
g_snprintf (buf, len,
|
||||
"macvlan%s%s%s",
|
||||
lnk->mode ? " mode " : "",
|
||||
lnk->mode ?: "",
|
||||
lnk->no_promisc ? " not-promisc" : " promisc");
|
||||
"macvlan mode %u %s",
|
||||
lnk->mode,
|
||||
lnk->no_promisc ? "not-promisc" : "promisc");
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
@ -3667,7 +3713,7 @@ int
|
|||
nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b)
|
||||
{
|
||||
_CMP_SELF (a, b);
|
||||
_CMP_FIELD_STR_INTERNED (a, b, mode);
|
||||
_CMP_FIELD (a, b, mode);
|
||||
_CMP_FIELD_BOOL (a, b, no_promisc);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/if_link.h>
|
||||
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "nm-default.h"
|
||||
|
|
@ -399,10 +400,13 @@ typedef struct {
|
|||
} NMPlatformLnkIpIp;
|
||||
|
||||
typedef struct {
|
||||
const char *mode;
|
||||
guint mode;
|
||||
gboolean no_promisc;
|
||||
gboolean tap;
|
||||
} NMPlatformLnkMacvlan;
|
||||
|
||||
typedef NMPlatformLnkMacvlan NMPlatformLnkMacvtap;
|
||||
|
||||
typedef struct {
|
||||
int parent_ifindex;
|
||||
in_addr_t local;
|
||||
|
|
@ -564,6 +568,8 @@ typedef struct {
|
|||
NMPlatformLink *out_link);
|
||||
gboolean (*link_ipip_add) (NMPlatform *, const char *name, NMPlatformLnkIpIp *props,
|
||||
NMPlatformLink *out_link);
|
||||
gboolean (*link_macvlan_add) (NMPlatform *, const char *name, int parent, NMPlatformLnkMacvlan *props,
|
||||
NMPlatformLink *out_link);
|
||||
gboolean (*link_sit_add) (NMPlatform *, const char *name, NMPlatformLnkSit *props,
|
||||
NMPlatformLink *out_link);
|
||||
|
||||
|
|
@ -760,6 +766,7 @@ const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int if
|
|||
const NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkMacvlan *nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkMacvtap *nm_platform_link_get_lnk_macvtap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
|
|
@ -816,6 +823,8 @@ NMPlatformError nm_platform_link_ip6tnl_add (NMPlatform *self, const char *name,
|
|||
NMPlatformLink *out_link);
|
||||
NMPlatformError nm_platform_link_ipip_add (NMPlatform *self, const char *name, NMPlatformLnkIpIp *props,
|
||||
NMPlatformLink *out_link);
|
||||
NMPlatformError nm_platform_link_macvlan_add (NMPlatform *self, const char *name, int parent, NMPlatformLnkMacvlan *props,
|
||||
NMPlatformLink *out_link);
|
||||
NMPlatformError nm_platform_link_sit_add (NMPlatform *self, const char *name, NMPlatformLnkSit *props,
|
||||
NMPlatformLink *out_link);
|
||||
|
||||
|
|
|
|||
|
|
@ -2072,6 +2072,15 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string,
|
||||
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp,
|
||||
},
|
||||
[NMP_OBJECT_TYPE_LNK_MACVTAP - 1] = {
|
||||
.obj_type = NMP_OBJECT_TYPE_LNK_MACVTAP,
|
||||
.sizeof_data = sizeof (NMPObjectLnkMacvtap),
|
||||
.sizeof_public = sizeof (NMPlatformLnkMacvtap),
|
||||
.obj_type_name = "macvtap",
|
||||
.lnk_link_type = NM_LINK_TYPE_MACVTAP,
|
||||
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string,
|
||||
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp,
|
||||
},
|
||||
[NMP_OBJECT_TYPE_LNK_SIT - 1] = {
|
||||
.obj_type = NMP_OBJECT_TYPE_LNK_SIT,
|
||||
.sizeof_data = sizeof (NMPObjectLnkSit),
|
||||
|
|
|
|||
|
|
@ -181,6 +181,8 @@ typedef struct {
|
|||
NMPlatformLnkMacvlan _public;
|
||||
} NMPObjectLnkMacvlan;
|
||||
|
||||
typedef NMPObjectLnkMacvlan NMPObjectLnkMacvtap;
|
||||
|
||||
typedef struct {
|
||||
NMPlatformLnkSit _public;
|
||||
} NMPObjectLnkSit;
|
||||
|
|
|
|||
|
|
@ -774,6 +774,40 @@ nmtstp_link_ipip_add (gboolean external_command, const char *name, NMPlatformLnk
|
|||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmtstp_link_macvlan_add (gboolean external_command, const char *name, int parent, NMPlatformLnkMacvlan *lnk)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
external_command = nmtstp_run_command_check_external (external_command);
|
||||
|
||||
if (external_command) {
|
||||
const char *dev;
|
||||
char *modes[] = {
|
||||
[MACVLAN_MODE_BRIDGE] = "bridge",
|
||||
[MACVLAN_MODE_VEPA] = "vepa",
|
||||
[MACVLAN_MODE_PRIVATE] = "private",
|
||||
[MACVLAN_MODE_PASSTHRU] = "passthru",
|
||||
};
|
||||
|
||||
dev = nm_platform_link_get_name (NM_PLATFORM_GET, parent);
|
||||
g_assert (dev);
|
||||
g_assert_cmpint (lnk->mode, <, G_N_ELEMENTS (modes));
|
||||
|
||||
success = !nmtstp_run_command ("ip link add name %s link %s type %s mode %s %s",
|
||||
name,
|
||||
dev,
|
||||
lnk->tap ? "macvtap" : "macvlan",
|
||||
modes[lnk->mode],
|
||||
lnk->no_promisc ? "nopromisc" : "");
|
||||
if (success)
|
||||
nmtstp_assert_wait_for_link (name, lnk->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN, 100);
|
||||
} else
|
||||
success = nm_platform_link_macvlan_add (NM_PLATFORM_GET, name, parent, lnk, NULL) == NM_PLATFORM_ERROR_SUCCESS;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmtstp_link_sit_add (gboolean external_command, const char *name, NMPlatformLnkSit *lnk)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -144,6 +144,9 @@ gboolean nmtstp_link_ip6tnl_add (gboolean external_command,
|
|||
gboolean nmtstp_link_ipip_add (gboolean external_command,
|
||||
const char *name,
|
||||
NMPlatformLnkIpIp *lnk);
|
||||
gboolean nmtstp_link_macvlan_add (gboolean external_command,
|
||||
const char *name,
|
||||
int parent, NMPlatformLnkMacvlan *lnk);
|
||||
gboolean nmtstp_link_sit_add (gboolean external_command,
|
||||
const char *name,
|
||||
NMPlatformLnkSit *lnk);
|
||||
|
|
|
|||
|
|
@ -740,9 +740,28 @@ test_software_detect (gconstpointer user_data)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_MACVLAN:
|
||||
nmtstp_run_command_check ("ip link add name %s link %s type macvlan", DEVICE_NAME, PARENT_NAME);
|
||||
case NM_LINK_TYPE_MACVLAN: {
|
||||
NMPlatformLnkMacvlan lnk_macvlan = { };
|
||||
|
||||
lnk_macvlan.mode = MACVLAN_MODE_BRIDGE;
|
||||
lnk_macvlan.no_promisc = FALSE;
|
||||
lnk_macvlan.tap = FALSE;
|
||||
|
||||
if (!nmtstp_link_macvlan_add (EX, DEVICE_NAME, ifindex_parent, &lnk_macvlan))
|
||||
g_error ("Failed adding MACVLAN interface");
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_MACVTAP: {
|
||||
NMPlatformLnkMacvtap lnk_macvtap = { };
|
||||
|
||||
lnk_macvtap.mode = MACVLAN_MODE_PRIVATE;
|
||||
lnk_macvtap.no_promisc = FALSE;
|
||||
lnk_macvtap.tap = TRUE;
|
||||
|
||||
if (!nmtstp_link_macvlan_add (EX, DEVICE_NAME, ifindex_parent, &lnk_macvtap))
|
||||
g_error ("Failed adding MACVTAP interface");
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_SIT: {
|
||||
NMPlatformLnkSit lnk_sit = { };
|
||||
gboolean gracefully_skip = FALSE;
|
||||
|
|
@ -867,7 +886,15 @@ test_software_detect (gconstpointer user_data)
|
|||
|
||||
g_assert (plnk == nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, ifindex, NULL));
|
||||
g_assert_cmpint (plnk->no_promisc, ==, FALSE);
|
||||
g_assert_cmpstr (plnk->mode, ==, "vepa");
|
||||
g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_BRIDGE);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_MACVTAP: {
|
||||
const NMPlatformLnkMacvtap *plnk = &lnk->lnk_macvlan;
|
||||
|
||||
g_assert (plnk == nm_platform_link_get_lnk_macvtap (NM_PLATFORM_GET, ifindex, NULL));
|
||||
g_assert_cmpint (plnk->no_promisc, ==, FALSE);
|
||||
g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_PRIVATE);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_SIT: {
|
||||
|
|
@ -1703,6 +1730,7 @@ setup_tests (void)
|
|||
test_software_detect_add ("/link/software/detect/ip6tnl", NM_LINK_TYPE_IP6TNL, 0);
|
||||
test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0);
|
||||
test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0);
|
||||
test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0);
|
||||
test_software_detect_add ("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0);
|
||||
test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0);
|
||||
test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue