mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-08 17:20:31 +01:00
ethernet: add reconnect delay for PPPoE connections (rh #1023503)
Attempting an immediate reconnect if the peer terminates the connection sometimes results in the peer not being ready to negotiate a new connection, while a short delay allows the peer to correctly tear down the old connection and get listen for a new one. Introduce a short delay when activating a PPPoE connection if a PPPoE connection was recently deactivated. https://bugzilla.redhat.com/show_bug.cgi?id=1023503 https://bugzilla.redhat.com/show_bug.cgi?id=602265 Rebased to master by jklimes.
This commit is contained in:
parent
df104771ae
commit
5fad262b9f
1 changed files with 58 additions and 9 deletions
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2005 - 2012 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2013 Red Hat, Inc.
|
||||
* Copyright (C) 2006 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -66,8 +66,12 @@ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE)
|
|||
|
||||
#define WIRED_SECRETS_TRIES "wired-secrets-tries"
|
||||
|
||||
#define PPPOE_RECONNECT_DELAY 7
|
||||
|
||||
#define NM_ETHERNET_ERROR (nm_ethernet_error_quark ())
|
||||
|
||||
static NMSetting *device_get_setting (NMDevice *device, GType setting_type);
|
||||
|
||||
typedef struct Supplicant {
|
||||
NMSupplicantManager *mgr;
|
||||
NMSupplicantInterface *iface;
|
||||
|
|
@ -99,6 +103,8 @@ typedef struct {
|
|||
/* PPPoE */
|
||||
NMPPPManager *ppp_manager;
|
||||
NMIP4Config *pending_ip4_config;
|
||||
time_t last_pppoe_time;
|
||||
guint pppoe_wait_id;
|
||||
} NMDeviceEthernetPrivate;
|
||||
|
||||
enum {
|
||||
|
|
@ -272,15 +278,10 @@ device_state_changed (NMDevice *device,
|
|||
NMDeviceState old_state,
|
||||
NMDeviceStateReason reason)
|
||||
{
|
||||
switch (new_state) {
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
case NM_DEVICE_STATE_FAILED:
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
if ( new_state == NM_DEVICE_STATE_ACTIVATED
|
||||
|| new_state == NM_DEVICE_STATE_FAILED
|
||||
|| new_state == NM_DEVICE_STATE_DISCONNECTED)
|
||||
clear_secrets_tries (device);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -891,10 +892,24 @@ supplicant_interface_init (NMDeviceEthernet *self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pppoe_reconnect_delay (gpointer user_data)
|
||||
{
|
||||
NMDevice *device = NM_DEVICE (user_data);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
|
||||
|
||||
priv->pppoe_wait_id = 0;
|
||||
nm_log_info (LOGD_DEVICE, "(%s) PPPoE reconnect delay complete, resuming connection...",
|
||||
nm_device_get_iface (device));
|
||||
nm_device_activate_schedule_stage2_device_config (device);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
||||
{
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
NMActRequest *req;
|
||||
NMSettingWired *s_wired;
|
||||
const GByteArray *cloned_mac;
|
||||
|
|
@ -914,6 +929,26 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
if (cloned_mac && (cloned_mac->len == ETH_ALEN))
|
||||
nm_device_set_hw_addr (dev, cloned_mac->data, "set", LOGD_ETHER);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
*/
|
||||
if (priv->last_pppoe_time) {
|
||||
time_t delay = time (NULL) - priv->last_pppoe_time;
|
||||
|
||||
if (delay < PPPOE_RECONNECT_DELAY && device_get_setting (dev, NM_TYPE_SETTING_PPPOE)) {
|
||||
nm_log_info (LOGD_DEVICE, "(%s) delaying PPPoE reconnect to ensure peer is ready...",
|
||||
nm_device_get_iface (dev));
|
||||
g_assert (!priv->pppoe_wait_id);
|
||||
priv->pppoe_wait_id = g_timeout_add_seconds (delay,
|
||||
pppoe_reconnect_delay,
|
||||
self);
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
} else
|
||||
priv->last_pppoe_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1141,6 +1176,11 @@ deactivate (NMDevice *device)
|
|||
/* Clear wired secrets tries when deactivating */
|
||||
clear_secrets_tries (device);
|
||||
|
||||
if (priv->pppoe_wait_id) {
|
||||
g_source_remove (priv->pppoe_wait_id);
|
||||
priv->pppoe_wait_id = 0;
|
||||
}
|
||||
|
||||
if (priv->pending_ip4_config) {
|
||||
g_object_unref (priv->pending_ip4_config);
|
||||
priv->pending_ip4_config = NULL;
|
||||
|
|
@ -1164,6 +1204,10 @@ deactivate (NMDevice *device)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set last PPPoE connection time */
|
||||
if (device_get_setting (device, NM_TYPE_SETTING_PPPOE))
|
||||
NM_DEVICE_ETHERNET_GET_PRIVATE (device)->last_pppoe_time = time (NULL);
|
||||
|
||||
/* Reset MAC address back to initial address */
|
||||
nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER);
|
||||
}
|
||||
|
|
@ -1347,6 +1391,11 @@ dispose (GObject *object)
|
|||
g_free (priv->subchan3);
|
||||
g_free (priv->subchannels);
|
||||
|
||||
if (priv->pppoe_wait_id) {
|
||||
g_source_remove (priv->pppoe_wait_id);
|
||||
priv->pppoe_wait_id = 0;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue