NMDeviceVLAN represents a VLAN device in NetworkManager. When a VLAN device is created in kernel, NetworkManager will receive the event and create a corresponding NMDeviceVLAN.
Signed-off-by: Weiping Pan <[email protected]> --- include/NetworkManager.h | 1 + src/Makefile.am | 2 + src/nm-device-vlan.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++ src/nm-device-vlan.h | 59 ++++++++ 4 files changed, 392 insertions(+), 0 deletions(-) create mode 100644 src/nm-device-vlan.c create mode 100644 src/nm-device-vlan.h diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 3522dd2..87d7d7f 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -114,6 +114,7 @@ typedef enum { NM_DEVICE_TYPE_OLPC_MESH = 6, NM_DEVICE_TYPE_WIMAX = 7, NM_DEVICE_TYPE_MODEM = 8, + NM_DEVICE_TYPE_VLAN = 9, } NMDeviceType; /** diff --git a/src/Makefile.am b/src/Makefile.am index cbcfdc6..e086024 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -126,6 +126,8 @@ NetworkManager_SOURCES = \ nm-device-bt.h \ nm-device-modem.h \ nm-device-modem.c \ + nm-device-vlan.h \ + nm-device-vlan.c \ nm-wifi-ap.c \ nm-wifi-ap.h \ nm-wifi-ap-utils.c \ diff --git a/src/nm-device-vlan.c b/src/nm-device-vlan.c new file mode 100644 index 0000000..23abdbc --- /dev/null +++ b/src/nm-device-vlan.c @@ -0,0 +1,330 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#include <string.h> +#include <glib.h> + +#include "nm-system.h" +#include "nm-device-vlan.h" +#include "nm-device-interface.h" +#include "nm-device-private.h" +#include "nm-properties-changed-signal.h" +#include "nm-marshal.h" +#include "nm-logging.h" + +static void device_interface_init (NMDeviceInterface *iface_class); + +G_DEFINE_TYPE_EXTENDED (NMDeviceVLAN, nm_device_vlan, NM_TYPE_DEVICE, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) + +#define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVLANPrivate)) + +typedef struct { + char *interface_name; + guint32 vlan_id; + guint32 vlan_flags; + char *vlan_priority_ingress_map; + char *vlan_priority_egress_map; +} NMDeviceVLANPrivate; + +enum { + PROP_0, + PROP_INTERFACE_NAME, + PROP_VLAN_ID, + PROP_VLAN_FLAGS, + PROP_VLAN_PRIORITY_INGRESS_MAP, + PROP_VLAN_PRIORITY_EGRESS_MAP, + LAST_PROP +}; + +static guint32 +real_get_generic_capabilities (NMDevice *device) +{ + return NM_DEVICE_CAP_NM_SUPPORTED; +} + +static NMConnection * +real_get_best_auto_connection (NMDevice *device, + GSList *connections, + char **specific_object) +{ + GSList *iter; + + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *connection = NM_CONNECTION (iter->data); + NMSettingConnection *s_con; + NMSettingVLAN *s_vlan; + const char *connection_type; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + connection_type = nm_setting_connection_get_connection_type (s_con); + if (!strcmp (connection_type, NM_SETTING_VLAN_SETTING_NAME)) { + s_vlan = (NMSettingVLAN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VLAN); + if (s_vlan) { + int vlan_id = 0; + const char *interface_name = NULL; + vlan_id = nm_setting_vlan_get_vlan_id(s_vlan); + interface_name = nm_setting_vlan_get_interface_name(s_vlan); + if (!strcmp(interface_name, nm_device_get_iface(device))) { + return connection; + } + } + } + } + + return NULL; +} + +static gboolean +real_check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error) +{ + NMSettingConnection *s_con; + NMSettingVLAN *s_vlan; + const char *connection_type; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + connection_type = nm_setting_connection_get_connection_type (s_con); + + if (!strcmp (connection_type, NM_SETTING_VLAN_SETTING_NAME)) { + s_vlan = (NMSettingVLAN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VLAN); + if (s_vlan) { + return TRUE; + } + } + + return FALSE; +} + +static gboolean +real_is_up (NMDevice *device) +{ + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); +} + +static gboolean +real_bring_up (NMDevice *device) +{ + return TRUE; +} + +static void +real_take_down (NMDevice *device) +{ +} + +static gboolean +real_hw_is_up (NMDevice *device) +{ + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); +} + +static gboolean +real_hw_bring_up (NMDevice *dev, gboolean *no_firmware) +{ + return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware); +} + +static void +real_hw_take_down (NMDevice *dev) +{ + nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL); +} + +static void +device_state_changed (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) +{ + nm_device_state_changed (device, new_state, reason); +} + +NMDevice * +nm_device_vlan_new (NMSettingVLAN *setting) +{ + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, + NM_DEVICE_INTERFACE_UDI, nm_setting_vlan_get_interface_name(setting), + NM_DEVICE_INTERFACE_IFACE, nm_setting_vlan_get_interface_name(setting), + NM_DEVICE_INTERFACE_DRIVER, "8021q", + NM_DEVICE_INTERFACE_TYPE_DESC, "VLAN", + NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, + NULL); +} + +static void +device_interface_init (NMDeviceInterface *iface_class) +{ +} + +static void +nm_device_vlan_init (NMDeviceVLAN *self) +{ + NMDeviceVLANPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + priv->vlan_priority_ingress_map = NULL; + priv->vlan_priority_egress_map = NULL; + g_signal_connect (self, "state-changed", G_CALLBACK (device_state_changed), self); +} + +static void +finalize (GObject *object) +{ + NMDeviceVLANPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); + + g_free(priv->interface_name); + g_free(priv->vlan_priority_ingress_map); + g_free(priv->vlan_priority_egress_map); + + G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMDeviceVLAN *vlan = NM_DEVICE_VLAN (object); + NMDeviceVLANPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (vlan); + + switch (prop_id) { + case PROP_INTERFACE_NAME: + g_free(priv->interface_name); + priv->interface_name = g_value_dup_string (value); + break; + case PROP_VLAN_ID: + priv->vlan_id = g_value_get_uint(value); + break; + case PROP_VLAN_FLAGS: + priv->vlan_flags |= g_value_get_uint(value); + break; + case PROP_VLAN_PRIORITY_INGRESS_MAP: + g_free(priv->vlan_priority_ingress_map); + priv->vlan_priority_ingress_map = g_value_dup_string(value); + break; + case PROP_VLAN_PRIORITY_EGRESS_MAP: + g_free(priv->vlan_priority_egress_map); + priv->vlan_priority_egress_map = g_value_dup_string(value); + break; + default: + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMDeviceVLAN *vlan= NM_DEVICE_VLAN (object); + NMDeviceVLANPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (vlan); + + switch (prop_id) { + case PROP_INTERFACE_NAME: + g_value_set_string(value, priv->interface_name); + break; + case PROP_VLAN_ID: + g_value_set_uint(value, priv->vlan_id); + break; + case PROP_VLAN_FLAGS: + g_value_set_uint(value, priv->vlan_flags); + break; + case PROP_VLAN_PRIORITY_INGRESS_MAP: + g_value_set_string(value, priv->vlan_priority_ingress_map); + break; + case PROP_VLAN_PRIORITY_EGRESS_MAP: + g_value_set_string(value, priv->vlan_priority_egress_map); + break; + default: + break; + } +} + +static void +nm_device_vlan_class_init (NMDeviceVLANClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (class); + + g_type_class_add_private (object_class, sizeof (NMDeviceVLANPrivate)); + + /* Virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + object_class->set_property = set_property; + + device_class->get_generic_capabilities = real_get_generic_capabilities; + device_class->check_connection_compatible = real_check_connection_compatible; + device_class->hw_is_up = real_hw_is_up; + device_class->hw_bring_up = real_hw_bring_up; + device_class->hw_take_down = real_hw_take_down; + device_class->is_up = real_is_up; + device_class->bring_up = real_bring_up; + device_class->take_down = real_take_down; + device_class->get_best_auto_connection = real_get_best_auto_connection; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_INTERFACE_NAME, + g_param_spec_string( NM_DEVICE_VLAN_INTERFACE_NAME, + "InterfaceName", + NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT )); + + g_object_class_install_property + (object_class, PROP_VLAN_ID, + g_param_spec_uint (NM_DEVICE_VLAN_VLAN_ID, + "vlan id", + NULL, + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT )); + + g_object_class_install_property + (object_class, PROP_VLAN_FLAGS, + g_param_spec_uint (NM_DEVICE_VLAN_VLAN_FLAGS, + "vlan flags", + NULL, + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT )); + + g_object_class_install_property + (object_class, PROP_VLAN_PRIORITY_INGRESS_MAP, + g_param_spec_string( NM_DEVICE_VLAN_VLAN_INGRESS_PRIORITY_MAP, + "vlan ingress priority map", + NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT )); + + g_object_class_install_property + (object_class, PROP_VLAN_PRIORITY_EGRESS_MAP, + g_param_spec_string( NM_DEVICE_VLAN_VLAN_EGRESS_PRIORITY_MAP, + "vlan egress priority map", + NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); +} diff --git a/src/nm-device-vlan.h b/src/nm-device-vlan.h new file mode 100644 index 0000000..33b88ae --- /dev/null +++ b/src/nm-device-vlan.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef NM_DEVICE_VLAN_H +#define NM_DEVICE_VLAN_H + +#include <glib.h> +#include <glib-object.h> + +#include "nm-device.h" +#include "nm-setting-vlan.h" + +#define NM_TYPE_DEVICE_VLAN (nm_device_vlan_get_type ()) +#define NM_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVLAN)) +#define NM_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VLAN, NMDeviceVLANClass)) +#define NM_IS_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VLAN)) +#define NM_IS_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE_VLAN)) +#define NM_DEVICE_VLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVLANClass)) + +#define NM_DEVICE_VLAN_INTERFACE_NAME "interface-name" +#define NM_DEVICE_VLAN_VLAN_SLAVE "vlan-slave" +#define NM_DEVICE_VLAN_VLAN_ID "vlan-id" +#define NM_DEVICE_VLAN_VLAN_FLAGS "vlan-flags" +#define NM_DEVICE_VLAN_VLAN_NAME_TYPE "vlan-name-type" +#define NM_DEVICE_VLAN_VLAN_INGRESS_PRIORITY_MAP "vlan-priority-ingress-map" +#define NM_DEVICE_VLAN_VLAN_EGRESS_PRIORITY_MAP "vlan-priority-egress-map" + +typedef struct { + NMDevice parent; +} NMDeviceVLAN; + +typedef struct { + NMDeviceClass parent; + + void (*properties_changed) (NMDeviceVLAN *self, GHashTable *properties); +} NMDeviceVLANClass; + +GType nm_device_vlan_get_type (void); + +NMDevice *nm_device_vlan_new (NMSettingVLAN *setting); + +#endif /* NM_DEVICE_VLAN_H */ -- 1.7.4.4 _______________________________________________ networkmanager-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/networkmanager-list
