device: merge branch 'th/act-stage1-re-entrant'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/245
This commit is contained in:
Thomas Haller 2019-08-28 16:27:16 +02:00
commit 397b05e8ba
28 changed files with 703 additions and 693 deletions

View file

@ -230,20 +230,6 @@ update_connection (NMDevice *device, NMConnection *connection)
NULL);
}
static NMActStageReturn
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *out_failure_reason)
{
NMActStageReturn ret;
ret = NM_DEVICE_CLASS (nm_device_6lowpan_parent_class)->act_stage1_prepare (dev, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
return NM_ACT_STAGE_RETURN_FAILURE;
return NM_ACT_STAGE_RETURN_SUCCESS;
}
/*****************************************************************************/
static void
@ -273,7 +259,7 @@ nm_device_6lowpan_class_init (NMDevice6LowpanClass *klass)
device_class->connection_type_check_compatible = NM_SETTING_6LOWPAN_SETTING_NAME;
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_6LOWPAN);
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
device_class->complete_connection = complete_connection;
device_class->create_and_realize = create_and_realize;
device_class->get_generic_capabilities = get_generic_capabilities;

View file

@ -213,10 +213,10 @@ set_simple_option (NMDevice *device,
set_bond_attr (device, mode, opt, value);
}
static NMActStageReturn
apply_bonding_config (NMDevice *device)
static gboolean
apply_bonding_config (NMDeviceBond *self)
{
NMDeviceBond *self = NM_DEVICE_BOND (device);
NMDevice *device = NM_DEVICE (self);
NMSettingBond *s_bond;
int ifindex = nm_device_get_ifindex (device);
const char *mode_str, *value;
@ -239,7 +239,7 @@ apply_bonding_config (NMDevice *device)
s_bond = nm_device_get_applied_setting (device, NM_TYPE_SETTING_BOND);
g_return_val_if_fail (s_bond, NM_ACT_STAGE_RETURN_FAILURE);
g_return_val_if_fail (s_bond, FALSE);
mode_str = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE);
if (!mode_str)
@ -248,7 +248,7 @@ apply_bonding_config (NMDevice *device)
mode = _nm_setting_bond_mode_from_string (mode_str);
if (mode == NM_BOND_MODE_UNKNOWN) {
_LOGW (LOGD_BOND, "unknown bond mode '%s'", mode_str);
return NM_ACT_STAGE_RETURN_FAILURE;
return FALSE;
}
/* Set mode first, as some other options (e.g. arp_interval) are valid
@ -334,24 +334,26 @@ apply_bonding_config (NMDevice *device)
else
set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA);
return NM_ACT_STAGE_RETURN_SUCCESS;
return TRUE;
}
static NMActStageReturn
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *out_failure_reason)
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceBond *self = NM_DEVICE_BOND (device);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
ret = NM_DEVICE_CLASS (nm_device_bond_parent_class)->act_stage1_prepare (dev, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
/* Interface must be down to set bond options */
nm_device_take_down (dev, TRUE);
ret = apply_bonding_config (dev);
if (ret != NM_ACT_STAGE_RETURN_FAILURE)
ret = nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE);
nm_device_bring_up (dev, TRUE, NULL);
nm_device_take_down (device, TRUE);
if (!apply_bonding_config (self))
ret = NM_ACT_STAGE_RETURN_FAILURE;
else {
if (!nm_device_hw_addr_set_cloned (device,
nm_device_get_applied_connection (device),
FALSE))
ret = NM_ACT_STAGE_RETURN_FAILURE;
}
nm_device_bring_up (device, TRUE, NULL);
return ret;
}

View file

@ -225,7 +225,7 @@ commit_option (NMDevice *device, NMSetting *setting, const Option *option, gbool
GParamSpec *pspec;
GValue val = G_VALUE_INIT;
guint32 uval = 0;
gs_free char *value = NULL;
char value[100];
g_assert (setting);
@ -258,10 +258,10 @@ commit_option (NMDevice *device, NMSetting *setting, const Option *option, gbool
if (option->user_hz_compensate)
uval *= 100;
} else
g_assert_not_reached ();
nm_assert_not_reached ();
g_value_unset (&val);
value = g_strdup_printf ("%u", uval);
nm_sprintf_buf (value, "%u", uval);
if (slave)
nm_platform_sysctl_slave_set_option (nm_device_get_platform (device), ifindex, option->sysname, value);
else
@ -497,27 +497,16 @@ bridge_set_vlan_options (NMDevice *device, NMSettingBridge *s_bridge)
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMActStageReturn ret;
NMConnection *connection;
NMSetting *s_bridge;
const Option *option;
NM_DEVICE_BRIDGE (device)->vlan_configured = FALSE;
ret = NM_DEVICE_CLASS (nm_device_bridge_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
connection = nm_device_get_applied_connection (device);
g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
s_bridge = (NMSetting *) nm_connection_get_setting_bridge (connection);
g_return_val_if_fail (s_bridge, NM_ACT_STAGE_RETURN_FAILURE);
if (!nm_device_hw_addr_set_cloned (device, connection, FALSE)) {
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
return NM_ACT_STAGE_RETURN_FAILURE;
}
for (option = master_options; option->name; option++)
commit_option (device, s_bridge, option, FALSE);
@ -555,6 +544,10 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
static void
deactivate (NMDevice *device)
{
NMDeviceBridge *self = NM_DEVICE_BRIDGE (device);
self->vlan_configured = FALSE;
if (nm_bt_vtable_network_server) {
/* always call unregister. It does nothing if the device
* isn't registered as a hotspot bridge. */
@ -760,6 +753,7 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass)
device_class->master_update_slave_connection = master_update_slave_connection;
device_class->create_and_realize = create_and_realize;
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->act_stage2_config = act_stage2_config;
device_class->deactivate = deactivate;

View file

@ -116,21 +116,6 @@ create_and_realize (NMDevice *device,
return TRUE;
}
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMActStageReturn ret;
ret = NM_DEVICE_CLASS (nm_device_dummy_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
return NM_ACT_STAGE_RETURN_FAILURE;
return NM_ACT_STAGE_RETURN_SUCCESS;
}
/*****************************************************************************/
static void
@ -167,7 +152,7 @@ nm_device_dummy_class_init (NMDeviceDummyClass *klass)
device_class->create_and_realize = create_and_realize;
device_class->get_generic_capabilities = get_generic_capabilities;
device_class->update_connection = update_connection;
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired;
}

View file

@ -454,8 +454,10 @@ wired_secrets_cb (NMActRequest *req,
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else
nm_device_activate_schedule_stage1_device_prepare (device);
return;
}
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
@ -496,17 +498,17 @@ link_timeout_cb (gpointer user_data)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
NMDevice *dev = NM_DEVICE (self);
NMDevice *device = NM_DEVICE (self);
NMActRequest *req;
NMConnection *applied_connection;
const char *setting_name;
priv->supplicant_timeout_id = 0;
req = nm_device_get_act_request (dev);
req = nm_device_get_act_request (device);
if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) {
nm_device_state_changed (dev,
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT);
return FALSE;
@ -516,7 +518,7 @@ link_timeout_cb (gpointer user_data)
* ARE checked - we are likely to have wrong key. Ask the user for
* another one.
*/
if (nm_device_get_state (dev) != NM_DEVICE_STATE_CONFIG)
if (nm_device_get_state (device) != NM_DEVICE_STATE_CONFIG)
goto time_out;
nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req));
@ -530,14 +532,14 @@ link_timeout_cb (gpointer user_data)
"Activation: (ethernet) disconnected during authentication, asking for new key.");
supplicant_interface_release (self);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
wired_secrets_get_secrets (self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
return FALSE;
time_out:
_LOGW (LOGD_DEVICE | LOGD_ETHER, "link timed out.");
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
return FALSE;
}
@ -794,14 +796,19 @@ link_negotiation_set (NMDevice *device)
autoneg = nm_setting_wired_get_auto_negotiate (s_wired);
speed = nm_setting_wired_get_speed (s_wired);
duplex = link_duplex_to_platform (nm_setting_wired_get_duplex (s_wired));
if (!autoneg && !speed && !duplex) {
if ( !autoneg
&& !speed
&& !duplex) {
_LOGD (LOGD_DEVICE, "set-link: ignore link negotiation");
return;
}
}
if (!nm_platform_ethtool_get_link_settings (nm_device_get_platform (device), nm_device_get_ifindex (device),
&link_autoneg, &link_speed, &link_duplex)) {
if (!nm_platform_ethtool_get_link_settings (nm_device_get_platform (device),
nm_device_get_ifindex (device),
&link_autoneg,
&link_speed,
&link_duplex)) {
_LOGW (LOGD_DEVICE, "set-link: unable to retrieve link negotiation");
return;
}
@ -814,16 +821,18 @@ link_negotiation_set (NMDevice *device)
return;
}
if (autoneg && !speed && !duplex)
if ( autoneg
&& !speed
&& !duplex)
_LOGD (LOGD_DEVICE, "set-link: configure auto-negotiation");
else {
_LOGD (LOGD_DEVICE, "set-link: configure %snegotiation (%u Mbit%s - %s duplex%s)",
autoneg ? "auto-" : "static ",
speed ?: link_speed,
speed ? "" : "*",
duplex
? nm_platform_link_duplex_type_to_string (duplex)
: nm_platform_link_duplex_type_to_string (link_duplex),
duplex
? nm_platform_link_duplex_type_to_string (duplex)
: nm_platform_link_duplex_type_to_string (link_duplex),
duplex ? "" : "*");
}
@ -844,45 +853,44 @@ pppoe_reconnect_delay (gpointer user_data)
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
priv->pppoe_wait_id = 0;
priv->last_pppoe_time = 0;
_LOGI (LOGD_DEVICE, "PPPoE reconnect delay complete, resuming connection...");
nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self));
return FALSE;
nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self));
return G_SOURCE_REMOVE;
}
static NMActStageReturn
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *out_failure_reason)
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
NMActStageReturn ret;
ret = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage1_prepare (dev, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
link_negotiation_set (dev);
if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
return NM_ACT_STAGE_RETURN_FAILURE;
link_negotiation_set (device);
/* If we're re-activating a PPPoE connection a short while after
* a previous PPPoE connection was torn down, wait a bit to allow the
* remote side to handle the disconnection. Otherwise the peer may
* get confused and fail to negotiate the new connection. (rh #1023503)
*
* FIXME(shutdown): when exiting, we also need to wait before quiting,
* at least for additional NM_SHUTDOWN_TIMEOUT_MS seconds because
* otherwise after restart the device won't work for the first seconds.
*/
if (priv->last_pppoe_time) {
if (priv->last_pppoe_time != 0) {
gint32 delay = nm_utils_get_monotonic_timestamp_s () - priv->last_pppoe_time;
if ( delay < PPPOE_RECONNECT_DELAY
&& nm_device_get_applied_setting (dev, NM_TYPE_SETTING_PPPOE)) {
_LOGI (LOGD_DEVICE, "delaying PPPoE reconnect for %d seconds to ensure peer is ready...",
delay);
g_assert (!priv->pppoe_wait_id);
priv->pppoe_wait_id = g_timeout_add_seconds (delay,
pppoe_reconnect_delay,
self);
&& nm_device_get_applied_setting (device, NM_TYPE_SETTING_PPPOE)) {
if (priv->pppoe_wait_id == 0) {
_LOGI (LOGD_DEVICE, "delaying PPPoE reconnect for %d seconds to ensure peer is ready...",
delay);
priv->pppoe_wait_id = g_timeout_add_seconds (delay,
pppoe_reconnect_delay,
self);
}
return NM_ACT_STAGE_RETURN_POSTPONE;
}
nm_clear_g_source (&priv->pppoe_wait_id);
priv->last_pppoe_time = 0;
}
@ -1763,6 +1771,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
device_class->new_default_connection = new_default_connection;
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
device_class->act_stage2_config = act_stage2_config;
device_class->act_stage3_ip_config_start = act_stage3_ip_config_start;
device_class->get_configured_mtu = get_configured_mtu;

View file

@ -76,16 +76,11 @@ static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
nm_auto_close int dirfd = -1;
NMActStageReturn ret;
NMSettingInfiniband *s_infiniband;
char ifname_verified[IFNAMSIZ];
const char *transport_mode;
gboolean ok;
ret = NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
s_infiniband = nm_device_get_applied_setting (device, NM_TYPE_SETTING_INFINIBAND);
g_return_val_if_fail (s_infiniband, NM_ACT_STAGE_RETURN_FAILURE);
@ -94,7 +89,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
dirfd = nm_platform_sysctl_open_netdir (nm_device_get_platform (device), nm_device_get_ifindex (device), ifname_verified);
if (dirfd < 0) {
if (!strcmp (transport_mode, "datagram"))
if (nm_streq (transport_mode, "datagram"))
return NM_ACT_STAGE_RETURN_SUCCESS;
else {
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_INFINIBAND_MODE);

View file

@ -965,21 +965,6 @@ set_property (GObject *object, guint prop_id,
}
}
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMActStageReturn ret;
ret = NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
return NM_ACT_STAGE_RETURN_FAILURE;
return NM_ACT_STAGE_RETURN_SUCCESS;
}
/*****************************************************************************/
static void
@ -1066,7 +1051,7 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
NM_LINK_TYPE_IPIP,
NM_LINK_TYPE_SIT);
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
device_class->link_changed = link_changed;
device_class->can_reapply_change = can_reapply_change;
device_class->complete_connection = complete_connection;

