merge: vxlan devices creation support

https://bugzilla.gnome.org/show_bug.cgi?id=756963
This commit is contained in:
Beniamino Galvani 2015-12-09 16:37:05 +01:00
commit efd5515f96
32 changed files with 3085 additions and 53 deletions

View file

@ -120,6 +120,7 @@ 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[];
extern NmcOutputField nmc_fields_setting_vxlan[];
/* Available settings for 'connection show <con>' - profile part */
static NmcOutputField nmc_fields_settings_names[] = {
@ -151,6 +152,7 @@ static NmcOutputField nmc_fields_settings_names[] = {
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 */
SETTING_FIELD (NM_SETTING_VXLAN_SETTING_NAME, nmc_fields_setting_vxlan + 1), /* 28 */
{NULL, NULL, 0, NULL, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTINGS_NAMES_ALL_X NM_SETTING_CONNECTION_SETTING_NAME","\
@ -179,7 +181,8 @@ static NmcOutputField nmc_fields_settings_names[] = {
NM_SETTING_DCB_SETTING_NAME"," \
NM_SETTING_TUN_SETTING_NAME"," \
NM_SETTING_IP_TUNNEL_SETTING_NAME"," \
NM_SETTING_MACVLAN_SETTING_NAME
NM_SETTING_MACVLAN_SETTING_NAME"," \
NM_SETTING_VXLAN_SETTING_NAME
#define NMC_FIELDS_SETTINGS_NAMES_ALL NMC_FIELDS_SETTINGS_NAMES_ALL_X
/* Active connection data */
@ -429,6 +432,13 @@ usage_connection_add (void)
" macvlan: dev <parent device (connection UUID, ifname, or MAC)>\n"
" mode vepa|bridge|private|passthru|source\n"
" [tap yes|no]\n\n"
" vxlan: id <VXLAN ID>\n"
" remote <IP of multicast group or remote address>\n"
" [dev <parent device (ifname or connection UUID)>]\n"
" [local <source IP>]\n"
" [source-port-min <0-65535>]\n"
" [source-port-max <0-65535>]\n"
" [destination-port <0-65535>]\n\n"
" SLAVE_OPTIONS:\n"
" bridge: [priority <0-63>]\n"
" [path-cost <1-65535>]\n"
@ -2826,6 +2836,14 @@ static const NameItem nmc_macvlan_settings [] = {
{ NULL, NULL, NULL, FALSE }
};
static const NameItem nmc_vxlan_settings [] = {
{ NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE },
{ NM_SETTING_VXLAN_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 },
@ -2850,6 +2868,7 @@ static const NameItem nmc_valid_connection_types[] = {
{ 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 },
{ NM_SETTING_VXLAN_SETTING_NAME, NULL, nmc_vxlan_settings },
{ NULL, NULL, NULL }
};
@ -4222,7 +4241,6 @@ do_questionnaire_adsl (gboolean echo, char **password, char **encapsulation)
}
}
static void
do_questionnaire_macvlan (char **tap)
{
@ -4249,6 +4267,85 @@ do_questionnaire_macvlan (char **tap)
}
}
static void
do_questionnaire_vxlan (char **parent, char **local, char **src_port_min,
char **src_port_max, char **dst_port)
{
unsigned long tmp;
gboolean once_more;
/* Ask for optional 'vxlan' arguments. */
if (!want_provide_opt_args (_("VXLAN"), 4))
return;
if (!*parent) {
do {
*parent = nmc_readline (_("Parent device [none]: "));
once_more = *parent
&& !nm_utils_is_uuid (*parent)
&& !nm_utils_iface_valid_name (*parent);
if (once_more) {
g_print (_("Error: 'dev': '%s' is neither UUID nor interface name.\n"),
*parent);
g_free (*parent);
}
} while (once_more);
}
if (!*local) {
do {
*local = nmc_readline (_("Local address [none]: "));
once_more = *local
&& !nm_utils_ipaddr_valid (AF_INET, *local)
&& !nm_utils_ipaddr_valid (AF_INET6, *local);
if (once_more) {
g_print (_("Error: 'local': '%s' is not a valid IP address.\n"),
*local);
g_free (*local);
}
} while (once_more);
}
if (!*src_port_min) {
do {
*src_port_min = nmc_readline (_("Minimum source port [0]: "));
*src_port_min = *src_port_min ? *src_port_min : g_strdup ("0");
once_more = !nmc_string_to_uint (*src_port_min, TRUE, 0, 65535, &tmp);
if (once_more) {
g_print (_("Error: 'source-port-min': '%s' is not a valid number <0-65535>.\n"),
*src_port_min);
g_free (*src_port_min);
}
} while (once_more);
}
if (!*src_port_max) {
do {
*src_port_max = nmc_readline (_("Maximum source port [0]: "));
*src_port_max = *src_port_max ? *src_port_max : g_strdup ("0");
once_more = !nmc_string_to_uint (*src_port_max, TRUE, 0, 65535, &tmp);
if (once_more) {
g_print (_("Error: 'source-port-max': '%s' is not a valid number <0-65535>.\n"),
*src_port_max);
g_free (*src_port_max);
}
} while (once_more);
}
if (!*dst_port) {
do {
*dst_port = nmc_readline (_("Destination port [8472]: "));
*dst_port = *dst_port ? *dst_port : g_strdup ("8472");
once_more = !nmc_string_to_uint (*dst_port, TRUE, 0, 65535, &tmp);
if (once_more) {
g_print (_("Error: 'destination-port': '%s' is not a valid number <0-65535>.\n"),
*dst_port);
g_free (*dst_port);
}
} while (once_more);
}
}
static gboolean
split_address (char* str, char **ip, char **rest)
{
@ -4720,6 +4817,7 @@ complete_connection_by_type (NMConnection *connection,
NMSettingTun *s_tun;
NMSettingIPTunnel *s_ip_tunnel;
NMSettingMacvlan *s_macvlan;
NMSettingVxlan *s_vxlan;
const char *slave_type;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@ -6119,6 +6217,144 @@ cleanup_tun:
cleanup_tunnel:
g_free (remote_ask);
g_free (mode_ask);
} else if (!strcmp (con_type, NM_SETTING_VXLAN_SETTING_NAME)) {
/* Build up the settings required for 'vxlan' */
gboolean success = FALSE;
char *id_ask = NULL;
const char *id = NULL;
char *remote_ask = NULL;
const char *remote = NULL;
const char *parent_c = NULL, *local_c = NULL;
const char *src_port_min_c = NULL, *src_port_max_c = NULL;
const char *dst_port_c = NULL;
char *parent = NULL, *local = NULL;
char *src_port_min = NULL, *src_port_max = NULL, *dst_port = NULL;
unsigned long int vni;
unsigned long sport_min = G_MAXULONG, sport_max = G_MAXULONG;
unsigned long dport = G_MAXULONG;
nmc_arg_t exp_args[] = { {"id", TRUE, &id, !ask},
{"remote", TRUE, &remote, !ask},
{"dev", TRUE, &parent_c, FALSE},
{"local", TRUE, &local_c, FALSE},
{"source-port-min", TRUE, &src_port_min_c, FALSE},
{"source-port-max", TRUE, &src_port_max_c, FALSE},
{"destination-port", TRUE, &dst_port_c, FALSE},
{NULL} };
if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error))
return FALSE;
if (!id && ask)
id = id_ask = nmc_readline (_("VXLAN ID: "));
if (!id) {
g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'id' is required."));
goto cleanup_vxlan;
}
if (!remote && ask)
remote = remote_ask = nmc_readline (_("Remote: "));
if (!remote) {
g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'remote' is required."));
goto cleanup_vxlan;
}
if (!nmc_string_to_uint (id, TRUE, 0, (1UL << 24) - 1, &vni)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'id': '%s' is not valid; use <0-16777215>."), id);
goto cleanup_vxlan;
}
parent = g_strdup (parent_c);
local = g_strdup (local_c);
src_port_min = g_strdup (src_port_min_c);
src_port_max = g_strdup (src_port_max_c);
dst_port = g_strdup (dst_port_c);
if (ask)
do_questionnaire_vxlan (&parent, &local, &src_port_min, &src_port_max, &dst_port);
if (parent) {
if ( !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 nor interface name."),
parent);
goto cleanup_vxlan;
}
}
if ( !nm_utils_ipaddr_valid (AF_INET, remote)
&& !nm_utils_ipaddr_valid (AF_INET6, remote)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'remote': '%s' is not a valid IP address"),
remote);
goto cleanup_vxlan;
}
if (local) {
if ( !nm_utils_ipaddr_valid (AF_INET, local)
&& !nm_utils_ipaddr_valid (AF_INET6, local)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'local': '%s' is not a valid IP address"),
local);
goto cleanup_vxlan;
}
}
if (src_port_min) {
if (!nmc_string_to_uint (src_port_min, TRUE, 0, 65535, &sport_min)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'source-port-min': %s is not valid; use <0-65535>."),
src_port_min);
goto cleanup_vxlan;
}
}
if (src_port_max) {
if (!nmc_string_to_uint (src_port_max, TRUE, 0, 65535, &sport_max)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'source-port-max': %s is not valid; use <0-65535>."),
src_port_max);
goto cleanup_vxlan;
}
}
if (dst_port) {
if (!nmc_string_to_uint (dst_port, TRUE, 0, 65535, &dport)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'destination-port': %s is not valid; use <0-65535>."),
dst_port);
goto cleanup_vxlan;
}
}
/* Add 'vxlan' setting */
s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new ();
nm_connection_add_setting (connection, NM_SETTING (s_vxlan));
g_object_set (s_vxlan, NM_SETTING_VXLAN_ID, (guint) vni, NULL);
g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE, remote, NULL);
g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL, local, NULL);
g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, parent, NULL);
if (sport_min != G_MAXULONG)
g_object_set (s_vxlan, NM_SETTING_VXLAN_SOURCE_PORT_MIN, sport_min, NULL);
if (sport_max != G_MAXULONG)
g_object_set (s_vxlan, NM_SETTING_VXLAN_SOURCE_PORT_MAX, sport_max, NULL);
if (dport != G_MAXULONG)
g_object_set (s_vxlan, NM_SETTING_VXLAN_DESTINATION_PORT, dport, NULL);
success = TRUE;
cleanup_vxlan:
g_free (id_ask);
g_free (remote_ask);
g_free (parent);
g_free (local);
g_free (src_port_min);
g_free (src_port_max);
if (!success)
return FALSE;

View file

@ -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 macvlan"
_nmcli_list "ethernet wifi wimax gsm cdma infiniband bluetooth vpn olpc-mesh vlan bond bridge team pppoe adsl tun ip-tunnel macvlan vxlan"
fi
return 0
fi

View file

