diff --git a/clients/cli/devices.c b/clients/cli/devices.c
index 9c64c880d1..5530adc73c 100644
--- a/clients/cli/devices.c
+++ b/clients/cli/devices.c
@@ -192,11 +192,12 @@ static NmcOutputField nmc_fields_dev_show_master_prop[] = {
/* Available fields for 'device show' - VLAN part */
static NmcOutputField nmc_fields_dev_show_vlan_prop[] = {
{"NAME", N_("NAME"), 18}, /* 0 */
- {"ID", N_("ID"), 5}, /* 1 */
+ {"PARENT", N_("PARENT"), 10}, /* 1 */
+ {"ID", N_("ID"), 5}, /* 2 */
{NULL, NULL, 0}
};
-#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_ALL "NAME,ID"
-#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_COMMON "NAME,ID"
+#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_ALL "NAME,PARENT,ID"
+#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_COMMON "NAME,PARENT,ID"
/* Available fields for 'device show' - BLUETOOTH part */
static NmcOutputField nmc_fields_dev_show_bluetooth[] = {
@@ -1084,6 +1085,7 @@ show_device_info (NMDevice *device, NmCli *nmc)
if ((NM_IS_DEVICE_VLAN (device))) {
if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[14].name)) {
char * vlan_id_str = g_strdup_printf ("%u", nm_device_vlan_get_vlan_id (NM_DEVICE_VLAN (device)));
+ NMDevice *parent = nm_device_vlan_get_parent (NM_DEVICE_VLAN (device));
tmpl = nmc_fields_dev_show_vlan_prop;
tmpl_len = sizeof (nmc_fields_dev_show_vlan_prop);
@@ -1094,7 +1096,8 @@ show_device_info (NMDevice *device, NmCli *nmc)
arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX);
set_val_strc (arr, 0, nmc_fields_dev_show_sections[14].name); /* "VLAN" */
- set_val_str (arr, 1, vlan_id_str);
+ set_val_strc (arr, 1, parent ? nm_device_get_iface (parent) : NULL);
+ set_val_str (arr, 2, vlan_id_str);
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */
diff --git a/introspection/nm-device-vlan.xml b/introspection/nm-device-vlan.xml
index 54b7bbe482..992340e009 100644
--- a/introspection/nm-device-vlan.xml
+++ b/introspection/nm-device-vlan.xml
@@ -15,6 +15,12 @@
+
+
+ Object path of the parent device of this VLAN device.
+
+
+
The VLAN ID of this VLAN interface.
diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver
index c0f1bba0dc..9219c4a2bb 100644
--- a/libnm-glib/libnm-glib.ver
+++ b/libnm-glib/libnm-glib.ver
@@ -183,6 +183,7 @@ global:
nm_device_vlan_error_quark;
nm_device_vlan_get_carrier;
nm_device_vlan_get_hw_address;
+ nm_device_vlan_get_parent;
nm_device_vlan_get_type;
nm_device_vlan_get_vlan_id;
nm_device_vlan_new;
diff --git a/libnm-glib/nm-device-vlan.c b/libnm-glib/nm-device-vlan.c
index 8f8750e22d..f28b86a1c0 100644
--- a/libnm-glib/nm-device-vlan.c
+++ b/libnm-glib/nm-device-vlan.c
@@ -42,6 +42,7 @@ typedef struct {
char *hw_address;
gboolean carrier;
+ NMDevice *parent;
guint vlan_id;
} NMDeviceVlanPrivate;
@@ -49,6 +50,7 @@ enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_CARRIER,
+ PROP_PARENT,
PROP_VLAN_ID,
LAST_PROP
@@ -131,6 +133,23 @@ nm_device_vlan_get_carrier (NMDeviceVlan *device)
return NM_DEVICE_VLAN_GET_PRIVATE (device)->carrier;
}
+/**
+ * nm_device_vlan_get_parent:
+ * @device: a #NMDeviceVlan
+ *
+ * Returns: the device's parent device
+ *
+ * Since: 1.0
+ **/
+NMDevice *
+nm_device_vlan_get_parent (NMDeviceVlan *device)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE);
+
+ _nm_object_ensure_inited (NM_OBJECT (device));
+ return NM_DEVICE_VLAN_GET_PRIVATE (device)->parent;
+}
+
/**
* nm_device_vlan_get_vlan_id:
* @device: a #NMDeviceVlan
@@ -231,6 +250,7 @@ register_properties (NMDeviceVlan *device)
const NMPropertiesInfo property_info[] = {
{ NM_DEVICE_VLAN_HW_ADDRESS, &priv->hw_address },
{ NM_DEVICE_VLAN_CARRIER, &priv->carrier },
+ { NM_DEVICE_VLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
{ NM_DEVICE_VLAN_VLAN_ID, &priv->vlan_id },
{ NULL },
};
@@ -256,6 +276,7 @@ dispose (GObject *object)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
+ g_clear_object (&priv->parent);
g_clear_object (&priv->proxy);
G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object);
@@ -288,6 +309,9 @@ get_property (GObject *object,
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_vlan_get_carrier (device));
break;
+ case PROP_PARENT:
+ g_value_set_object (value, nm_device_vlan_get_parent (device));
+ break;
case PROP_VLAN_ID:
g_value_set_uint (value, nm_device_vlan_get_vlan_id (device));
break;
@@ -340,6 +364,20 @@ nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
+ /**
+ * NMDeviceVlan:parent:
+ *
+ * The devices's parent device.
+ *
+ * Since: 1.0
+ **/
+ g_object_class_install_property
+ (object_class, PROP_PARENT,
+ g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "",
+ NM_TYPE_DEVICE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
/**
* NMDeviceVlan:vlan-id:
*
diff --git a/libnm-glib/nm-device-vlan.h b/libnm-glib/nm-device-vlan.h
index 511d02215b..107cfea88f 100644
--- a/libnm-glib/nm-device-vlan.h
+++ b/libnm-glib/nm-device-vlan.h
@@ -15,7 +15,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
- * Copyright 2012 Red Hat, Inc.
+ * Copyright 2012 - 2014 Red Hat, Inc.
*/
#ifndef NM_DEVICE_VLAN_H
@@ -55,6 +55,7 @@ GQuark nm_device_vlan_error_quark (void);
#define NM_DEVICE_VLAN_HW_ADDRESS "hw-address"
#define NM_DEVICE_VLAN_CARRIER "carrier"
+#define NM_DEVICE_VLAN_PARENT "parent"
#define NM_DEVICE_VLAN_VLAN_ID "vlan-id"
typedef struct {
@@ -79,6 +80,8 @@ GObject *nm_device_vlan_new (DBusGConnection *connection, const char *path);
const char * nm_device_vlan_get_hw_address (NMDeviceVlan *device);
gboolean nm_device_vlan_get_carrier (NMDeviceVlan *device);
+NM_AVAILABLE_IN_1_0
+NMDevice * nm_device_vlan_get_parent (NMDeviceVlan *device);
guint nm_device_vlan_get_vlan_id (NMDeviceVlan *device);
G_END_DECLS
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index b402be6c0f..d81a24c7eb 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -237,6 +237,7 @@ global:
nm_device_type_get_type;
nm_device_vlan_get_carrier;
nm_device_vlan_get_hw_address;
+ nm_device_vlan_get_parent;
nm_device_vlan_get_type;
nm_device_vlan_get_vlan_id;
nm_device_wifi_capabilities_get_type;
diff --git a/libnm/nm-device-vlan.c b/libnm/nm-device-vlan.c
index b34b3e14d2..c4a036c1ec 100644
--- a/libnm/nm-device-vlan.c
+++ b/libnm/nm-device-vlan.c
@@ -41,6 +41,7 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE)
typedef struct {
char *hw_address;
gboolean carrier;
+ NMDevice *parent;
guint vlan_id;
} NMDeviceVlanPrivate;
@@ -48,6 +49,7 @@ enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_CARRIER,
+ PROP_PARENT,
PROP_VLAN_ID,
LAST_PROP
@@ -86,6 +88,20 @@ nm_device_vlan_get_carrier (NMDeviceVlan *device)
return NM_DEVICE_VLAN_GET_PRIVATE (device)->carrier;
}
+/**
+ * nm_device_vlan_get_parent:
+ * @device: a #NMDeviceVlan
+ *
+ * Returns: the device's parent device
+ **/
+NMDevice *
+nm_device_vlan_get_parent (NMDeviceVlan *device)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE);
+
+ return NM_DEVICE_VLAN_GET_PRIVATE (device)->parent;
+}
+
/**
* nm_device_vlan_get_vlan_id:
* @device: a #NMDeviceVlan
@@ -166,6 +182,7 @@ init_dbus (NMObject *object)
const NMPropertiesInfo property_info[] = {
{ NM_DEVICE_VLAN_HW_ADDRESS, &priv->hw_address },
{ NM_DEVICE_VLAN_CARRIER, &priv->carrier },
+ { NM_DEVICE_VLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
{ NM_DEVICE_VLAN_VLAN_ID, &priv->vlan_id },
{ NULL },
};
@@ -183,6 +200,7 @@ finalize (GObject *object)
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
g_free (priv->hw_address);
+ g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object);
}
@@ -202,6 +220,9 @@ get_property (GObject *object,
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_vlan_get_carrier (device));
break;
+ case PROP_PARENT:
+ g_value_set_object (value, nm_device_vlan_get_parent (device));
+ break;
case PROP_VLAN_ID:
g_value_set_uint (value, nm_device_vlan_get_vlan_id (device));
break;
@@ -258,6 +279,18 @@ nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
+ /**
+ * NMDeviceVlan:parent:
+ *
+ * The devices's parent device.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_PARENT,
+ g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "",
+ NM_TYPE_DEVICE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
/**
* NMDeviceVlan:vlan-id:
*
diff --git a/libnm/nm-device-vlan.h b/libnm/nm-device-vlan.h
index 824944f743..6ab2420220 100644
--- a/libnm/nm-device-vlan.h
+++ b/libnm/nm-device-vlan.h
@@ -15,7 +15,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
- * Copyright 2012 Red Hat, Inc.
+ * Copyright 2012 - 2014 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_VLAN_H__
@@ -38,6 +38,7 @@ G_BEGIN_DECLS
#define NM_DEVICE_VLAN_HW_ADDRESS "hw-address"
#define NM_DEVICE_VLAN_CARRIER "carrier"
+#define NM_DEVICE_VLAN_PARENT "parent"
#define NM_DEVICE_VLAN_VLAN_ID "vlan-id"
struct _NMDeviceVlan {
@@ -55,6 +56,7 @@ GType nm_device_vlan_get_type (void);
const char * nm_device_vlan_get_hw_address (NMDeviceVlan *device);
gboolean nm_device_vlan_get_carrier (NMDeviceVlan *device);
+NMDevice * nm_device_vlan_get_parent (NMDeviceVlan *device);
guint nm_device_vlan_get_vlan_id (NMDeviceVlan *device);
G_END_DECLS
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index 555180f4e7..a245a434b2 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -67,6 +67,8 @@ enum {
PROP_PARENT,
PROP_VLAN_ID,
+ PROP_INT_PARENT_DEVICE,
+
LAST_PROP
};
@@ -406,16 +408,7 @@ parent_state_changed (NMDevice *parent,
if (reason == NM_DEVICE_STATE_REASON_CARRIER)
return;
- if (new_state < NM_DEVICE_STATE_DISCONNECTED) {
- /* If the parent becomes unavailable or unmanaged so does the VLAN */
- nm_device_state_changed (NM_DEVICE (self), new_state, reason);
- } else if ( new_state == NM_DEVICE_STATE_DISCONNECTED
- && old_state < NM_DEVICE_STATE_DISCONNECTED) {
- /* Mark VLAN interface as available/disconnected when the parent
- * becomes available as a result of becoming initialized.
- */
- nm_device_state_changed (NM_DEVICE (self), new_state, reason);
- }
+ nm_device_set_unmanaged (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent), reason);
}
/******************************************************************/
@@ -477,6 +470,12 @@ get_property (GObject *object, guint prop_id,
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
switch (prop_id) {
+ case PROP_PARENT:
+ g_value_set_boxed (value, priv->parent ? nm_device_get_path (priv->parent) : "/");
+ break;
+ case PROP_INT_PARENT_DEVICE:
+ g_value_set_object (value, priv->parent);
+ break;
case PROP_VLAN_ID:
g_value_set_uint (value, priv->vlan_id);
break;
@@ -493,7 +492,7 @@ set_property (GObject *object, guint prop_id,
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
switch (prop_id) {
- case PROP_PARENT:
+ case PROP_INT_PARENT_DEVICE:
nm_device_vlan_set_parent (NM_DEVICE_VLAN (object), g_value_get_object (value));
break;
case PROP_VLAN_ID:
@@ -564,10 +563,10 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
/* properties */
g_object_class_install_property
(object_class, PROP_PARENT,
- g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "",
- NM_TYPE_DEVICE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
+ g_param_spec_boxed (NM_DEVICE_VLAN_PARENT, "", "",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_VLAN_ID,
g_param_spec_uint (NM_DEVICE_VLAN_ID, "", "",
@@ -575,6 +574,14 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
+ /* Internal properties */
+ g_object_class_install_property
+ (object_class, PROP_INT_PARENT_DEVICE,
+ g_param_spec_object (NM_DEVICE_VLAN_INT_PARENT_DEVICE, "", "",
+ NM_TYPE_DEVICE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
G_TYPE_FROM_CLASS (klass),
&dbus_glib_nm_device_vlan_object_info);
@@ -613,7 +620,7 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error)
device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN,
NM_DEVICE_PLATFORM_DEVICE, plink,
- NM_DEVICE_VLAN_PARENT, parent,
+ NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent,
NM_DEVICE_DRIVER, "8021q",
NM_DEVICE_TYPE_DESC, "VLAN",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN,
@@ -623,6 +630,10 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error)
device = NULL;
}
+ /* Set initial parent-dependent unmanaged flag */
+ if (device)
+ nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_PARENT, !nm_device_get_managed (parent));
+
return device;
}
@@ -663,7 +674,7 @@ create_virtual_device_for_connection (NMDeviceFactory *factory,
device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN,
NM_DEVICE_IFACE, iface,
- NM_DEVICE_VLAN_PARENT, parent,
+ NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent,
NM_DEVICE_DRIVER, "8021q",
NM_DEVICE_TYPE_DESC, "VLAN",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN,
@@ -674,6 +685,10 @@ create_virtual_device_for_connection (NMDeviceFactory *factory,
device = NULL;
}
+ /* Set initial parent-dependent unmanaged flag */
+ if (device)
+ nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_PARENT, !nm_device_get_managed (parent));
+
return device;
}
diff --git a/src/devices/nm-device-vlan.h b/src/devices/nm-device-vlan.h
index e1618db440..20fc345379 100644
--- a/src/devices/nm-device-vlan.h
+++ b/src/devices/nm-device-vlan.h
@@ -40,9 +40,13 @@ typedef enum {
NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
} NMVlanError;
+/* D-Bus exported properties */
#define NM_DEVICE_VLAN_PARENT "parent"
#define NM_DEVICE_VLAN_ID "vlan-id"
+/* Internal non-exported properties */
+#define NM_DEVICE_VLAN_INT_PARENT_DEVICE "int-parent-device"
+
typedef NMDevice NMDeviceVlan;
typedef NMDeviceClass NMDeviceVlanClass;
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 9d0ff78179..ab54262623 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -301,12 +301,14 @@ RfKillType nm_device_get_rfkill_type (NMDevice *device);
* @NM_UNMANAGED_INTERNAL: %TRUE when unmanaged by internal decision (ie,
* because NM is sleeping or not managed for some other reason)
* @NM_UNMANAGED_USER: %TRUE when unmanaged by user decision (via unmanaged-specs)
+ * @NM_UNMANAGED_PARENT: %TRUE when unmanaged due to parent device being unmanaged
*/
typedef enum {
NM_UNMANAGED_NONE = 0x00,
NM_UNMANAGED_DEFAULT = 0x01,
NM_UNMANAGED_INTERNAL = 0x02,
NM_UNMANAGED_USER = 0x04,
+ NM_UNMANAGED_PARENT = 0x08,
/* Boundary value */
__NM_UNMANAGED_LAST,