View file

@ -308,8 +308,10 @@ macsec_secrets_cb (NMActRequest *req,
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else
nm_device_activate_schedule_stage1_device_prepare (device);
return;
}
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void

View file

@ -270,7 +270,7 @@ create_and_realize (NMDevice *device,
/*****************************************************************************/
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
get_generic_capabilities (NMDevice *device)
{
/* We assume MACVLAN interfaces always support carrier detect */
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
@ -415,20 +415,6 @@ update_connection (NMDevice *device, NMConnection *connection)
NULL);
}
static NMActStageReturn
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *out_failure_reason)
{
NMActStageReturn ret;
ret = NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->act_stage1_prepare (dev, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE))
return NM_ACT_STAGE_RETURN_FAILURE;
return NM_ACT_STAGE_RETURN_SUCCESS;
}
/*****************************************************************************/
static void
@ -507,7 +493,7 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass)
device_class->connection_type_check_compatible = NM_SETTING_MACVLAN_SETTING_NAME;
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP);
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
device_class->check_connection_compatible = check_connection_compatible;
device_class->complete_connection = complete_connection;
device_class->create_and_realize = create_and_realize;

View file

@ -25,6 +25,12 @@
/* This file should only be used by subclasses of NMDevice */
typedef enum {
NM_DEVICE_STAGE_STATE_INIT = 0,
NM_DEVICE_STAGE_STATE_PENDING = 1,
NM_DEVICE_STAGE_STATE_COMPLETED = 2,
} NMDeviceStageState;
typedef enum {
NM_DEVICE_IP_STATE_NONE,
NM_DEVICE_IP_STATE_WAIT,

View file

@ -351,18 +351,17 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceTun *self = NM_DEVICE_TUN (device);
NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self);
NMActStageReturn ret;
ret = NM_DEVICE_CLASS (nm_device_tun_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
/* Nothing to do for TUN devices */
if (priv->props.type == IFF_TUN)
return NM_ACT_STAGE_RETURN_SUCCESS;
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
return NM_ACT_STAGE_RETURN_FAILURE;
if (priv->props.type == IFF_TUN) {
/* Nothing to do for TUN devices */
} else {
if (!nm_device_hw_addr_set_cloned (device,
nm_device_get_applied_connection (device),
FALSE)) {
*out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
return NM_ACT_STAGE_RETURN_FAILURE;
}
}
return NM_ACT_STAGE_RETURN_SUCCESS;
}

View file

@ -477,14 +477,6 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDevice *parent_device;
NMSettingVlan *s_vlan;
NMActStageReturn ret;
ret = NM_DEVICE_CLASS (nm_device_vlan_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
return NM_ACT_STAGE_RETURN_FAILURE;
/* Change MAC address to parent's one if needed */
parent_device = nm_device_parent_get_device (device);
@ -497,7 +489,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
if (s_vlan) {
gs_free NMVlanQosMapping *ingress_map = NULL;
gs_free NMVlanQosMapping *egress_map = NULL;
guint n_ingress_map = 0, n_egress_map = 0;
guint n_ingress_map = 0;
guint n_egress_map = 0;
_nm_setting_vlan_get_priorities (s_vlan,
NM_VLAN_INGRESS_MAP,
@ -520,7 +513,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
n_egress_map);
}
return ret;
return NM_ACT_STAGE_RETURN_SUCCESS;
}
static guint32
@ -603,6 +596,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
device_class->link_changed = link_changed;
device_class->unrealize_notify = unrealize_notify;
device_class->get_generic_capabilities = get_generic_capabilities;
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->get_configured_mtu = get_configured_mtu;
device_class->is_available = is_available;

View file

@ -481,21 +481,6 @@ update_connection (NMDevice *device, NMConnection *connection)
}
}
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMActStageReturn ret;
ret = NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
return NM_ACT_STAGE_RETURN_FAILURE;
return NM_ACT_STAGE_RETURN_SUCCESS;
}
/*****************************************************************************/
static void
@ -620,7 +605,7 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
device_class->complete_connection = complete_connection;
device_class->get_generic_capabilities = get_generic_capabilities;
device_class->update_connection = update_connection;
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired;
obj_properties[PROP_ID] =

View file

@ -1276,8 +1276,10 @@ _secrets_cb (NMActRequest *req,
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else
nm_device_activate_schedule_stage1_device_prepare (device);
return;
}
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
@ -1517,17 +1519,6 @@ link_config_delayed_resolver_cb (gpointer user_data)
return G_SOURCE_REMOVE;
}
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (device);
priv->auto_default_route_initialized = FALSE;
priv->auto_default_route_priority_initialized = FALSE;
return NM_DEVICE_CLASS (nm_device_wireguard_parent_class)->act_stage1_prepare (device, out_failure_reason);
}
static NMActStageReturn
act_stage2_config (NMDevice *device,
NMDeviceStateReason *out_failure_reason)
@ -1968,7 +1959,6 @@ nm_device_wireguard_class_init (NMDeviceWireGuardClass *klass)
device_class->connection_type_check_compatible = NM_SETTING_WIREGUARD_SETTING_NAME;
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WIREGUARD);
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->state_changed = device_state_changed;
device_class->create_and_realize = create_and_realize;
device_class->act_stage2_config = act_stage2_config;

View file

