From 4d0192e661e08727bb53295934ec8c3756bd93d7 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 17 Sep 2015 18:13:49 +0200 Subject: [PATCH] libnm-core: add NMSettingMacvlan The setting contains properties that are specific to macvlans and macvtaps. --- libnm-core/Makefile.libnm-core | 2 + libnm-core/nm-connection.c | 18 ++ libnm-core/nm-connection.h | 2 + libnm-core/nm-core-internal.h | 1 + libnm-core/nm-core-types.h | 1 + libnm-core/nm-setting-macvlan.c | 350 ++++++++++++++++++++++++++++++++ libnm-core/nm-setting-macvlan.h | 94 +++++++++ libnm/NetworkManager.h | 1 + libnm/libnm.ver | 8 + po/POTFILES.in | 1 + 10 files changed, 478 insertions(+) create mode 100644 libnm-core/nm-setting-macvlan.c create mode 100644 libnm-core/nm-setting-macvlan.h diff --git a/libnm-core/Makefile.libnm-core b/libnm-core/Makefile.libnm-core index 02c1d1021b..8a81f00f10 100644 --- a/libnm-core/Makefile.libnm-core +++ b/libnm-core/Makefile.libnm-core @@ -28,6 +28,7 @@ libnm_core_headers = \ $(core)/nm-setting-ip-tunnel.h \ $(core)/nm-setting-ip4-config.h \ $(core)/nm-setting-ip6-config.h \ + $(core)/nm-setting-macvlan.h \ $(core)/nm-setting-olpc-mesh.h \ $(core)/nm-setting-ppp.h \ $(core)/nm-setting-pppoe.h \ @@ -86,6 +87,7 @@ libnm_core_sources = \ $(core)/nm-setting-ip-tunnel.c \ $(core)/nm-setting-ip4-config.c \ $(core)/nm-setting-ip6-config.c \ + $(core)/nm-setting-macvlan.c \ $(core)/nm-setting-olpc-mesh.c \ $(core)/nm-setting-ppp.c \ $(core)/nm-setting-pppoe.c \ diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index e801f2fd47..d0c976111a 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -1905,6 +1905,24 @@ nm_connection_get_setting_ip6_config (NMConnection *connection) return (NMSettingIPConfig *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); } +/** + * nm_connection_get_setting_macvlan: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingMacvlan the connection might contain. + * + * Returns: (transfer none): an #NMSettingMacvlan if the connection contains one, otherwise %NULL + * + * Since: 1.2 + **/ +NMSettingMacvlan * +nm_connection_get_setting_macvlan (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingMacvlan *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MACVLAN); +} + /** * nm_connection_get_setting_olpc_mesh: * @connection: the #NMConnection diff --git a/libnm-core/nm-connection.h b/libnm-core/nm-connection.h index 8896e59bab..855fbc4c5b 100644 --- a/libnm-core/nm-connection.h +++ b/libnm-core/nm-connection.h @@ -206,6 +206,8 @@ NM_AVAILABLE_IN_1_2 NMSettingIPTunnel * nm_connection_get_setting_ip_tunnel (NMConnection *connection); NMSettingIPConfig * nm_connection_get_setting_ip4_config (NMConnection *connection); NMSettingIPConfig * nm_connection_get_setting_ip6_config (NMConnection *connection); +NM_AVAILABLE_IN_1_2 +NMSettingMacvlan * nm_connection_get_setting_macvlan (NMConnection *connection); NMSettingOlpcMesh * nm_connection_get_setting_olpc_mesh (NMConnection *connection); NMSettingPpp * nm_connection_get_setting_ppp (NMConnection *connection); NMSettingPppoe * nm_connection_get_setting_pppoe (NMConnection *connection); diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index c1eea777f2..f2c6c6c07e 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -52,6 +52,7 @@ #include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-macvlan.h" #include "nm-setting-olpc-mesh.h" #include "nm-setting-ppp.h" #include "nm-setting-pppoe.h" diff --git a/libnm-core/nm-core-types.h b/libnm-core/nm-core-types.h index 29a34cc68d..68a1ebc6e6 100644 --- a/libnm-core/nm-core-types.h +++ b/libnm-core/nm-core-types.h @@ -45,6 +45,7 @@ typedef struct _NMSettingIPConfig NMSettingIPConfig; typedef struct _NMSettingIPTunnel NMSettingIPTunnel; typedef struct _NMSettingIP4Config NMSettingIP4Config; typedef struct _NMSettingIP6Config NMSettingIP6Config; +typedef struct _NMSettingMacvlan NMSettingMacvlan; typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh; typedef struct _NMSettingPpp NMSettingPpp; typedef struct _NMSettingPppoe NMSettingPppoe; diff --git a/libnm-core/nm-setting-macvlan.c b/libnm-core/nm-setting-macvlan.c new file mode 100644 index 0000000000..7bedf5143d --- /dev/null +++ b/libnm-core/nm-setting-macvlan.c @@ -0,0 +1,350 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2015 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-macvlan.h" +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-setting-wired.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-macvlan + * @short_description: Describes connection properties for macvlan interfaces + * + * The #NMSettingMacvlan object is a #NMSetting subclass that describes properties + * necessary for connection to macvlan interfaces. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingMacvlan, nm_setting_macvlan, NM_TYPE_SETTING, + _nm_register_setting (MACVLAN, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_MACVLAN) + +#define NM_SETTING_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanPrivate)) + +typedef struct { + char *parent; + NMSettingMacvlanMode mode; + gboolean promiscuous; + gboolean tap; +} NMSettingMacvlanPrivate; + +enum { + PROP_0, + PROP_PARENT, + PROP_MODE, + PROP_PROMISCUOUS, + PROP_TAP, + LAST_PROP +}; + +/** + * nm_setting_macvlan_new: + * + * Creates a new #NMSettingMacvlan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingMacvlan object + * + * Since: 1.2 + **/ +NMSetting * +nm_setting_macvlan_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_MACVLAN, NULL); +} + +/** + * nm_setting_macvlan_get_parent: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:parent property of the setting + * + * Since: 1.2 + **/ +const char * +nm_setting_macvlan_get_parent (NMSettingMacvlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), NULL); + return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->parent; +} + +/** + * nm_setting_macvlan_get_mode: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:mode property of the setting + * + * Since: 1.2 + **/ +NMSettingMacvlanMode +nm_setting_macvlan_get_mode (NMSettingMacvlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), NM_SETTING_MACVLAN_MODE_UNKNOWN); + return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->mode; +} + +/** + * nm_setting_macvlan_get_promiscuous: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:promiscuous property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_macvlan_get_promiscuous (NMSettingMacvlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), FALSE); + return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->promiscuous; +} + +/** + * nm_setting_macvlan_get_tap: + * @setting: the #NMSettingMacvlan + * + * Returns: the #NMSettingMacvlan:tap property of the setting + * + * Since: 1.2 + **/ +gboolean +nm_setting_macvlan_get_tap (NMSettingMacvlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), FALSE); + return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->tap; +} + +/*********************************************************************/ + +static void +nm_setting_macvlan_init (NMSettingMacvlan *setting) +{ +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting); + NMSettingConnection *s_con; + NMSettingWired *s_wired; + + if (connection) { + s_con = nm_connection_get_setting_connection (connection); + s_wired = nm_connection_get_setting_wired (connection); + } else { + s_con = NULL; + s_wired = NULL; + } + + if (priv->parent) { + if ( !nm_utils_is_uuid (priv->parent) + && !nm_utils_iface_valid_name (priv->parent)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT); + return FALSE; + } + } else { + /* If parent is NULL, the parent must be specified via + * NMSettingWired:mac-address. + */ + if ( connection + && (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified and neither is '%s:%s'"), + NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); + g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT); + return FALSE; + } + } + + if (!priv->promiscuous && priv->mode != NM_SETTING_MACVLAN_MODE_PASSTHRU) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("non promiscuous operation is allowed only in passthru mode'")); + g_prefix_error (error, "%s.%s: ", + NM_SETTING_MACVLAN_SETTING_NAME, + NM_SETTING_MACVLAN_PROMISCUOUS); + return FALSE; + + } + + return TRUE; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_free (priv->parent); + priv->parent = g_value_dup_string (value); + break; + case PROP_MODE: + priv->mode = g_value_get_uint (value); + break; + case PROP_PROMISCUOUS: + priv->promiscuous = g_value_get_boolean (value); + break; + case PROP_TAP: + priv->tap = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string (value, priv->parent); + break; + case PROP_MODE: + g_value_set_uint (value, priv->mode); + break; + case PROP_PROMISCUOUS: + g_value_set_boolean (value, priv->promiscuous); + break; + case PROP_TAP: + g_value_set_boolean (value, priv->tap); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +finalize (GObject *object) +{ + NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object); + NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting); + + g_free (priv->parent); + + G_OBJECT_CLASS (nm_setting_macvlan_parent_class)->finalize (object); +} + +static void +nm_setting_macvlan_class_init (NMSettingMacvlanClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingMacvlanPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + + /** + * NMSettingMacvlan:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * from which this MAC-VLAN interface should be created. If this property is + * not specified, the connection must contain an #NMSettingWired setting + * with a #NMSettingWired:mac-address property. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_string (NM_SETTING_MACVLAN_PARENT, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingMacvlan:mode: + * + * The macvlan mode, which specifies the communication mechanism between multiple + * macvlans on the same lower device. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_uint (NM_SETTING_MACVLAN_MODE, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingMacvlan:promiscuous: + * + * Whether the interface should be put in promiscuous mode. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_PROMISCUOUS, + g_param_spec_boolean (NM_SETTING_MACVLAN_PROMISCUOUS, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingMacvlan:tap: + * + * Whether the interface should be a MACVTAP. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_TAP, + g_param_spec_boolean (NM_SETTING_MACVLAN_TAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-macvlan.h b/libnm-core/nm-setting-macvlan.h new file mode 100644 index 0000000000..3922cd93f6 --- /dev/null +++ b/libnm-core/nm-setting-macvlan.h @@ -0,0 +1,94 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2015 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_MACVLAN_H__ +#define __NM_SETTING_MACVLAN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_MACVLAN (nm_setting_macvlan_get_type ()) +#define NM_SETTING_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlan)) +#define NM_SETTING_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_MACVLANCONFIG, NMSettingMacvlanClass)) +#define NM_IS_SETTING_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_MACVLAN)) +#define NM_IS_SETTING_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_MACVLAN)) +#define NM_SETTING_MACVLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanClass)) + +#define NM_SETTING_MACVLAN_SETTING_NAME "macvlan" + +#define NM_SETTING_MACVLAN_PARENT "parent" +#define NM_SETTING_MACVLAN_MODE "mode" +#define NM_SETTING_MACVLAN_PROMISCUOUS "promiscuous" +#define NM_SETTING_MACVLAN_TAP "tap" + +struct _NMSettingMacvlan { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingMacvlanClass; + +/** + * NMSettingMacvlanMode: + * @NM_SETTING_MACVLAN_MODE_UNKNOWN: unknown/unset mode + * @NM_SETTING_MACVLAN_MODE_VEPA: Virtual Ethernet Port Aggregator mode + * @NM_SETTING_MACVLAN_MODE_BRIDGE: bridge mode + * @NM_SETTING_MACVLAN_MODE_PRIVATE: private mode + * @NM_SETTING_MACVLAN_MODE_PASSTHRU: passthru mode + * @NM_SETTING_MACVLAN_MODE_SOURCE: source mode + **/ +typedef enum { + NM_SETTING_MACVLAN_MODE_UNKNOWN = 0, + NM_SETTING_MACVLAN_MODE_VEPA = 1, + NM_SETTING_MACVLAN_MODE_BRIDGE = 2, + NM_SETTING_MACVLAN_MODE_PRIVATE = 3, + NM_SETTING_MACVLAN_MODE_PASSTHRU = 4, + NM_SETTING_MACVLAN_MODE_SOURCE = 5, + _NM_SETTING_MACVLAN_MODE_NUM, /*< skip >*/ + NM_SETTING_MACVLAN_MODE_LAST = _NM_SETTING_MACVLAN_MODE_NUM - 1, /*< skip >*/ +} NMSettingMacvlanMode; + +NM_AVAILABLE_IN_1_2 +GType nm_setting_macvlan_get_type (void); +NM_AVAILABLE_IN_1_2 +NMSetting *nm_setting_macvlan_new (void); + +NM_AVAILABLE_IN_1_2 +const char *nm_setting_macvlan_get_parent (NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +NMSettingMacvlanMode nm_setting_macvlan_get_mode (NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_macvlan_get_promiscuous (NMSettingMacvlan *setting); +NM_AVAILABLE_IN_1_2 +gboolean nm_setting_macvlan_get_tap (NMSettingMacvlan *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_MACVLAN_H__ */ diff --git a/libnm/NetworkManager.h b/libnm/NetworkManager.h index 17e7a3523b..51a703ed0e 100644 --- a/libnm/NetworkManager.h +++ b/libnm/NetworkManager.h @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include diff --git a/libnm/libnm.ver b/libnm/libnm.ver index e092a5845a..66747d1b45 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -859,6 +859,7 @@ libnm_1_2_0 { global: nm_access_point_get_last_seen; nm_connection_get_setting_ip_tunnel; + nm_connection_get_setting_macvlan; nm_connection_verify_secrets; nm_device_ethernet_get_s390_subchannels; nm_client_get_all_devices; @@ -944,6 +945,13 @@ global: nm_setting_tun_new; nm_setting_verify_secrets; nm_setting_vpn_get_timeout; + nm_setting_macvlan_get_mode; + nm_setting_macvlan_get_parent; + nm_setting_macvlan_get_promiscuous; + nm_setting_macvlan_get_tap; + nm_setting_macvlan_get_type; + nm_setting_macvlan_mode_get_type; + nm_setting_macvlan_new; nm_setting_wired_get_wake_on_lan; nm_setting_wired_get_wake_on_lan_password; nm_setting_wired_wake_on_lan_get_type; diff --git a/po/POTFILES.in b/po/POTFILES.in index 90dc131304..5316f53840 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -67,6 +67,7 @@ libnm-core/nm-setting-ip-config.c libnm-core/nm-setting-ip4-config.c libnm-core/nm-setting-ip6-config.c libnm-core/nm-setting-ip-tunnel.c +libnm-core/nm-setting-macvlan.c libnm-core/nm-setting-olpc-mesh.c libnm-core/nm-setting-ppp.c libnm-core/nm-setting-pppoe.c