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:
@@ -67,7 +67,6 @@ nm_adsl_error_quark (void)
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean disposed;
|
gboolean disposed;
|
||||||
gboolean carrier;
|
|
||||||
guint carrier_poll_id;
|
guint carrier_poll_id;
|
||||||
int atm_index;
|
int atm_index;
|
||||||
|
|
||||||
@@ -84,48 +83,14 @@ typedef struct {
|
|||||||
char * nas_ifname;
|
char * nas_ifname;
|
||||||
} NMDeviceAdslPrivate;
|
} NMDeviceAdslPrivate;
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_0,
|
|
||||||
PROP_CARRIER,
|
|
||||||
|
|
||||||
LAST_PROP
|
|
||||||
};
|
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
|
||||||
static guint32
|
static guint32
|
||||||
get_generic_capabilities (NMDevice *dev)
|
get_generic_capabilities (NMDevice *dev)
|
||||||
{
|
{
|
||||||
guint32 caps = NM_DEVICE_CAP_NM_SUPPORTED;
|
return ( NM_DEVICE_CAP_NM_SUPPORTED
|
||||||
caps |= NM_DEVICE_CAP_CARRIER_DETECT;
|
| NM_DEVICE_CAP_CARRIER_DETECT
|
||||||
return caps;
|
| NM_DEVICE_CAP_NONSTANDARD_CARRIER);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -576,22 +541,6 @@ get_hw_address_length (NMDevice *device)
|
|||||||
return priv->nas_ifname ? ETH_ALEN : 0;
|
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
|
static gboolean
|
||||||
carrier_update_cb (gpointer user_data)
|
carrier_update_cb (gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -619,7 +568,7 @@ carrier_update_cb (gpointer user_data)
|
|||||||
|
|
||||||
carrier = (gboolean) atoi (contents);
|
carrier = (gboolean) atoi (contents);
|
||||||
g_free (contents);
|
g_free (contents);
|
||||||
set_carrier (self, carrier);
|
nm_device_set_carrier (NM_DEVICE (self), carrier);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,34 +669,6 @@ dispose (GObject *object)
|
|||||||
G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (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
|
static void
|
||||||
nm_device_adsl_init (NMDeviceAdsl *self)
|
nm_device_adsl_init (NMDeviceAdsl *self)
|
||||||
{
|
{
|
||||||
@@ -767,12 +688,8 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass)
|
|||||||
|
|
||||||
object_class->constructor = constructor;
|
object_class->constructor = constructor;
|
||||||
object_class->dispose = dispose;
|
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->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->check_connection_compatible = check_connection_compatible;
|
||||||
parent_class->complete_connection = complete_connection;
|
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->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
|
||||||
parent_class->deactivate = deactivate;
|
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 (),
|
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
|
||||||
G_TYPE_FROM_CLASS (klass),
|
G_TYPE_FROM_CLASS (klass),
|
||||||
&dbus_glib_nm_device_adsl_object_info);
|
&dbus_glib_nm_device_adsl_object_info);
|
||||||
|
@@ -42,8 +42,6 @@ typedef enum {
|
|||||||
NM_ADSL_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
NM_ADSL_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
||||||
} NMAdslError;
|
} NMAdslError;
|
||||||
|
|
||||||
#define NM_DEVICE_ADSL_CARRIER "carrier"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDevice parent;
|
NMDevice parent;
|
||||||
} NMDeviceAdsl;
|
} NMDeviceAdsl;
|
||||||
|
@@ -51,7 +51,6 @@ typedef struct {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_CARRIER,
|
|
||||||
PROP_SLAVES,
|
PROP_SLAVES,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
@@ -320,8 +319,6 @@ get_property (GObject *object, guint prop_id,
|
|||||||
GSList *list, *iter;
|
GSList *list, *iter;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_CARRIER:
|
|
||||||
g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object)));
|
|
||||||
break;
|
break;
|
||||||
case PROP_SLAVES:
|
case PROP_SLAVES:
|
||||||
slaves = g_ptr_array_new ();
|
slaves = g_ptr_array_new ();
|
||||||
@@ -374,14 +371,6 @@ nm_device_bond_class_init (NMDeviceBondClass *klass)
|
|||||||
parent_class->release_slave = release_slave;
|
parent_class->release_slave = release_slave;
|
||||||
|
|
||||||
/* properties */
|
/* 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
|
g_object_class_install_property
|
||||||
(object_class, PROP_SLAVES,
|
(object_class, PROP_SLAVES,
|
||||||
g_param_spec_boxed (NM_DEVICE_BOND_SLAVES,
|
g_param_spec_boxed (NM_DEVICE_BOND_SLAVES,
|
||||||
|
@@ -40,7 +40,6 @@ typedef enum {
|
|||||||
NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
||||||
} NMBondError;
|
} NMBondError;
|
||||||
|
|
||||||
#define NM_DEVICE_BOND_CARRIER "carrier"
|
|
||||||
#define NM_DEVICE_BOND_SLAVES "slaves"
|
#define NM_DEVICE_BOND_SLAVES "slaves"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -51,7 +51,6 @@ typedef struct {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_CARRIER,
|
|
||||||
PROP_SLAVES,
|
PROP_SLAVES,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
@@ -353,8 +352,6 @@ get_property (GObject *object, guint prop_id,
|
|||||||
GSList *list, *iter;
|
GSList *list, *iter;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_CARRIER:
|
|
||||||
g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object)));
|
|
||||||
break;
|
break;
|
||||||
case PROP_SLAVES:
|
case PROP_SLAVES:
|
||||||
slaves = g_ptr_array_new ();
|
slaves = g_ptr_array_new ();
|
||||||
@@ -406,14 +403,6 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass)
|
|||||||
parent_class->release_slave = release_slave;
|
parent_class->release_slave = release_slave;
|
||||||
|
|
||||||
/* properties */
|
/* 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
|
g_object_class_install_property
|
||||||
(object_class, PROP_SLAVES,
|
(object_class, PROP_SLAVES,
|
||||||
g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES,
|
g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES,
|
||||||
|
@@ -40,7 +40,6 @@ typedef enum {
|
|||||||
NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
||||||
} NMBridgeError;
|
} NMBridgeError;
|
||||||
|
|
||||||
#define NM_DEVICE_BRIDGE_CARRIER "carrier"
|
|
||||||
#define NM_DEVICE_BRIDGE_SLAVES "slaves"
|
#define NM_DEVICE_BRIDGE_SLAVES "slaves"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -102,7 +102,6 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_PERM_HW_ADDRESS,
|
PROP_PERM_HW_ADDRESS,
|
||||||
PROP_SPEED,
|
PROP_SPEED,
|
||||||
PROP_CARRIER,
|
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
@@ -1345,9 +1344,6 @@ get_property (GObject *object, guint prop_id,
|
|||||||
case PROP_SPEED:
|
case PROP_SPEED:
|
||||||
g_value_set_uint (value, nm_device_wired_get_speed (NM_DEVICE_WIRED (self)));
|
g_value_set_uint (value, nm_device_wired_get_speed (NM_DEVICE_WIRED (self)));
|
||||||
break;
|
break;
|
||||||
case PROP_CARRIER:
|
|
||||||
g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (self)));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -1416,14 +1412,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
|
|||||||
0, G_MAXUINT32, 0,
|
0, G_MAXUINT32, 0,
|
||||||
G_PARAM_READABLE));
|
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 (),
|
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
|
||||||
G_TYPE_FROM_CLASS (klass),
|
G_TYPE_FROM_CLASS (klass),
|
||||||
&dbus_glib_nm_device_ethernet_object_info);
|
&dbus_glib_nm_device_ethernet_object_info);
|
||||||
|
@@ -44,7 +44,6 @@ typedef enum
|
|||||||
|
|
||||||
#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address"
|
#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address"
|
||||||
#define NM_DEVICE_ETHERNET_SPEED "speed"
|
#define NM_DEVICE_ETHERNET_SPEED "speed"
|
||||||
#define NM_DEVICE_ETHERNET_CARRIER "carrier"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDeviceWired parent;
|
NMDeviceWired parent;
|
||||||
|
@@ -49,7 +49,6 @@ typedef struct {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_CARRIER,
|
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
@@ -300,9 +299,6 @@ get_property (GObject *object, guint prop_id,
|
|||||||
GValue *value, GParamSpec *pspec)
|
GValue *value, GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_CARRIER:
|
|
||||||
g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object)));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -344,13 +340,6 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass)
|
|||||||
parent_class->get_connection_hw_address = get_connection_hw_address;
|
parent_class->get_connection_hw_address = get_connection_hw_address;
|
||||||
|
|
||||||
/* properties */
|
/* 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 (),
|
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
|
||||||
G_TYPE_FROM_CLASS (klass),
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
@@ -40,8 +40,6 @@ typedef enum {
|
|||||||
NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
||||||
} NMInfinibandError;
|
} NMInfinibandError;
|
||||||
|
|
||||||
#define NM_DEVICE_INFINIBAND_CARRIER "carrier"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDeviceWired parent;
|
NMDeviceWired parent;
|
||||||
} NMDeviceInfiniband;
|
} NMDeviceInfiniband;
|
||||||
|
@@ -34,6 +34,10 @@ enum NMActStageReturn {
|
|||||||
NM_ACT_STAGE_RETURN_STOP /* Activation stage done; nothing to do */
|
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_set_ip_iface (NMDevice *self, const char *iface);
|
||||||
|
|
||||||
void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device);
|
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);
|
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 */
|
#endif /* NM_DEVICE_PRIVATE_H */
|
||||||
|
@@ -32,10 +32,10 @@
|
|||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
#include "nm-device-private.h"
|
#include "nm-device-private.h"
|
||||||
#include "nm-netlink-monitor.h"
|
|
||||||
#include "nm-enum-types.h"
|
#include "nm-enum-types.h"
|
||||||
#include "nm-system.h"
|
#include "nm-system.h"
|
||||||
#include "nm-dbus-manager.h"
|
#include "nm-dbus-manager.h"
|
||||||
|
#include "nm-netlink-monitor.h"
|
||||||
|
|
||||||
#include "nm-device-vlan-glue.h"
|
#include "nm-device-vlan-glue.h"
|
||||||
|
|
||||||
@@ -53,25 +53,15 @@ typedef struct {
|
|||||||
guint parent_state_id;
|
guint parent_state_id;
|
||||||
|
|
||||||
guint vlan_id;
|
guint vlan_id;
|
||||||
|
|
||||||
gboolean carrier;
|
|
||||||
NMNetlinkMonitor *monitor;
|
|
||||||
gulong link_connected_id;
|
|
||||||
gulong link_disconnected_id;
|
|
||||||
} NMDeviceVlanPrivate;
|
} NMDeviceVlanPrivate;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_CARRIER,
|
|
||||||
PROP_VLAN_ID,
|
PROP_VLAN_ID,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
set_carrier (NMDeviceVlan *self,
|
|
||||||
const gboolean carrier);
|
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
static GQuark
|
static GQuark
|
||||||
@@ -92,29 +82,6 @@ get_generic_capabilities (NMDevice *dev)
|
|||||||
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NM_SUPPORTED;
|
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
|
static gboolean
|
||||||
hw_bring_up (NMDevice *dev, gboolean *no_firmware)
|
hw_bring_up (NMDevice *dev, gboolean *no_firmware)
|
||||||
{
|
{
|
||||||
@@ -132,8 +99,22 @@ hw_bring_up (NMDevice *dev, gboolean *no_firmware)
|
|||||||
*/
|
*/
|
||||||
i = 20;
|
i = 20;
|
||||||
while (i-- > 0) {
|
while (i-- > 0) {
|
||||||
carrier = get_carrier_sync (NM_DEVICE_VLAN (dev));
|
GError *error = NULL;
|
||||||
set_carrier (NM_DEVICE_VLAN (dev), carrier);
|
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)
|
if (carrier)
|
||||||
break;
|
break;
|
||||||
g_usleep (100);
|
g_usleep (100);
|
||||||
@@ -142,24 +123,6 @@ hw_bring_up (NMDevice *dev, gboolean *no_firmware)
|
|||||||
return success;
|
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
|
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
|
static void
|
||||||
parent_state_changed (NMDevice *parent,
|
parent_state_changed (NMDevice *parent,
|
||||||
NMDeviceState new_state,
|
NMDeviceState new_state,
|
||||||
@@ -405,14 +312,17 @@ parent_state_changed (NMDevice *parent,
|
|||||||
{
|
{
|
||||||
NMDeviceVlan *self = NM_DEVICE_VLAN (user_data);
|
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 (new_state < NM_DEVICE_STATE_DISCONNECTED) {
|
||||||
/* If the parent becomes unavailable or unmanaged so does the VLAN */
|
/* If the parent becomes unavailable or unmanaged so does the VLAN */
|
||||||
nm_device_state_changed (NM_DEVICE (self), new_state, reason);
|
nm_device_state_changed (NM_DEVICE (self), new_state, reason);
|
||||||
} else if ( new_state == NM_DEVICE_STATE_DISCONNECTED
|
} else if ( new_state == NM_DEVICE_STATE_DISCONNECTED
|
||||||
&& old_state < NM_DEVICE_STATE_DISCONNECTED) {
|
&& old_state < NM_DEVICE_STATE_DISCONNECTED) {
|
||||||
/* Mark VLAN interface as available/disconnected when the parent
|
/* Mark VLAN interface as available/disconnected when the parent
|
||||||
* becomes available as a result of carrier changes or becoming
|
* becomes available as a result of becoming initialized.
|
||||||
* initialized.
|
|
||||||
*/
|
*/
|
||||||
nm_device_state_changed (NM_DEVICE (self), new_state, reason);
|
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),
|
G_CALLBACK (parent_state_changed),
|
||||||
device);
|
device);
|
||||||
|
|
||||||
carrier_watch_init (NM_DEVICE_VLAN (device));
|
|
||||||
|
|
||||||
nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): kernel ifindex %d", iface, ifindex);
|
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",
|
nm_log_info (LOGD_HW | LOGD_ETHER, "(%s): VLAN ID %d with parent %s",
|
||||||
iface, priv->vlan_id, nm_device_get_iface (parent));
|
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);
|
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_CARRIER:
|
|
||||||
g_value_set_boolean (value, priv->carrier);
|
|
||||||
break;
|
|
||||||
case PROP_VLAN_ID:
|
case PROP_VLAN_ID:
|
||||||
g_value_set_uint (value, priv->vlan_id);
|
g_value_set_uint (value, priv->vlan_id);
|
||||||
break;
|
break;
|
||||||
@@ -533,11 +438,6 @@ dispose (GObject *object)
|
|||||||
}
|
}
|
||||||
priv->disposed = TRUE;
|
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_signal_handler_disconnect (priv->parent, priv->parent_state_id);
|
||||||
g_object_unref (priv->parent);
|
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->get_generic_capabilities = get_generic_capabilities;
|
||||||
parent_class->hw_bring_up = hw_bring_up;
|
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->check_connection_compatible = check_connection_compatible;
|
||||||
parent_class->complete_connection = complete_connection;
|
parent_class->complete_connection = complete_connection;
|
||||||
parent_class->match_l2_config = match_l2_config;
|
parent_class->match_l2_config = match_l2_config;
|
||||||
|
|
||||||
/* properties */
|
/* 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
|
g_object_class_install_property
|
||||||
(object_class, PROP_VLAN_ID,
|
(object_class, PROP_VLAN_ID,
|
||||||
g_param_spec_uint (NM_DEVICE_VLAN_ID,
|
g_param_spec_uint (NM_DEVICE_VLAN_ID,
|
||||||
|
@@ -40,7 +40,6 @@ typedef enum {
|
|||||||
NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
|
||||||
} NMVlanError;
|
} NMVlanError;
|
||||||
|
|
||||||
#define NM_DEVICE_VLAN_CARRIER "carrier"
|
|
||||||
#define NM_DEVICE_VLAN_ID "vlan-id"
|
#define NM_DEVICE_VLAN_ID "vlan-id"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
#include <linux/if_infiniband.h>
|
#include <linux/if_infiniband.h>
|
||||||
@@ -35,8 +36,6 @@
|
|||||||
#include "nm-device-private.h"
|
#include "nm-device-private.h"
|
||||||
#include "nm-dhcp-manager.h"
|
#include "nm-dhcp-manager.h"
|
||||||
#include "nm-logging.h"
|
#include "nm-logging.h"
|
||||||
#include "nm-netlink-monitor.h"
|
|
||||||
#include "nm-netlink-utils.h"
|
|
||||||
#include "nm-system.h"
|
#include "nm-system.h"
|
||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
#include "NetworkManagerUtils.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)
|
#define NM_DEVICE_WIRED_LOG_LEVEL(dev) ((nm_device_get_device_type (dev) == NM_DEVICE_TYPE_INFINIBAND) ? LOGD_INFINIBAND : LOGD_ETHER)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean carrier;
|
|
||||||
guint32 speed;
|
guint32 speed;
|
||||||
|
|
||||||
NMNetlinkMonitor * monitor;
|
|
||||||
gulong link_connected_id;
|
|
||||||
gulong link_disconnected_id;
|
|
||||||
|
|
||||||
} NMDeviceWiredPrivate;
|
} NMDeviceWiredPrivate;
|
||||||
|
|
||||||
|
|
||||||
@@ -120,134 +113,14 @@ set_speed (NMDeviceWired *self, const guint32 speed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_carrier (NMDeviceWired *self,
|
carrier_changed (NMDevice *device, gboolean carrier)
|
||||||
gboolean carrier)
|
|
||||||
{
|
{
|
||||||
NMDevice *device = NM_DEVICE (self);
|
NMDeviceWired *wired_device = NM_DEVICE_WIRED (device);
|
||||||
NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self);
|
|
||||||
guint32 caps;
|
|
||||||
|
|
||||||
if (priv->carrier == carrier)
|
if (carrier)
|
||||||
return;
|
set_speed (wired_device, ethtool_get_speed (wired_device));
|
||||||
|
|
||||||
/* Warn if we try to set carrier down on a device that
|
G_OBJECT_CLASS (nm_device_wired_parent_class)->carrier_changed (device, carrier);
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
static void
|
||||||
nm_device_wired_class_init (NMDeviceWiredClass *klass)
|
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));
|
g_type_class_add_private (object_class, sizeof (NMDeviceWiredPrivate));
|
||||||
|
|
||||||
/* virtual methods */
|
/* virtual methods */
|
||||||
object_class->constructor = constructor;
|
|
||||||
object_class->dispose = dispose;
|
|
||||||
|
|
||||||
parent_class->hw_bring_up = hw_bring_up;
|
parent_class->carrier_changed = carrier_changed;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -41,12 +41,10 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDeviceClass parent;
|
NMDeviceClass parent;
|
||||||
|
|
||||||
} NMDeviceWiredClass;
|
} NMDeviceWiredClass;
|
||||||
|
|
||||||
GType nm_device_wired_get_type (void);
|
GType nm_device_wired_get_type (void);
|
||||||
|
|
||||||
gboolean nm_device_wired_get_carrier (NMDeviceWired *dev);
|
|
||||||
guint32 nm_device_wired_get_speed (NMDeviceWired *dev);
|
guint32 nm_device_wired_get_speed (NMDeviceWired *dev);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@@ -111,6 +111,7 @@ enum {
|
|||||||
PROP_DRIVER_VERSION,
|
PROP_DRIVER_VERSION,
|
||||||
PROP_FIRMWARE_VERSION,
|
PROP_FIRMWARE_VERSION,
|
||||||
PROP_CAPABILITIES,
|
PROP_CAPABILITIES,
|
||||||
|
PROP_CARRIER,
|
||||||
PROP_IP4_ADDRESS,
|
PROP_IP4_ADDRESS,
|
||||||
PROP_IP4_CONFIG,
|
PROP_IP4_CONFIG,
|
||||||
PROP_DHCP4_CONFIG,
|
PROP_DHCP4_CONFIG,
|
||||||
@@ -202,6 +203,13 @@ typedef struct {
|
|||||||
gulong secrets_updated_id;
|
gulong secrets_updated_id;
|
||||||
gulong secrets_failed_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 */
|
/* Generic DHCP stuff */
|
||||||
NMDHCPManager * dhcp_manager;
|
NMDHCPManager * dhcp_manager;
|
||||||
guint32 dhcp_timeout;
|
guint32 dhcp_timeout;
|
||||||
@@ -273,10 +281,6 @@ typedef struct {
|
|||||||
guint cp_removed_id;
|
guint cp_removed_id;
|
||||||
guint cp_updated_id;
|
guint cp_updated_id;
|
||||||
|
|
||||||
/* carrier handling */
|
|
||||||
gboolean ignore_carrier;
|
|
||||||
guint carrier_action_defer_id;
|
|
||||||
|
|
||||||
} NMDevicePrivate;
|
} NMDevicePrivate;
|
||||||
|
|
||||||
static void nm_device_take_down (NMDevice *dev, gboolean wait, NMDeviceStateReason reason);
|
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 const char *state_to_string (NMDeviceState state);
|
||||||
|
|
||||||
static void carrier_changed (GObject *object, GParamSpec *param, gpointer user_data);
|
static void link_connected_cb (NMNetlinkMonitor *monitor, int ifindex, NMDevice *device);
|
||||||
static void carrier_action_defer_clear (NMDevice *self);
|
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 nm_device_queued_ip_config_change_clear (NMDevice *self);
|
||||||
static void update_ip_config (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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
device_has_capability (NMDevice *device, NMDeviceCapabilities caps)
|
||||||
|
{
|
||||||
|
return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & caps);
|
||||||
|
}
|
||||||
|
|
||||||
static GObject*
|
static GObject*
|
||||||
constructor (GType type,
|
constructor (GType type,
|
||||||
guint n_construct_params,
|
guint n_construct_params,
|
||||||
@@ -497,7 +508,7 @@ constructor (GType type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev);
|
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);
|
nm_log_warn (LOGD_DEVICE, "(%s): Device unsupported, ignoring.", priv->iface);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -524,6 +535,7 @@ static void
|
|||||||
constructed (GObject *object)
|
constructed (GObject *object)
|
||||||
{
|
{
|
||||||
NMDevice *dev = NM_DEVICE (object);
|
NMDevice *dev = NM_DEVICE (object);
|
||||||
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
|
||||||
|
|
||||||
nm_device_update_hw_address (dev);
|
nm_device_update_hw_address (dev);
|
||||||
|
|
||||||
@@ -534,13 +546,38 @@ constructed (GObject *object)
|
|||||||
NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address (dev);
|
NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address (dev);
|
||||||
|
|
||||||
/* Have to call update_initial_hw_address() before calling get_ignore_carrier() */
|
/* Have to call update_initial_hw_address() before calling get_ignore_carrier() */
|
||||||
if (g_object_class_find_property (G_OBJECT_GET_CLASS (dev), "carrier")) {
|
if (device_has_capability (dev, NM_DEVICE_CAP_CARRIER_DETECT)) {
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
|
priv->ignore_carrier = nm_config_get_ignore_carrier (nm_config_get (), NM_CONFIG_DEVICE (dev));
|
||||||
NMConfig *config = nm_config_get ();
|
|
||||||
|
|
||||||
priv->ignore_carrier = nm_config_get_ignore_carrier (config, NM_CONFIG_DEVICE (dev));
|
check_carrier (dev);
|
||||||
if (!priv->ignore_carrier)
|
nm_log_info (LOGD_HW,
|
||||||
g_signal_connect (dev, "notify::carrier", G_CALLBACK (carrier_changed), NULL);
|
"(%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)
|
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;
|
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
|
static void
|
||||||
slave_state_changed (NMDevice *slave,
|
slave_state_changed (NMDevice *slave,
|
||||||
NMDeviceState slave_new_state,
|
NMDeviceState slave_new_state,
|
||||||
@@ -1219,109 +1412,6 @@ nm_device_get_act_request (NMDevice *self)
|
|||||||
return NM_DEVICE_GET_PRIVATE (self)->act_request;
|
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 *
|
NMConnection *
|
||||||
nm_device_get_connection (NMDevice *self)
|
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;
|
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
|
gboolean
|
||||||
nm_device_is_available (NMDevice *self)
|
nm_device_is_available (NMDevice *self)
|
||||||
{
|
{
|
||||||
@@ -1338,9 +1436,7 @@ nm_device_is_available (NMDevice *self)
|
|||||||
if (priv->firmware_missing)
|
if (priv->firmware_missing)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (NM_DEVICE_GET_CLASS (self)->is_available)
|
|
||||||
return NM_DEVICE_GET_CLASS (self)->is_available (self);
|
return NM_DEVICE_GET_CLASS (self)->is_available (self);
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@@ -2420,6 +2516,14 @@ act_stage3_ip4_config_start (NMDevice *self,
|
|||||||
|
|
||||||
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
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);
|
connection = nm_device_get_connection (self);
|
||||||
g_assert (connection);
|
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);
|
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);
|
connection = nm_device_get_connection (self);
|
||||||
g_assert (connection);
|
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
|
gboolean
|
||||||
nm_device_can_interrupt_activation (NMDevice *self)
|
nm_device_can_interrupt_activation (NMDevice *self)
|
||||||
{
|
{
|
||||||
@@ -4426,8 +4547,18 @@ static gboolean
|
|||||||
hw_bring_up (NMDevice *device, gboolean *no_firmware)
|
hw_bring_up (NMDevice *device, gboolean *no_firmware)
|
||||||
{
|
{
|
||||||
int ifindex = nm_device_get_ip_ifindex (device);
|
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
|
void
|
||||||
@@ -4572,6 +4703,15 @@ dispose (GObject *object)
|
|||||||
}
|
}
|
||||||
g_free (priv->ip6_privacy_tempaddr_path);
|
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) {
|
if (priv->cp_added_id) {
|
||||||
g_signal_handler_disconnect (priv->con_provider, priv->cp_added_id);
|
g_signal_handler_disconnect (priv->con_provider, priv->cp_added_id);
|
||||||
priv->cp_added_id = 0;
|
priv->cp_added_id = 0;
|
||||||
@@ -4592,8 +4732,6 @@ dispose (GObject *object)
|
|||||||
priv->cp_updated_id = 0;
|
priv->cp_updated_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
carrier_action_defer_clear (self);
|
|
||||||
|
|
||||||
g_hash_table_unref (priv->available_connections);
|
g_hash_table_unref (priv->available_connections);
|
||||||
|
|
||||||
activation_source_clear (self, TRUE, AF_INET);
|
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);
|
g_value_set_string (value, priv->firmware_version);
|
||||||
break;
|
break;
|
||||||
case PROP_CAPABILITIES:
|
case PROP_CAPABILITIES:
|
||||||
g_value_set_uint (value, priv->capabilities);
|
g_value_set_uint (value, (priv->capabilities & ~NM_DEVICE_CAP_INTERNAL_MASK));
|
||||||
break;
|
break;
|
||||||
case PROP_IP4_ADDRESS:
|
case PROP_IP4_ADDRESS:
|
||||||
g_value_set_uint (value, priv->ip4_address);
|
g_value_set_uint (value, priv->ip4_address);
|
||||||
break;
|
break;
|
||||||
|
case PROP_CARRIER:
|
||||||
|
g_value_set_boolean (value, priv->carrier);
|
||||||
|
break;
|
||||||
case PROP_IP4_CONFIG:
|
case PROP_IP4_CONFIG:
|
||||||
if (has_ip_config (self) && priv->ip4_config)
|
if (has_ip_config (self) && priv->ip4_config)
|
||||||
g_value_set_boxed (value, nm_ip4_config_get_dbus_path (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
|
static void
|
||||||
nm_device_class_init (NMDeviceClass *klass)
|
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_type_capabilities = get_type_capabilities;
|
||||||
klass->get_generic_capabilities = get_generic_capabilities;
|
klass->get_generic_capabilities = get_generic_capabilities;
|
||||||
|
klass->is_available = is_available;
|
||||||
klass->act_stage1_prepare = act_stage1_prepare;
|
klass->act_stage1_prepare = act_stage1_prepare;
|
||||||
klass->act_stage2_config = act_stage2_config;
|
klass->act_stage2_config = act_stage2_config;
|
||||||
klass->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
|
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_is_up = hw_is_up;
|
||||||
klass->hw_bring_up = hw_bring_up;
|
klass->hw_bring_up = hw_bring_up;
|
||||||
klass->hw_take_down = hw_take_down;
|
klass->hw_take_down = hw_take_down;
|
||||||
|
klass->carrier_changed = carrier_changed;
|
||||||
|
klass->can_interrupt_activation = can_interrupt_activation;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
@@ -4956,6 +5099,14 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||||||
0, G_MAXUINT32, NM_DEVICE_CAP_NONE,
|
0, G_MAXUINT32, NM_DEVICE_CAP_NONE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
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
|
g_object_class_install_property
|
||||||
(object_class, PROP_IP4_ADDRESS,
|
(object_class, PROP_IP4_ADDRESS,
|
||||||
g_param_spec_uint (NM_DEVICE_IP4_ADDRESS,
|
g_param_spec_uint (NM_DEVICE_IP4_ADDRESS,
|
||||||
|
@@ -45,6 +45,7 @@
|
|||||||
#define NM_DEVICE_DRIVER_VERSION "driver-version"
|
#define NM_DEVICE_DRIVER_VERSION "driver-version"
|
||||||
#define NM_DEVICE_FIRMWARE_VERSION "firmware-version"
|
#define NM_DEVICE_FIRMWARE_VERSION "firmware-version"
|
||||||
#define NM_DEVICE_CAPABILITIES "capabilities"
|
#define NM_DEVICE_CAPABILITIES "capabilities"
|
||||||
|
#define NM_DEVICE_CARRIER "carrier"
|
||||||
#define NM_DEVICE_IP4_ADDRESS "ip4-address"
|
#define NM_DEVICE_IP4_ADDRESS "ip4-address"
|
||||||
#define NM_DEVICE_IP4_CONFIG "ip4-config"
|
#define NM_DEVICE_IP4_CONFIG "ip4-config"
|
||||||
#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
|
#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
|
||||||
@@ -99,11 +100,14 @@ typedef struct {
|
|||||||
NMDeviceState old_state,
|
NMDeviceState old_state,
|
||||||
NMDeviceStateReason reason);
|
NMDeviceStateReason reason);
|
||||||
|
|
||||||
/* Hardware state, ie IFF_UP */
|
/* Hardware state (IFF_UP) */
|
||||||
gboolean (*hw_is_up) (NMDevice *self);
|
gboolean (*hw_is_up) (NMDevice *self);
|
||||||
gboolean (*hw_bring_up) (NMDevice *self, gboolean *no_firmware);
|
gboolean (*hw_bring_up) (NMDevice *self, gboolean *no_firmware);
|
||||||
void (*hw_take_down) (NMDevice *self);
|
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
|
/* Additional stuff required to operate the device, like a
|
||||||
* connection to the supplicant, Bluez, etc
|
* 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_is_available (NMDevice *dev);
|
||||||
gboolean nm_device_can_activate (NMDevice *dev);
|
gboolean nm_device_can_activate (NMDevice *dev);
|
||||||
|
|
||||||
|
gboolean nm_device_has_carrier (NMDevice *dev);
|
||||||
gboolean nm_device_ignore_carrier (NMDevice *dev);
|
gboolean nm_device_ignore_carrier (NMDevice *dev);
|
||||||
|
|
||||||
NMConnection * nm_device_get_best_auto_connection (NMDevice *dev,
|
NMConnection * nm_device_get_best_auto_connection (NMDevice *dev,
|
||||||
|
Reference in New Issue
Block a user