diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-10-14 10:52:09 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-12-09 15:54:57 +0100 |
commit | 592b02a1e1adb3ff5bf495e54a473b654dd50a9f (patch) | |
tree | 2503f17faa31505f89a5efcb398a1b4494b01684 | |
parent | eb1619e475ee18942b8bc18db52c7ec6e42b95fa (diff) | |
download | NetworkManager-592b02a1e1adb3ff5bf495e54a473b654dd50a9f.tar.gz |
device/vxlan: support device creation
-rw-r--r-- | introspection/nm-device-vxlan.xml | 6 | ||||
-rw-r--r-- | libnm-core/nm-connection.c | 3 | ||||
-rw-r--r-- | libnm-core/nm-dbus-interface.h | 2 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/devices/nm-device-vxlan.c | 454 | ||||
-rw-r--r-- | src/devices/nm-device-vxlan.h | 4 | ||||
-rw-r--r-- | src/devices/nm-device.c | 2 |
7 files changed, 446 insertions, 26 deletions
diff --git a/introspection/nm-device-vxlan.xml b/introspection/nm-device-vxlan.xml index 053eea4d2d..4dd254a223 100644 --- a/introspection/nm-device-vxlan.xml +++ b/introspection/nm-device-vxlan.xml @@ -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). diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 3af8dfe9e0..5a491b4068 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -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)) { diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h index df10e9d80c..b32aabc2b5 100644 --- a/libnm-core/nm-dbus-interface.h +++ b/libnm-core/nm-dbus-interface.h @@ -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; /** diff --git a/po/POTFILES.in b/po/POTFILES.in index f3d20c0c71..45d54adb68 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -158,6 +158,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 diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index beee9f2c6c..7eabbcdb1f 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -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 @@ -237,6 +593,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) { GObjectClass *object_class = G_OBJECT_CLASS (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)); @@ -317,22 +689,22 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) G_PARAM_STATIC_STRINGS)); g_object_class_install_property - (object_class, PROP_DST_PORT, - g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "", + (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)); g_object_class_install_property - (object_class, PROP_SRC_PORT_MIN, - g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, "", "", + (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)); g_object_class_install_property - (object_class, PROP_SRC_PORT_MAX, - g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MAX, "", "", + (object_class, PROP_DST_PORT, + g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "", 0, 65535, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); @@ -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; ) diff --git a/src/devices/nm-device-vxlan.h b/src/devices/nm-device-vxlan.h index 9db78cdfcb..7de04a1242 100644 --- a/src/devices/nm-device-vxlan.h +++ b/src/devices/nm-device-vxlan.h @@ -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); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 36971049dd..d72e8fdcff 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -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: |