@ -131,12 +131,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
NMDevice *lowpan_device = NULL;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
ret = NM_DEVICE_CLASS (nm_device_wpan_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
platform = nm_device_get_platform (device);
g_return_val_if_fail (platform, NM_ACT_STAGE_RETURN_FAILURE);
nm_assert (NM_IS_PLATFORM (platform));
ifindex = nm_device_get_ifindex (device);
@ -147,7 +143,11 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
g_return_val_if_fail (s_wpan, NM_ACT_STAGE_RETURN_FAILURE);
hwaddr = nm_platform_link_get_address (platform, ifindex, &hwaddr_len);
g_return_val_if_fail (hwaddr, NM_ACT_STAGE_RETURN_FAILURE);
if (!hwaddr) {
*out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
return NM_ACT_STAGE_RETURN_FAILURE;
}
/* As of kernel 4.16, the 6LoWPAN devices layered on top of WPANs
* need to be DOWN as well as the WPAN device itself in order to
@ -156,7 +156,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
NM_LINK_TYPE_6LOWPAN,
hwaddr,
hwaddr_len);
if (lowpan_plink && NM_FLAGS_HAS (lowpan_plink->n_ifi_flags, IFF_UP)) {
if ( lowpan_plink
&& NM_FLAGS_HAS (lowpan_plink->n_ifi_flags, IFF_UP)) {
lowpan_device = nm_manager_get_device_by_ifindex (nm_manager_get (),
lowpan_plink->ifindex);
}
@ -192,6 +193,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
}
ret = NM_ACT_STAGE_RETURN_SUCCESS;
out:
nm_device_bring_up (device, TRUE, NULL);

View file

@ -102,11 +102,6 @@ _LOG_DECLARE_SELF (NMDevice);
typedef void (*ActivationHandleFunc) (NMDevice *self);
typedef struct {
ActivationHandleFunc func;
guint id;
} ActivationHandleData;
typedef enum {
CLEANUP_TYPE_KEEP,
CLEANUP_TYPE_REMOVED,
@ -333,8 +328,23 @@ typedef struct _NMDevicePrivate {
NMActRequest * queued_act_request;
bool queued_act_request_is_waiting_for_carrier:1;
NMDBusTrackObjPath act_request;
ActivationHandleData act_handle4; /* for layer2 and IPv4. */
ActivationHandleData act_handle6;
union {
struct {
guint activation_source_id_6;
guint activation_source_id_4; /* for layer2 and IPv4. */
};
guint activation_source_id_x[2];
};
union {
struct {
ActivationHandleFunc activation_source_func_6;
ActivationHandleFunc activation_source_func_4; /* for layer2 and IPv4. */
};
ActivationHandleFunc activation_source_func_x[2];
};
guint recheck_assume_id;
struct {
@ -394,7 +404,6 @@ typedef struct _NMDevicePrivate {
NMDeviceAutoconnectBlockedFlags autoconnect_blocked_flags:5;
bool is_enslaved:1;
bool master_ready_handled:1;
bool ipv6ll_handle:1; /* TRUE if NM handles the device's IPv6LL address */
bool ipv6ll_has:1;
@ -403,6 +412,8 @@ typedef struct _NMDevicePrivate {
bool concheck_rp_filter_checked:1;
NMDeviceStageState stage1_sriov_state:3;
/* Generic DHCP stuff */
char * dhcp_anycast_address;
@ -633,7 +644,6 @@ static void _carrier_wait_check_queued_act_request (NMDevice *self);
static gint64 _get_carrier_wait_ms (NMDevice *self);
static const char *_activation_func_to_string (ActivationHandleFunc func);
static void activation_source_handle_cb (NMDevice *self, int addr_family);
static void _set_state_full (NMDevice *self,
NMDeviceState state,
@ -671,6 +681,10 @@ static void (*const activate_stage4_ip_config_timeout_x[2]) (NMDevice *self) = {
activate_stage4_ip_config_timeout_4,
};
static void sriov_op_cb (GError *error, gpointer user_data);
static void activate_stage2_device_config (NMDevice *self);
static void activate_stage5_ip_config_result_4 (NMDevice *self);
static void activate_stage5_ip_config_result_6 (NMDevice *self);
@ -4234,7 +4248,7 @@ nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink
}
}
static void sriov_op_cb (GError *error, gpointer user_data);
/*****************************************************************************/
static void
sriov_op_start (NMDevice *self, SriovOp *op)
@ -4267,11 +4281,14 @@ sriov_op_cb (GError *error, gpointer user_data)
priv->sriov.pending = NULL;
g_clear_object (&op->cancellable);
if (op->callback)
op->callback (error, op->callback_data);
g_clear_object (&op->cancellable);
g_slice_free (SriovOp, op);
nm_assert (!priv->sriov.pending);
nm_g_slice_free (op);
if (priv->sriov.next) {
sriov_op_start (self,
@ -4279,6 +4296,44 @@ sriov_op_cb (GError *error, gpointer user_data)
}
}
static void
sriov_op_queue_op (NMDevice *self,
SriovOp *op)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->sriov.next) {
SriovOp *op_next = g_steal_pointer (&priv->sriov.next);
/* Cancel the next operation immediately */
if (op_next->callback) {
gs_free_error GError *error = NULL;
nm_utils_error_set_cancelled (&error, FALSE, NULL);
op_next->callback (error, op_next->callback_data);
}
nm_g_slice_free (op_next);
if (!priv->sriov.pending) {
/* This (having "next" set but "pending" not) can only happen if we are
* called from inside the callback again.
*
* That means we append the new request as "next" and return. Once
* the callback returns, it will schedule the request. */
priv->sriov.next = op;
return;
}
} else if (priv->sriov.pending) {
priv->sriov.next = op;
g_cancellable_cancel (priv->sriov.pending->cancellable);
return;
}
if (op)
sriov_op_start (self, op);
}
static void
sriov_op_queue (NMDevice *self,
guint num_vfs,
@ -4286,32 +4341,35 @@ sriov_op_queue (NMDevice *self,
NMPlatformAsyncCallback callback,
gpointer callback_data)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
GError *error = NULL;
SriovOp *op;
op = g_slice_new0 (SriovOp);
op->num_vfs = num_vfs;
op->autoprobe = autoprobe;
op->callback = callback;
op->callback_data = callback_data;
/* We usually never want to cancel an async write operation, unless it's superseded
* by a newer operation (that resets the state). That is, because we need to ensure
* that we never end up doing two concurrent writes (since we write on a background
* thread, that would be unordered/racy).
* Of course, since we queue requests only per-device, when devices get renamed we
* might end up writing the same sysctl concurrently still. But that's really
* unlikely, and don't rename after udev completes!
*
* The "next" operation is not yet even started. It can be replaced/canceled right away
* when a newer request comes.
* The "pending" operation is currently ongoing, and we may cancel it if
* we have a follow-up operation (queued in "next"). Unless we have a such
* a newer request, we cannot cancel it!
*
* FIXME(shutdown): However, during shutdown we don't have a follow-up write request to cancel
* this operation and we have to give it at least some time to complete. The solution is that
* we register a way to abort the last call during shutdown, and after NM_SHUTDOWN_TIMEOUT_MS
* grace period we pull the plug and cancel it. */
if (priv->sriov.next) {
/* Cancel the next operation immediately */
if (priv->sriov.next->callback) {
nm_utils_error_set_cancelled (&error, FALSE, NULL);
priv->sriov.next->callback (error, priv->sriov.next->callback_data);
g_clear_error (&error);
}
g_slice_free (SriovOp, priv->sriov.next);
priv->sriov.next = NULL;
}
if (priv->sriov.pending) {
priv->sriov.next = op;
g_cancellable_cancel (priv->sriov.pending->cancellable);
} else
sriov_op_start (self, op);
op = g_slice_new (SriovOp);
*op = (SriovOp) {
.num_vfs = num_vfs,
.autoprobe = autoprobe,
.callback = callback,
.callback_data = callback_data,
};
sriov_op_queue_op (self, op);
}
static void
@ -6094,119 +6152,102 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us
/*****************************************************************************/
static gboolean
activation_source_handle_cb4 (gpointer user_data)
{
activation_source_handle_cb (user_data, AF_INET);
return G_SOURCE_REMOVE;
}
static gboolean
activation_source_handle_cb6 (gpointer user_data)
{
activation_source_handle_cb (user_data, AF_INET6);
return G_SOURCE_REMOVE;
}
static ActivationHandleData *
activation_source_get_by_family (NMDevice *self,
int addr_family,
GSourceFunc *out_idle_func)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
switch (addr_family) {
case AF_INET6:
NM_SET_OUT (out_idle_func, activation_source_handle_cb6);
return &priv->act_handle6;
case AF_INET:
NM_SET_OUT (out_idle_func, activation_source_handle_cb4);
return &priv->act_handle4;
}
g_return_val_if_reached (NULL);
}
static void
activation_source_clear (NMDevice *self,
int addr_family)
{
ActivationHandleData *act_data;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
const gboolean IS_IPv4 = (addr_family == AF_INET);
act_data = activation_source_get_by_family (self, addr_family, NULL);
if (act_data->id) {
if (priv->activation_source_id_x[IS_IPv4] != 0) {
_LOGD (LOGD_DEVICE, "activation-stage: clear %s,v%c (id %u)",
_activation_func_to_string (act_data->func),
_activation_func_to_string (priv->activation_source_func_x[IS_IPv4]),
nm_utils_addr_family_to_char (addr_family),
act_data->id);
nm_clear_g_source (&act_data->id);
act_data->func = NULL;
priv->activation_source_id_x[IS_IPv4]);
nm_clear_g_source (&priv->activation_source_id_x[IS_IPv4]);
priv->activation_source_func_x[IS_IPv4] = NULL;
}
}
static void
static gboolean
activation_source_handle_cb (NMDevice *self,
int addr_family)
{
ActivationHandleData *act_data, a;
NMDevicePrivate *priv;
const gboolean IS_IPv4 = (addr_family == AF_INET);
ActivationHandleFunc activation_source_func;
guint activation_source_id;
g_return_if_fail (NM_IS_DEVICE (self));
g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
act_data = activation_source_get_by_family (self, addr_family, NULL);
priv = NM_DEVICE_GET_PRIVATE (self);
g_return_if_fail (act_data->id);
g_return_if_fail (act_data->func);
activation_source_func = priv->activation_source_func_x[IS_IPv4];
activation_source_id = priv->activation_source_id_x[IS_IPv4];
a = *act_data;
g_return_val_if_fail (activation_source_id != 0, G_SOURCE_REMOVE);
nm_assert (activation_source_func);
act_data->func = NULL;
act_data->id = 0;
priv->activation_source_func_x[IS_IPv4] = NULL;
priv->activation_source_id_x[IS_IPv4] = 0;
_LOGD (LOGD_DEVICE, "activation-stage: invoke %s,v%c (id %u)",
_activation_func_to_string (a.func),
_activation_func_to_string (activation_source_func),
nm_utils_addr_family_to_char (addr_family),
a.id);
activation_source_id);
a.func (self);
activation_source_func (self);
_LOGD (LOGD_DEVICE, "activation-stage: complete %s,v%c (id %u)",
_activation_func_to_string (a.func),
_LOGT (LOGD_DEVICE, "activation-stage: complete %s,v%c (id %u)",
_activation_func_to_string (activation_source_func),
nm_utils_addr_family_to_char (addr_family),
a.id);
activation_source_id);
return G_SOURCE_REMOVE;
}
static gboolean
activation_source_handle_cb_4 (gpointer user_data)
{
return activation_source_handle_cb (user_data, AF_INET);
}
static gboolean
activation_source_handle_cb_6 (gpointer user_data)
{
return activation_source_handle_cb (user_data, AF_INET6);
}
static void
activation_source_schedule (NMDevice *self, ActivationHandleFunc func, int addr_family)
{
ActivationHandleData *act_data;
GSourceFunc source_func = NULL;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
const gboolean IS_IPv4 = (addr_family == AF_INET);
guint new_id = 0;
act_data = activation_source_get_by_family (self, addr_family, &source_func);
if (act_data->id && act_data->func == func) {
/* Don't bother rescheduling the same function that's about to
* run anyway. Fixes issues with crappy wireless drivers sending
* streams of associate events before NM has had a chance to process
* the first one.
*/
_LOGD (LOGD_DEVICE, "activation-stage: already scheduled %s,v%c (id %u)",
if ( priv->activation_source_id_x[IS_IPv4] != 0
&& priv->activation_source_func_x[IS_IPv4] == func) {
/* Scheduling the same stage multiple times is fine. */
_LOGT (LOGD_DEVICE, "activation-stage: already scheduled %s,v%c (id %u)",
_activation_func_to_string (func),
nm_utils_addr_family_to_char (addr_family),
act_data->id);
priv->activation_source_id_x[IS_IPv4]);
return;
}
new_id = g_idle_add (source_func, self);
new_id = g_idle_add ( IS_IPv4
? activation_source_handle_cb_4
: activation_source_handle_cb_6,
self);
if (act_data->id) {
_LOGW (LOGD_DEVICE, "activation-stage: schedule %s,v%c which replaces %s,v%c (id %u -> %u)",
if (priv->activation_source_id_x[IS_IPv4] != 0) {
_LOGD (LOGD_DEVICE, "activation-stage: schedule %s,v%c which replaces %s,v%c (id %u -> %u)",
_activation_func_to_string (func),
nm_utils_addr_family_to_char (addr_family),
_activation_func_to_string (act_data->func),
_activation_func_to_string (priv->activation_source_func_x[IS_IPv4]),
nm_utils_addr_family_to_char (addr_family),
act_data->id, new_id);
nm_clear_g_source (&act_data->id);
priv->activation_source_id_x[IS_IPv4], new_id);
nm_clear_g_source (&priv->activation_source_id_x[IS_IPv4]);
} else {
_LOGD (LOGD_DEVICE, "activation-stage: schedule %s,v%c (id %u)",
_activation_func_to_string (func),
@ -6214,19 +6255,38 @@ activation_source_schedule (NMDevice *self, ActivationHandleFunc func, int addr_
new_id);
}
act_data->func = func;
act_data->id = new_id;
priv->activation_source_func_x[IS_IPv4] = func;
priv->activation_source_id_x[IS_IPv4] = new_id;
}
static gboolean
activation_source_is_scheduled (NMDevice *self,
ActivationHandleFunc func,
int addr_family)
static void
activation_source_invoke_sync (NMDevice *self, ActivationHandleFunc func, int addr_family)
{
ActivationHandleData *act_data;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
const gboolean IS_IPv4 = (addr_family == AF_INET);
act_data = activation_source_get_by_family (self, addr_family, NULL);
return act_data->func == func;
if (priv->activation_source_id_x[IS_IPv4] == 0) {
_LOGD (LOGD_DEVICE, "activation-stage: synchronously invoke %s,v%c",
_activation_func_to_string (func),
nm_utils_addr_family_to_char (addr_family));
} else if (priv->activation_source_func_x[IS_IPv4] == func) {
_LOGD (LOGD_DEVICE, "activation-stage: synchronously invoke %s,v%c which was already scheduled (id %u)",
_activation_func_to_string (func),
nm_utils_addr_family_to_char (addr_family),
priv->activation_source_id_x[IS_IPv4]);
} else {
_LOGD (LOGD_DEVICE, "activation-stage: synchronously invoke %s,v%c which replaces %s,v%c (id %u)",
_activation_func_to_string (func),
nm_utils_addr_family_to_char (addr_family),
_activation_func_to_string (priv->activation_source_func_x[IS_IPv4]),
nm_utils_addr_family_to_char (addr_family),
priv->activation_source_id_x[IS_IPv4]);
}
nm_clear_g_source (&priv->activation_source_id_x[IS_IPv4]);
priv->activation_source_func_x[IS_IPv4] = NULL;
func (self);
}
/*****************************************************************************/
@ -6239,22 +6299,18 @@ master_ready (NMDevice *self,
NMActiveConnection *master_connection;
NMDevice *master;
g_return_if_fail (priv->state == NM_DEVICE_STATE_PREPARE);
g_return_if_fail (!priv->master_ready_handled);
/* Notify a master device that it has a new slave */
g_return_if_fail (nm_active_connection_get_master_ready (active));
master_connection = nm_active_connection_get_master (active);
nm_assert (nm_active_connection_get_master_ready (active));
priv->master_ready_handled = TRUE;
nm_clear_g_signal_handler (active, &priv->master_ready_id);
master_connection = nm_active_connection_get_master (active);
master = nm_active_connection_get_device (master_connection);
_LOGD (LOGD_DEVICE, "master connection ready; master device %s",
nm_device_get_iface (master));
if (priv->master && priv->master != master)
if ( priv->master
&& priv->master != master)
nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
/* If the master didn't change, add-slave only rechecks whether to assume a connection. */
@ -6268,8 +6324,12 @@ master_ready_cb (NMActiveConnection *active,
GParamSpec *pspec,
NMDevice *self)
{
master_ready (self, active);
nm_device_activate_schedule_stage2_device_config (self);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
nm_assert (nm_active_connection_get_master_ready (active));
if (priv->state == NM_DEVICE_STATE_PREPARE)
nm_device_activate_schedule_stage1_device_prepare (self);
}
static void
@ -6415,64 +6475,9 @@ sriov_params_cb (GError *error, gpointer data)
return;
}
nm_device_activate_schedule_stage2_device_config (self);
}
priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_COMPLETED;
static NMActStageReturn
act_stage1_prepare (NMDevice *self, NMDeviceStateReason *out_failure_reason)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMSettingSriov *s_sriov;
guint i, num;
if ( priv->ifindex > 0
&& nm_device_has_capability (self, NM_DEVICE_CAP_SRIOV)
&& (s_sriov = nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))) {
nm_auto_freev NMPlatformVF **plat_vfs = NULL;
gs_free_error GError *error = NULL;
NMSriovVF *vf;
NMTernary autoprobe;
gpointer *data;
autoprobe = nm_setting_sriov_get_autoprobe_drivers (s_sriov);
if (autoprobe == NM_TERNARY_DEFAULT) {
autoprobe = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
NM_CON_DEFAULT ("sriov.autoprobe-drivers"),
self,
NM_TERNARY_FALSE,
NM_TERNARY_TRUE,
NM_TERNARY_TRUE);
}
num = nm_setting_sriov_get_num_vfs (s_sriov);
plat_vfs = g_new0 (NMPlatformVF *, num + 1);
for (i = 0; i < num; i++) {
vf = nm_setting_sriov_get_vf (s_sriov, i);
plat_vfs[i] = sriov_vf_config_to_platform (self, vf, &error);
if (!plat_vfs[i]) {
_LOGE (LOGD_DEVICE,
"failed to apply SR-IOV VF '%s': %s",
nm_utils_sriov_vf_to_str (vf, FALSE, NULL),
error->message);
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
return NM_ACT_STAGE_RETURN_FAILURE;
}
}
/* When changing the number of VFs the kernel can block
* for very long time in the write to sysfs, especially
* if autoprobe-drivers is enabled. Do it asynchronously
* to avoid blocking the entire NM process.
*/
data = nm_utils_user_data_pack (self, g_steal_pointer (&plat_vfs));
sriov_op_queue (self,
nm_setting_sriov_get_total_vfs (s_sriov),
autoprobe,
sriov_params_cb,
data);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
return NM_ACT_STAGE_RETURN_SUCCESS;
nm_device_activate_schedule_stage1_device_prepare (self);
}
/*
@ -6486,6 +6491,8 @@ activate_stage1_device_prepare (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
NMActiveConnection *active;
NMActiveConnection *master;
priv->v4_route_table_initialized = FALSE;
priv->v6_route_table_initialized = FALSE;
@ -6500,21 +6507,117 @@ activate_stage1_device_prepare (NMDevice *self)
nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
/* Assumed connections were already set up outside NetworkManager */
if (!nm_device_sys_iface_state_is_external_or_assume (self)) {
NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
if (priv->stage1_sriov_state != NM_DEVICE_STAGE_STATE_COMPLETED) {
NMSettingSriov *s_sriov;
ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &failure_reason);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* pass */
} else if (priv->stage1_sriov_state == NM_DEVICE_STAGE_STATE_PENDING)
return;
} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason);
else if ( priv->ifindex > 0
&& nm_device_has_capability (self, NM_DEVICE_CAP_SRIOV)
&& (s_sriov = nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))) {
nm_auto_freev NMPlatformVF **plat_vfs = NULL;
gs_free_error GError *error = NULL;
NMSriovVF *vf;
NMTernary autoprobe;
guint i, num;
autoprobe = nm_setting_sriov_get_autoprobe_drivers (s_sriov);
if (autoprobe == NM_TERNARY_DEFAULT) {
autoprobe = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
NM_CON_DEFAULT ("sriov.autoprobe-drivers"),
self,
NM_TERNARY_FALSE,
NM_TERNARY_TRUE,
NM_TERNARY_TRUE);
}
num = nm_setting_sriov_get_num_vfs (s_sriov);
plat_vfs = g_new0 (NMPlatformVF *, num + 1);
for (i = 0; i < num; i++) {
vf = nm_setting_sriov_get_vf (s_sriov, i);
plat_vfs[i] = sriov_vf_config_to_platform (self, vf, &error);
if (!plat_vfs[i]) {
_LOGE (LOGD_DEVICE,
"failed to apply SR-IOV VF '%s': %s",
nm_utils_sriov_vf_to_str (vf, FALSE, NULL),
error->message);
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
return;
}
}
/* When changing the number of VFs the kernel can block
* for very long time in the write to sysfs, especially
* if autoprobe-drivers is enabled. Do it asynchronously
* to avoid blocking the entire NM process.
*/
sriov_op_queue (self,
nm_setting_sriov_get_total_vfs (s_sriov),
autoprobe,
sriov_params_cb,
nm_utils_user_data_pack (self,
g_steal_pointer (&plat_vfs)));
priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_PENDING;
return;
}
g_return_if_fail (ret == NM_ACT_STAGE_RETURN_SUCCESS);
priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_COMPLETED;
}
nm_device_activate_schedule_stage2_device_config (self);
/* Assumed connections were already set up outside NetworkManager */
if (!nm_device_sys_iface_state_is_external_or_assume (self)) {
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
if (klass->act_stage1_prepare_set_hwaddr_ethernet) {
if (!nm_device_hw_addr_set_cloned (self,
nm_device_get_applied_connection (self),
FALSE)) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
return;
}
}
if (klass->act_stage1_prepare) {
NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
ret = klass->act_stage1_prepare (self, &failure_reason);
if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason);
return;
}
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
return;
nm_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
}
}
active = NM_ACTIVE_CONNECTION (priv->act_request.obj);
master = nm_active_connection_get_master (active);
if (master) {
/* If the master connection is ready for slaves, attach ourselves */
if (!nm_active_connection_get_master_ready (active)) {
if (nm_active_connection_get_state (master) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
_LOGD (LOGD_DEVICE, "master connection is deactivating");
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED);
return;
}
if (priv->master_ready_id == 0) {
_LOGD (LOGD_DEVICE, "waiting for master connection to become ready");
priv->master_ready_id = g_signal_connect (active,
"notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY,
(GCallback) master_ready_cb,
self);
}
return;
}
}
nm_clear_g_signal_handler (priv->act_request.obj, &priv->master_ready_id);
if (master)
master_ready (self, active);
activation_source_invoke_sync (self, activate_stage2_device_config, AF_INET);
}
/*
@ -6905,44 +7008,8 @@ activate_stage2_device_config (NMDevice *self)
void
nm_device_activate_schedule_stage2_device_config (NMDevice *self)
{
NMDevicePrivate *priv;
g_return_if_fail (NM_IS_DEVICE (self));
priv = NM_DEVICE_GET_PRIVATE (self);
g_return_if_fail (priv->act_request.obj);
if (!priv->master_ready_handled) {
NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request.obj);
NMActiveConnection *master;
master = nm_active_connection_get_master (active);
if (!master) {
g_warn_if_fail (!priv->master_ready_id);
priv->master_ready_handled = TRUE;
} else {
/* If the master connection is ready for slaves, attach ourselves */
if (nm_active_connection_get_master_ready (active))
master_ready (self, active);
else if (nm_active_connection_get_state (master) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
_LOGD (LOGD_DEVICE, "master connection is deactivating");
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED);
} else {
_LOGD (LOGD_DEVICE, "waiting for master connection to become ready");
if (priv->master_ready_id == 0) {
priv->master_ready_id = g_signal_connect (active,
"notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY,
(GCallback) master_ready_cb,
self);
}
/* Postpone */
return;
}
}
}
activation_source_schedule (self, activate_stage2_device_config, AF_INET);
}
@ -9930,7 +9997,7 @@ _ip6_privacy_get (NMDevice *self)
return ip6_privacy;
if (!nm_device_get_ip_ifindex (self))
return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;;
return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
/* 3.) No valid default-value configured. Fallback to reading sysctl.
*
@ -12269,7 +12336,7 @@ nm_device_is_activating (NMDevice *self)
* handler is actually run. If there's an activation handler scheduled
* we're activating anyway.
*/
return priv->act_handle4.id ? TRUE : FALSE;
return priv->activation_source_id_4 != 0;
}
NMProxyConfig *
@ -13251,9 +13318,8 @@ queued_ip_config_change (NMDevice *self, int addr_family)
* it changing IP configurations before they are applied. Postpone the
* update in such case.
*/
if (activation_source_is_scheduled (self,
activate_stage5_ip_config_result_x[IS_IPv4],
addr_family))
if ( priv->activation_source_id_x[IS_IPv4] != 0
&& priv->activation_source_func_x[IS_IPv4] == activate_stage5_ip_config_result_x[IS_IPv4])
return G_SOURCE_CONTINUE;
priv->queued_ip_config_id_x[IS_IPv4] = 0;
@ -14592,6 +14658,8 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type)
_cancel_activation (self);
priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_INIT;
if (cleanup_type != CLEANUP_TYPE_KEEP) {
nm_manager_device_route_metric_clear (nm_manager_get (),
nm_device_get_ip_ifindex (self));
@ -14670,10 +14738,7 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
if (priv->act_request.obj) {
nm_active_connection_set_default (NM_ACTIVE_CONNECTION (priv->act_request.obj), AF_INET, FALSE);
priv->master_ready_handled = FALSE;
nm_clear_g_signal_handler (priv->act_request.obj, &priv->master_ready_id);
act_request_set (self, NULL);
}
@ -15030,9 +15095,9 @@ deactivate_ready (NMDevice *self, NMDeviceStateReason reason)
if (priv->dispatcher.call_id)
return;
if (priv->sriov.pending)
if ( priv->sriov.pending
|| priv->sriov.next)
return;
nm_assert (!priv->sriov.next);
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
}
@ -16616,14 +16681,15 @@ dispose (GObject *object)
_cleanup_generic_pre (self, CLEANUP_TYPE_KEEP);
g_warn_if_fail (c_list_is_empty (&priv->slaves));
g_assert (priv->master_ready_id == 0);
nm_assert (c_list_is_empty (&priv->slaves));
/* Let the kernel manage IPv6LL again */
set_nm_ipv6ll (self, FALSE);
_cleanup_generic_post (self, CLEANUP_TYPE_KEEP);
nm_assert (priv->master_ready_id == 0);
g_hash_table_remove_all (priv->ip6_saved_properties);
nm_clear_g_source (&priv->recheck_assume_id);
@ -17139,7 +17205,6 @@ nm_device_class_init (NMDeviceClass *klass)
klass->link_changed = link_changed;
klass->is_available = is_available;
klass->act_stage1_prepare = act_stage1_prepare;
klass->act_stage2_config = act_stage2_config;
klass->act_stage3_ip_config_start = act_stage3_ip_config_start;
klass->act_stage4_ip_config_timeout = act_stage4_ip_config_timeout;

View file

@ -470,6 +470,9 @@ typedef struct _NMDeviceClass {
* a device or for external activations. In this case, act_stage2_config() must
* take care not to touch the device's configuration. */
bool act_stage2_config_also_for_external_or_assume:1;
bool act_stage1_prepare_set_hwaddr_ethernet:1;
} NMDeviceClass;
typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device,

View file

@ -49,14 +49,14 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceTeam,
typedef struct {
struct teamdctl *tdc;
char *config;
GPid teamd_pid;
guint teamd_process_watch;
guint teamd_timeout;
guint teamd_read_timeout;
guint teamd_dbus_watch;
char *config;
gboolean kill_in_progress;
NMConnection *connection;
bool kill_in_progress:1;
NMDeviceStageState stage1_state:3;
} NMDeviceTeamPrivate;
struct _NMDeviceTeam {
@ -70,11 +70,11 @@ struct _NMDeviceTeamClass {
G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE)
#define NM_DEVICE_TEAM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceTeam, NM_IS_DEVICE_TEAM)
#define NM_DEVICE_TEAM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceTeam, NM_IS_DEVICE_TEAM, NMDevice)
/*****************************************************************************/
static gboolean teamd_start (NMDevice *device, NMConnection *connection);
static gboolean teamd_start (NMDeviceTeam *self);
/*****************************************************************************/
@ -141,9 +141,8 @@ _get_config (NMDeviceTeam *self)
}
static gboolean
teamd_read_config (NMDevice *device)
teamd_read_config (NMDeviceTeam *self)
{
NMDeviceTeam *self = NM_DEVICE_TEAM (device);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
const char *config = NULL;
int err;
@ -170,11 +169,11 @@ teamd_read_config (NMDevice *device)
static gboolean
teamd_read_timeout_cb (gpointer user_data)
{
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE ((NMDeviceTeam *) user_data);
NMDeviceTeam *self = user_data;
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
teamd_read_config ((NMDevice *) user_data);
priv->teamd_read_timeout = 0;
teamd_read_config (self);
return G_SOURCE_REMOVE;
}
@ -192,8 +191,9 @@ update_connection (NMDevice *device, NMConnection *connection)
}
/* Read the configuration only if not already set */
if (!priv->config && ensure_teamd_connection (device))
teamd_read_config (device);
if ( !priv->config
&& ensure_teamd_connection (device))
teamd_read_config (self);
/* Restore previous tdc state */
if (priv->tdc && !tdc) {
@ -273,31 +273,32 @@ master_update_slave_connection (NMDevice *self,
}
/*****************************************************************************/
static void
teamd_kill_cb (pid_t pid, gboolean success, int child_status, void *user_data)
{
NMDevice *device = NM_DEVICE (user_data);
NMDeviceTeam *self = (NMDeviceTeam *) device;
gs_unref_object NMDeviceTeam *self = user_data;
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
priv->kill_in_progress = FALSE;
if (priv->connection) {
_LOGT (LOGD_TEAM, "kill terminated, starting teamd...");
if (!teamd_start (device, priv->connection)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
g_clear_object (&priv->connection);
if (nm_device_get_state (NM_DEVICE (self)) != NM_DEVICE_STATE_PREPARE) {
_LOGT (LOGD_TEAM, "kill terminated");
return;
}
_LOGT (LOGD_TEAM, "kill terminated, starting teamd...");
if (!teamd_start (self)) {
nm_device_state_changed (NM_DEVICE (self),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
g_object_unref (device);
}
static void
teamd_cleanup (NMDevice *device, gboolean free_tdc)
teamd_cleanup (NMDeviceTeam *self, gboolean free_tdc)
{
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE ((NMDeviceTeam *) device);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
nm_clear_g_source (&priv->teamd_process_watch);
nm_clear_g_source (&priv->teamd_timeout);
@ -305,15 +306,18 @@ teamd_cleanup (NMDevice *device, gboolean free_tdc)
if (priv->teamd_pid > 0) {
priv->kill_in_progress = TRUE;
nm_utils_kill_child_async (priv->teamd_pid, SIGTERM,
LOGD_TEAM, "teamd",
nm_utils_kill_child_async (priv->teamd_pid,
SIGTERM,
LOGD_TEAM,
"teamd",
2000,
teamd_kill_cb,
g_object_ref (device));
g_object_ref (self));
priv->teamd_pid = 0;
}
if (priv->tdc && free_tdc) {
if ( priv->tdc
&& free_tdc) {
teamdctl_disconnect (priv->tdc);
teamdctl_free (priv->tdc);
priv->tdc = NULL;
@ -333,7 +337,7 @@ teamd_timeout_cb (gpointer user_data)
if (priv->teamd_pid && !priv->tdc) {
/* Timed out launching our own teamd process */
_LOGW (LOGD_TEAM, "teamd timed out");
teamd_cleanup (device, TRUE);
teamd_cleanup (self, TRUE);
g_warn_if_fail (nm_device_is_activating (device));
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
@ -341,7 +345,7 @@ teamd_timeout_cb (gpointer user_data)
/* Read again the configuration after the timeout since it might
* have changed.
*/
if (!teamd_read_config (device)) {
if (!teamd_read_config (self)) {
_LOGW (LOGD_TEAM, "failed to read teamd configuration");
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
@ -388,7 +392,7 @@ teamd_dbus_appeared (GDBusConnection *connection,
if (ret) {
g_variant_get (ret, "(u)", &pid);
if (pid != priv->teamd_pid)
teamd_cleanup (device, FALSE);
teamd_cleanup (self, FALSE);
} else {
_LOGW (LOGD_TEAM, "failed to determine D-Bus name owner");
/* If we can't determine the bus name owner, don't kill our
@ -403,16 +407,21 @@ teamd_dbus_appeared (GDBusConnection *connection,
* device activation.
*/
success = ensure_teamd_connection (device);
if (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE) {
if (success)
success = teamd_read_config (device);
if (success)
nm_device_activate_schedule_stage2_device_config (device);
else if (!nm_device_sys_iface_state_is_external_or_assume (device)) {
teamd_cleanup (device, TRUE);
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
if ( nm_device_get_state (device) != NM_DEVICE_STATE_PREPARE
|| priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING)
return;
if (success)
success = teamd_read_config (self);
if (!success) {
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
return;
}
priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED;
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
@ -437,15 +446,16 @@ teamd_dbus_vanished (GDBusConnection *dbus_connection,
}
_LOGI (LOGD_TEAM, "teamd vanished from D-Bus");
teamd_cleanup (device, TRUE);
teamd_cleanup (self, TRUE);
/* Attempt to respawn teamd */
if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) {
NMConnection *connection = nm_device_get_applied_connection (device);
g_assert (connection);
if (!teamd_start (device, connection))
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
if ( state >= NM_DEVICE_STATE_PREPARE
&& state <= NM_DEVICE_STATE_ACTIVATED) {
if (!teamd_start (self)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
}
}
@ -470,7 +480,7 @@ teamd_process_watch_cb (GPid pid, int status, gpointer user_data)
(state >= NM_DEVICE_STATE_PREPARE) &&
(state <= NM_DEVICE_STATE_ACTIVATED)) {
_LOGW (LOGD_TEAM, "teamd process %lld quit unexpectedly; failing activation", (long long) pid);
teamd_cleanup (device, TRUE);
teamd_cleanup (self, TRUE);
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
}
@ -525,11 +535,11 @@ teamd_kill (NMDeviceTeam *self, const char *teamd_binary, GError **error)
}
static gboolean
teamd_start (NMDevice *device, NMConnection *connection)
teamd_start (NMDeviceTeam *self)
{
NMDeviceTeam *self = NM_DEVICE_TEAM (device);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
const char *iface = nm_device_get_ip_iface (device);
const char *iface = nm_device_get_ip_iface (NM_DEVICE (self));
NMConnection *connection;
gs_unref_ptrarray GPtrArray *argv = NULL;
gs_free_error GError *error = NULL;
gs_free char *tmp_str = NULL;
@ -540,8 +550,13 @@ teamd_start (NMDevice *device, NMConnection *connection)
gs_free char *cloned_mac = NULL;
gs_free const char **envp = NULL;
connection = nm_device_get_applied_connection (NM_DEVICE (self));
s_team = nm_connection_get_setting_team (connection);
g_return_val_if_fail (s_team, FALSE);
if (!s_team)
g_return_val_if_reached (FALSE);
nm_assert (iface);
teamd_binary = nm_utils_find_helper ("teamd", NULL, NULL);
if (!teamd_binary) {
@ -553,7 +568,7 @@ teamd_start (NMDevice *device, NMConnection *connection)
g_warn_if_reached ();
if (!priv->teamd_pid)
teamd_kill (self, teamd_binary, NULL);
teamd_cleanup (device, TRUE);
teamd_cleanup (self, TRUE);
}
/* Start teamd now */
@ -568,7 +583,7 @@ teamd_start (NMDevice *device, NMConnection *connection)
g_ptr_array_add (argv, (gpointer) iface);
config = nm_setting_team_get_config (s_team);
if (!nm_device_hw_addr_get_cloned (device, connection, FALSE, &cloned_mac, NULL, &error)) {
if (!nm_device_hw_addr_get_cloned (NM_DEVICE (self), connection, FALSE, &cloned_mac, NULL, &error)) {
_LOGW (LOGD_DEVICE, "set-hw-addr: %s", error->message);
return FALSE;
}
@ -615,18 +630,18 @@ teamd_start (NMDevice *device, NMConnection *connection)
if (!g_spawn_async ("/", (char **) argv->pdata, (char **) envp, G_SPAWN_DO_NOT_REAP_CHILD,
teamd_child_setup, NULL, &priv->teamd_pid, &error)) {
_LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: %s", error->message);
teamd_cleanup (device, TRUE);
teamd_cleanup (self, TRUE);
return FALSE;
}
/* Start a timeout for teamd to appear at D-Bus */
if (!priv->teamd_timeout)
priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, device);
priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, self);
/* Monitor the child process so we know when it dies */
priv->teamd_process_watch = g_child_watch_add (priv->teamd_pid,
teamd_process_watch_cb,
device);
self);
_LOGI (LOGD_TEAM, "Activation: (team) started teamd [pid %u]...", (guint) priv->teamd_pid);
return TRUE;
@ -637,21 +652,21 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceTeam *self = NM_DEVICE_TEAM (device);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
gs_free_error GError *error = NULL;
NMSettingTeam *s_team;
NMConnection *connection;
const char *cfg;
ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
s_team = nm_device_get_applied_setting (device, NM_TYPE_SETTING_TEAM);
if (!s_team)
g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_device_get_applied_connection (device);
g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING)
return NM_ACT_STAGE_RETURN_POSTPONE;
s_team = nm_connection_get_setting_team (connection);
g_return_val_if_fail (s_team, NM_ACT_STAGE_RETURN_FAILURE);
if (priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED)
return NM_ACT_STAGE_RETURN_SUCCESS;
priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING;
if (priv->tdc) {
/* If the existing teamd config is the same as we're about to use,
@ -660,7 +675,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
* have a PID, then we must fail.
*/
cfg = teamdctl_config_get_raw (priv->tdc);
if (cfg && nm_streq0 (cfg, nm_setting_team_get_config (s_team))) {
if ( cfg
&& nm_streq0 (cfg, nm_setting_team_get_config (s_team))) {
_LOGD (LOGD_TEAM, "using existing matching teamd config");
return NM_ACT_STAGE_RETURN_SUCCESS;
}
@ -675,17 +691,18 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
}
_LOGD (LOGD_TEAM, "existing teamd config mismatch; respawning...");
teamd_cleanup (device, TRUE);
teamd_cleanup (self, TRUE);
}
if (priv->kill_in_progress) {
_LOGT (LOGD_TEAM, "kill in progress, wait before starting teamd");
priv->connection = g_object_ref (connection);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
return teamd_start (device, connection) ?
NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
if (!teamd_start (self))
return NM_ACT_STAGE_RETURN_FAILURE;
return NM_ACT_STAGE_RETURN_POSTPONE;
}
static void
@ -694,16 +711,19 @@ deactivate (NMDevice *device)
NMDeviceTeam *self = NM_DEVICE_TEAM (device);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT;
if (nm_device_sys_iface_state_is_external (device))
return;
if (priv->teamd_pid || priv->tdc)
if ( priv->teamd_pid
|| priv->tdc)
_LOGI (LOGD_TEAM, "deactivation: stopping teamd...");
if (!priv->teamd_pid)
teamd_kill (self, NULL, NULL);
teamd_cleanup (device, TRUE);
g_clear_object (&priv->connection);
teamd_cleanup (self, TRUE);
}
static gboolean
@ -871,7 +891,7 @@ static void
constructed (GObject *object)
{
NMDevice *device = NM_DEVICE (object);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE ((NMDeviceTeam *) device);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device);
char *tmp_str = NULL;
G_OBJECT_CLASS (nm_device_team_parent_class)->constructed (object);
@ -903,15 +923,15 @@ nm_device_team_new (const char *iface)
static void
dispose (GObject *object)
{
NMDevice *device = NM_DEVICE (object);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE ((NMDeviceTeam *) device);
NMDeviceTeam *self = NM_DEVICE_TEAM (object);
NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
if (priv->teamd_dbus_watch) {
g_bus_unwatch_name (priv->teamd_dbus_watch);
priv->teamd_dbus_watch = 0;
}
teamd_cleanup (device, TRUE);
teamd_cleanup (self, TRUE);
g_clear_pointer (&priv->config, g_free);
G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object);

View file

@ -1714,18 +1714,14 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceIwd *self = NM_DEVICE_IWD (device);
NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
NMActStageReturn ret;
NMWifiAP *ap = NULL;
gs_unref_object NMWifiAP *ap_fake = NULL;
NMActRequest *req;
NMConnection *connection;
NMSettingWireless *s_wireless;
const char *mode;
const char *ap_path;
ret = NM_DEVICE_CLASS (nm_device_iwd_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
req = nm_device_get_act_request (device);
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
@ -1741,7 +1737,9 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
goto add_new;
ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
ap = ap_path ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) : NULL;
ap = ap_path
? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path)
: NULL;
if (ap) {
set_current_ap (self, ap, TRUE);
return NM_ACT_STAGE_RETURN_SUCCESS;
@ -1767,19 +1765,19 @@ add_new:
* until the real one is found in the scan list (Ad-Hoc or Hidden), or until
* the device is deactivated (Ad-Hoc or Hotspot).
*/
ap = nm_wifi_ap_new_fake_from_connection (connection);
g_return_val_if_fail (ap != NULL, NM_ACT_STAGE_RETURN_FAILURE);
ap_fake = nm_wifi_ap_new_fake_from_connection (connection);
if (!ap_fake)
g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE);
if (nm_wifi_ap_is_hotspot (ap))
nm_wifi_ap_set_address (ap, nm_device_get_hw_address (device));
if (nm_wifi_ap_is_hotspot (ap_fake))
nm_wifi_ap_set_address (ap_fake, nm_device_get_hw_address (device));
g_object_freeze_notify (G_OBJECT (self));
ap_add_remove (self, TRUE, ap, FALSE);
ap_add_remove (self, TRUE, ap_fake, FALSE);
g_object_thaw_notify (G_OBJECT (self));
set_current_ap (self, ap, FALSE);
set_current_ap (self, ap_fake, FALSE);
nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req),
nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
g_object_unref (ap);
nm_dbus_object_get_path (NM_DBUS_OBJECT (ap_fake)));
return NM_ACT_STAGE_RETURN_SUCCESS;
}

View file

@ -58,7 +58,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceOlpcMesh,
typedef struct {
NMDevice *companion;
NMManager *manager;
gboolean stage1_waiting;
bool stage1_waiting:1;
} NMDeviceOlpcMeshPrivate;
struct _NMDeviceOlpcMesh {
@ -145,13 +145,8 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device);
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
NMActStageReturn ret;
gboolean scanning;
ret = NM_DEVICE_CLASS (nm_device_olpc_mesh_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
/* disconnect companion device, if it is connected */
if (nm_device_get_act_request (NM_DEVICE (priv->companion))) {
_LOGI (LOGD_OLPC, "disconnecting companion device %s",
@ -171,6 +166,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
return NM_ACT_STAGE_RETURN_POSTPONE;
}
priv->stage1_waiting = FALSE;
return NM_ACT_STAGE_RETURN_SUCCESS;
}
@ -254,10 +250,9 @@ companion_notify_cb (NMDeviceWifi *companion, GParamSpec *pspec, gpointer user_d
return;
g_object_get (companion, NM_DEVICE_WIFI_SCANNING, &scanning, NULL);
if (!scanning) {
priv->stage1_waiting = FALSE;
nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self));
nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self));
}
}

View file

@ -63,6 +63,7 @@ typedef struct {
CList peers_lst_head;
guint find_peer_timeout_id;
guint sup_timeout_id;
guint peer_dump_id;
guint peer_missing_id;
@ -349,7 +350,7 @@ supplicant_find_timeout_cb (gpointer user_data)
NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data);
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
priv->sup_timeout_id = 0;
priv->find_peer_timeout_id = 0;
nm_supplicant_interface_p2p_cancel_connect (priv->mgmt_iface);
@ -368,27 +369,16 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device);
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
NMActStageReturn ret;
NMActRequest *req;
NMConnection *connection;
NMSettingWifiP2P *s_wifi_p2p;
NMWifiP2PPeer *peer;
nm_clear_g_source (&priv->sup_timeout_id);
ret = NM_DEVICE_CLASS (nm_device_wifi_p2p_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
if (!priv->mgmt_iface) {
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
return NM_ACT_STAGE_RETURN_FAILURE;
}
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_act_request_get_applied_connection (req);
connection = nm_device_get_applied_connection (NM_DEVICE (self));
g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
s_wifi_p2p = NM_SETTING_WIFI_P2P (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIFI_P2P));
@ -397,33 +387,19 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
peer = nm_wifi_p2p_peers_find_first_compatible (&priv->peers_lst_head, connection);
if (!peer) {
/* Set up a timeout on the find attempt and run a find for the same period of time */
priv->sup_timeout_id = g_timeout_add_seconds (10,
supplicant_find_timeout_cb,
self);
nm_supplicant_interface_p2p_start_find (priv->mgmt_iface, 10);
if (priv->find_peer_timeout_id == 0) {
priv->find_peer_timeout_id = g_timeout_add_seconds (10,
supplicant_find_timeout_cb,
self);
nm_supplicant_interface_p2p_start_find (priv->mgmt_iface, 10);
}
return NM_ACT_STAGE_RETURN_POSTPONE;
}
return NM_ACT_STAGE_RETURN_SUCCESS;
}
static void
cleanup_p2p_connect_attempt (NMDeviceWifiP2P *self, gboolean disconnect)
{
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
nm_clear_g_source (&priv->sup_timeout_id);
nm_clear_g_source (&priv->peer_missing_id);
if (priv->mgmt_iface)
nm_supplicant_interface_p2p_cancel_connect (priv->mgmt_iface);
if (disconnect && priv->group_iface)
nm_supplicant_interface_p2p_disconnect (priv->group_iface);
}
/*
* supplicant_connection_timeout_cb
*
@ -461,7 +437,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
NMWifiP2PPeer *peer;
GBytes *wfd_ies;
nm_clear_g_source (&priv->sup_timeout_id);
if (nm_clear_g_source (&priv->find_peer_timeout_id))
nm_assert_not_reached ();
if (!priv->mgmt_iface) {
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
@ -493,9 +470,11 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
"pbc", NULL);
/* Set up a timeout on the connect attempt */
priv->sup_timeout_id = g_timeout_add_seconds (45,
supplicant_connection_timeout_cb,
self);
if (priv->sup_timeout_id == 0) {
priv->sup_timeout_id = g_timeout_add_seconds (45,
supplicant_connection_timeout_cb,
self);
}
/* We'll get stage3 started when the P2P group has been started */
return NM_ACT_STAGE_RETURN_POSTPONE;
@ -550,17 +529,19 @@ peer_add_remove (NMDeviceWifiP2P *self,
if (is_adding) {
/* If we are in prepare state, then we are currently runnign a find
* to search for the requested peer. */
if (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE) {
if (priv->find_peer_timeout_id != 0) {
NMConnection *connection;
nm_assert (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE);
connection = nm_device_get_applied_connection (device);
g_assert (connection);
nm_assert (NM_IS_CONNECTION (connection));
peer = nm_wifi_p2p_peers_find_first_compatible (&priv->peers_lst_head, connection);
if (peer) {
/* A peer for the connection was found, cancel the timeout and go to configure state. */
nm_clear_g_source (&priv->sup_timeout_id);
nm_device_activate_schedule_stage2_device_config (device);
nm_clear_g_source (&priv->find_peer_timeout_id);
nm_device_activate_schedule_stage1_device_prepare (device);
}
}
@ -620,8 +601,17 @@ deactivate (NMDevice *device)
{
NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device);
int ifindex = nm_device_get_ip_ifindex (device);
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
cleanup_p2p_connect_attempt (self, TRUE);
nm_clear_g_source (&priv->find_peer_timeout_id);
nm_clear_g_source (&priv->sup_timeout_id);
nm_clear_g_source (&priv->peer_missing_id);
if (priv->mgmt_iface)
nm_supplicant_interface_p2p_cancel_connect (priv->mgmt_iface);
if (priv->group_iface)
nm_supplicant_interface_p2p_disconnect (priv->group_iface);
/* Clear any critical protocol notification in the Wi-Fi stack */
if (ifindex > 0)
@ -919,6 +909,7 @@ supplicant_interfaces_release (NMDeviceWifiP2P *self, gboolean set_is_waiting)
nm_supplicant_manager_set_wfd_ies (priv->sup_mgr, NULL);
g_signal_handlers_disconnect_by_data (priv->mgmt_iface, self);
g_clear_object (&priv->mgmt_iface);
nm_clear_g_source (&priv->find_peer_timeout_id);
nm_clear_g_source (&priv->sup_timeout_id);
}

View file

@ -411,7 +411,9 @@ set_current_ap (NMDeviceWifi *self, NMWifiAP *new_ap, gboolean recheck_available
NM80211Mode mode = nm_wifi_ap_get_mode (old_ap);
/* Remove any AP from the internal list if it was created by NM or isn't known to the supplicant */
if (mode == NM_802_11_MODE_ADHOC || mode == NM_802_11_MODE_AP || nm_wifi_ap_get_fake (old_ap))
if ( NM_IN_SET (mode, NM_802_11_MODE_ADHOC,
NM_802_11_MODE_AP)
|| nm_wifi_ap_get_fake (old_ap))
ap_add_remove (self, FALSE, old_ap, recheck_available_connections);
g_object_unref (old_ap);
}
@ -1229,7 +1231,8 @@ scanning_prohibited (NMDeviceWifi *self, gboolean periodic)
/* Don't scan when a an AP or Ad-Hoc connection is active as it will
* disrupt connected clients or peers.
*/
if (priv->mode == NM_802_11_MODE_ADHOC || priv->mode == NM_802_11_MODE_AP)
if (NM_IN_SET (priv->mode, NM_802_11_MODE_ADHOC,
NM_802_11_MODE_AP))
return TRUE;
switch (nm_device_get_state (NM_DEVICE (self))) {
@ -1732,8 +1735,10 @@ wifi_secrets_cb (NMActRequest *req,
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else
nm_device_activate_schedule_stage1_device_prepare (device);
return;
}
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
@ -1752,10 +1757,11 @@ supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface,
NMDeviceWifi *self)
{
NMActRequest *req;
GVariant *val, *secrets = NULL;
gs_unref_variant GVariant *val_key = NULL;
gs_unref_variant GVariant *secrets = NULL;
gs_free_error GError *error = NULL;
const char *array;
gsize psk_len = 0;
GError *error = NULL;
if (nm_device_get_state (NM_DEVICE (self)) != NM_DEVICE_STATE_NEED_AUTH) {
_LOGI (LOGD_DEVICE | LOGD_WIFI, "WPS: The connection can't be updated with credentials");
@ -1767,11 +1773,11 @@ supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface,
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_if_fail (NM_IS_ACT_REQUEST (req));
val = g_variant_lookup_value (credentials, "Key", G_VARIANT_TYPE_BYTESTRING);
if (val) {
val_key = g_variant_lookup_value (credentials, "Key", G_VARIANT_TYPE_BYTESTRING);
if (val_key) {
char psk[64];
array = g_variant_get_fixed_array (val, &psk_len, 1);
array = g_variant_get_fixed_array (val_key, &psk_len, 1);
if (psk_len >= 8 && psk_len <= 63) {
memcpy (psk, array, psk_len);
psk[psk_len] = '\0';
@ -1784,22 +1790,22 @@ supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface,
}
if (!secrets)
_LOGW (LOGD_DEVICE | LOGD_WIFI, "WPS: ignore invalid PSK");
g_variant_unref (val);
}
if (secrets) {
if (nm_settings_connection_new_secrets (nm_act_request_get_settings_connection (req),
nm_act_request_get_applied_connection (req),
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
secrets,
&error)) {
wifi_secrets_cancel (self);
nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self));
} else {
_LOGW (LOGD_DEVICE | LOGD_WIFI, "WPS: Could not update the connection with credentials: %s", error->message);
g_error_free (error);
}
g_variant_unref (secrets);
if (!secrets)
return;
if (!nm_settings_connection_new_secrets (nm_act_request_get_settings_connection (req),
nm_act_request_get_applied_connection (req),
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
secrets,
&error)) {
_LOGW (LOGD_DEVICE | LOGD_WIFI, "WPS: Could not update the connection with credentials: %s", error->message);
return;
}
wifi_secrets_cancel (self);
nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self));
}
static gboolean
@ -2409,9 +2415,9 @@ supplicant_connection_timeout_cb (gpointer user_data)
connection = nm_act_request_get_applied_connection (req);
g_assert (connection);
if ( priv->mode == NM_802_11_MODE_ADHOC
|| priv->mode == NM_802_11_MODE_MESH
|| priv->mode == NM_802_11_MODE_AP) {
if (NM_IN_SET (priv->mode, NM_802_11_MODE_ADHOC,
NM_802_11_MODE_MESH,
NM_802_11_MODE_AP)) {
/* In Ad-Hoc and AP modes there's nothing to check the encryption key
* (if any), so supplicant timeouts here are almost certainly the wifi
* driver being really stupid.
@ -2617,18 +2623,14 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMActStageReturn ret;
NMWifiAP *ap = NULL;
gs_unref_object NMWifiAP *ap_fake = NULL;
NMActRequest *req;
NMConnection *connection;
NMSettingWireless *s_wireless;
const char *mode;
const char *ap_path;
ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
@ -2658,48 +2660,45 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
priv->hw_addr_scan_expire = 0;
/* Set spoof MAC to the interface */
if (!nm_device_hw_addr_set_cloned (device, connection, TRUE))
if (!nm_device_hw_addr_set_cloned (device, connection, TRUE)) {
*out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
return NM_ACT_STAGE_RETURN_FAILURE;
}
/* AP and Mesh modes never use a specific object or existing scanned AP */
if (priv->mode != NM_802_11_MODE_AP && priv->mode != NM_802_11_MODE_MESH) {
if (!NM_IN_SET (priv->mode, NM_802_11_MODE_AP,
NM_802_11_MODE_MESH)) {
ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
ap = ap_path ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) : NULL;
if (ap)
goto done;
ap = ap_path
? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path)
: NULL;
}
if (!ap)
ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection);
if (!ap) {
/* If the user is trying to connect to an AP that NM doesn't yet know about
* (hidden network or something), starting a Hotspot or joining a Mesh,
* create a fake APfrom the security settings in the connection. This "fake"
* AP gets used until the real one is found in the scan list (Ad-Hoc or Hidden),
* or until the device is deactivated (Hotspot).
*/
ap_fake = nm_wifi_ap_new_fake_from_connection (connection);
if (!ap_fake)
g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE);
if (nm_wifi_ap_is_hotspot (ap_fake))
nm_wifi_ap_set_address (ap_fake, nm_device_get_hw_address (device));
g_object_freeze_notify (G_OBJECT (self));
ap_add_remove (self, TRUE, ap_fake, TRUE);
g_object_thaw_notify (G_OBJECT (self));
ap = ap_fake;
}
if (ap) {
nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req),
nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
goto done;
}
/* If the user is trying to connect to an AP that NM doesn't yet know about
* (hidden network or something), starting a Hotspot or joining a Mesh,
* create a fake APfrom the security settings in the connection. This "fake"
* AP gets used until the real one is found in the scan list (Ad-Hoc or Hidden),
* or until the device is deactivated (Hotspot).
*/
ap = nm_wifi_ap_new_fake_from_connection (connection);
g_return_val_if_fail (ap != NULL, NM_ACT_STAGE_RETURN_FAILURE);
if (nm_wifi_ap_is_hotspot (ap))
nm_wifi_ap_set_address (ap, nm_device_get_hw_address (device));
g_object_freeze_notify (G_OBJECT (self));
ap_add_remove (self, TRUE, ap, TRUE);
g_object_thaw_notify (G_OBJECT (self));
set_current_ap (self, ap, FALSE);
nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req),
nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
g_object_unref (ap);
return NM_ACT_STAGE_RETURN_SUCCESS;
done:
set_current_ap (self, ap, TRUE);
return NM_ACT_STAGE_RETURN_SUCCESS;
}
@ -2834,8 +2833,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
* if the user didn't specify one and we didn't find an AP that matched
* the connection, just pick a frequency the device supports.
*/
if ( ap_mode == NM_802_11_MODE_ADHOC
|| ap_mode == NM_802_11_MODE_MESH
if ( NM_IN_SET (ap_mode, NM_802_11_MODE_ADHOC,
NM_802_11_MODE_MESH)
|| nm_wifi_ap_is_hotspot (ap))
ensure_hotspot_frequency (self, s_wireless, ap);

View file

@ -48,10 +48,11 @@ typedef struct {
NMModem *modem;
NMDeviceModemCapabilities caps;
NMDeviceModemCapabilities current_caps;
gboolean rf_enabled;
char *device_id;
char *operator_code;
char *apn;
bool rf_enabled:1;
NMDeviceStageState stage1_state:3;
} NMDeviceModemPrivate;
struct _NMDeviceModem {
@ -119,16 +120,17 @@ modem_prepare_result (NMModem *modem,
gpointer user_data)
{
NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
NMDevice *device = NM_DEVICE (self);
NMDeviceState state;
NMDeviceStateReason reason = i_reason;
state = nm_device_get_state (device);
g_return_if_fail (state == NM_DEVICE_STATE_PREPARE);
if ( nm_device_get_state (device) != NM_DEVICE_STATE_PREPARE
|| priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) {
nm_assert_not_reached ();
success = FALSE;
}
if (success)
nm_device_activate_schedule_stage2_device_config (device);
else {
if (!success) {
/* There are several reasons to block autoconnection at device level:
*
* - Wrong SIM-PIN: The device won't autoconnect because it doesn't make sense
@ -164,7 +166,11 @@ modem_prepare_result (NMModem *modem,
break;
}
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
return;
}
priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED;
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
@ -187,16 +193,19 @@ static void
modem_auth_result (NMModem *modem, GError *error, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
if (error) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else {
/* Otherwise, on success for modem secrets we need to schedule stage1 again */
g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
nm_device_activate_schedule_stage1_device_prepare (device);
return;
}
priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT;
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
@ -355,7 +364,7 @@ modem_state_cb (NMModem *modem,
NMModemState new_state = new_state_i;
NMModemState old_state = old_state_i;
NMDevice *device = NM_DEVICE (user_data);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
NMDeviceState dev_state = nm_device_get_state (device);
if (new_state <= NM_MODEM_STATE_DISABLING &&
@ -409,7 +418,7 @@ modem_removed_cb (NMModem *modem, gpointer user_data)
static gboolean
owns_iface (NMDevice *device, const char *iface)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
g_return_val_if_fail (priv->modem, FALSE);
@ -447,7 +456,7 @@ get_generic_capabilities (NMDevice *device)
static const char *
get_type_description (NMDevice *device)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
if (NM_FLAGS_HAS (priv->current_caps, NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS))
return "gsm";
@ -464,7 +473,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError
if (!NM_DEVICE_CLASS (nm_device_modem_parent_class)->check_connection_compatible (device, connection, error))
return FALSE;
if (!nm_modem_check_connection_compatible (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem,
if (!nm_modem_check_connection_compatible (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem,
connection,
error ? &local : NULL)) {
if (error) {
@ -530,7 +539,7 @@ complete_connection (NMDevice *device,
NMConnection *const*existing_connections,
GError **error)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
return nm_modem_complete_connection (priv->modem,
nm_device_get_iface (device),
@ -542,7 +551,10 @@ complete_connection (NMDevice *device,
static void
deactivate (NMDevice *device)
{
nm_modem_deactivate (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
nm_modem_deactivate (priv->modem, device);
priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT;
}
/*****************************************************************************/
@ -583,17 +595,24 @@ deactivate_async (NMDevice *self,
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
NMActStageReturn ret;
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
NMActRequest *req;
ret = NM_DEVICE_CLASS (nm_device_modem_parent_class)->act_stage1_prepare (device, out_failure_reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
return ret;
req = nm_device_get_act_request (device);
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
return nm_modem_act_stage1_prepare (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, req, out_failure_reason);
if (priv->stage1_state == NM_DEVICE_STAGE_STATE_INIT) {
priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING;
return nm_modem_act_stage1_prepare (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem,
req,
out_failure_reason);
}
if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING)
return NM_ACT_STAGE_RETURN_POSTPONE;
nm_assert (priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED);
return NM_ACT_STAGE_RETURN_SUCCESS;
}
static NMActStageReturn
@ -604,7 +623,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
req = nm_device_get_act_request (device);
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
return nm_modem_act_stage2_config (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, req, out_failure_reason);
return nm_modem_act_stage2_config (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, req, out_failure_reason);
}
static NMActStageReturn
@ -632,7 +651,7 @@ act_stage3_ip_config_start (NMDevice *device,
static void
ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
{
nm_modem_ip4_pre_commit (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, device, config);
nm_modem_ip4_pre_commit (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device, config);
}
static gboolean
@ -654,7 +673,7 @@ get_ip_iface_identifier (NMDevice *device, NMUtilsIPv6IfaceId *out_iid)
static gboolean
get_enabled (NMDevice *device)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
NMModemState modem_state = nm_modem_get_state (priv->modem);
return priv->rf_enabled && (modem_state >= NM_MODEM_STATE_LOCKED);
@ -745,7 +764,7 @@ static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) object);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object);
switch (prop_id) {
case PROP_MODEM:
@ -776,7 +795,7 @@ static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) object);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object);
switch (prop_id) {
case PROP_MODEM:
@ -834,7 +853,7 @@ nm_device_modem_new (NMModem *modem)
static void
dispose (GObject *object)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) object);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object);
if (priv->modem) {
g_signal_handlers_disconnect_by_data (priv->modem, NM_DEVICE_MODEM (object));

View file

@ -586,9 +586,9 @@ connect_context_step (NMModemBroadband *self)
}
static NMActStageReturn
act_stage1_prepare (NMModem *_self,
NMConnection *connection,
NMDeviceStateReason *out_failure_reason)
modem_act_stage1_prepare (NMModem *_self,
NMConnection *connection,
NMDeviceStateReason *out_failure_reason)
{
NMModemBroadband *self = NM_MODEM_BROADBAND (_self);
@ -1512,7 +1512,7 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass)
modem_class->get_user_pass = get_user_pass;
modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem;
modem_class->complete_connection = complete_connection;
modem_class->act_stage1_prepare = act_stage1_prepare;
modem_class->modem_act_stage1_prepare = modem_act_stage1_prepare;
modem_class->owns_port = owns_port;
obj_properties[PROP_MODEM] =

View file

@ -1114,9 +1114,9 @@ create_connect_properties (NMConnection *connection)
}
static NMActStageReturn
act_stage1_prepare (NMModem *modem,
NMConnection *connection,
NMDeviceStateReason *out_failure_reason)
modem_act_stage1_prepare (NMModem *modem,
NMConnection *connection,
NMDeviceStateReason *out_failure_reason)
{
NMModemOfono *self = NM_MODEM_OFONO (modem);
NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
@ -1308,6 +1308,6 @@ nm_modem_ofono_class_init (NMModemOfonoClass *klass)
modem_class->deactivate_cleanup = deactivate_cleanup;
modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem;
modem_class->act_stage1_prepare = act_stage1_prepare;
modem_class->modem_act_stage1_prepare = modem_act_stage1_prepare;
modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start;
}

View file

@ -974,9 +974,9 @@ nm_modem_get_secrets (NMModem *self,
/*****************************************************************************/
static NMActStageReturn
act_stage1_prepare (NMModem *modem,
NMConnection *connection,
NMDeviceStateReason *out_failure_reason)
modem_act_stage1_prepare (NMModem *modem,
NMConnection *connection,
NMDeviceStateReason *out_failure_reason)
{
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_UNKNOWN);
return NM_ACT_STAGE_RETURN_FAILURE;
@ -1003,7 +1003,7 @@ nm_modem_act_stage1_prepare (NMModem *self,
setting_name = nm_connection_need_secrets (connection, &hints);
if (!setting_name) {
nm_assert (!hints);
return NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self, connection, out_failure_reason);
return NM_MODEM_GET_CLASS (self)->modem_act_stage1_prepare (self, connection, out_failure_reason);
}
/* Secrets required... */
@ -1798,7 +1798,7 @@ nm_modem_class_init (NMModemClass *klass)
object_class->dispose = dispose;
object_class->finalize = finalize;
klass->act_stage1_prepare = act_stage1_prepare;
klass->modem_act_stage1_prepare = modem_act_stage1_prepare;
klass->stage3_ip6_config_request = stage3_ip6_config_request;
klass->deactivate_cleanup = deactivate_cleanup;

View file

@ -136,9 +136,9 @@ typedef struct {
NMConnection *const*existing_connections,
GError **error);
NMActStageReturn (*act_stage1_prepare) (NMModem *modem,
NMConnection *connection,
NMDeviceStateReason *out_failure_reason);
NMActStageReturn (*modem_act_stage1_prepare) (NMModem *modem,
NMConnection *connection,
NMDeviceStateReason *out_failure_reason);
NMActStageReturn (*static_stage3_ip4_config_start) (NMModem *self,
NMActRequest *req,

View file

@ -1886,7 +1886,7 @@ device_state_changed (NMDevice *device,
switch (nm_device_state_reason_check (reason)) {
case NM_DEVICE_STATE_REASON_USER_REQUESTED:
blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST;
blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST;
break;
case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED:
blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED;