core: move carrier handling to NMDevice

Move carrier handling for most device types into NMDevice.

Based on an earlier patch by Pavel Šimerda.
This commit is contained in:
Dan Winship
2013-05-07 10:23:44 -04:00
parent 5a223b9089
commit 82222d3898
17 changed files with 320 additions and 664 deletions

View File

@@ -67,7 +67,6 @@ nm_adsl_error_quark (void)
typedef struct {
gboolean disposed;
gboolean carrier;
guint carrier_poll_id;
int atm_index;
@@ -84,48 +83,14 @@ typedef struct {
char * nas_ifname;
} NMDeviceAdslPrivate;
enum {
PROP_0,
PROP_CARRIER,
LAST_PROP
};
/**************************************************************/
static guint32
get_generic_capabilities (NMDevice *dev)
{
guint32 caps = NM_DEVICE_CAP_NM_SUPPORTED;
caps |= NM_DEVICE_CAP_CARRIER_DETECT;
return caps;
}
static gboolean
can_interrupt_activation (NMDevice *dev)
{
NMDeviceAdsl *self = NM_DEVICE_ADSL (dev);
gboolean interrupt = FALSE;
/* Devices that support carrier detect can interrupt activation
* if the link becomes inactive.
*/
if (NM_DEVICE_ADSL_GET_PRIVATE (self)->carrier == FALSE)
interrupt = TRUE;
return interrupt;
}
static gboolean
is_available (NMDevice *dev)
{
NMDeviceAdsl *self = NM_DEVICE_ADSL (dev);
/* Can't do anything if there isn't a carrier */
if (!NM_DEVICE_ADSL_GET_PRIVATE (self)->carrier)
return FALSE;
return TRUE;
return ( NM_DEVICE_CAP_NM_SUPPORTED
| NM_DEVICE_CAP_CARRIER_DETECT
| NM_DEVICE_CAP_NONSTANDARD_CARRIER);
}
static gboolean
@@ -576,22 +541,6 @@ get_hw_address_length (NMDevice *device)
return priv->nas_ifname ? ETH_ALEN : 0;
}
static void
set_carrier (NMDeviceAdsl *self, const gboolean carrier)
{
NMDeviceAdslPrivate *priv;
g_return_if_fail (NM_IS_DEVICE (self));
priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
if (priv->carrier == carrier)
return;
priv->carrier = carrier;
g_object_notify (G_OBJECT (self), NM_DEVICE_ADSL_CARRIER);
}
static gboolean
carrier_update_cb (gpointer user_data)
{
@@ -619,7 +568,7 @@ carrier_update_cb (gpointer user_data)
carrier = (gboolean) atoi (contents);
g_free (contents);
set_carrier (self, carrier);
nm_device_set_carrier (NM_DEVICE (self), carrier);
return TRUE;
}
@@ -720,34 +669,6 @@ dispose (GObject *object)
G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMDeviceAdsl *self = NM_DEVICE_ADSL (object);
NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self);
switch (prop_id) {
case PROP_CARRIER:
g_value_set_boolean (value, priv->carrier);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_device_adsl_init (NMDeviceAdsl *self)
{
@@ -767,12 +688,8 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass)
object_class->constructor = constructor;
object_class->dispose = dispose;
object_class->get_property = get_property;
object_class->set_property = set_property;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->can_interrupt_activation = can_interrupt_activation;
parent_class->is_available = is_available;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->complete_connection = complete_connection;
@@ -782,15 +699,6 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass)
parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
parent_class->deactivate = deactivate;
/* properties */
g_object_class_install_property
(object_class, PROP_CARRIER,
g_param_spec_boolean (NM_DEVICE_ADSL_CARRIER,
"Carrier",
"Carrier",
FALSE,
G_PARAM_READABLE));
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
G_TYPE_FROM_CLASS (klass),
&dbus_glib_nm_device_adsl_object_info);

View File

@@ -42,8 +42,6 @@ typedef enum {
NM_ADSL_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
} NMAdslError;
#define NM_DEVICE_ADSL_CARRIER "carrier"
typedef struct {
NMDevice parent;
} NMDeviceAdsl;

View File

@@ -51,7 +51,6 @@ typedef struct {
enum {
PROP_0,
PROP_CARRIER,
PROP_SLAVES,
LAST_PROP
@@ -320,8 +319,6 @@ get_property (GObject *object, guint prop_id,
GSList *list, *iter;
switch (prop_id) {
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object)));
break;
case PROP_SLAVES:
slaves = g_ptr_array_new ();
@@ -374,14 +371,6 @@ nm_device_bond_class_init (NMDeviceBondClass *klass)
parent_class->release_slave = release_slave;
/* properties */
g_object_class_install_property
(object_class, PROP_CARRIER,
g_param_spec_boolean (NM_DEVICE_BOND_CARRIER,
"Carrier",
"Carrier",
FALSE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_SLAVES,
g_param_spec_boxed (NM_DEVICE_BOND_SLAVES,

View File

@@ -40,7 +40,6 @@ typedef enum {
NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
} NMBondError;
#define NM_DEVICE_BOND_CARRIER "carrier"
#define NM_DEVICE_BOND_SLAVES "slaves"
typedef struct {

View File

@@ -51,7 +51,6 @@ typedef struct {
enum {
PROP_0,
PROP_CARRIER,
PROP_SLAVES,
LAST_PROP
@@ -353,8 +352,6 @@ get_property (GObject *object, guint prop_id,
GSList *list, *iter;
switch (prop_id) {
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object)));
break;
case PROP_SLAVES:
slaves = g_ptr_array_new ();
@@ -406,14 +403,6 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass)
parent_class->release_slave = release_slave;
/* properties */
g_object_class_install_property
(object_class, PROP_CARRIER,
g_param_spec_boolean (NM_DEVICE_BRIDGE_CARRIER,
"Carrier",
"Carrier",
FALSE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_SLAVES,
g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES,

View File

@@ -40,7 +40,6 @@ typedef enum {
NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
} NMBridgeError;
#define NM_DEVICE_BRIDGE_CARRIER "carrier"
#define NM_DEVICE_BRIDGE_SLAVES "slaves"
typedef struct {

View File

@@ -102,7 +102,6 @@ enum {
PROP_0,
PROP_PERM_HW_ADDRESS,
PROP_SPEED,
PROP_CARRIER,
LAST_PROP
};
@@ -1345,9 +1344,6 @@ get_property (GObject *object, guint prop_id,
case PROP_SPEED:
g_value_set_uint (value, nm_device_wired_get_speed (NM_DEVICE_WIRED (self)));
break;
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (self)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1416,14 +1412,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
0, G_MAXUINT32, 0,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_CARRIER,
g_param_spec_boolean (NM_DEVICE_ETHERNET_CARRIER,
"Carrier",
"Carrier",
FALSE,
G_PARAM_READABLE));
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
G_TYPE_FROM_CLASS (klass),
&dbus_glib_nm_device_ethernet_object_info);

View File

@@ -44,7 +44,6 @@ typedef enum
#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address"
#define NM_DEVICE_ETHERNET_SPEED "speed"
#define NM_DEVICE_ETHERNET_CARRIER "carrier"
typedef struct {
NMDeviceWired parent;

View File

@@ -49,7 +49,6 @@ typedef struct {
enum {
PROP_0,
PROP_CARRIER,
LAST_PROP
};
@@ -300,9 +299,6 @@ get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -344,13 +340,6 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass)
parent_class->get_connection_hw_address = get_connection_hw_address;
/* properties */
g_object_class_install_property
(object_class, PROP_CARRIER,
g_param_spec_boolean (NM_DEVICE_INFINIBAND_CARRIER,
"Carrier",
"Carrier",
FALSE,
G_PARAM_READABLE));
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
G_TYPE_FROM_CLASS (klass),

View File

@@ -40,8 +40,6 @@ typedef enum {
NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
} NMInfinibandError;
#define NM_DEVICE_INFINIBAND_CARRIER "carrier"
typedef struct {
NMDeviceWired parent;
} NMDeviceInfiniband;

View File

@@ -34,6 +34,10 @@ enum NMActStageReturn {
NM_ACT_STAGE_RETURN_STOP /* Activation stage done; nothing to do */
};
#define NM_DEVICE_CAP_NONSTANDARD_CARRIER 0x80000000
#define NM_DEVICE_CAP_INTERNAL_MASK 0x80000000
void nm_device_set_ip_iface (NMDevice *self, const char *iface);
void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device);
@@ -87,4 +91,6 @@ gboolean nm_device_get_enslaved (NMDevice *device);
NMDevice *nm_device_master_get_slave_by_ifindex (NMDevice *dev, int ifindex);
void nm_device_set_carrier (NMDevice *device, gboolean carrier);
#endif /* NM_DEVICE_PRIVATE_H */

View File

@@ -32,10 +32,10 @@
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
#include "nm-device-private.h"
#include "nm-netlink-monitor.h"
#include "nm-enum-types.h"
#include "nm-system.h"
#include "nm-dbus-manager.h"
#include "nm-netlink-monitor.h"
#include "nm-device-vlan-glue.h"
@@ -53,25 +53,15 @@ typedef struct {
guint parent_state_id;
guint vlan_id;
gboolean carrier;
NMNetlinkMonitor *monitor;
gulong link_connected_id;
gulong link_disconnected_id;
} NMDeviceVlanPrivate;
enum {
PROP_0,
PROP_CARRIER,
PROP_VLAN_ID,
LAST_PROP
};
static void
set_carrier (NMDeviceVlan *self,
const gboolean carrier);
/******************************************************************/
static GQuark
@@ -92,29 +82,6 @@ get_generic_capabilities (NMDevice *dev)
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NM_SUPPORTED;
}
static gboolean
get_carrier_sync (NMDeviceVlan *self)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
GError *error = NULL;
guint32 ifflags = 0;
/* Get initial link state */
if (!nm_netlink_monitor_get_flags_sync (priv->monitor,
nm_device_get_ip_ifindex (NM_DEVICE (self)),
&ifflags,
&error)) {
nm_log_warn (LOGD_HW | LOGD_VLAN,
"(%s): couldn't get carrier state: (%d) %s",
nm_device_get_ip_iface (NM_DEVICE (self)),
error ? error->code : -1,
(error && error->message) ? error->message : "unknown");
g_clear_error (&error);
}
return !!(ifflags & IFF_LOWER_UP);
}
static gboolean
hw_bring_up (NMDevice *dev, gboolean *no_firmware)
{
@@ -132,8 +99,22 @@ hw_bring_up (NMDevice *dev, gboolean *no_firmware)
*/
i = 20;
while (i-- > 0) {
carrier = get_carrier_sync (NM_DEVICE_VLAN (dev));
set_carrier (NM_DEVICE_VLAN (dev), carrier);
GError *error = NULL;
guint32 ifflags = 0;
if (!nm_netlink_monitor_get_flags_sync (nm_netlink_monitor_get (),
nm_device_get_ifindex (dev),
&ifflags, &error)) {
nm_log_warn (LOGD_DEVICE | LOGD_VLAN,
"(%s): couldn't get carrier state: %s",
nm_device_get_iface (dev),
error->message);
g_clear_error (&error);
break;
}
carrier = !!(ifflags & IFF_LOWER_UP);
nm_device_set_carrier (dev, carrier);
if (carrier)
break;
g_usleep (100);
@@ -142,24 +123,6 @@ hw_bring_up (NMDevice *dev, gboolean *no_firmware)
return success;
}
static gboolean
can_interrupt_activation (NMDevice *dev)
{
/* Can interrupt activation if the carrier drops while activating */
if (nm_device_ignore_carrier (dev))
return FALSE;
return NM_DEVICE_VLAN_GET_PRIVATE (dev)->carrier ? FALSE : TRUE;
}
static gboolean
is_available (NMDevice *dev)
{
if (nm_device_ignore_carrier (dev))
return TRUE;
return NM_DEVICE_VLAN_GET_PRIVATE (dev)->carrier ? TRUE : FALSE;
}
/******************************************************************/
static gboolean
@@ -340,62 +303,6 @@ match_l2_config (NMDevice *device, NMConnection *connection)
/******************************************************************/
static void
set_carrier (NMDeviceVlan *self,
const gboolean carrier)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
if (priv->carrier == carrier)
return;
priv->carrier = carrier;
g_object_notify (G_OBJECT (self), NM_DEVICE_VLAN_CARRIER);
}
static void
carrier_on (NMNetlinkMonitor *monitor, int idx, NMDevice *device)
{
/* Make sure signal is for us */
if (idx == nm_device_get_ifindex (device))
set_carrier (NM_DEVICE_VLAN (device), TRUE);
}
static void
carrier_off (NMNetlinkMonitor *monitor, int idx, NMDevice *device)
{
/* Make sure signal is for us */
if (idx == nm_device_get_ifindex (device))
set_carrier (NM_DEVICE_VLAN (device), FALSE);
}
static void
carrier_watch_init (NMDeviceVlan *self)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
priv->monitor = nm_netlink_monitor_get ();
priv->link_connected_id = g_signal_connect (priv->monitor, "carrier-on",
G_CALLBACK (carrier_on),
self);
priv->link_disconnected_id = g_signal_connect (priv->monitor, "carrier-off",
G_CALLBACK (carrier_off),
self);
priv->carrier = get_carrier_sync (NM_DEVICE_VLAN (self));
nm_log_info (LOGD_HW | LOGD_VLAN, "(%s): carrier is %s",
nm_device_get_iface (NM_DEVICE (self)),
priv->carrier ? "ON" : "OFF");
/* Request link state again just in case an error occurred getting the
* initial link state.
*/
nm_netlink_monitor_request_status (priv->monitor);
}
/******************************************************************/
static void
parent_state_changed (NMDevice *parent,
NMDeviceState new_state,
@@ -405,14 +312,17 @@ parent_state_changed (NMDevice *parent,
{
NMDeviceVlan *self = NM_DEVICE_VLAN (user_data);
/* We'll react to our own carrier state notifications. Ignore the parent's. */
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 carrier changes or becoming
* initialized.
* becomes available as a result of becoming initialized.
*/
nm_device_state_changed (NM_DEVICE (self), new_state, reason);
}
@@ -471,8 +381,6 @@ nm_device_vlan_new (const char *udi, const char *iface, NMDevice *parent)
G_CALLBACK (parent_state_changed),
device);
carrier_watch_init (NM_DEVICE_VLAN (device));
nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): kernel ifindex %d", iface, ifindex);
nm_log_info (LOGD_HW | LOGD_ETHER, "(%s): VLAN ID %d with parent %s",
iface, priv->vlan_id, nm_device_get_iface (parent));
@@ -493,9 +401,6 @@ get_property (GObject *object, guint prop_id,
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
switch (prop_id) {
case PROP_CARRIER:
g_value_set_boolean (value, priv->carrier);
break;
case PROP_VLAN_ID:
g_value_set_uint (value, priv->vlan_id);
break;
@@ -533,11 +438,6 @@ dispose (GObject *object)
}
priv->disposed = TRUE;
if (priv->link_connected_id)
g_signal_handler_disconnect (priv->monitor, priv->link_connected_id);
if (priv->link_disconnected_id)
g_signal_handler_disconnect (priv->monitor, priv->link_disconnected_id);
g_signal_handler_disconnect (priv->parent, priv->parent_state_id);
g_object_unref (priv->parent);
@@ -559,22 +459,12 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->hw_bring_up = hw_bring_up;
parent_class->can_interrupt_activation = can_interrupt_activation;
parent_class->is_available = is_available;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->complete_connection = complete_connection;
parent_class->match_l2_config = match_l2_config;
/* properties */
g_object_class_install_property
(object_class, PROP_CARRIER,
g_param_spec_boolean (NM_DEVICE_VLAN_CARRIER,
"Carrier",
"Carrier",
FALSE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_VLAN_ID,
g_param_spec_uint (NM_DEVICE_VLAN_ID,

View File

@@ -40,7 +40,6 @@ typedef enum {
NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
} NMVlanError;
#define NM_DEVICE_VLAN_CARRIER "carrier"
#define NM_DEVICE_VLAN_ID "vlan-id"
typedef struct {

View File

@@ -21,6 +21,7 @@
#include "config.h"
#include <glib.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_infiniband.h>
@@ -35,8 +36,6 @@
#include "nm-device-private.h"
#include "nm-dhcp-manager.h"
#include "nm-logging.h"
#include "nm-netlink-monitor.h"
#include "nm-netlink-utils.h"
#include "nm-system.h"
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
@@ -49,13 +48,7 @@ G_DEFINE_TYPE (NMDeviceWired, nm_device_wired, NM_TYPE_DEVICE)
#define NM_DEVICE_WIRED_LOG_LEVEL(dev) ((nm_device_get_device_type (dev) == NM_DEVICE_TYPE_INFINIBAND) ? LOGD_INFINIBAND : LOGD_ETHER)
typedef struct {
gboolean carrier;
guint32 speed;
NMNetlinkMonitor * monitor;
gulong link_connected_id;
gulong link_disconnected_id;
} NMDeviceWiredPrivate;
@@ -120,134 +113,14 @@ set_speed (NMDeviceWired *self, const guint32 speed)
}
static void
set_carrier (NMDeviceWired *self,
gboolean carrier)
carrier_changed (NMDevice *device, gboolean carrier)
{
NMDevice *device = NM_DEVICE (self);
NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self);
guint32 caps;
NMDeviceWired *wired_device = NM_DEVICE_WIRED (device);
if (priv->carrier == carrier)
return;
if (carrier)
set_speed (wired_device, ethtool_get_speed (wired_device));
/* Warn if we try to set carrier down on a device that
* doesn't support carrier detect. These devices assume
* the carrier is always up.
*/
caps = nm_device_get_capabilities (device);
g_return_if_fail (caps & NM_DEVICE_CAP_CARRIER_DETECT);
priv->carrier = carrier;
g_object_notify (G_OBJECT (self), "carrier");
}
static void
carrier_on (NMNetlinkMonitor *monitor,
int idx,
gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
NMDeviceWired *self = NM_DEVICE_WIRED (device);
/* Make sure signal is for us */
if (idx == nm_device_get_ifindex (device)) {
set_carrier (self, TRUE);
set_speed (self, ethtool_get_speed (self));
}
}
static void
carrier_off (NMNetlinkMonitor *monitor,
int idx,
gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
NMDeviceWired *self = NM_DEVICE_WIRED (device);
/* Make sure signal is for us */
if (idx == nm_device_get_ifindex (device))
set_carrier (self, FALSE);
}
static gboolean
get_carrier_sync (NMDeviceWired *self)
{
NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self);
GError *error = NULL;
guint32 ifflags = 0;
/* Get initial link state */
if (!nm_netlink_monitor_get_flags_sync (priv->monitor,
nm_device_get_ip_ifindex (NM_DEVICE (self)),
&ifflags,
&error)) {
nm_log_warn (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)),
"(%s): couldn't get carrier state: (%d) %s",
nm_device_get_ip_iface (NM_DEVICE (self)),
error ? error->code : -1,
(error && error->message) ? error->message : "unknown");
g_clear_error (&error);
}
return !!(ifflags & IFF_LOWER_UP);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
{
GObject *object;
NMDeviceWiredPrivate *priv;
NMDevice *self;
guint32 caps;
object = G_OBJECT_CLASS (nm_device_wired_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
self = NM_DEVICE (object);
priv = NM_DEVICE_WIRED_GET_PRIVATE (self);
nm_log_dbg (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)),
"(%s): kernel ifindex %d",
nm_device_get_iface (NM_DEVICE (self)),
nm_device_get_ifindex (NM_DEVICE (self)));
caps = nm_device_get_capabilities (self);
if (caps & NM_DEVICE_CAP_CARRIER_DETECT) {
/* Only listen to netlink for cards that support carrier detect */
priv->monitor = nm_netlink_monitor_get ();
priv->link_connected_id = g_signal_connect (priv->monitor, "carrier-on",
G_CALLBACK (carrier_on),
self);
priv->link_disconnected_id = g_signal_connect (priv->monitor, "carrier-off",
G_CALLBACK (carrier_off),
self);
priv->carrier = get_carrier_sync (NM_DEVICE_WIRED (self));
nm_log_info (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)),
"(%s): carrier is %s",
nm_device_get_iface (NM_DEVICE (self)),
priv->carrier ? "ON" : "OFF");
/* Request link state again just in case an error occurred getting the
* initial link state.
*/
nm_netlink_monitor_request_status (priv->monitor);
} else {
nm_log_info (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)),
"(%s): driver '%s' does not support carrier detection.",
nm_device_get_iface (self),
nm_device_get_driver (self));
priv->carrier = TRUE;
}
return object;
G_OBJECT_CLASS (nm_device_wired_parent_class)->carrier_changed (device, carrier);
}
static void
@@ -255,103 +128,6 @@ nm_device_wired_init (NMDeviceWired * self)
{
}
static gboolean
hw_bring_up (NMDevice *dev, gboolean *no_firmware)
{
gboolean result, carrier;
guint32 caps;
result = NM_DEVICE_CLASS(nm_device_wired_parent_class)->hw_bring_up (dev, no_firmware);
if (result) {
caps = nm_device_get_capabilities (dev);
if (caps & NM_DEVICE_CAP_CARRIER_DETECT) {
carrier = get_carrier_sync (NM_DEVICE_WIRED (dev));
set_carrier (NM_DEVICE_WIRED (dev), carrier);
}
}
return result;
}
/* Returns %TRUE if @self is unavailable for connections because it
* needs carrier but does not have it.
*/
static gboolean
nm_device_wired_unavailable_because_of_carrier (NMDeviceWired *self)
{
NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self);
return !priv->carrier && !nm_device_ignore_carrier (NM_DEVICE (self));
}
static gboolean
can_interrupt_activation (NMDevice *dev)
{
NMDeviceWired *self = NM_DEVICE_WIRED (dev);
/* Devices that support carrier detect can interrupt activation
* if the link becomes inactive.
*/
return nm_device_wired_unavailable_because_of_carrier (self);
}
static gboolean
is_available (NMDevice *dev)
{
NMDeviceWired *self = NM_DEVICE_WIRED (dev);
return !nm_device_wired_unavailable_because_of_carrier (self);
}
static NMActStageReturn
act_stage3_ip4_config_start (NMDevice *device,
NMIP4Config **out_config,
NMDeviceStateReason *reason)
{
if ( nm_device_is_master (device)
&& nm_device_wired_unavailable_because_of_carrier (NM_DEVICE_WIRED (device))) {
nm_log_info (LOGD_IP4 | NM_DEVICE_WIRED_LOG_LEVEL (device),
"(%s): IPv4 config waiting until carrier is on",
nm_device_get_ip_iface (device));
return NM_ACT_STAGE_RETURN_WAIT;
}
return NM_DEVICE_CLASS (nm_device_wired_parent_class)->act_stage3_ip4_config_start (device, out_config, reason);
}
static NMActStageReturn
act_stage3_ip6_config_start (NMDevice *device,
NMIP6Config **out_config,
NMDeviceStateReason *reason)
{
if ( nm_device_is_master (device)
&& nm_device_wired_unavailable_because_of_carrier (NM_DEVICE_WIRED (device))) {
nm_log_info (LOGD_IP6 | NM_DEVICE_WIRED_LOG_LEVEL (device),
"(%s): IPv6 config waiting until carrier is on",
nm_device_get_ip_iface (device));
return NM_ACT_STAGE_RETURN_WAIT;
}
return NM_DEVICE_CLASS (nm_device_wired_parent_class)->act_stage3_ip6_config_start (device, out_config, reason);
}
static void
dispose (GObject *object)
{
NMDeviceWired *self = NM_DEVICE_WIRED (object);
NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self);
if (priv->link_connected_id) {
g_signal_handler_disconnect (priv->monitor, priv->link_connected_id);
priv->link_connected_id = 0;
}
if (priv->link_disconnected_id) {
g_signal_handler_disconnect (priv->monitor, priv->link_disconnected_id);
priv->link_disconnected_id = 0;
}
G_OBJECT_CLASS (nm_device_wired_parent_class)->dispose (object);
}
static void
nm_device_wired_class_init (NMDeviceWiredClass *klass)
{
@@ -361,33 +137,8 @@ nm_device_wired_class_init (NMDeviceWiredClass *klass)
g_type_class_add_private (object_class, sizeof (NMDeviceWiredPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->dispose = dispose;
parent_class->hw_bring_up = hw_bring_up;
parent_class->can_interrupt_activation = can_interrupt_activation;
parent_class->is_available = is_available;
parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
parent_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
}
/**
* nm_device_wired_get_carrier:
* @dev: an #NMDeviceWired
*
* Get @dev's carrier status
*
* Return value: @dev's carrier
*/
gboolean
nm_device_wired_get_carrier (NMDeviceWired *dev)
{
NMDeviceWiredPrivate *priv;
g_return_val_if_fail (dev != NULL, FALSE);
priv = NM_DEVICE_WIRED_GET_PRIVATE (dev);
return priv->carrier;
parent_class->carrier_changed = carrier_changed;
}
/**

View File

@@ -41,12 +41,10 @@ typedef struct {
typedef struct {
NMDeviceClass parent;
} NMDeviceWiredClass;
GType nm_device_wired_get_type (void);
gboolean nm_device_wired_get_carrier (NMDeviceWired *dev);
guint32 nm_device_wired_get_speed (NMDeviceWired *dev);
G_END_DECLS

View File

@@ -111,6 +111,7 @@ enum {
PROP_DRIVER_VERSION,
PROP_FIRMWARE_VERSION,
PROP_CAPABILITIES,
PROP_CARRIER,
PROP_IP4_ADDRESS,
PROP_IP4_CONFIG,
PROP_DHCP4_CONFIG,
@@ -202,6 +203,13 @@ typedef struct {
gulong secrets_updated_id;
gulong secrets_failed_id;
/* Link stuff */
guint link_connected_id;
guint link_disconnected_id;
guint carrier_defer_id;
gboolean carrier;
gboolean ignore_carrier;
/* Generic DHCP stuff */
NMDHCPManager * dhcp_manager;
guint32 dhcp_timeout;
@@ -273,10 +281,6 @@ typedef struct {
guint cp_removed_id;
guint cp_updated_id;
/* carrier handling */
gboolean ignore_carrier;
guint carrier_action_defer_id;
} NMDevicePrivate;
static void nm_device_take_down (NMDevice *dev, gboolean wait, NMDeviceStateReason reason);
@@ -312,8 +316,9 @@ static void cp_connection_updated (NMConnectionProvider *cp, NMConnection *conne
static const char *state_to_string (NMDeviceState state);
static void carrier_changed (GObject *object, GParamSpec *param, gpointer user_data);
static void carrier_action_defer_clear (NMDevice *self);
static void link_connected_cb (NMNetlinkMonitor *monitor, int ifindex, NMDevice *device);
static void link_disconnected_cb (NMNetlinkMonitor *monitor, int ifindex, NMDevice *device);
static void check_carrier (NMDevice *device);
static void nm_device_queued_ip_config_change_clear (NMDevice *self);
static void update_ip_config (NMDevice *self);
@@ -468,6 +473,12 @@ device_get_driver_info (const char *iface, char **driver_version, char **firmwar
return TRUE;
}
static gboolean
device_has_capability (NMDevice *device, NMDeviceCapabilities caps)
{
return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & caps);
}
static GObject*
constructor (GType type,
guint n_construct_params,
@@ -497,7 +508,7 @@ constructor (GType type,
}
priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev);
if (!(priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) {
if (!device_has_capability (dev, NM_DEVICE_CAP_NM_SUPPORTED)) {
nm_log_warn (LOGD_DEVICE, "(%s): Device unsupported, ignoring.", priv->iface);
goto error;
}
@@ -524,6 +535,7 @@ static void
constructed (GObject *object)
{
NMDevice *dev = NM_DEVICE (object);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
nm_device_update_hw_address (dev);
@@ -534,13 +546,38 @@ constructed (GObject *object)
NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address (dev);
/* Have to call update_initial_hw_address() before calling get_ignore_carrier() */
if (g_object_class_find_property (G_OBJECT_GET_CLASS (dev), "carrier")) {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
NMConfig *config = nm_config_get ();
if (device_has_capability (dev, NM_DEVICE_CAP_CARRIER_DETECT)) {
priv->ignore_carrier = nm_config_get_ignore_carrier (nm_config_get (), NM_CONFIG_DEVICE (dev));
priv->ignore_carrier = nm_config_get_ignore_carrier (config, NM_CONFIG_DEVICE (dev));
if (!priv->ignore_carrier)
g_signal_connect (dev, "notify::carrier", G_CALLBACK (carrier_changed), NULL);
check_carrier (dev);
nm_log_info (LOGD_HW,
"(%s): carrier is %s%s",
nm_device_get_iface (NM_DEVICE (dev)),
priv->carrier ? "ON" : "OFF",
priv->ignore_carrier ? " (but ignored)" : "");
if (!device_has_capability (dev, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) {
NMNetlinkMonitor *netlink_monitor = nm_netlink_monitor_get ();
priv->link_connected_id = g_signal_connect (netlink_monitor, "carrier-on",
G_CALLBACK (link_connected_cb), dev);
priv->link_disconnected_id = g_signal_connect (netlink_monitor, "carrier-off",
G_CALLBACK (link_disconnected_cb), dev);
/* Request link state again just in case an error occurred getting the
* initial link state.
*
* TODO: Check if this is necessary at all.
*/
nm_netlink_monitor_request_status (netlink_monitor);
}
} else {
nm_log_info (LOGD_HW,
"(%s): driver '%s' does not support carrier detection.",
nm_device_get_iface (dev),
nm_device_get_driver (dev));
/* Fake online link when carrier detection is not available. */
priv->carrier = TRUE;
}
if (G_OBJECT_CLASS (nm_device_parent_class)->constructed)
@@ -986,6 +1023,162 @@ nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean failed)
return success;
}
static void
carrier_changed (NMDevice *device, gboolean carrier)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
if (priv->ignore_carrier || !nm_device_get_managed (device))
return;
if (nm_device_is_master (device)) {
/* Bridge/bond carrier does not affect its own activation, but
* when carrier comes on, if there are slaves waiting, it will
* restart them.
*/
if (!carrier)
return;
if (nm_device_activate_ip4_state_in_wait (device))
nm_device_activate_stage3_ip4_start (device);
if (nm_device_activate_ip6_state_in_wait (device))
nm_device_activate_stage3_ip6_start (device);
return;
} else if (nm_device_get_enslaved (device) && !carrier) {
/* Slaves don't deactivate when they lose carrier; for bonds
* in particular that would be actively counterproductive.
*/
return;
}
if (carrier) {
g_warn_if_fail (priv->state >= NM_DEVICE_STATE_UNAVAILABLE);
if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_CARRIER);
}
} else {
g_return_if_fail (priv->state >= NM_DEVICE_STATE_UNAVAILABLE);
if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
if (nm_device_queued_state_peek (device) >= NM_DEVICE_STATE_DISCONNECTED)
nm_device_queued_state_clear (device);
} else {
nm_device_queue_state (device, NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_CARRIER);
}
}
}
gboolean
nm_device_has_carrier (NMDevice *device)
{
return NM_DEVICE_GET_PRIVATE (device)->carrier;
}
/* Returns %TRUE if @device is unavailable for connections because it
* needs carrier but does not have it.
*/
static gboolean
nm_device_is_unavailable_because_of_carrier (NMDevice *device)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
return !priv->carrier && !priv->ignore_carrier;
}
#define LINK_DISCONNECT_DELAY 4
static gboolean
link_disconnect_action_cb (gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
priv->carrier_defer_id = 0;
nm_log_info (LOGD_DEVICE, "(%s): link disconnected (calling deferred action)",
nm_device_get_iface (device));
NM_DEVICE_GET_CLASS (device)->carrier_changed (device, FALSE);
return FALSE;
}
void
nm_device_set_carrier (NMDevice *device, gboolean carrier)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device);
NMDeviceState state = nm_device_get_state (device);
const char *iface = nm_device_get_iface (device);
if (priv->carrier == carrier)
return;
priv->carrier = carrier;
g_object_notify (G_OBJECT (device), NM_DEVICE_CARRIER);
if (priv->carrier) {
nm_log_info (LOGD_DEVICE, "(%s): link connected", iface);
if (priv->carrier_defer_id) {
g_source_remove (priv->carrier_defer_id);
priv->carrier_defer_id = 0;
}
klass->carrier_changed (device, TRUE);
} else if (state <= NM_DEVICE_STATE_DISCONNECTED) {
nm_log_info (LOGD_DEVICE, "(%s): link disconnected", iface);
klass->carrier_changed (device, FALSE);
} else {
nm_log_info (LOGD_DEVICE, "(%s): link disconnected (deferring action for %d seconds)",
iface, LINK_DISCONNECT_DELAY);
priv->carrier_defer_id = g_timeout_add_seconds (LINK_DISCONNECT_DELAY,
link_disconnect_action_cb, device);
}
}
static void
link_connected_cb (NMNetlinkMonitor *monitor, int ifindex, NMDevice *device)
{
if (ifindex == nm_device_get_ifindex (device))
nm_device_set_carrier (device, TRUE);
}
static void
link_disconnected_cb (NMNetlinkMonitor *monitor, int ifindex, NMDevice *device)
{
if (ifindex == nm_device_get_ifindex (device))
nm_device_set_carrier (device, FALSE);
}
static void
check_carrier (NMDevice *device)
{
GError *error = NULL;
guint32 ifflags = 0;
if (device_has_capability (device, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) {
/* Don't try to get an updated state, just keep the old one. */
return;
}
if (!nm_netlink_monitor_get_flags_sync (nm_netlink_monitor_get (),
nm_device_get_ip_ifindex (device),
&ifflags,
&error)) {
nm_log_warn (LOGD_DEVICE,
"(%s): couldn't get carrier state: (%d) %s",
nm_device_get_ip_iface (device),
error ? error->code : -1,
(error && error->message) ? error->message : "unknown");
g_clear_error (&error);
}
nm_device_set_carrier (device, !!(ifflags & IFF_LOWER_UP));
}
static void
slave_state_changed (NMDevice *slave,
NMDeviceState slave_new_state,
@@ -1219,109 +1412,6 @@ nm_device_get_act_request (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->act_request;
}
static void
carrier_action_defer_clear (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->carrier_action_defer_id) {
g_source_remove (priv->carrier_action_defer_id);
priv->carrier_action_defer_id = 0;
}
}
static gboolean
carrier_action_defer_cb (gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMDeviceState state;
priv->carrier_action_defer_id = 0;
/* We know that carrier is FALSE */
state = nm_device_get_state (self);
if (state >= NM_DEVICE_STATE_DISCONNECTED)
nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER);
return FALSE;
}
static void
carrier_changed (GObject *object, GParamSpec *param, gpointer user_data)
{
NMDevice *self = NM_DEVICE (object);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean carrier, defer_action = FALSE;
NMDeviceState state;
/* Clear any previous deferred action */
carrier_action_defer_clear (self);
state = nm_device_get_state (self);
if (state < NM_DEVICE_STATE_UNAVAILABLE)
return;
g_object_get (object, "carrier", &carrier, NULL);
if (nm_device_is_master (self)) {
/* Bridge/bond carrier does not affect its own activation, but
* when carrier comes on, if there are slaves waiting, it will
* restart them.
*/
if (!carrier)
return;
if (!nm_device_activate_ip4_state_in_wait (self) &&
!nm_device_activate_ip6_state_in_wait (self))
return;
} else if (nm_device_get_enslaved (self) && !carrier) {
/* Slaves don't deactivate when they lose carrier; for bonds
* in particular that would be actively counterproductive.
*/
return;
}
if (priv->act_request && !carrier)
defer_action = TRUE;
nm_log_info (LOGD_HW | LOGD_DEVICE, "(%s): carrier now %s (device state %d%s)",
nm_device_get_iface (self),
carrier ? "ON" : "OFF",
state,
defer_action ? ", deferring action for 4 seconds" : "");
if (nm_device_is_master (self)) {
if (nm_device_activate_ip4_state_in_wait (self))
nm_device_activate_stage3_ip4_start (self);
if (nm_device_activate_ip6_state_in_wait (self))
nm_device_activate_stage3_ip6_start (self);
return;
}
if (state == NM_DEVICE_STATE_UNAVAILABLE) {
if (carrier)
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER);
else {
/* clear any queued state changes if they wouldn't be valid when the
* carrier is off.
*/
if (nm_device_queued_state_peek (self) >= NM_DEVICE_STATE_DISCONNECTED)
nm_device_queued_state_clear (self);
}
} else if (state >= NM_DEVICE_STATE_DISCONNECTED) {
if (!carrier) {
if (defer_action)
priv->carrier_action_defer_id = g_timeout_add_seconds (4, carrier_action_defer_cb, self);
else
nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER);
}
}
}
NMConnection *
nm_device_get_connection (NMDevice *self)
{
@@ -1330,6 +1420,14 @@ nm_device_get_connection (NMDevice *self)
return priv->act_request ? nm_act_request_get_connection (priv->act_request) : NULL;
}
static gboolean
is_available (NMDevice *device)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
return priv->carrier || priv->ignore_carrier;
}
gboolean
nm_device_is_available (NMDevice *self)
{
@@ -1338,9 +1436,7 @@ nm_device_is_available (NMDevice *self)
if (priv->firmware_missing)
return FALSE;
if (NM_DEVICE_GET_CLASS (self)->is_available)
return NM_DEVICE_GET_CLASS (self)->is_available (self);
return TRUE;
}
gboolean
@@ -2420,6 +2516,14 @@ act_stage3_ip4_config_start (NMDevice *self,
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
if ( nm_device_is_master (self)
&& nm_device_is_unavailable_because_of_carrier (self)) {
nm_log_info (LOGD_IP4 | LOGD_DEVICE,
"(%s): IPv4 config waiting until carrier is on",
nm_device_get_ip_iface (self));
return NM_ACT_STAGE_RETURN_WAIT;
}
connection = nm_device_get_connection (self);
g_assert (connection);
@@ -3019,6 +3123,14 @@ act_stage3_ip6_config_start (NMDevice *self,
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
if ( nm_device_is_master (self)
&& nm_device_is_unavailable_because_of_carrier (self)) {
nm_log_info (LOGD_IP6 | LOGD_DEVICE,
"(%s): IPv6 config waiting until carrier is on",
nm_device_get_ip_iface (self));
return NM_ACT_STAGE_RETURN_WAIT;
}
connection = nm_device_get_connection (self);
g_assert (connection);
@@ -4212,6 +4324,15 @@ nm_device_is_activating (NMDevice *device)
}
static gboolean
can_interrupt_activation (NMDevice *device)
{
/* Devices that support carrier detect can interrupt activation
* if the link becomes inactive.
*/
return nm_device_is_unavailable_because_of_carrier (device);
}
gboolean
nm_device_can_interrupt_activation (NMDevice *self)
{
@@ -4426,8 +4547,18 @@ static gboolean
hw_bring_up (NMDevice *device, gboolean *no_firmware)
{
int ifindex = nm_device_get_ip_ifindex (device);
gboolean result;
return ifindex > 0 ? nm_system_iface_set_up (ifindex, TRUE, no_firmware) : TRUE;
if (!ifindex)
return TRUE;
result = nm_system_iface_set_up (ifindex, TRUE, no_firmware);
/* Store carrier immediately. */
if (result && device_has_capability (device, NM_DEVICE_CAP_CARRIER_DETECT))
check_carrier (device);
return result;
}
void
@@ -4572,6 +4703,15 @@ dispose (GObject *object)
}
g_free (priv->ip6_privacy_tempaddr_path);
if (priv->link_connected_id)
g_signal_handler_disconnect (nm_netlink_monitor_get (), priv->link_connected_id);
if (priv->link_disconnected_id)
g_signal_handler_disconnect (nm_netlink_monitor_get (), priv->link_disconnected_id);
if (priv->carrier_defer_id) {
g_source_remove (priv->carrier_defer_id);
priv->carrier_defer_id = 0;
}
if (priv->cp_added_id) {
g_signal_handler_disconnect (priv->con_provider, priv->cp_added_id);
priv->cp_added_id = 0;
@@ -4592,8 +4732,6 @@ dispose (GObject *object)
priv->cp_updated_id = 0;
}
carrier_action_defer_clear (self);
g_hash_table_unref (priv->available_connections);
activation_source_clear (self, TRUE, AF_INET);
@@ -4781,11 +4919,14 @@ get_property (GObject *object, guint prop_id,
g_value_set_string (value, priv->firmware_version);
break;
case PROP_CAPABILITIES:
g_value_set_uint (value, priv->capabilities);
g_value_set_uint (value, (priv->capabilities & ~NM_DEVICE_CAP_INTERNAL_MASK));
break;
case PROP_IP4_ADDRESS:
g_value_set_uint (value, priv->ip4_address);
break;
case PROP_CARRIER:
g_value_set_boolean (value, priv->carrier);
break;
case PROP_IP4_CONFIG:
if (has_ip_config (self) && priv->ip4_config)
g_value_set_boxed (value, nm_ip4_config_get_dbus_path (priv->ip4_config));
@@ -4865,7 +5006,6 @@ get_property (GObject *object, guint prop_id,
}
}
static void
nm_device_class_init (NMDeviceClass *klass)
{
@@ -4883,6 +5023,7 @@ nm_device_class_init (NMDeviceClass *klass)
klass->get_type_capabilities = get_type_capabilities;
klass->get_generic_capabilities = get_generic_capabilities;
klass->is_available = is_available;
klass->act_stage1_prepare = act_stage1_prepare;
klass->act_stage2_config = act_stage2_config;
klass->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
@@ -4898,6 +5039,8 @@ nm_device_class_init (NMDeviceClass *klass)
klass->hw_is_up = hw_is_up;
klass->hw_bring_up = hw_bring_up;
klass->hw_take_down = hw_take_down;
klass->carrier_changed = carrier_changed;
klass->can_interrupt_activation = can_interrupt_activation;
/* Properties */
g_object_class_install_property
@@ -4956,6 +5099,14 @@ nm_device_class_init (NMDeviceClass *klass)
0, G_MAXUINT32, NM_DEVICE_CAP_NONE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
(object_class, PROP_CARRIER,
g_param_spec_boolean (NM_DEVICE_CARRIER,
"Carrier",
"Carrier",
FALSE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_IP4_ADDRESS,
g_param_spec_uint (NM_DEVICE_IP4_ADDRESS,

View File

@@ -45,6 +45,7 @@
#define NM_DEVICE_DRIVER_VERSION "driver-version"
#define NM_DEVICE_FIRMWARE_VERSION "firmware-version"
#define NM_DEVICE_CAPABILITIES "capabilities"
#define NM_DEVICE_CARRIER "carrier"
#define NM_DEVICE_IP4_ADDRESS "ip4-address"
#define NM_DEVICE_IP4_CONFIG "ip4-config"
#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
@@ -99,11 +100,14 @@ typedef struct {
NMDeviceState old_state,
NMDeviceStateReason reason);
/* Hardware state, ie IFF_UP */
/* Hardware state (IFF_UP) */
gboolean (*hw_is_up) (NMDevice *self);
gboolean (*hw_bring_up) (NMDevice *self, gboolean *no_firmware);
void (*hw_take_down) (NMDevice *self);
/* Carrier state (IFF_LOWER_UP) */
void (*carrier_changed) (NMDevice *, gboolean carrier);
/* Additional stuff required to operate the device, like a
* connection to the supplicant, Bluez, etc
*/
@@ -239,6 +243,7 @@ NMConnection * nm_device_get_connection (NMDevice *dev);
gboolean nm_device_is_available (NMDevice *dev);
gboolean nm_device_can_activate (NMDevice *dev);
gboolean nm_device_has_carrier (NMDevice *dev);
gboolean nm_device_ignore_carrier (NMDevice *dev);
NMConnection * nm_device_get_best_auto_connection (NMDevice *dev,