@ -764,6 +764,46 @@ NmcOutputField nmc_fields_setting_macvlan[] = {
NM_SETTING_MACVLAN_TAP
#define NMC_FIELDS_SETTING_MACVLAN_COMMON NMC_FIELDS_SETTING_MACVLAN_ALL
/* Available fields for NM_SETTING_VXLAN_SETTING_NAME */
NmcOutputField nmc_fields_setting_vxlan[] = {
SETTING_FIELD ("name"), /* 0 */
SETTING_FIELD (NM_SETTING_VXLAN_PARENT), /* 1 */
SETTING_FIELD (NM_SETTING_VXLAN_ID), /* 2 */
SETTING_FIELD (NM_SETTING_VXLAN_LOCAL), /* 3 */
SETTING_FIELD (NM_SETTING_VXLAN_REMOTE), /* 4 */
SETTING_FIELD (NM_SETTING_VXLAN_SOURCE_PORT_MIN), /* 5 */
SETTING_FIELD (NM_SETTING_VXLAN_SOURCE_PORT_MAX), /* 6 */
SETTING_FIELD (NM_SETTING_VXLAN_DESTINATION_PORT), /* 7 */
SETTING_FIELD (NM_SETTING_VXLAN_TOS), /* 8 */
SETTING_FIELD (NM_SETTING_VXLAN_TTL), /* 9 */
SETTING_FIELD (NM_SETTING_VXLAN_AGEING), /* 10 */
SETTING_FIELD (NM_SETTING_VXLAN_LIMIT), /* 11 */
SETTING_FIELD (NM_SETTING_VXLAN_LEARNING), /* 12 */
SETTING_FIELD (NM_SETTING_VXLAN_PROXY), /* 13 */
SETTING_FIELD (NM_SETTING_VXLAN_RSC), /* 14 */
SETTING_FIELD (NM_SETTING_VXLAN_L2_MISS), /* 15 */
SETTING_FIELD (NM_SETTING_VXLAN_L3_MISS), /* 16 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_VXLAN_ALL "name"","\
NM_SETTING_VXLAN_PARENT","\
NM_SETTING_VXLAN_ID","\
NM_SETTING_VXLAN_LOCAL","\
NM_SETTING_VXLAN_REMOTE","\
NM_SETTING_VXLAN_SOURCE_PORT_MIN","\
NM_SETTING_VXLAN_SOURCE_PORT_MAX","\
NM_SETTING_VXLAN_DESTINATION_PORT","\
NM_SETTING_VXLAN_TOS","\
NM_SETTING_VXLAN_TTL","\
NM_SETTING_VXLAN_AGEING","\
NM_SETTING_VXLAN_LIMIT","\
NM_SETTING_VXLAN_LEARNING","\
NM_SETTING_VXLAN_PROXY","\
NM_SETTING_VXLAN_RSC","\
NM_SETTING_VXLAN_L2_MISS","\
NM_SETTING_VXLAN_L3_MISS
#define NMC_FIELDS_SETTING_VXLAN_COMMON NMC_FIELDS_SETTING_VXLAN_ALL
/*----------------------------------------------------------------------------*/
static char *
wep_key_type_to_string (NMWepKeyType type)
@ -1937,6 +1977,24 @@ nmc_property_macvlan_set_mode (NMSetting *setting, const char *prop,
return TRUE;
}
/* --- NM_SETTING_VXLAN_SETTING_NAME property get functions --- */
DEFINE_GETTER (nmc_property_vxlan_get_parent, NM_SETTING_VXLAN_PARENT)
DEFINE_GETTER (nmc_property_vxlan_get_id, NM_SETTING_VXLAN_ID)
DEFINE_GETTER (nmc_property_vxlan_get_local, NM_SETTING_VXLAN_LOCAL)
DEFINE_GETTER (nmc_property_vxlan_get_remote, NM_SETTING_VXLAN_REMOTE)
DEFINE_GETTER (nmc_property_vxlan_get_source_port_min, NM_SETTING_VXLAN_SOURCE_PORT_MIN)
DEFINE_GETTER (nmc_property_vxlan_get_source_port_max, NM_SETTING_VXLAN_SOURCE_PORT_MAX)
DEFINE_GETTER (nmc_property_vxlan_get_destination_port, NM_SETTING_VXLAN_DESTINATION_PORT)
DEFINE_GETTER (nmc_property_vxlan_get_tos, NM_SETTING_VXLAN_TOS)
DEFINE_GETTER (nmc_property_vxlan_get_ttl, NM_SETTING_VXLAN_TTL)
DEFINE_GETTER (nmc_property_vxlan_get_ageing, NM_SETTING_VXLAN_AGEING)
DEFINE_GETTER (nmc_property_vxlan_get_limit, NM_SETTING_VXLAN_LIMIT)
DEFINE_GETTER (nmc_property_vxlan_get_learning, NM_SETTING_VXLAN_LEARNING)
DEFINE_GETTER (nmc_property_vxlan_get_proxy, NM_SETTING_VXLAN_PROXY)
DEFINE_GETTER (nmc_property_vxlan_get_rsc, NM_SETTING_VXLAN_RSC)
DEFINE_GETTER (nmc_property_vxlan_get_l2_miss, NM_SETTING_VXLAN_L2_MISS)
DEFINE_GETTER (nmc_property_vxlan_get_l3_miss, NM_SETTING_VXLAN_L3_MISS)
/*----------------------------------------------------------------------------*/
static void
@ -7332,6 +7390,120 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
/* Add editable properties for NM_SETTING_VXLAN_SETTING_NAME */
nmc_add_prop_funcs (GLUE (VXLAN, PARENT),
nmc_property_vxlan_get_parent,
nmc_property_set_string,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, ID),
nmc_property_vxlan_get_id,
nmc_property_set_uint,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, LOCAL),
nmc_property_vxlan_get_local,
nmc_property_set_string,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, REMOTE),
nmc_property_vxlan_get_remote,
nmc_property_set_string,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, SOURCE_PORT_MIN),
nmc_property_vxlan_get_source_port_min,
nmc_property_set_uint,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, SOURCE_PORT_MAX),
nmc_property_vxlan_get_source_port_max,
nmc_property_set_uint,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, DESTINATION_PORT),
nmc_property_vxlan_get_destination_port,
nmc_property_set_uint,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, TOS),
nmc_property_vxlan_get_tos,
nmc_property_set_uint,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, TTL),
nmc_property_vxlan_get_ttl,
nmc_property_set_uint,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, AGEING),
nmc_property_vxlan_get_ageing,
nmc_property_set_uint,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, LIMIT),
nmc_property_vxlan_get_limit,
nmc_property_set_uint,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, LEARNING),
nmc_property_vxlan_get_learning,
nmc_property_set_bool,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, PROXY),
nmc_property_vxlan_get_proxy,
nmc_property_set_bool,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, RSC),
nmc_property_vxlan_get_rsc,
nmc_property_set_bool,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, L2_MISS),
nmc_property_vxlan_get_l2_miss,
nmc_property_set_bool,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (VXLAN, L3_MISS),
nmc_property_vxlan_get_l3_miss,
nmc_property_set_bool,
NULL,
NULL,
NULL,
NULL);
}
void
@ -8577,6 +8749,47 @@ setting_macvlan_details (NMSetting *setting, NmCli *nmc, const char *one_prop,
return TRUE;
}
static gboolean
setting_vxlan_details (NMSetting *setting, NmCli *nmc, const char *one_prop, gboolean secrets)
{
NMSettingVxlan *s_vxlan = NM_SETTING_VXLAN (setting);
NmcOutputField *tmpl, *arr;
size_t tmpl_len;
g_return_val_if_fail (NM_IS_SETTING_VXLAN (s_vxlan), FALSE);
tmpl = nmc_fields_setting_vxlan;
tmpl_len = sizeof (nmc_fields_setting_vxlan);
nmc->print_fields.indices = parse_output_fields (one_prop ? one_prop : NMC_FIELDS_SETTING_VXLAN_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_vxlan_get_parent (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 2, nmc_property_vxlan_get_id (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 3, nmc_property_vxlan_get_local (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 4, nmc_property_vxlan_get_remote (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 5, nmc_property_vxlan_get_source_port_min (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 6, nmc_property_vxlan_get_source_port_max (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 7, nmc_property_vxlan_get_destination_port (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 8, nmc_property_vxlan_get_tos (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 9, nmc_property_vxlan_get_ttl (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 10, nmc_property_vxlan_get_ageing (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 11, nmc_property_vxlan_get_limit (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 12, nmc_property_vxlan_get_learning (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 13, nmc_property_vxlan_get_proxy (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 14, nmc_property_vxlan_get_rsc (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 15, nmc_property_vxlan_get_l2_miss (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 16, nmc_property_vxlan_get_l3_miss (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);
@ -8611,6 +8824,7 @@ static const SettingDetails detail_printers[] = {
{ 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 },
{ NM_SETTING_VXLAN_SETTING_NAME, setting_vxlan_details },
{ NULL },
};

View file

@ -10,6 +10,12 @@
</tp:docstring>
</property>
<property name="HwAddress" type="s" access="read">
<tp:docstring>
Hardware address of the device.
</tp:docstring>
</property>
<property name="Id" type="u" access="read">
<tp:docstring>
The VXLAN Network Identifier (VNI).

View file

@ -38,6 +38,7 @@ libnm_core_headers = \
$(core)/nm-setting-tun.h \
$(core)/nm-setting-vlan.h \
$(core)/nm-setting-vpn.h \
$(core)/nm-setting-vxlan.h \
$(core)/nm-setting-wimax.h \
$(core)/nm-setting-wired.h \
$(core)/nm-setting-wireless-security.h \
@ -97,6 +98,7 @@ libnm_core_sources = \
$(core)/nm-setting-tun.c \
$(core)/nm-setting-vlan.c \
$(core)/nm-setting-vpn.c \
$(core)/nm-setting-vxlan.c \
$(core)/nm-setting-wimax.c \
$(core)/nm-setting-wired.c \
$(core)/nm-setting-wireless-security.c \

View file

@ -1597,7 +1597,8 @@ nm_connection_is_virtual (NMConnection *connection)
|| !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_MACVLAN_SETTING_NAME))
|| !strcmp (type, NM_SETTING_MACVLAN_SETTING_NAME)
|| !strcmp (type, NM_SETTING_VXLAN_SETTING_NAME))
return TRUE;
if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) {
@ -2022,6 +2023,24 @@ nm_connection_get_setting_vpn (NMConnection *connection)
return (NMSettingVpn *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
}
/**
* nm_connection_get_setting_vxlan:
* @connection: the #NMConnection
*
* A shortcut to return any #NMSettingVxlan the connection might contain.
*
* Returns: (transfer none): an #NMSettingVxlan if the connection contains one, otherwise %NULL
*
* Since: 1.2
**/
NMSettingVxlan *
nm_connection_get_setting_vxlan (NMConnection *connection)
{
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
return (NMSettingVxlan *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VXLAN);
}
/**
* nm_connection_get_setting_wimax:
* @connection: the #NMConnection

View file

@ -220,6 +220,8 @@ NMSettingWired * nm_connection_get_setting_wired (NMConnec
NMSettingWireless * nm_connection_get_setting_wireless (NMConnection *connection);
NMSettingWirelessSecurity *nm_connection_get_setting_wireless_security (NMConnection *connection);
NMSettingVlan * nm_connection_get_setting_vlan (NMConnection *connection);
NM_AVAILABLE_IN_1_2
NMSettingVxlan * nm_connection_get_setting_vxlan (NMConnection *connection);
G_END_DECLS

View file

@ -62,6 +62,7 @@
#include "nm-setting-tun.h"
#include "nm-setting-vlan.h"
#include "nm-setting-vpn.h"
#include "nm-setting-vxlan.h"
#include "nm-setting-wimax.h"
#include "nm-setting-wired.h"
#include "nm-setting-wireless-security.h"

View file

@ -55,6 +55,7 @@ typedef struct _NMSettingTeamPort NMSettingTeamPort;
typedef struct _NMSettingTun NMSettingTun;
typedef struct _NMSettingVlan NMSettingVlan;
typedef struct _NMSettingVpn NMSettingVpn;
typedef struct _NMSettingVxlan NMSettingVxlan;
typedef struct _NMSettingWimax NMSettingWimax;
typedef struct _NMSettingWired NMSettingWired;
typedef struct _NMSettingWireless NMSettingWireless;

View file

@ -151,6 +151,7 @@ typedef enum {
* @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
* @NM_DEVICE_TYPE_VXLAN: a VXLAN interface
*
* #NMDeviceType values indicate the type of hardware represented by
* an #NMDevice.
@ -177,6 +178,7 @@ typedef enum {
NM_DEVICE_TYPE_TUN = 16,
NM_DEVICE_TYPE_IP_TUNNEL = 17,
NM_DEVICE_TYPE_MACVLAN = 18,
NM_DEVICE_TYPE_VXLAN = 19,
} NMDeviceType;
/**

View file

@ -0,0 +1,843 @@
/* -*- 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-vxlan.h"
#include "nm-utils.h"
#include "nm-setting-private.h"
/**
* SECTION:nm-setting-vxlan
* @short_description: Describes connection properties for VXLAN interfaces
*
* The #NMSettingVxlan object is a #NMSetting subclass that describes properties
* necessary for connection to VXLAN interfaces.
**/
G_DEFINE_TYPE_WITH_CODE (NMSettingVxlan, nm_setting_vxlan, NM_TYPE_SETTING,
_nm_register_setting (VXLAN, 1))
NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_VXLAN)
#define NM_SETTING_VXLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VXLAN, NMSettingVxlanPrivate))
typedef struct {
char *parent;
guint id;
char *local;
char *remote;
guint source_port_min;
guint source_port_max;
guint destination_port;
guint tos;
guint ttl;
guint ageing;
guint limit;
gboolean learning;
gboolean proxy;
gboolean rsc;
gboolean l2_miss;
gboolean l3_miss;
} NMSettingVxlanPrivate;
enum {
PROP_0,
PROP_PARENT,
PROP_ID,
PROP_LOCAL,
PROP_REMOTE,
PROP_SOURCE_PORT_MIN,
PROP_SOURCE_PORT_MAX,
PROP_DESTINATION_PORT,
PROP_TOS,
PROP_TTL,
PROP_AGEING,
PROP_LIMIT,
PROP_LEARNING,
PROP_PROXY,
PROP_RSC,
PROP_L2_MISS,
PROP_L3_MISS,
LAST_PROP
};
#define DST_PORT_DEFAULT 8472
/**
* nm_setting_vxlan_new:
*
* Creates a new #NMSettingVxlan object with default values.
*
* Returns: (transfer full): the new empty #NMSettingVxlan object
*
* Since: 1.2
**/
NMSetting *
nm_setting_vxlan_new (void)
{
return (NMSetting *) g_object_new (NM_TYPE_SETTING_VXLAN, NULL);
}
/**
* nm_setting_vxlan_get_parent:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:parent property of the setting
*
* Since: 1.2
**/
const char *
nm_setting_vxlan_get_parent (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), NULL);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->parent;
}
/**
* nm_setting_vxlan_get_id:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:id property of the setting
*
* Since: 1.2
**/
guint
nm_setting_vxlan_get_id (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->id;
}
/**
* nm_setting_vxlan_get_local:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:local property of the setting
*
* Since: 1.2
**/
const char *
nm_setting_vxlan_get_local (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), NULL);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->local;
}
/**
* nm_setting_vxlan_get_remote:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:remote property of the setting
*
* Since: 1.2
**/
const char *
nm_setting_vxlan_get_remote (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), NULL);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->remote;
}
/**
* nm_setting_vxlan_get_source_port_min:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:source-port-min property of the setting
*
* Since: 1.2
**/
guint
nm_setting_vxlan_get_source_port_min (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->source_port_min;
}
/**
* nm_setting_vxlan_get_source_port_max:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:source-port-max property of the setting
*
* Since: 1.2
**/
guint
nm_setting_vxlan_get_source_port_max (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->source_port_max;
}
/**
* nm_setting_vxlan_get_destination_port:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:destination-port property of the setting
*
* Since: 1.2
**/
guint
nm_setting_vxlan_get_destination_port (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), DST_PORT_DEFAULT);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->destination_port;
}
/**
* nm_setting_vxlan_get_proxy:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:proxy property of the setting
*
* Since: 1.2
**/
gboolean
nm_setting_vxlan_get_proxy (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->proxy;
}
/**
* nm_setting_vxlan_get_ageing:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:ageing property of the setting
*
* Since: 1.2
**/
guint
nm_setting_vxlan_get_ageing (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->ageing;
}
/**
* nm_setting_vxlan_get_limit:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:limit property of the setting
*
* Since: 1.2
**/
guint
nm_setting_vxlan_get_limit (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->limit;
}
/**
* nm_setting_vxlan_get_tos:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:tos property of the setting
*
* Since: 1.2
**/
guint
nm_setting_vxlan_get_tos (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->tos;
}
/**
* nm_setting_vxlan_get_ttl:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:ttl property of the setting
*
* Since: 1.2
**/
guint
nm_setting_vxlan_get_ttl (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), 0);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->ttl;
}
/**
* nm_setting_vxlan_get_learning:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:learning property of the setting
*
* Since: 1.2
**/
gboolean
nm_setting_vxlan_get_learning (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->learning;
}
/**
* nm_setting_vxlan_get_rsc:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:rsc property of the setting
*
* Since: 1.2
**/
gboolean
nm_setting_vxlan_get_rsc (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->rsc;
}
/**
* nm_setting_vxlan_get_l2_miss:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:l2_miss property of the setting
*
* Since: 1.2
**/
gboolean
nm_setting_vxlan_get_l2_miss (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->l2_miss;
}
/**
* nm_setting_vxlan_get_l3_miss:
* @setting: the #NMSettingVxlan
*
* Returns: the #NMSettingVxlan:l3_miss property of the setting
*
* Since: 1.2
**/
gboolean
nm_setting_vxlan_get_l3_miss (NMSettingVxlan *setting)
{
g_return_val_if_fail (NM_IS_SETTING_VXLAN (setting), FALSE);
return NM_SETTING_VXLAN_GET_PRIVATE (setting)->l3_miss;
}
/*********************************************************************/
static void
nm_setting_vxlan_init (NMSettingVxlan *setting)
{
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting);
int family = AF_UNSPEC;
if (!priv->remote) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ",
NM_SETTING_VXLAN_SETTING_NAME,
NM_SETTING_VXLAN_REMOTE);
return FALSE;
}
if (nm_utils_ipaddr_valid (AF_INET, priv->remote))
family = AF_INET;
else if (nm_utils_ipaddr_valid (AF_INET6, priv->remote))
family = AF_INET6;
else {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid IP address"),
priv->remote);
g_prefix_error (error, "%s.%s: ",
NM_SETTING_VXLAN_SETTING_NAME,
NM_SETTING_VXLAN_REMOTE);
return FALSE;
}
if (priv->local) {
if (!nm_utils_ipaddr_valid (family, priv->local)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid IP%c address"),
priv->local, family == AF_INET ? '4' : '6');
g_prefix_error (error, "%s.%s: ",
NM_SETTING_VXLAN_SETTING_NAME,
NM_SETTING_VXLAN_LOCAL);
return FALSE;
}
}
if ( priv->parent
&& !nm_utils_iface_valid_name (priv->parent)
&& !nm_utils_is_uuid (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_VXLAN_SETTING_NAME,
NM_SETTING_VXLAN_PARENT);
return FALSE;
}
if ( (priv->source_port_min || priv->source_port_max)
&& (priv->source_port_min > priv->source_port_max)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("%d is greater than local port max %d"),
priv->source_port_min,
priv->source_port_max);
g_prefix_error (error, "%s.%s: ",
NM_SETTING_VXLAN_SETTING_NAME,
NM_SETTING_VXLAN_SOURCE_PORT_MIN);
return FALSE;
}
return TRUE;
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMSettingVxlan *setting = NM_SETTING_VXLAN (object);
NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting);
switch (prop_id) {
case PROP_PARENT:
g_free (priv->parent);
priv->parent = g_value_dup_string (value);
break;
case PROP_ID:
priv->id = g_value_get_uint (value);
break;
case PROP_LOCAL:
g_free (priv->local);
priv->local = g_value_dup_string (value);
break;
case PROP_REMOTE:
g_free (priv->remote);
priv->remote = g_value_dup_string (value);
break;
case PROP_SOURCE_PORT_MIN:
priv->source_port_min = g_value_get_uint (value);
break;
case PROP_SOURCE_PORT_MAX:
priv->source_port_max = g_value_get_uint (value);
break;
case PROP_DESTINATION_PORT:
priv->destination_port = g_value_get_uint (value);
break;
case PROP_TOS:
priv->tos = g_value_get_uint (value);
break;
case PROP_AGEING:
priv->ageing = g_value_get_uint (value);
break;
case PROP_LIMIT:
priv->limit = g_value_get_uint (value);
break;
case PROP_PROXY:
priv->proxy = g_value_get_boolean (value);
break;
case PROP_TTL:
priv->ttl = g_value_get_uint (value);
break;
case PROP_LEARNING:
priv->learning = g_value_get_boolean (value);
break;
case PROP_RSC:
priv->rsc = g_value_get_boolean (value);
break;
case PROP_L2_MISS:
priv->l2_miss = g_value_get_boolean (value);
break;
case PROP_L3_MISS:
priv->l3_miss = 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)
{
NMSettingVxlan *setting = NM_SETTING_VXLAN (object);
NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting);
switch (prop_id) {
case PROP_PARENT:
g_value_set_string (value, priv->parent);
break;
case PROP_ID:
g_value_set_uint (value, priv->id);
break;
case PROP_LOCAL:
g_value_set_string (value, priv->local);
break;
case PROP_REMOTE:
g_value_set_string (value, priv->remote);
break;
case PROP_SOURCE_PORT_MIN:
g_value_set_uint (value, priv->source_port_min);
break;
case PROP_SOURCE_PORT_MAX:
g_value_set_uint (value, priv->source_port_max);
break;
case PROP_DESTINATION_PORT:
g_value_set_uint (value, priv->destination_port);
break;
case PROP_TOS:
g_value_set_uint (value, priv->tos);
break;
case PROP_AGEING:
g_value_set_uint (value, priv->ageing);
break;
case PROP_LIMIT:
g_value_set_uint (value, priv->limit);
break;
case PROP_PROXY:
g_value_set_boolean (value, priv->proxy);
break;
case PROP_TTL:
g_value_set_uint (value, priv->ttl);
break;
case PROP_LEARNING:
g_value_set_boolean (value, priv->learning);
break;
case PROP_RSC:
g_value_set_boolean (value, priv->rsc);
break;
case PROP_L2_MISS:
g_value_set_boolean (value, priv->l2_miss);
break;
case PROP_L3_MISS:
g_value_set_boolean (value, priv->l3_miss);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
finalize (GObject *object)
{
NMSettingVxlan *setting = NM_SETTING_VXLAN (object);
NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting);
g_free (priv->parent);
g_free (priv->local);
g_free (priv->remote);
G_OBJECT_CLASS (nm_setting_vxlan_parent_class)->finalize (object);
}
static void
nm_setting_vxlan_class_init (NMSettingVxlanClass *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 (NMSettingVxlanPrivate));
/* virtual methods */
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
/* Properties */
/**
* NMSettingVxlan:parent:
*
* If given, specifies the parent interface name or parent connection UUID.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_PARENT,
g_param_spec_string (NM_SETTING_VXLAN_PARENT, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:id:
*
* Specifies the VXLAN Network Identifer (or VXLAN Segment Identifier) to
* use.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_ID,
g_param_spec_uint (NM_SETTING_VXLAN_ID, "", "",
0, (1 << 24) - 1, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:local:
*
* If given, specifies the source IP address to use in outgoing packets.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_LOCAL,
g_param_spec_string (NM_SETTING_VXLAN_LOCAL, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:remote:
*
* Specifies the unicast destination IP address to use in outgoing packets
* when the destination link layer address is not known in the VXLAN device
* forwarding database, or the multicast IP address to join.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_REMOTE,
g_param_spec_string (NM_SETTING_VXLAN_REMOTE, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:source-port-min:
*
* Specifies the minimum UDP source port to communicate to the remote VXLAN
* tunnel endpoint.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_SOURCE_PORT_MIN,
g_param_spec_uint (NM_SETTING_VXLAN_SOURCE_PORT_MIN, "", "",
0, G_MAXUINT16, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:source-port-max:
*
* Specifies the maximum UDP source port to communicate to the remote VXLAN
* tunnel endpoint.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_SOURCE_PORT_MAX,
g_param_spec_uint (NM_SETTING_VXLAN_SOURCE_PORT_MAX, "", "",
0, G_MAXUINT16, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:destination-port:
*
* Specifies the UDP destination port to communicate to the remote VXLAN
* tunnel endpoint.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_DESTINATION_PORT,
g_param_spec_uint (NM_SETTING_VXLAN_DESTINATION_PORT, "", "",
0, G_MAXUINT16, DST_PORT_DEFAULT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:ageing:
*
* Specifies the lifetime in seconds of FDB entries learnt by the kernel.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_AGEING,
g_param_spec_uint (NM_SETTING_VXLAN_AGEING, "", "",
0, G_MAXINT32, 300,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:limit:
*
* Specifies the maximum number of FDB entries. A value of zero means that
* the kernel will store unlimited entries.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_AGEING,
g_param_spec_uint (NM_SETTING_VXLAN_LIMIT, "", "",
0, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:tos:
*
* Specifies the TOS value to use in outgoing packets.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_TOS,
g_param_spec_uint (NM_SETTING_VXLAN_TOS, "", "",
0, 255, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:ttl:
*
* Specifies the time-to-live value to use in outgoing packets.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_TTL,
g_param_spec_uint (NM_SETTING_VXLAN_TTL, "", "",
0, 255, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:proxy:
*
* Specifies whether ARP proxy is turned on.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_PROXY,
g_param_spec_boolean (NM_SETTING_VXLAN_PROXY, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:learning:
*
* Specifies whether unknown source link layer addresses and IP addresses
* are entered into the VXLAN device forwarding database.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_LEARNING,
g_param_spec_boolean (NM_SETTING_VXLAN_LEARNING, "", "",
TRUE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:rsc:
*
* Specifies whether route short circuit is turned on.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_RSC,
g_param_spec_boolean (NM_SETTING_VXLAN_RSC, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:l2-miss:
*
* Specifies whether netlink LL ADDR miss notifications are generated.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_L2_MISS,
g_param_spec_boolean (NM_SETTING_VXLAN_L2_MISS, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingVxlan:l3-miss:
*
* Specifies whether netlink IP ADDR miss notifications are generated.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_L3_MISS,
g_param_spec_boolean (NM_SETTING_VXLAN_L3_MISS, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
}

View file

@ -0,0 +1,109 @@
/* -*- 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_VXLAN_H__
#define __NM_SETTING_VXLAN_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_VXLAN (nm_setting_vxlan_get_type ())
#define NM_SETTING_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_VXLAN, NMSettingVxlan))
#define NM_SETTING_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_VXLANCONFIG, NMSettingVxlanClass))
#define NM_IS_SETTING_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_VXLAN))
#define NM_IS_SETTING_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_VXLAN))
#define NM_SETTING_VXLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_VXLAN, NMSettingVxlanClass))
#define NM_SETTING_VXLAN_SETTING_NAME "vxlan"
#define NM_SETTING_VXLAN_PARENT "parent"
#define NM_SETTING_VXLAN_ID "id"
#define NM_SETTING_VXLAN_LOCAL "local"
#define NM_SETTING_VXLAN_REMOTE "remote"
#define NM_SETTING_VXLAN_SOURCE_PORT_MIN "source-port-min"
#define NM_SETTING_VXLAN_SOURCE_PORT_MAX "source-port-max"
#define NM_SETTING_VXLAN_DESTINATION_PORT "destination-port"
#define NM_SETTING_VXLAN_TOS "tos"
#define NM_SETTING_VXLAN_TTL "ttl"
#define NM_SETTING_VXLAN_AGEING "ageing"
#define NM_SETTING_VXLAN_LIMIT "limit"
#define NM_SETTING_VXLAN_PROXY "proxy"
#define NM_SETTING_VXLAN_LEARNING "learning"
#define NM_SETTING_VXLAN_RSC "rsc"
#define NM_SETTING_VXLAN_L2_MISS "l2-miss"
#define NM_SETTING_VXLAN_L3_MISS "l3-miss"
struct _NMSettingVxlan {
NMSetting parent;
};
typedef struct {
NMSettingClass parent;
/*< private >*/
gpointer padding[4];
} NMSettingVxlanClass;
NM_AVAILABLE_IN_1_2
GType nm_setting_vxlan_get_type (void);
NM_AVAILABLE_IN_1_2
NMSetting *nm_setting_vxlan_new (void);
NM_AVAILABLE_IN_1_2
const char *nm_setting_vxlan_get_parent (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_vxlan_get_id (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
const char *nm_setting_vxlan_get_local (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
const char *nm_setting_vxlan_get_remote (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_vxlan_get_source_port_min (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_vxlan_get_source_port_max (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_vxlan_get_destination_port (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_vxlan_get_tos (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_vxlan_get_ttl (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_vxlan_get_ageing (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_vxlan_get_limit (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
gboolean nm_setting_vxlan_get_proxy (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
gboolean nm_setting_vxlan_get_learning (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
gboolean nm_setting_vxlan_get_rsc (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
gboolean nm_setting_vxlan_get_l2_miss (NMSettingVxlan *setting);
NM_AVAILABLE_IN_1_2
gboolean nm_setting_vxlan_get_l3_miss (NMSettingVxlan *setting);
G_END_DECLS
#endif /* __NM_SETTING_VXLAN_H__ */

View file

@ -327,8 +327,8 @@ _nm_device_gtype_from_dtype (NMDeviceType dtype)
case NM_DEVICE_TYPE_IP_TUNNEL:
return NM_TYPE_DEVICE_GENERIC;
default:
g_warning ("Unknown device type %d", dtype);
return G_TYPE_INVALID;
/* Fall back to NMDeviceGeneric for unknown devices */
return NM_TYPE_DEVICE_GENERIC;
}
}

View file

@ -45,6 +45,7 @@ libnminclude_hfiles = \
nm-device-team.h \
nm-device-tun.h \
nm-device-vlan.h \
nm-device-vxlan.h \
nm-device-wifi.h \
nm-device-wimax.h \
nm-device.h \
@ -99,6 +100,7 @@ libnm_la_csources = \
nm-device-team.c \
nm-device-tun.c \
nm-device-vlan.c \
nm-device-vxlan.c \
nm-device-wifi.c \
nm-device-wimax.c \
nm-device.c \

View file

@ -74,6 +74,7 @@
#include <nm-setting-tun.h>
#include <nm-setting-vlan.h>
#include <nm-setting-vpn.h>
#include <nm-setting-vxlan.h>
#include <nm-setting-wimax.h>
#include <nm-setting-wired.h>
#include <nm-setting-wireless-security.h>

View file

@ -860,6 +860,7 @@ global:
nm_access_point_get_last_seen;
nm_connection_get_setting_ip_tunnel;
nm_connection_get_setting_macvlan;
nm_connection_get_setting_vxlan;
nm_connection_verify_secrets;
nm_device_ethernet_get_s390_subchannels;
nm_client_get_all_devices;
@ -894,6 +895,23 @@ global:
nm_device_tun_get_no_pi;
nm_device_tun_get_type;
nm_device_tun_get_vnet_hdr;
nm_device_vxlan_get_ageing;
nm_device_vxlan_get_dst_port;
nm_device_vxlan_get_group;
nm_device_vxlan_get_hw_address;
nm_device_vxlan_get_id;
nm_device_vxlan_get_l2miss;
nm_device_vxlan_get_l3miss;
nm_device_vxlan_get_learning;
nm_device_vxlan_get_limit;
nm_device_vxlan_get_local;
nm_device_vxlan_get_parent;
nm_device_vxlan_get_proxy;
nm_device_vxlan_get_src_port_max;
nm_device_vxlan_get_src_port_min;
nm_device_vxlan_get_tos;
nm_device_vxlan_get_ttl;
nm_device_vxlan_get_type;
nm_device_wifi_request_scan_options;
nm_device_wifi_request_scan_options_async;
nm_ip_tunnel_mode_get_type;
@ -958,6 +976,24 @@ global:
nm_setting_macvlan_get_type;
nm_setting_macvlan_mode_get_type;
nm_setting_macvlan_new;
nm_setting_vxlan_get_ageing;
nm_setting_vxlan_get_destination_port;
nm_setting_vxlan_get_id;
nm_setting_vxlan_get_l2_miss;
nm_setting_vxlan_get_l3_miss;
nm_setting_vxlan_get_learning;
nm_setting_vxlan_get_limit;
nm_setting_vxlan_get_local;
nm_setting_vxlan_get_parent;
nm_setting_vxlan_get_proxy;
nm_setting_vxlan_get_remote;
nm_setting_vxlan_get_rsc;
nm_setting_vxlan_get_source_port_max;
nm_setting_vxlan_get_source_port_min;
nm_setting_vxlan_get_tos;
nm_setting_vxlan_get_ttl;
nm_setting_vxlan_get_type;
nm_setting_vxlan_new;
nm_setting_wired_get_wake_on_lan;
nm_setting_wired_get_wake_on_lan_password;
nm_setting_wired_wake_on_lan_get_type;

815
libnm/nm-device-vxlan.c Normal file
View file

@ -0,0 +1,815 @@
/* -*- 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-vxlan.h>
#include <nm-utils.h>
#include "nm-default.h"
#include "nm-device-vxlan.h"
#include "nm-device-private.h"
#include "nm-object-private.h"
G_DEFINE_TYPE (NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE)
#define NM_DEVICE_VXLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanPrivate))
typedef struct {
NMDevice *parent;
char *hw_address;
gboolean carrier;
guint id;
char *group;
char *local;
guint src_port_min;
guint src_port_max;
guint dst_port;
guint tos;
guint ttl;
guint limit;
gboolean learning;
guint ageing;
gboolean proxy;
gboolean rsc;
gboolean l2miss;
gboolean l3miss;
} NMDeviceVxlanPrivate;
enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_CARRIER,
PROP_PARENT,
PROP_ID,
PROP_GROUP,
PROP_LOCAL,
PROP_TOS,
PROP_TTL,
PROP_LIMIT,
PROP_LEARNING,
PROP_AGEING,
PROP_DST_PORT,
PROP_SRC_PORT_MIN,
PROP_SRC_PORT_MAX,
PROP_PROXY,
PROP_RSC,
PROP_L2MISS,
PROP_L3MISS,
LAST_PROP
};
/**
* nm_device_vxlan_get_hw_address:
* @device: a #NMDeviceVxlan
*
* Gets the hardware (MAC) address of the #NMDeviceVxlan
*
* 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_vxlan_get_hw_address (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->hw_address;
}
/**
* nm_device_vxlan_get_carrier:
* @device: a #NMDeviceVxlan
*
* Whether the device has carrier.
*
* Returns: %TRUE if the device has carrier.
*
* Since: 1.2
**/
gboolean
nm_device_vxlan_get_carrier (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->carrier;
}
/**
* nm_device_vxlan_get_parent:
* @device: a #NMDeviceVxlan
*
* Returns: (transfer none): the device's parent device
*
* Since: 1.2
**/
NMDevice *
nm_device_vxlan_get_parent (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->parent;
}
/**
* nm_device_vxlan_get_id:
* @device: a #NMDeviceVxlan
*
* Returns: the device's VXLAN ID.
*
* Since: 1.2
**/
guint
nm_device_vxlan_get_id (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->id;
}
/**
* nm_device_vxlan_get_group:
* @device: a #NMDeviceVxlan
*
* Returns: The unicast destination IP address or the multicast
* IP address joined
*
* Since: 1.2
**/
const char *
nm_device_vxlan_get_group (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->group;
}
/**
* nm_device_vxlan_get_local:
* @device: a #NMDeviceVxlan
*
* Returns: the source IP address to use in outgoing packets
*
* Since: 1.2
**/
const char *
nm_device_vxlan_get_local (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->local;
}
/**
* nm_device_vxlan_get_src_port_min:
* @device: a #NMDeviceVxlan
*
* Returns: the minimum UDP source port
*
* Since: 1.2
**/
guint
nm_device_vxlan_get_src_port_min (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->src_port_min;
}
/**
* nm_device_vxlan_get_src_port_max:
* @device: a #NMDeviceVxlan
*
* Returns: the maximum UDP source port
*
* Since: 1.2
**/
guint
nm_device_vxlan_get_src_port_max (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->src_port_max;
}
/**
* nm_device_vxlan_get_dst_port:
* @device: a #NMDeviceVxlan
*
* Returns: the UDP destination port
*
* Since: 1.2
**/
guint
nm_device_vxlan_get_dst_port (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->dst_port;
}
/**
* nm_device_vxlan_get_learning:
* @device: a #NMDeviceVxlan
*
* Returns: whether address learning is enabled
*
* Since: 1.2
**/
gboolean
nm_device_vxlan_get_learning (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->learning;
}
/**
* nm_device_vxlan_get_ageing:
* @device: a #NMDeviceVxlan
*
* Returns: the lifetime in seconds of FDB entries learnt by the kernel
*
* Since: 1.2
**/
guint
nm_device_vxlan_get_ageing (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->ageing;
}
/**
* nm_device_vxlan_get_tos:
* @device: a #NMDeviceVxlan
*
* Returns: the TOS value to use in outgoing packets
*
* Since: 1.2
**/
guint
nm_device_vxlan_get_tos (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->tos;
}
/**
* nm_device_vxlan_get_ttl:
* @device: a #NMDeviceVxlan
*
* Returns: the time-to-live value to use in outgoing packets
*
* Since: 1.2
**/
guint
nm_device_vxlan_get_ttl (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->ttl;
}
/**
* nm_device_vxlan_get_limit:
* @device: a #NMDeviceVxlan
*
* Returns: the maximum number of entries that can be added to the
* forwarding table
*
* Since: 1.2
**/
guint
nm_device_vxlan_get_limit (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->limit;
}
/**
* nm_device_vxlan_get_proxy:
* @device: a #NMDeviceVxlan
*
* Returns: whether ARP proxy is turned on
*
* Since: 1.2
**/
gboolean
nm_device_vxlan_get_proxy (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->proxy;
}
/**
* nm_device_vxlan_get_rsc:
* @device: a #NMDeviceVxlan
*
* Returns: whether route short circuit is turned on
*
* Since: 1.2
**/
gboolean
nm_device_vxlan_get_rsc (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->rsc;
}
/**
* nm_device_vxlan_get_l2miss:
* @device: a #NMDeviceVxlan
*
* Returns: whether netlink LL ADDR miss notifications are generated
*
* Since: 1.2
**/
gboolean
nm_device_vxlan_get_l2miss (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->l2miss;
}
/**
* nm_device_vxlan_get_l3miss:
* @device: a #NMDeviceVxlan
*
* Returns: wether netlink IP ADDR miss notifications are generated
*
* Since: 1.2
**/
gboolean
nm_device_vxlan_get_l3miss (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE);
return NM_DEVICE_VXLAN_GET_PRIVATE (device)->l3miss;
}
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
NMSettingVxlan *s_vxlan;
if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->connection_compatible (device, connection, error))
return FALSE;
if (!nm_connection_is_type (connection, NM_SETTING_VXLAN_SETTING_NAME)) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
_("The connection was not a VXLAN connection."));
return FALSE;
}
s_vxlan = nm_connection_get_setting_vxlan (connection);
if (nm_setting_vxlan_get_id (s_vxlan) != nm_device_vxlan_get_id (NM_DEVICE_VXLAN (device))) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
_("The VXLAN identifiers of the device and the connection didn't match."));
return FALSE;
}
return TRUE;
}
static GType
get_setting_type (NMDevice *device)
{
return NM_TYPE_SETTING_VXLAN;
}
static const char *
get_hw_address (NMDevice *device)
{
return nm_device_vxlan_get_hw_address (NM_DEVICE_VXLAN (device));
}
/***********************************************************/
static void
nm_device_vxlan_init (NMDeviceVxlan *device)
{
_nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_VXLAN);
}
static void
init_dbus (NMObject *object)
{
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);
const NMPropertiesInfo property_info[] = {
{ NM_DEVICE_VXLAN_HW_ADDRESS, &priv->hw_address },
{ NM_DEVICE_VXLAN_CARRIER, &priv->carrier },
{ NM_DEVICE_VXLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
{ NM_DEVICE_VXLAN_ID, &priv->id },
{ NM_DEVICE_VXLAN_GROUP, &priv->group },
{ NM_DEVICE_VXLAN_LOCAL, &priv->local },
{ NM_DEVICE_VXLAN_SRC_PORT_MIN, &priv->src_port_min },
{ NM_DEVICE_VXLAN_SRC_PORT_MAX, &priv->src_port_max },
{ NM_DEVICE_VXLAN_DST_PORT, &priv->dst_port },
{ NM_DEVICE_VXLAN_TOS, &priv->tos },
{ NM_DEVICE_VXLAN_TTL, &priv->ttl },
{ NM_DEVICE_VXLAN_LIMIT, &priv->limit },
{ NM_DEVICE_VXLAN_LEARNING, &priv->learning },
{ NM_DEVICE_VXLAN_AGEING, &priv->ageing },
{ NM_DEVICE_VXLAN_PROXY, &priv->proxy },
{ NM_DEVICE_VXLAN_RSC, &priv->rsc },
{ NM_DEVICE_VXLAN_L2MISS, &priv->l2miss },
{ NM_DEVICE_VXLAN_L3MISS, &priv->l3miss },
{ NULL },
};
NM_OBJECT_CLASS (nm_device_vxlan_parent_class)->init_dbus (object);
_nm_object_register_properties (object,
NM_DBUS_INTERFACE_DEVICE_VXLAN,
property_info);
}
static void
finalize (GObject *object)
{
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);
g_free (priv->hw_address);
g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_vxlan_parent_class)->finalize (object);
}
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NMDeviceVxlan *device = NM_DEVICE_VXLAN (object);
switch (prop_id) {
case PROP_HW_ADDRESS:
g_value_set_string (value, nm_device_vxlan_get_hw_address (device));
break;
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_vxlan_get_carrier (device));
break;
case PROP_PARENT:
g_value_set_object (value, nm_device_vxlan_get_parent (device));
break;
case PROP_ID:
g_value_set_uint (value, nm_device_vxlan_get_id (device));
break;
case PROP_GROUP:
g_value_set_string (value, nm_device_vxlan_get_group (device));
break;
case PROP_LOCAL:
g_value_set_string (value, nm_device_vxlan_get_local (device));
break;
case PROP_TOS:
g_value_set_uint (value, nm_device_vxlan_get_tos (device));
break;
case PROP_TTL:
g_value_set_uint (value, nm_device_vxlan_get_ttl (device));
break;
case PROP_LIMIT:
g_value_set_uint (value, nm_device_vxlan_get_limit (device));
break;
case PROP_LEARNING:
g_value_set_boolean (value, nm_device_vxlan_get_learning (device));
break;
case PROP_AGEING:
g_value_set_uint (value, nm_device_vxlan_get_ageing (device));
break;
case PROP_DST_PORT:
g_value_set_uint (value, nm_device_vxlan_get_dst_port (device));
break;
case PROP_SRC_PORT_MIN:
g_value_set_uint (value, nm_device_vxlan_get_src_port_min (device));
break;
case PROP_SRC_PORT_MAX:
g_value_set_uint (value, nm_device_vxlan_get_src_port_max (device));
break;
case PROP_PROXY:
g_value_set_boolean (value, nm_device_vxlan_get_proxy (device));
break;
case PROP_RSC:
g_value_set_boolean (value, nm_device_vxlan_get_rsc (device));
break;
case PROP_L2MISS:
g_value_set_boolean (value, nm_device_vxlan_get_l2miss (device));
break;
case PROP_L3MISS:
g_value_set_boolean (value, nm_device_vxlan_get_l3miss (device));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_device_vxlan_class_init (NMDeviceVxlanClass *vxlan_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (vxlan_class);
NMObjectClass *nm_object_class = NM_OBJECT_CLASS (vxlan_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (vxlan_class);
g_type_class_add_private (vxlan_class, sizeof (NMDeviceVxlanPrivate));
_nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_VXLAN);
/* 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 */
/**
* NMDeviceVxlan: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_VXLAN_HW_ADDRESS, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:carrier:
*
* Whether the device has carrier.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_CARRIER,
g_param_spec_boolean (NM_DEVICE_VXLAN_CARRIER, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:parent:
*
* The devices's parent device.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_PARENT,
g_param_spec_object (NM_DEVICE_VXLAN_PARENT, "", "",
NM_TYPE_DEVICE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:id:
*
* The device's VXLAN ID.
*
* Since: 1.2
**/
g_object_class_install_property
(object_class, PROP_ID,
g_param_spec_uint (NM_DEVICE_VXLAN_ID, "", "",
0, (1 << 24) - 1, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:group:
*
* The unicast destination IP address used in outgoing packets when the
* destination link layer address is not known in the VXLAN device
* forwarding database or the multicast IP address joined.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_GROUP,
g_param_spec_string (NM_DEVICE_VXLAN_GROUP, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:local:
*
* The source IP address to use in outgoing packets.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_LOCAL,
g_param_spec_string (NM_DEVICE_VXLAN_LOCAL, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:tos:
*
* The TOS value to use in outgoing packets.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_TOS,
g_param_spec_uchar (NM_DEVICE_VXLAN_TOS, "", "",
0, 255, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:ttl:
*
* The time-to-live value to use in outgoing packets.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_TTL,
g_param_spec_uchar (NM_DEVICE_VXLAN_TTL, "", "",
0, 255, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:learning:
*
* Whether unknown source link layer addresses and IP addresses are entered
* into the VXLAN device forwarding database.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_LEARNING,
g_param_spec_boolean (NM_DEVICE_VXLAN_LEARNING, "", "",
TRUE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:ageing:
*
* The lifetime in seconds of FDB entries learnt by the kernel.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_AGEING,
g_param_spec_uint (NM_DEVICE_VXLAN_AGEING, "", "",
0, G_MAXUINT32, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:limit:
*
* The maximum number of entries that can be added to the forwarding table.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_LIMIT,
g_param_spec_uint (NM_DEVICE_VXLAN_LIMIT, "", "",
0, G_MAXUINT32, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:dst-port:
*
* The UDP destination port used to communicate with the remote VXLAN tunnel
* endpoint.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_DST_PORT,
g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "",
0, 65535, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:src-port-min:
*
* The minimum UDP source port used to communicate with the remote VXLAN
* tunnel endpoint.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_SRC_PORT_MIN,
g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, "", "",
0, 65535, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:src-port-max:
*
* The maximum UDP source port used to communicate with the remote VXLAN
* tunnel endpoint.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_SRC_PORT_MAX,
g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MAX, "", "",
0, 65535, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:proxy:
*
* Whether ARP proxy is turned on.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_PROXY,
g_param_spec_boolean (NM_DEVICE_VXLAN_PROXY, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:rsc:
*
* Whether route short circuit is turned on.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_RSC,
g_param_spec_boolean (NM_DEVICE_VXLAN_RSC, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:l2miss:
*
* Whether netlink LL ADDR miss notifications are generated.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_L2MISS,
g_param_spec_boolean (NM_DEVICE_VXLAN_L2MISS, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVxlan:l3miss:
*
* Whether netlink IP ADDR miss notifications are generated.
*
* Since: 1.2
*/
g_object_class_install_property
(object_class, PROP_L3MISS,
g_param_spec_boolean (NM_DEVICE_VXLAN_L3MISS, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
}

110
libnm/nm-device-vxlan.h Normal file
View file

@ -0,0 +1,110 @@
/* -*- 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_VXLAN_H__
#define __NM_DEVICE_VXLAN_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_VXLAN (nm_device_vxlan_get_type ())
#define NM_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlan))
#define NM_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass))
#define NM_IS_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VXLAN))
#define NM_IS_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VXLAN))
#define NM_DEVICE_VXLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass))
#define NM_DEVICE_VXLAN_HW_ADDRESS "hw-address"
#define NM_DEVICE_VXLAN_CARRIER "carrier"
#define NM_DEVICE_VXLAN_PARENT "parent"
#define NM_DEVICE_VXLAN_ID "id"
#define NM_DEVICE_VXLAN_GROUP "group"
#define NM_DEVICE_VXLAN_LOCAL "local"
#define NM_DEVICE_VXLAN_SRC_PORT_MIN "src-port-min"
#define NM_DEVICE_VXLAN_SRC_PORT_MAX "src-port-max"
#define NM_DEVICE_VXLAN_LEARNING "learning"
#define NM_DEVICE_VXLAN_AGEING "ageing"
#define NM_DEVICE_VXLAN_TOS "tos"
#define NM_DEVICE_VXLAN_TTL "ttl"
#define NM_DEVICE_VXLAN_LIMIT "limit"
#define NM_DEVICE_VXLAN_PROXY "proxy"
#define NM_DEVICE_VXLAN_RSC "rsc"
#define NM_DEVICE_VXLAN_L2MISS "l2miss"
#define NM_DEVICE_VXLAN_L3MISS "l3miss"
#define NM_DEVICE_VXLAN_DST_PORT "dst-port"
struct _NMDeviceVxlan {
NMDevice parent;
};
typedef struct {
NMDeviceClass parent;
/*< private >*/
gpointer padding[4];
} NMDeviceVxlanClass;
NM_AVAILABLE_IN_1_2
GType nm_device_vxlan_get_type (void);
NM_AVAILABLE_IN_1_2
const char * nm_device_vxlan_get_hw_address (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
gboolean nm_device_vxlan_get_carrier (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
NMDevice * nm_device_vxlan_get_parent (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
guint nm_device_vxlan_get_id (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
const char * nm_device_vxlan_get_group (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
const char * nm_device_vxlan_get_local (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
guint nm_device_vxlan_get_src_port_min (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
guint nm_device_vxlan_get_src_port_max (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
guint nm_device_vxlan_get_dst_port (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
gboolean nm_device_vxlan_get_learning (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
guint nm_device_vxlan_get_ageing (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
guint nm_device_vxlan_get_tos (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
guint nm_device_vxlan_get_ttl (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
guint nm_device_vxlan_get_limit (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
gboolean nm_device_vxlan_get_proxy (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
gboolean nm_device_vxlan_get_rsc (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
gboolean nm_device_vxlan_get_l2miss (NMDeviceVxlan *device);
NM_AVAILABLE_IN_1_2
gboolean nm_device_vxlan_get_l3miss (NMDeviceVxlan *device);
G_END_DECLS
#endif /* __NM_DEVICE_VXLAN_H__ */

View file

@ -40,6 +40,7 @@
#include "nm-device-team.h"
#include "nm-device-bridge.h"
#include "nm-device-vlan.h"
#include "nm-device-vxlan.h"
#include "nm-device-generic.h"
#include "nm-device-ip-tunnel.h"
#include "nm-device-macvlan.h"
@ -374,6 +375,8 @@ _nm_device_gtype_from_dtype (NMDeviceType dtype)
return NM_TYPE_DEVICE_IP_TUNNEL;
case NM_DEVICE_TYPE_MACVLAN:
return NM_TYPE_DEVICE_MACVLAN;
case NM_DEVICE_TYPE_VXLAN:
return NM_TYPE_DEVICE_VXLAN;
default:
g_warning ("Unknown device type %d", dtype);
return G_TYPE_INVALID;

View file

@ -44,6 +44,7 @@ typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh;
typedef struct _NMDeviceTeam NMDeviceTeam;
typedef struct _NMDeviceTun NMDeviceTun;
typedef struct _NMDeviceVlan NMDeviceVlan;
typedef struct _NMDeviceVxlan NMDeviceVxlan;
typedef struct _NMDeviceWifi NMDeviceWifi;
typedef struct _NMDeviceWimax NMDeviceWimax;
typedef struct _NMDhcpConfig NMDhcpConfig;

View file

@ -694,6 +694,22 @@ The value can be prefixed with \fBifname/\fP, \fBuuid/\fP or \fBid/\fP to disamb
.RE
.RS
.TP
.B vxlan:
.IP "\fIid <VXLAN ID>\fP" 42
\(en VXLAN Network Identifer to use
.IP "\fIremote <IP>\fP" 42
\(en unicast destination IP address or multicast IP address to join
.IP "\fI[local <IP>]\fP" 42
\(en source IP address
.IP "\fI[source-port-min <0-65535>]\fP" 42
\(en minimum UDP source port to communicate to the remote VXLAN tunnel endpoint
.IP "\fI[source-port-max <0-65535>]\fP" 42
\(en maximum UDP source port to communicate to the remote VXLAN tunnel endpoint
.IP "\fI[destination-port <0-65535>]\fP" 42
\(en UDP destination port to communicate to the remote VXLAN tunnel endpoint
.RE
.RS
.TP
.B SLAVE_OPTIONS:
.RE
.RS

View file

@ -75,6 +75,7 @@ libnm-core/nm-setting-team-port.c
libnm-core/nm-setting-tun.c
libnm-core/nm-setting-vlan.c
libnm-core/nm-setting-vpn.c
libnm-core/nm-setting-vxlan.c
libnm-core/nm-setting-wimax.c
libnm-core/nm-setting-wired.c
libnm-core/nm-setting-wireless-security.c
@ -128,6 +129,7 @@ libnm/nm-device-modem.c
libnm/nm-device-olpc-mesh.c
libnm/nm-device-team.c
libnm/nm-device-vlan.c
libnm/nm-device-vxlan.c
libnm/nm-device-wifi.c
libnm/nm-device-wimax.c
libnm/nm-device.c
@ -157,6 +159,7 @@ 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/nm-device-vxlan.c
src/devices/team/nm-device-team.c
src/devices/wifi/nm-device-olpc-mesh.c
src/devices/wifi/nm-device-wifi.c

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2013, 2014 Red Hat, Inc.
* Copyright 2013 - 2015 Red Hat, Inc.
*/
#include "config.h"
@ -29,17 +29,21 @@
#include "nm-platform.h"
#include "nm-utils.h"
#include "nm-device-factory.h"
#include "nm-setting-vxlan.h"
#include "nm-connection-provider.h"
#include "nm-activation-request.h"
#include "nmdbus-device-vxlan.h"
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceVxlan);
G_DEFINE_TYPE (NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE_GENERIC)
G_DEFINE_TYPE (NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE)
#define NM_DEVICE_VXLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanPrivate))
typedef struct {
NMDevice *parent;
NMPlatformLnkVxlan props;
} NMDeviceVxlanPrivate;
@ -47,16 +51,16 @@ enum {
PROP_0,
PROP_PARENT,
PROP_ID,
PROP_GROUP,
PROP_LOCAL,
PROP_GROUP,
PROP_TOS,
PROP_TTL,
PROP_LEARNING,
PROP_AGEING,
PROP_LIMIT,
PROP_DST_PORT,
PROP_SRC_PORT_MIN,
PROP_SRC_PORT_MAX,
PROP_DST_PORT,
PROP_PROXY,
PROP_RSC,
PROP_L2MISS,
@ -74,6 +78,7 @@ update_properties (NMDevice *device)
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
GObject *object = G_OBJECT (device);
const NMPlatformLnkVxlan *props;
NMDevice *parent;
props = nm_platform_link_get_lnk_vxlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), NULL);
if (!props) {
@ -83,18 +88,23 @@ update_properties (NMDevice *device)
g_object_freeze_notify (object);
if (priv->props.parent_ifindex != props->parent_ifindex)
if (priv->props.parent_ifindex != props->parent_ifindex) {
g_clear_object (&priv->parent);
parent = nm_manager_get_device_by_ifindex (nm_manager_get (), props->parent_ifindex);
if (parent)
priv->parent = g_object_ref (parent);
g_object_notify (object, NM_DEVICE_VXLAN_PARENT);
}
if (priv->props.id != props->id)
g_object_notify (object, NM_DEVICE_VXLAN_ID);
if (priv->props.group != props->group)
g_object_notify (object, NM_DEVICE_VXLAN_GROUP);
if (priv->props.local != props->local)
g_object_notify (object, NM_DEVICE_VXLAN_LOCAL);
if (memcmp (&priv->props.group6, &props->group6, sizeof (props->group6)) != 0)
g_object_notify (object, NM_DEVICE_VXLAN_GROUP);
if (memcmp (&priv->props.local6, &props->local6, sizeof (props->local6)) != 0)
g_object_notify (object, NM_DEVICE_VXLAN_LOCAL);
if (priv->props.group != props->group)
g_object_notify (object, NM_DEVICE_VXLAN_GROUP);
if (memcmp (&priv->props.group6, &props->group6, sizeof (props->group6)) != 0)
g_object_notify (object, NM_DEVICE_VXLAN_GROUP);
if (priv->props.tos != props->tos)
g_object_notify (object, NM_DEVICE_VXLAN_TOS);
if (priv->props.ttl != props->ttl)
@ -105,12 +115,12 @@ update_properties (NMDevice *device)
g_object_notify (object, NM_DEVICE_VXLAN_AGEING);
if (priv->props.limit != props->limit)
g_object_notify (object, NM_DEVICE_VXLAN_LIMIT);
if (priv->props.dst_port != props->dst_port)
g_object_notify (object, NM_DEVICE_VXLAN_DST_PORT);
if (priv->props.src_port_min != props->src_port_min)
g_object_notify (object, NM_DEVICE_VXLAN_SRC_PORT_MIN);
if (priv->props.src_port_max != props->src_port_max)
g_object_notify (object, NM_DEVICE_VXLAN_SRC_PORT_MAX);
if (priv->props.dst_port != props->dst_port)
g_object_notify (object, NM_DEVICE_VXLAN_DST_PORT);
if (priv->props.proxy != props->proxy)
g_object_notify (object, NM_DEVICE_VXLAN_PROXY);
if (priv->props.rsc != props->rsc)
@ -160,6 +170,352 @@ unrealize (NMDevice *device, gboolean remove_resources)
g_free (properties);
}
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;
NMPlatformLnkVxlan props = { };
NMSettingVxlan *s_vxlan;
const char *str;
int ret;
s_vxlan = nm_connection_get_setting_vxlan (connection);
g_assert (s_vxlan);
g_assert (out_plink);
if (parent)
props.parent_ifindex = nm_device_get_ifindex (parent);
props.id = nm_setting_vxlan_get_id (s_vxlan);
str = nm_setting_vxlan_get_local (s_vxlan);
if (str) {
ret = inet_pton (AF_INET, str, &props.local);
if (ret != 1)
ret = inet_pton (AF_INET6, str, &props.local6);
if (ret != 1)
return FALSE;
}
str = nm_setting_vxlan_get_remote (s_vxlan);
ret = inet_pton (AF_INET, str, &props.group);
if (ret != 1)
ret = inet_pton (AF_INET6, str, &props.group6);
if (ret != 1)
return FALSE;
props.tos = nm_setting_vxlan_get_tos (s_vxlan);
props.ttl = nm_setting_vxlan_get_ttl (s_vxlan);
props.learning = nm_setting_vxlan_get_learning (s_vxlan);
props.ageing = nm_setting_vxlan_get_ageing (s_vxlan);
props.limit = nm_setting_vxlan_get_limit (s_vxlan);
props.src_port_min = nm_setting_vxlan_get_source_port_min (s_vxlan);
props.src_port_max = nm_setting_vxlan_get_source_port_max (s_vxlan);
props.dst_port = nm_setting_vxlan_get_destination_port (s_vxlan);
props.proxy = nm_setting_vxlan_get_proxy (s_vxlan);
props.rsc = nm_setting_vxlan_get_rsc (s_vxlan);
props.l2miss = nm_setting_vxlan_get_l2_miss (s_vxlan);
props.l3miss = nm_setting_vxlan_get_l3_miss (s_vxlan);
plerr = nm_platform_link_vxlan_add (NM_PLATFORM_GET, iface, &props, 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 VXLAN interface '%s' for '%s': %s",
iface,
nm_connection_get_id (connection),
nm_platform_error_to_string (plerr));
return FALSE;
}
return TRUE;
}
static gboolean
realize (NMDevice *device, NMPlatformLink *plink, GError **error)
{
g_assert (plink->type == NM_LINK_TYPE_VXLAN);
update_properties (device);
return TRUE;
}
static gboolean
match_parent (NMDeviceVxlan *self, const char *parent)
{
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_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
address_matches (const char *str, in_addr_t addr4, struct in6_addr *addr6)
{
in_addr_t new_addr4 = 0;
struct in6_addr new_addr6 = { };
if (!str) {
return addr4 == 0
&& !memcmp (addr6, &in6addr_any, sizeof (in6addr_any));
}
if (inet_pton (AF_INET, str, &new_addr4) == 1)
return new_addr4 == addr4;
else if (inet_pton (AF_INET6, str, &new_addr6) == 1)
return !memcmp (&new_addr6, addr6, sizeof (new_addr6));
else
return FALSE;
}
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
NMSettingVxlan *s_vxlan;
const char *iface, *parent;
if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->check_connection_compatible (device, connection))
return FALSE;
s_vxlan = nm_connection_get_setting_vxlan (connection);
if (!s_vxlan)
return FALSE;
iface = nm_connection_get_interface_name (connection);
if (iface) {
if (g_strcmp0 (nm_device_get_ip_iface (device), iface) != 0)
return FALSE;
}
if (nm_device_is_real (device)) {
parent = nm_setting_vxlan_get_parent (s_vxlan);
if ( parent
&& !match_parent (NM_DEVICE_VXLAN (device), parent))
return FALSE;
if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan))
return FALSE;
if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6))
return FALSE;
if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6))
return FALSE;
if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan))
return FALSE;
if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan))
return FALSE;
if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan))
return FALSE;
if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan))
return FALSE;
if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan))
return FALSE;
if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan))
return FALSE;
if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan))
return FALSE;
if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan))
return FALSE;
if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan))
return FALSE;
if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan))
return FALSE;
if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan))
return FALSE;
}
return TRUE;
}
static gboolean
complete_connection (NMDevice *device,
NMConnection *connection,
const char *specific_object,
const GSList *existing_connections,
GError **error)
{
NMSettingVxlan *s_vxlan;
nm_utils_complete_generic (connection,
NM_SETTING_VXLAN_SETTING_NAME,
existing_connections,
NULL,
_("VXLAN connection"),
NULL,
TRUE);
s_vxlan = nm_connection_get_setting_vxlan (connection);
if (!s_vxlan) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
"A 'vxlan' setting is required.");
return FALSE;
}
return TRUE;
}
static void
update_connection (NMDevice *device, NMConnection *connection)
{
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
NMSettingVxlan *s_vxlan = nm_connection_get_setting_vxlan (connection);
NMDevice *parent = NULL;
const char *setting_parent, *new_parent;
if (!s_vxlan) {
s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new ();
nm_connection_add_setting (connection, (NMSetting *) s_vxlan);
}
if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan))
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_ID, priv->props.id, NULL);
if (priv->props.parent_ifindex != NM_PLATFORM_LINK_OTHER_NETNS)
parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->props.parent_ifindex);
/* Update parent in the connection; default to parent's interface name */
if (parent) {
new_parent = nm_device_get_iface (parent);
setting_parent = nm_setting_vxlan_get_parent (s_vxlan);
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 (parent, parent_connection))
new_parent = NULL;
}
if (new_parent)
g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, new_parent, NULL);
} else
g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, NULL, NULL);
if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) {
if (priv->props.group) {
g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE,
nm_utils_inet4_ntop (priv->props.group, NULL),
NULL);
} else {
g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE,
nm_utils_inet6_ntop (&priv->props.group6, NULL),
NULL);
}
}
if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6)) {
if (priv->props.local) {
g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL,
nm_utils_inet4_ntop (priv->props.local, NULL),
NULL);
} else if (memcmp (&priv->props.local6, &in6addr_any, sizeof (in6addr_any))) {
g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL,
nm_utils_inet6_ntop (&priv->props.local6, NULL),
NULL);
}
}
if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_SOURCE_PORT_MIN,
priv->props.src_port_min, NULL);
}
if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_SOURCE_PORT_MAX,
priv->props.src_port_max, NULL);
}
if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_DESTINATION_PORT,
priv->props.dst_port, NULL);
}
if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_TOS,
priv->props.tos, NULL);
}
if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_TTL,
priv->props.ttl, NULL);
}
if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_LEARNING,
priv->props.learning, NULL);
}
if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_AGEING,
priv->props.ageing, NULL);
}
if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_PROXY,
priv->props.proxy, NULL);
}
if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_RSC,
priv->props.rsc, NULL);
}
if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_L2_MISS,
priv->props.l2miss, NULL);
}
if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan)) {
g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_L3_MISS,
priv->props.l3miss, NULL);
}
}
/**************************************************************/
static void
@ -236,6 +592,15 @@ get_property (GObject *object, guint prop_id,
}
}
static void
dispose (GObject *object)
{
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);
g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_vxlan_parent_class)->dispose (object);
}
static void
nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
{
@ -247,10 +612,17 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VXLAN)
object_class->get_property = get_property;
object_class->dispose = dispose;
device_class->link_changed = link_changed;
device_class->setup_start = setup_start;
device_class->unrealize = unrealize;
device_class->connection_type = NM_SETTING_VXLAN_SETTING_NAME;
device_class->create_and_realize = create_and_realize;
device_class->realize = realize;
device_class->check_connection_compatible = check_connection_compatible;
device_class->complete_connection = complete_connection;
device_class->update_connection = update_connection;
/* properties */
g_object_class_install_property
@ -268,15 +640,15 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_GROUP,
g_param_spec_string (NM_DEVICE_VXLAN_GROUP, "", "",
(object_class, PROP_LOCAL,
g_param_spec_string (NM_DEVICE_VXLAN_LOCAL, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_LOCAL,
g_param_spec_string (NM_DEVICE_VXLAN_LOCAL, "", "",
(object_class, PROP_GROUP,
g_param_spec_string (NM_DEVICE_VXLAN_GROUP, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
@ -316,13 +688,6 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_DST_PORT,
g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "",
0, 65535, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_SRC_PORT_MIN,
g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, "", "",
@ -337,6 +702,13 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_DST_PORT,
g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "",
0, 65535, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_PROXY,
g_param_spec_boolean (NM_DEVICE_VXLAN_PROXY, "", "",
@ -385,13 +757,49 @@ create_device (NMDeviceFactory *factory,
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VXLAN,
NM_DEVICE_IFACE, iface,
NM_DEVICE_TYPE_DESC, "Vxlan",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC,
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VXLAN,
NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_VXLAN,
NULL);
}
static const char *
get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
{
NMSettingVxlan *s_vxlan;
g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_VXLAN_SETTING_NAME), NULL);
s_vxlan = nm_connection_get_setting_vxlan (connection);
g_assert (s_vxlan);
return nm_setting_vxlan_get_parent (s_vxlan);
}
static char *
get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
{
const char *ifname;
NMSettingVxlan *s_vxlan;
g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_VXLAN_SETTING_NAME), NULL);
s_vxlan = nm_connection_get_setting_vxlan (connection);
g_assert (s_vxlan);
if (nm_setting_vxlan_get_parent (s_vxlan) && !parent_iface)
return NULL;
ifname = nm_connection_get_interface_name (connection);
return g_strdup (ifname);
}
NM_DEVICE_FACTORY_DEFINE_INTERNAL (VXLAN, Vxlan, vxlan,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VXLAN),
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VXLAN)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_VXLAN_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;
)

