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

Reply via email to