View file

@ -49,8 +49,8 @@ G_BEGIN_DECLS
#define NM_DEVICE_VXLAN_L2MISS "l2miss"
#define NM_DEVICE_VXLAN_L3MISS "l3miss"
typedef NMDeviceGeneric NMDeviceVxlan;
typedef NMDeviceGenericClass NMDeviceVxlanClass;
typedef NMDevice NMDeviceVxlan;
typedef NMDeviceClass NMDeviceVxlanClass;
GType nm_device_vxlan_get_type (void);

View file

@ -787,6 +787,8 @@ nm_device_get_priority (NMDevice *self)
return 425;
case NM_DEVICE_TYPE_TUN:
return 450;
case NM_DEVICE_TYPE_VXLAN:
return 500;
case NM_DEVICE_TYPE_WIFI:
return 600;
case NM_DEVICE_TYPE_OLPC_MESH:

View file

@ -708,6 +708,31 @@ link_vlan_change (NMPlatform *platform,
return FALSE;
}
static gboolean
link_vxlan_add (NMPlatform *platform,
const char *name,
NMPlatformLnkVxlan *props,
NMPlatformLink *out_link)
{
NMFakePlatformLink *device;
if (!link_add (platform, name, NM_LINK_TYPE_VXLAN, NULL, 0, NULL))
return FALSE;
device = link_get (platform, nm_platform_link_get_ifindex (platform, name));
g_return_val_if_fail (device, FALSE);
g_return_val_if_fail (!device->lnk, FALSE);
device->lnk = nmp_object_new (NMP_OBJECT_TYPE_LNK_VXLAN, NULL);
device->lnk->lnk_vxlan = *props;
device->link.parent = props->parent_ifindex;
if (out_link)
*out_link = device->link;
return TRUE;
}
static gboolean
infiniband_partition_add (NMPlatform *platform, int parent, int p_key, NMPlatformLink *out_link)
{
@ -1458,6 +1483,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->vlan_add = vlan_add;
platform_class->link_vlan_change = link_vlan_change;
platform_class->link_vxlan_add = link_vxlan_add;
platform_class->infiniband_partition_add = infiniband_partition_add;

View file

@ -25,6 +25,7 @@
#include <sys/ioctl.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <arpa/inet.h>
#include <netinet/icmp6.h>
#include <netinet/in.h>
#include <linux/ip.h>
@ -4466,6 +4467,80 @@ nla_put_failure:
g_return_val_if_reached (FALSE);
}
static gboolean
link_vxlan_add (NMPlatform *platform,
const char *name,
NMPlatformLnkVxlan *props,
NMPlatformLink *out_link)
{
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
struct nlattr *info;
struct nlattr *data;
struct nm_ifla_vxlan_port_range port_range;
g_return_val_if_fail (props, FALSE);
_LOGD ("link: add vxlan '%s', parent %d, vxlan id %d",
name, props->parent_ifindex, props->id);
nlmsg = _nl_msg_new_link (RTM_NEWLINK,
NLM_F_CREATE,
0,
name,
0,
0);
if (!nlmsg)
return FALSE;
if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO)))
goto nla_put_failure;
NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "vxlan");
if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA)))
goto nla_put_failure;
NLA_PUT_U32 (nlmsg, IFLA_VXLAN_ID, props->id);
if (props->group)
NLA_PUT (nlmsg, IFLA_VXLAN_GROUP, sizeof (props->group), &props->group);
else if (memcmp (&props->group6, &in6addr_any, sizeof (in6addr_any)))
NLA_PUT (nlmsg, IFLA_VXLAN_GROUP6, sizeof (props->group6), &props->group6);
if (props->local)
NLA_PUT (nlmsg, IFLA_VXLAN_LOCAL, sizeof (props->local), &props->local);
else if (memcmp (&props->local6, &in6addr_any, sizeof (in6addr_any)))
NLA_PUT (nlmsg, IFLA_VXLAN_LOCAL6, sizeof (props->local6), &props->local6);
if (props->parent_ifindex >= 0)
NLA_PUT_U32 (nlmsg, IFLA_VXLAN_LINK, props->parent_ifindex);
if (props->src_port_min || props->src_port_max) {
port_range.low = htons (props->src_port_min);
port_range.high = htons (props->src_port_max);
NLA_PUT (nlmsg, IFLA_VXLAN_PORT_RANGE, sizeof (port_range), &port_range);
}
NLA_PUT_U16 (nlmsg, IFLA_VXLAN_PORT, htons (props->dst_port));
NLA_PUT_U8 (nlmsg, IFLA_VXLAN_TOS, props->tos);
NLA_PUT_U8 (nlmsg, IFLA_VXLAN_TTL, props->ttl);
NLA_PUT_U32 (nlmsg, IFLA_VXLAN_AGEING, props->ageing);
NLA_PUT_U32 (nlmsg, IFLA_VXLAN_LIMIT, props->limit);
NLA_PUT_U8 (nlmsg, IFLA_VXLAN_LEARNING, !!props->learning);
NLA_PUT_U8 (nlmsg, IFLA_VXLAN_PROXY, !!props->proxy);
NLA_PUT_U8 (nlmsg, IFLA_VXLAN_RSC, !!props->rsc);
NLA_PUT_U8 (nlmsg, IFLA_VXLAN_L2MISS, !!props->l2miss);
NLA_PUT_U8 (nlmsg, IFLA_VXLAN_L3MISS, !!props->l3miss);
nla_nest_end (nlmsg, data);
nla_nest_end (nlmsg, info);
return do_add_link_with_lookup (platform, NM_LINK_TYPE_VXLAN, name, nlmsg, out_link);
nla_put_failure:
g_return_val_if_reached (FALSE);
}
static void
_vlan_change_vlan_qos_mapping_create (gboolean is_ingress_map,
gboolean reset_all,
@ -5899,6 +5974,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->vlan_add = vlan_add;
platform_class->link_vlan_change = link_vlan_change;
platform_class->link_vxlan_add = link_vxlan_add;
platform_class->tun_add = tun_add;

View file

@ -1559,6 +1559,38 @@ nm_platform_vlan_add (NMPlatform *self,
return NM_PLATFORM_ERROR_SUCCESS;
}
/**
* nm_platform_link_vxlan_add:
* @self: platform instance
* @name: New interface name
* @props: properties of the new link
* @out_link: on success, the link object
*
* Create a VXLAN device.
*/
NMPlatformError
nm_platform_link_vxlan_add (NMPlatform *self,
const char *name,
NMPlatformLnkVxlan *props,
NMPlatformLink *out_link)
{
NMPlatformError plerr;
_CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG);
plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_VXLAN, out_link);
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
return plerr;
_LOGD ("link: adding vxlan '%s' parent %d id %d",
name, props->parent_ifindex, props->id);
if (!klass->link_vxlan_add (self, name, props, out_link))
return NM_PLATFORM_ERROR_UNSPECIFIED;
return NM_PLATFORM_ERROR_SUCCESS;
}
/**
* nm_platform_tun_add:
* @self: platform instance
@ -1596,7 +1628,6 @@ nm_platform_tun_add (NMPlatform *self, const char *name, gboolean tap,
return NM_PLATFORM_ERROR_SUCCESS;
}
gboolean
nm_platform_master_set_option (NMPlatform *self, int ifindex, const char *option, const char *value)
{

View file

@ -561,6 +561,8 @@ typedef struct {
gboolean egress_reset_all,
const NMVlanQosMapping *egress_map,
gsize n_egress_map);
gboolean (*link_vxlan_add) (NMPlatform *, const char *name, NMPlatformLnkVxlan *props,
NMPlatformLink *out_link);
gboolean (*link_gre_add) (NMPlatform *, const char *name, NMPlatformLnkGre *props,
NMPlatformLink *out_link);
@ -785,6 +787,7 @@ gboolean nm_platform_link_vlan_change (NMPlatform *self,
const NMVlanQosMapping *egress_map,
gsize n_egress_map);
NMPlatformError nm_platform_link_vxlan_add (NMPlatform *self, const char *name, NMPlatformLnkVxlan *props, NMPlatformLink *out_link);
NMPlatformError nm_platform_tun_add (NMPlatform *self, const char *name, gboolean tap, gint64 owner, gint64 group, gboolean pi,
gboolean vnet_hdr, gboolean multi_queue, NMPlatformLink *out_link);

View file

@ -838,6 +838,49 @@ nmtstp_link_sit_add (gboolean external_command, const char *name, NMPlatformLnkS
return success;
}
gboolean
nmtstp_link_vxlan_add (gboolean external_command, const char *name, NMPlatformLnkVxlan *lnk)
{
gboolean success;
external_command = nmtstp_run_command_check_external (external_command);
if (external_command) {
gs_free char *dev = NULL;
gs_free char *local = NULL, *remote = NULL;
if (lnk->parent_ifindex)
dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (NM_PLATFORM_GET, lnk->parent_ifindex));
if (lnk->local)
local = g_strdup_printf ("%s", nm_utils_inet4_ntop (lnk->local, NULL));
else if (memcmp (&lnk->local6, &in6addr_any, sizeof (in6addr_any)))
local = g_strdup_printf ("%s", nm_utils_inet6_ntop (&lnk->local6, NULL));
if (lnk->group)
remote = g_strdup_printf ("%s", nm_utils_inet4_ntop (lnk->group, NULL));
else if (memcmp (&lnk->group6, &in6addr_any, sizeof (in6addr_any)))
remote = g_strdup_printf ("%s", nm_utils_inet6_ntop (&lnk->group6, NULL));
success = !nmtstp_run_command ("ip link add %s type vxlan id %u %s local %s group %s ttl %u tos %02x dstport %u srcport %u %u ageing %u",
name,
lnk->id,
dev ? dev : "",
local,
remote,
lnk->ttl,
lnk->tos,
lnk->dst_port,
lnk->src_port_min, lnk->src_port_max,
lnk->ageing);
if (success)
nmtstp_assert_wait_for_link (name, NM_LINK_TYPE_VXLAN, 100);
} else
success = nm_platform_link_vxlan_add (NM_PLATFORM_GET, name, lnk, NULL) == NM_PLATFORM_ERROR_SUCCESS;
return success;
}
void
nmtstp_ip4_address_add (gboolean external_command,
int ifindex,

View file

@ -150,6 +150,9 @@ gboolean nmtstp_link_macvlan_add (gboolean external_command,
gboolean nmtstp_link_sit_add (gboolean external_command,
const char *name,
NMPlatformLnkSit *lnk);
gboolean nmtstp_link_vxlan_add (gboolean external_command,
const char *name,
NMPlatformLnkVxlan *lnk);
void init_tests (int *argc, char ***argv);
void setup_tests (void);

View file

@ -669,8 +669,8 @@ test_software_detect (gconstpointer user_data)
NMPlatformLnkGre lnk_gre = { };
gboolean gracefully_skip = FALSE;
inet_pton (AF_INET, "192.168.233.204", &lnk_gre.local);
inet_pton (AF_INET, "172.168.10.25", &lnk_gre.remote);
lnk_gre.local = nmtst_inet4_from_string ("192.168.233.204");
lnk_gre.remote = nmtst_inet4_from_string ("172.168.10.25");
lnk_gre.parent_ifindex = ifindex_parent;
lnk_gre.ttl = 174;
lnk_gre.tos = 37;
@ -699,8 +699,8 @@ test_software_detect (gconstpointer user_data)
gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ipip", NULL) != 0;
}
inet_pton (AF_INET, "1.2.3.4", &lnk_ipip.local);
inet_pton (AF_INET, "5.6.7.8", &lnk_ipip.remote);
lnk_ipip.local = nmtst_inet4_from_string ("1.2.3.4");
lnk_ipip.remote = nmtst_inet4_from_string ("5.6.7.8");
lnk_ipip.parent_ifindex = ifindex_parent;
lnk_ipip.tos = 32;
lnk_ipip.path_mtu_discovery = FALSE;
@ -723,8 +723,8 @@ test_software_detect (gconstpointer user_data)
gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_tunnel", NULL) != 0;
}
inet_pton (AF_INET6, "fd01::15", &lnk_ip6tnl.local);
inet_pton (AF_INET6, "fd01::16", &lnk_ip6tnl.remote);
lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::15");
lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::16");
lnk_ip6tnl.parent_ifindex = ifindex_parent;
lnk_ip6tnl.tclass = 20;
lnk_ip6tnl.encap_limit = 6;
@ -766,8 +766,8 @@ test_software_detect (gconstpointer user_data)
NMPlatformLnkSit lnk_sit = { };
gboolean gracefully_skip = FALSE;
inet_pton (AF_INET, "192.168.200.1", &lnk_sit.local);
inet_pton (AF_INET, "172.25.100.14", &lnk_sit.remote);
lnk_sit.local = nmtst_inet4_from_string ("192.168.200.1");
lnk_sit.remote = nmtst_inet4_from_string ("172.25.100.14");
lnk_sit.parent_ifindex = ifindex_parent;
lnk_sit.ttl = 0;
lnk_sit.tos = 31;
@ -790,22 +790,37 @@ test_software_detect (gconstpointer user_data)
case NM_LINK_TYPE_VLAN:
nmtstp_run_command_check ("ip link add name %s link %s type vlan id 1242", DEVICE_NAME, PARENT_NAME);
break;
case NM_LINK_TYPE_VXLAN:
case NM_LINK_TYPE_VXLAN: {
NMPlatformLnkVxlan lnk_vxlan = { };
switch (test_data->test_mode) {
case 0:
if (nmtstp_run_command ("ip link add %s type vxlan id 42 local 23.1.2.164 group 239.1.2.134 dev %s ageing 1245 dstport 4789", DEVICE_NAME, PARENT_NAME)) {
g_test_skip ("could not add a vxlan");
goto out_delete_parent;
}
lnk_vxlan.parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME);
lnk_vxlan.id = 42;
lnk_vxlan.local = nmtst_inet4_from_string ("23.1.2.164");
lnk_vxlan.group = nmtst_inet4_from_string ("239.1.2.134");
lnk_vxlan.dst_port = 4789;
lnk_vxlan.learning = TRUE;
lnk_vxlan.ageing = 1245;
break;
case 1:
if (nmtstp_run_command ("ip link add %s type vxlan id 11214423 local 1:2:3:4:334:23::23 group ff0e::115 dev %s ageing 3245 dstport 57412", DEVICE_NAME, PARENT_NAME)) {
g_test_skip ("could not add a vxlan");
goto out_delete_parent;
}
lnk_vxlan.parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME);
lnk_vxlan.id = 11214423;
lnk_vxlan.local6 = *nmtst_inet6_from_string ("1:2:3:4:334:23::23");
lnk_vxlan.group6 = *nmtst_inet6_from_string ("ff0e::115");
lnk_vxlan.ttl = 32;
lnk_vxlan.dst_port = 57412;
lnk_vxlan.src_port_min = 1000;
lnk_vxlan.src_port_max = 1003;
lnk_vxlan.learning = TRUE;
lnk_vxlan.ageing = 3245;
break;
}
if (!nmtstp_link_vxlan_add (EX, DEVICE_NAME, &lnk_vxlan))
g_error ("Failed adding VXLAN link");
break;
}
default:
g_assert_not_reached ();
}
@ -922,11 +937,8 @@ test_software_detect (gconstpointer user_data)
g_assert (plnk == nm_platform_link_get_lnk_vxlan (NM_PLATFORM_GET, ifindex, NULL));
g_assert_cmpint (plnk->parent_ifindex, !=, 0);
g_assert_cmpint (plnk->tos, ==, 0);
g_assert_cmpint (plnk->ttl, ==, 0);
g_assert_cmpint (plnk->learning, ==, TRUE);
g_assert_cmpint (plnk->limit, ==, 0);
g_assert_cmpint (plnk->src_port_min, ==, 0);
g_assert_cmpint (plnk->src_port_max, ==, 0);
g_assert_cmpint (plnk->proxy, ==, FALSE);
g_assert_cmpint (plnk->rsc, ==, FALSE);
g_assert_cmpint (plnk->l2miss, ==, FALSE);
@ -939,8 +951,11 @@ test_software_detect (gconstpointer user_data)
nmtst_assert_ip4_address (plnk->group, "239.1.2.134");
nmtst_assert_ip6_address (&plnk->group6, "::");
nmtst_assert_ip6_address (&plnk->local6, "::");
g_assert_cmpint (plnk->ttl, ==, 0);
g_assert_cmpint (plnk->ageing, ==, 1245);
g_assert_cmpint (plnk->dst_port, ==, 4789);
g_assert_cmpint (plnk->src_port_min, ==, 0);
g_assert_cmpint (plnk->src_port_max, ==, 0);
break;
case 1:
g_assert_cmpint (plnk->id, ==, 11214423);
@ -950,6 +965,9 @@ test_software_detect (gconstpointer user_data)
nmtst_assert_ip6_address (&plnk->local6, "1:2:3:4:334:23::23");
g_assert_cmpint (plnk->ageing, ==, 3245);
g_assert_cmpint (plnk->dst_port, ==, 57412);
g_assert_cmpint (plnk->ttl, ==, 32);
g_assert_cmpint (plnk->src_port_min, ==, 1000);
g_assert_cmpint (plnk->src_port_max, ==, 1003);
break;
}
break;