summary refs log tree commit diff
path: root/src/core/devices/nm-device-ethernet.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2022-02-14 19:23:28 +0100
committerMichael Biebl <biebl@debian.org>2022-02-14 19:23:28 +0100
commit2f94dba7385fd0e0ef19a06eb4a2fcf6c43d7946 (patch)
treee2222f5577115985dd52044d2991253403cdd952 /src/core/devices/nm-device-ethernet.c
parent88c227d90a6b7b388c5c85d72802a0ca8f05ed5c (diff)
New upstream version 1.35.91 upstream/1.35.91
Diffstat (limited to 'src/core/devices/nm-device-ethernet.c')
-rw-r--r--src/core/devices/nm-device-ethernet.c641
1 files changed, 327 insertions, 314 deletions
diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c
index 667ea9b9..6e18d119 100644
--- a/src/core/devices/nm-device-ethernet.c
+++ b/src/core/devices/nm-device-ethernet.c
@@ -14,38 +14,36 @@
 #include <libudev.h>
 #include <linux/if_ether.h>
 
-#include "libnm-glib-aux/nm-uuid.h"
-#include "nm-device-private.h"
-#include "nm-act-request.h"
-#include "nm-ip4-config.h"
 #include "NetworkManagerUtils.h"
-#include "supplicant/nm-supplicant-manager.h"
-#include "supplicant/nm-supplicant-interface.h"
-#include "supplicant/nm-supplicant-config.h"
-#include "ppp/nm-ppp-manager.h"
-#include "ppp/nm-ppp-manager-call.h"
-#include "ppp/nm-ppp-status.h"
-#include "libnm-platform/nm-platform.h"
+#include "NetworkManagerUtils.h"
+#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
+#include "libnm-core-intern/nm-core-internal.h"
+#include "libnm-glib-aux/nm-uuid.h"
 #include "libnm-platform/nm-platform-utils.h"
-#include "nm-dcb.h"
-#include "settings/nm-settings-connection.h"
+#include "libnm-platform/nm-platform.h"
+#include "libnm-udev-aux/nm-udev-utils.h"
+#include "nm-act-request.h"
 #include "nm-config.h"
+#include "nm-dcb.h"
 #include "nm-device-ethernet-utils.h"
-#include "settings/nm-settings.h"
 #include "nm-device-factory.h"
-#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
-#include "libnm-core-intern/nm-core-internal.h"
-#include "NetworkManagerUtils.h"
-#include "libnm-udev-aux/nm-udev-utils.h"
+#include "nm-device-private.h"
 #include "nm-device-veth.h"
+#include "nm-manager.h"
+#include "ppp/nm-ppp-mgr.h"
+#include "settings/nm-settings-connection.h"
+#include "settings/nm-settings.h"
+#include "supplicant/nm-supplicant-config.h"
+#include "supplicant/nm-supplicant-interface.h"
+#include "supplicant/nm-supplicant-manager.h"
 
 #define _NMLOG_DEVICE_TYPE NMDeviceEthernet
 #include "nm-device-logging.h"
 
 /*****************************************************************************/
 
-#define PPPOE_RECONNECT_DELAY 7
-#define PPPOE_ENCAP_OVERHEAD  8 /* 2 bytes for PPP, 6 for PPPoE */
+#define PPPOE_RECONNECT_DELAY_MSEC 7000
+#define PPPOE_ENCAP_OVERHEAD       8 /* 2 bytes for PPP, 6 for PPPoE */
 
 #define SUPPLICANT_LNK_TIMEOUT_SEC 15
 
@@ -67,21 +65,21 @@ typedef enum {
 
 typedef struct _NMDeviceEthernetPrivate {
     /* s390 */
-    char *      subchan1;
-    char *      subchan2;
-    char *      subchan3;
-    char *      subchannels;      /* Composite used for checking unmanaged specs */
-    char **     subchannels_dbus; /* Array exported on D-Bus */
-    char *      s390_nettype;
+    char       *subchan1;
+    char       *subchan2;
+    char       *subchan3;
+    char       *subchannels;      /* Composite used for checking unmanaged specs */
+    char      **subchannels_dbus; /* Array exported on D-Bus */
+    char       *s390_nettype;
     GHashTable *s390_options;
 
     guint32 speed;
     gulong  carrier_id;
 
     struct {
-        NMSupplicantManager *        mgr;
+        NMSupplicantManager         *mgr;
         NMSupplMgrCreateIfaceHandle *create_handle;
-        NMSupplicantInterface *      iface;
+        NMSupplicantInterface       *iface;
 
         gulong iface_state_id;
         gulong auth_state_id;
@@ -91,14 +89,16 @@ typedef struct _NMDeviceEthernetPrivate {
         guint lnk_timeout_id;
 
         bool is_associated : 1;
+        bool ready : 1;
     } supplicant;
 
     NMActRequestGetSecretsCallId *wired_secrets_id;
 
-    /* PPPoE */
-    NMPPPManager *ppp_manager;
-    gint32        last_pppoe_time;
-    guint         pppoe_wait_id;
+    struct {
+        NMPppMgr *ppp_mgr;
+        GSource  *wait_source;
+        gint64    last_pppoe_time_msec;
+    } ppp_data;
 
     /* DCB */
     DcbWait dcb_wait;
@@ -113,6 +113,8 @@ typedef struct _NMDeviceEthernetPrivate {
     bool ethtool_prev_set : 1;
     bool ethtool_prev_autoneg : 1;
 
+    bool stage2_ready_dcb : 1;
+
 } NMDeviceEthernetPrivate;
 
 NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceEthernet, PROP_SPEED, PROP_S390_SUBCHANNELS, );
@@ -150,12 +152,12 @@ static void
 _update_s390_subchannels(NMDeviceEthernet *self)
 {
     NMDeviceEthernetPrivate *priv   = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    struct udev_device *     dev    = NULL;
-    struct udev_device *     parent = NULL;
-    const char *             parent_path, *item;
+    struct udev_device      *dev    = NULL;
+    struct udev_device      *parent = NULL;
+    const char              *parent_path, *item;
     int                      ifindex;
-    GDir *                   dir;
-    GError *                 error = NULL;
+    GDir                    *dir;
+    GError                  *error = NULL;
 
     if (priv->subchannels) {
         /* only read the subchannels once. For one, we don't expect them to change
@@ -251,7 +253,7 @@ _update_s390_subchannels(NMDeviceEthernet *self)
 }
 
 static void
-device_state_changed(NMDevice *          device,
+device_state_changed(NMDevice           *device,
                      NMDeviceState       new_state,
                      NMDeviceState       old_state,
                      NMDeviceStateReason reason)
@@ -306,7 +308,7 @@ static gboolean
 match_subchans(NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac)
 {
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    const char *const *      subchans;
+    const char *const       *subchans;
     guint32                  num1, num2;
     int                      i;
 
@@ -345,7 +347,7 @@ static gboolean
 check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error)
 {
     NMDeviceEthernet *self = NM_DEVICE_ETHERNET(device);
-    NMSettingWired *  s_wired;
+    NMSettingWired   *s_wired;
 
     if (!NM_DEVICE_CLASS(nm_device_ethernet_parent_class)
              ->check_connection_compatible(device, connection, error))
@@ -363,7 +365,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError *
     }
 
     if (s_wired) {
-        const char *       mac, *perm_hw_addr;
+        const char        *mac, *perm_hw_addr;
         gboolean           try_mac = TRUE;
         const char *const *mac_blacklist;
         int                i;
@@ -428,6 +430,7 @@ supplicant_interface_release(NMDeviceEthernet *self)
     nm_clear_g_source(&priv->supplicant.con_timeout_id);
     nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.iface_state_id);
     nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.auth_state_id);
+    priv->supplicant.ready = FALSE;
 
     if (priv->supplicant.iface) {
         nm_supplicant_interface_disconnect(priv->supplicant.iface);
@@ -437,8 +440,8 @@ supplicant_interface_release(NMDeviceEthernet *self)
 
 static void
 supplicant_auth_state_changed(NMSupplicantInterface *iface,
-                              GParamSpec *           pspec,
-                              NMDeviceEthernet *     self)
+                              GParamSpec            *pspec,
+                              NMDeviceEthernet      *self)
 {
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
     NMSupplicantAuthState    state;
@@ -466,40 +469,39 @@ static void
 wired_auth_cond_fail(NMDeviceEthernet *self, NMDeviceStateReason reason)
 {
     NMDeviceEthernetPrivate *priv   = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMDevice *               device = NM_DEVICE(self);
-
-    if (wired_auth_is_optional(self)) {
-        _LOGI(
-            LOGD_DEVICE | LOGD_ETHER,
-            "Activation: (ethernet) 802.1X authentication is optional, continuing after a failure");
-        if (NM_IN_SET(nm_device_get_state(device),
-                      NM_DEVICE_STATE_CONFIG,
-                      NM_DEVICE_STATE_NEED_AUTH))
-            nm_device_activate_schedule_stage3_ip_config_start(device);
-
-        if (!priv->supplicant.auth_state_id) {
-            priv->supplicant.auth_state_id =
-                g_signal_connect(priv->supplicant.iface,
-                                 "notify::" NM_SUPPLICANT_INTERFACE_AUTH_STATE,
-                                 G_CALLBACK(supplicant_auth_state_changed),
-                                 self);
-        }
+    NMDevice                *device = NM_DEVICE(self);
+
+    if (!wired_auth_is_optional(self)) {
+        supplicant_interface_release(self);
+        nm_device_state_changed(NM_DEVICE(self), NM_DEVICE_STATE_FAILED, reason);
         return;
     }
 
-    supplicant_interface_release(self);
-    nm_device_state_changed(NM_DEVICE(self), NM_DEVICE_STATE_FAILED, reason);
+    _LOGI(LOGD_DEVICE | LOGD_ETHER,
+          "Activation: (ethernet) 802.1X authentication is optional, continuing after a failure");
+    priv->supplicant.ready = TRUE;
+
+    if (NM_IN_SET(nm_device_get_state(device), NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_NEED_AUTH))
+        nm_device_activate_schedule_stage2_device_config(device, FALSE);
+
+    if (!priv->supplicant.auth_state_id) {
+        priv->supplicant.auth_state_id =
+            g_signal_connect(priv->supplicant.iface,
+                             "notify::" NM_SUPPLICANT_INTERFACE_AUTH_STATE,
+                             G_CALLBACK(supplicant_auth_state_changed),
+                             self);
+    }
 }
 
 static void
-wired_secrets_cb(NMActRequest *                req,
+wired_secrets_cb(NMActRequest                 *req,
                  NMActRequestGetSecretsCallId *call_id,
-                 NMSettingsConnection *        connection,
-                 GError *                      error,
+                 NMSettingsConnection         *connection,
+                 GError                       *error,
                  gpointer                      user_data)
 {
-    NMDeviceEthernet *       self   = user_data;
-    NMDevice *               device = user_data;
+    NMDeviceEthernet        *self   = user_data;
+    NMDevice                *device = user_data;
     NMDeviceEthernetPrivate *priv;
 
     g_return_if_fail(NM_IS_DEVICE_ETHERNET(self));
@@ -539,12 +541,12 @@ wired_secrets_cancel(NMDeviceEthernet *self)
 }
 
 static void
-wired_secrets_get_secrets(NMDeviceEthernet *           self,
-                          const char *                 setting_name,
+wired_secrets_get_secrets(NMDeviceEthernet            *self,
+                          const char                  *setting_name,
                           NMSecretAgentGetSecretsFlags flags)
 {
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMActRequest *           req;
+    NMActRequest            *req;
 
     wired_secrets_cancel(self);
 
@@ -559,12 +561,12 @@ wired_secrets_get_secrets(NMDeviceEthernet *           self,
 static gboolean
 supplicant_lnk_timeout_cb(gpointer user_data)
 {
-    NMDeviceEthernet *       self   = NM_DEVICE_ETHERNET(user_data);
+    NMDeviceEthernet        *self   = NM_DEVICE_ETHERNET(user_data);
     NMDeviceEthernetPrivate *priv   = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMDevice *               device = NM_DEVICE(self);
-    NMActRequest *           req;
-    NMConnection *           applied_connection;
-    const char *             setting_name;
+    NMDevice                *device = NM_DEVICE(self);
+    NMActRequest            *req;
+    NMConnection            *applied_connection;
+    const char              *setting_name;
 
     priv->supplicant.lnk_timeout_id = 0;
 
@@ -611,10 +613,10 @@ time_out:
 static NMSupplicantConfig *
 build_supplicant_config(NMDeviceEthernet *self, GError **error)
 {
-    const char *        con_uuid;
+    const char         *con_uuid;
     NMSupplicantConfig *config = NULL;
-    NMSetting8021x *    security;
-    NMConnection *      connection;
+    NMSetting8021x     *security;
+    NMConnection       *connection;
     guint32             mtu;
 
     connection = nm_device_get_applied_connection(NM_DEVICE(self));
@@ -644,14 +646,15 @@ supplicant_iface_state_is_completed(NMDeviceEthernet *self, NMSupplicantInterfac
     if (state == NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) {
         nm_clear_g_source(&priv->supplicant.lnk_timeout_id);
         nm_clear_g_source(&priv->supplicant.con_timeout_id);
+        priv->supplicant.ready = TRUE;
 
         /* If this is the initial association during device activation,
-         * schedule the next activation stage.
+         * schedule the activation stage again to proceed.
          */
         if (nm_device_get_state(NM_DEVICE(self)) == NM_DEVICE_STATE_CONFIG) {
             _LOGI(LOGD_DEVICE | LOGD_ETHER,
                   "Activation: (ethernet) Stage 2 of 5 (Device Configure) successful.");
-            nm_device_activate_schedule_stage3_ip_config_start(NM_DEVICE(self));
+            nm_device_activate_schedule_stage2_device_config(NM_DEVICE(self), FALSE);
         }
         return;
     }
@@ -664,7 +667,7 @@ supplicant_iface_state_is_completed(NMDeviceEthernet *self, NMSupplicantInterfac
 static void
 supplicant_iface_assoc_cb(NMSupplicantInterface *iface, GError *error, gpointer user_data)
 {
-    NMDeviceEthernet *       self;
+    NMDeviceEthernet        *self;
     NMDeviceEthernetPrivate *priv;
 
     if (nm_utils_error_is_cancelled_or_disposing(error))
@@ -692,9 +695,9 @@ supplicant_iface_assoc_cb(NMSupplicantInterface *iface, GError *error, gpointer
 static gboolean
 supplicant_iface_start(NMDeviceEthernet *self)
 {
-    NMDeviceEthernetPrivate *priv              = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
+    NMDeviceEthernetPrivate            *priv   = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
     gs_unref_object NMSupplicantConfig *config = NULL;
-    gs_free_error GError *error                = NULL;
+    gs_free_error GError               *error  = NULL;
 
     config = build_supplicant_config(self, &error);
     if (!config) {
@@ -720,8 +723,8 @@ supplicant_iface_state_cb(NMSupplicantInterface *iface,
                           int                    disconnect_reason,
                           gpointer               user_data)
 {
-    NMDeviceEthernet *         self      = NM_DEVICE_ETHERNET(user_data);
-    NMDeviceEthernetPrivate *  priv      = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
+    NMDeviceEthernet          *self      = NM_DEVICE_ETHERNET(user_data);
+    NMDeviceEthernetPrivate   *priv      = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
     NMSupplicantInterfaceState new_state = new_state_i;
     NMSupplicantInterfaceState old_state = old_state_i;
 
@@ -750,7 +753,7 @@ supplicant_iface_state_cb(NMSupplicantInterface *iface,
 static gboolean
 handle_auth_or_fail(NMDeviceEthernet *self, NMActRequest *req, gboolean new_secrets)
 {
-    const char *  setting_name;
+    const char   *setting_name;
     NMConnection *applied_connection;
 
     if (!nm_device_auth_retries_try_next(NM_DEVICE(self)))
@@ -789,11 +792,11 @@ handle_auth_or_fail(NMDeviceEthernet *self, NMActRequest *req, gboolean new_secr
 static gboolean
 supplicant_connection_timeout_cb(gpointer user_data)
 {
-    NMDeviceEthernet *       self   = NM_DEVICE_ETHERNET(user_data);
+    NMDeviceEthernet        *self   = NM_DEVICE_ETHERNET(user_data);
     NMDeviceEthernetPrivate *priv   = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMDevice *               device = NM_DEVICE(self);
-    NMActRequest *           req;
-    NMSettingsConnection *   connection;
+    NMDevice                *device = NM_DEVICE(self);
+    NMActRequest            *req;
+    NMSettingsConnection    *connection;
     guint64                  timestamp   = 0;
     gboolean                 new_secrets = TRUE;
 
@@ -833,13 +836,13 @@ supplicant_connection_timeout_cb(gpointer user_data)
 }
 
 static void
-supplicant_interface_create_cb(NMSupplicantManager *        supplicant_manager,
+supplicant_interface_create_cb(NMSupplicantManager         *supplicant_manager,
                                NMSupplMgrCreateIfaceHandle *handle,
-                               NMSupplicantInterface *      iface,
-                               GError *                     error,
+                               NMSupplicantInterface       *iface,
+                               GError                      *error,
                                gpointer                     user_data)
 {
-    NMDeviceEthernet *       self;
+    NMDeviceEthernet        *self;
     NMDeviceEthernetPrivate *priv;
     guint                    timeout;
 
@@ -894,9 +897,9 @@ link_duplex_to_platform(const char *duplex)
 static void
 link_negotiation_set(NMDevice *device)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(device);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMSettingWired *         s_wired;
+    NMSettingWired          *s_wired;
     gboolean                 autoneg = TRUE;
     gboolean                 link_autoneg;
     NMPlatformLinkDuplexType duplex      = NM_PLATFORM_LINK_DUPLEX_UNKNOWN;
@@ -966,20 +969,20 @@ link_negotiation_set(NMDevice *device)
 static gboolean
 pppoe_reconnect_delay(gpointer user_data)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(user_data);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(user_data);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
 
-    priv->pppoe_wait_id   = 0;
-    priv->last_pppoe_time = 0;
+    nm_clear_g_source_inst(&priv->ppp_data.wait_source);
+    priv->ppp_data.last_pppoe_time_msec = 0;
     _LOGI(LOGD_DEVICE, "PPPoE reconnect delay complete, resuming connection...");
     nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE);
-    return G_SOURCE_REMOVE;
+    return G_SOURCE_CONTINUE;
 }
 
 static NMActStageReturn
 act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(device);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
 
     if (nm_device_sys_iface_state_is_external_or_assume(device)) {
@@ -1014,21 +1017,24 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
      * 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 != 0) {
-        gint32 delay = nm_utils_get_monotonic_timestamp_sec() - priv->last_pppoe_time;
+    if (priv->ppp_data.last_pppoe_time_msec != 0) {
+        gint64 delay =
+            nm_utils_get_monotonic_timestamp_msec() - priv->ppp_data.last_pppoe_time_msec;
 
-        if (delay < PPPOE_RECONNECT_DELAY
+        if (delay < PPPOE_RECONNECT_DELAY_MSEC
             && nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE)) {
-            if (priv->pppoe_wait_id == 0) {
+            if (!priv->ppp_data.wait_source) {
                 _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);
+                      "delaying PPPoE reconnect for %d.%03d seconds to ensure peer is ready...",
+                      (int) (delay / 1000),
+                      (int) (delay % 1000));
+                priv->ppp_data.wait_source =
+                    nm_g_timeout_add_source(delay, pppoe_reconnect_delay, self);
             }
             return NM_ACT_STAGE_RETURN_POSTPONE;
         }
-        nm_clear_g_source(&priv->pppoe_wait_id);
-        priv->last_pppoe_time = 0;
+        nm_clear_g_source_inst(&priv->ppp_data.wait_source);
+        priv->ppp_data.last_pppoe_time_msec = 0;
     }
 
     return NM_ACT_STAGE_RETURN_SUCCESS;
@@ -1038,9 +1044,9 @@ static NMActStageReturn
 supplicant_check_secrets_needed(NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason)
 {
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMConnection *           connection;
-    NMSetting8021x *         security;
-    const char *             setting_name;
+    NMConnection            *connection;
+    NMSetting8021x          *security;
+    const char              *setting_name;
 
     connection = nm_device_get_applied_connection(NM_DEVICE(self));
     g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
@@ -1105,105 +1111,79 @@ carrier_changed(NMSupplicantInterface *iface, GParamSpec *pspec, NMDeviceEtherne
 }
 
 /*****************************************************************************/
-/* PPPoE */
 
 static void
-ppp_state_changed(NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data)
+_ppp_mgr_cleanup(NMDeviceEthernet *self)
 {
-    NMDevice *device = NM_DEVICE(user_data);
+    NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
 
-    switch (status) {
-    case NM_PPP_STATUS_DISCONNECT:
-        nm_device_state_changed(device,
-                                NM_DEVICE_STATE_FAILED,
-                                NM_DEVICE_STATE_REASON_PPP_DISCONNECT);
-        break;
-    case NM_PPP_STATUS_DEAD:
-        nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED);
-        break;
-    default:
-        break;
-    }
+    nm_clear_pointer(&priv->ppp_data.ppp_mgr, nm_ppp_mgr_destroy);
 }
 
 static void
-ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpointer user_data)
+_ppp_mgr_stage3_maybe_ready(NMDeviceEthernet *self)
 {
-    NMDevice *device = NM_DEVICE(user_data);
+    NMDevice                *device = NM_DEVICE(self);
+    NMDeviceEthernetPrivate *priv   = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
+    int                      IS_IPv4;
 
-    if (!nm_device_set_ip_ifindex(device, ifindex)) {
-        nm_device_state_changed(device,
-                                NM_DEVICE_STATE_FAILED,
-                                NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-    }
-}
+    for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
+        const int             addr_family = IS_IPv4 ? AF_INET : AF_INET6;
+        const NMPppMgrIPData *ip_data;
 
-static void
-ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data)
-{
-    NMDevice *device = NM_DEVICE(user_data);
+        ip_data = nm_ppp_mgr_get_ip_data(priv->ppp_data.ppp_mgr, addr_family);
+        if (ip_data->ip_received)
+            nm_device_devip_set_state(device, addr_family, NM_DEVICE_IP_STATE_READY, ip_data->l3cd);
+    }
 
-    /* Ignore PPP IP4 events that come in after initial configuration */
-    if (nm_device_activate_ip4_state_in_conf(device))
-        nm_device_activate_schedule_ip_config_result(device, AF_INET, NM_IP_CONFIG_CAST(config));
+    if (nm_ppp_mgr_get_state(priv->ppp_data.ppp_mgr) >= NM_PPP_MGR_STATE_HAVE_IP_CONFIG)
+        nm_device_devip_set_state(device, AF_UNSPEC, NM_DEVICE_IP_STATE_READY, NULL);
 }
 
-static NMActStageReturn
-pppoe_stage3_ip4_config_start(NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason)
+static void
+_ppp_mgr_callback(NMPppMgr *ppp_mgr, const NMPppMgrCallbackData *callback_data, gpointer user_data)
 {
-    NMDevice *               device = NM_DEVICE(self);
-    NMDeviceEthernetPrivate *priv   = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMSettingPppoe *         s_pppoe;
-    NMActRequest *           req;
-    GError *                 err = NULL;
-
-    req = nm_device_get_act_request(device);
-
-    g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE);
-
-    s_pppoe = nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE);
+    NMDeviceEthernet *self   = NM_DEVICE_ETHERNET(user_data);
+    NMDevice         *device = NM_DEVICE(self);
+    NMDeviceState     device_state;
 
-    g_return_val_if_fail(s_pppoe, NM_ACT_STAGE_RETURN_FAILURE);
+    if (callback_data->callback_type != NM_PPP_MGR_CALLBACK_TYPE_STATE_CHANGED)
+        return;
 
-    priv->ppp_manager = nm_ppp_manager_create(nm_device_get_iface(device), &err);
+    device_state = nm_device_get_state(device);
 
-    if (priv->ppp_manager) {
-        nm_ppp_manager_set_route_parameters(priv->ppp_manager,
-                                            nm_device_get_route_table(device, AF_INET),
-                                            nm_device_get_route_metric(device, AF_INET),
-                                            nm_device_get_route_table(device, AF_INET6),
-                                            nm_device_get_route_metric(device, AF_INET6));
+    if (callback_data->data.state >= _NM_PPP_MGR_STATE_FAILED_START) {
+        if (device_state <= NM_DEVICE_STATE_ACTIVATED)
+            nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, callback_data->data.reason);
+        return;
     }
 
-    if (!priv->ppp_manager
-        || !nm_ppp_manager_start(priv->ppp_manager,
-                                 req,
-                                 nm_setting_pppoe_get_username(s_pppoe),
-                                 30,
-                                 0,
-                                 &err)) {
-        _LOGW(LOGD_DEVICE, "PPPoE failed to start: %s", err->message);
-        g_error_free(err);
+    if (device_state < NM_DEVICE_STATE_IP_CONFIG) {
+        if (callback_data->data.state >= NM_PPP_MGR_STATE_HAVE_IFINDEX) {
+            gs_free char         *old_name = NULL;
+            gs_free_error GError *error    = NULL;
+
+            if (!nm_device_take_over_link(device, callback_data->data.ifindex, &old_name, &error)) {
+                _LOGW(LOGD_DEVICE | LOGD_PPP,
+                      "could not take control of link %d: %s",
+                      callback_data->data.ifindex,
+                      error->message);
+                _ppp_mgr_cleanup(self);
+                nm_device_state_changed(device,
+                                        NM_DEVICE_STATE_FAILED,
+                                        NM_DEVICE_STATE_REASON_CONFIG_FAILED);
+                return;
+            }
 
-        g_clear_object(&priv->ppp_manager);
+            if (old_name)
+                nm_manager_remove_device(NM_MANAGER_GET, old_name, NM_DEVICE_TYPE_PPP);
 
-        NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED);
-        return NM_ACT_STAGE_RETURN_FAILURE;
+            nm_device_activate_schedule_stage2_device_config(device, FALSE);
+        }
+        return;
     }
 
-    g_signal_connect(priv->ppp_manager,
-                     NM_PPP_MANAGER_SIGNAL_STATE_CHANGED,
-                     G_CALLBACK(ppp_state_changed),
-                     self);
-    g_signal_connect(priv->ppp_manager,
-                     NM_PPP_MANAGER_SIGNAL_IFINDEX_SET,
-                     G_CALLBACK(ppp_ifindex_set),
-                     self);
-    g_signal_connect(priv->ppp_manager,
-                     NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
-                     G_CALLBACK(ppp_ip4_config),
-                     self);
-    return NM_ACT_STAGE_RETURN_POSTPONE;
+    _ppp_mgr_stage3_maybe_ready(self);
 }
 
 /*****************************************************************************/
@@ -1213,9 +1193,9 @@ static void dcb_state(NMDevice *device, gboolean timeout);
 static gboolean
 dcb_carrier_timeout(gpointer user_data)
 {
-    NMDeviceEthernet *       self   = NM_DEVICE_ETHERNET(user_data);
+    NMDeviceEthernet        *self   = NM_DEVICE_ETHERNET(user_data);
     NMDeviceEthernetPrivate *priv   = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMDevice *               device = NM_DEVICE(user_data);
+    NMDevice                *device = NM_DEVICE(user_data);
 
     g_return_val_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG, G_SOURCE_REMOVE);
 
@@ -1230,10 +1210,10 @@ dcb_carrier_timeout(gpointer user_data)
 static gboolean
 dcb_configure(NMDevice *device)
 {
-    NMDeviceEthernet *       self = (NMDeviceEthernet *) device;
+    NMDeviceEthernet        *self = (NMDeviceEthernet *) device;
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMSettingDcb *           s_dcb;
-    GError *                 error = NULL;
+    NMSettingDcb            *s_dcb;
+    GError                  *error = NULL;
 
     nm_clear_g_source(&priv->dcb_timeout_id);
 
@@ -1259,9 +1239,9 @@ dcb_configure(NMDevice *device)
 static gboolean
 dcb_enable(NMDevice *device)
 {
-    NMDeviceEthernet *       self  = NM_DEVICE_ETHERNET(device);
+    NMDeviceEthernet        *self  = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv  = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    GError *                 error = NULL;
+    GError                  *error = NULL;
 
     nm_clear_g_source(&priv->dcb_timeout_id);
     if (!nm_dcb_enable(nm_device_get_iface(device), TRUE, &error)) {
@@ -1286,7 +1266,7 @@ dcb_enable(NMDevice *device)
 static void
 dcb_state(NMDevice *device, gboolean timeout)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(device);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
     gboolean                 carrier;
 
@@ -1351,7 +1331,7 @@ dcb_state(NMDevice *device, gboolean timeout)
             nm_clear_g_source(&priv->dcb_timeout_id);
             priv->dcb_handle_carrier_changes = FALSE;
             priv->dcb_wait                   = DCB_WAIT_UNKNOWN;
-            nm_device_activate_schedule_stage3_ip_config_start(device);
+            nm_device_activate_schedule_stage2_device_config(device, FALSE);
         }
         break;
     default:
@@ -1365,8 +1345,8 @@ static gboolean
 wake_on_lan_enable(NMDevice *device)
 {
     NMSettingWiredWakeOnLan wol;
-    NMSettingWired *        s_wired;
-    const char *            password = NULL;
+    NMSettingWired         *s_wired;
+    const char             *password = NULL;
 
     s_wired = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRED);
 
@@ -1407,31 +1387,98 @@ found:
 static NMActStageReturn
 act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
 {
-    NMDeviceEthernet *       self = (NMDeviceEthernet *) device;
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMSettingConnection *    s_con;
-    const char *             connection_type;
-    gboolean                 do_postpone = FALSE;
-    NMSettingDcb *           s_dcb;
+    NMConnection            *connection;
+    NMSettingConnection     *s_con;
+    const char              *connection_type;
+    NMSettingDcb            *s_dcb;
+    NMActRequest            *req;
 
-    s_con = nm_device_get_applied_setting(device, NM_TYPE_SETTING_CONNECTION);
+    connection = nm_device_get_applied_connection(device);
+    g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
 
+    s_con = _nm_connection_get_setting(connection, NM_TYPE_SETTING_CONNECTION);
     g_return_val_if_fail(s_con, NM_ACT_STAGE_RETURN_FAILURE);
 
     nm_clear_g_source(&priv->dcb_timeout_id);
     priv->dcb_handle_carrier_changes = FALSE;
 
+    connection_type = nm_setting_connection_get_connection_type(s_con);
+
+    if (nm_streq(connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
+        if (!priv->ppp_data.ppp_mgr) {
+            gs_free_error GError *error = NULL;
+            NMSettingPppoe       *s_pppoe;
+            NMSettingPpp         *s_ppp;
+
+            s_ppp = nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPP);
+            if (s_ppp) {
+                guint32 mtu;
+                guint32 mru;
+                guint32 mxu;
+
+                mtu = nm_setting_ppp_get_mtu(s_ppp);
+                mru = nm_setting_ppp_get_mru(s_ppp);
+                mxu = MAX(mru, mtu);
+                if (mxu) {
+                    _LOGD(LOGD_PPP,
+                          "set MTU to %u (PPP interface MRU %u, MTU %u)",
+                          mxu + PPPOE_ENCAP_OVERHEAD,
+                          mru,
+                          mtu);
+                    nm_platform_link_set_mtu(nm_device_get_platform(device),
+                                             nm_device_get_ifindex(device),
+                                             mxu + PPPOE_ENCAP_OVERHEAD);
+                }
+            }
+
+            req = nm_device_get_act_request(device);
+            g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE);
+
+            s_pppoe = _nm_connection_get_setting(connection, NM_TYPE_SETTING_PPPOE);
+            g_return_val_if_fail(s_pppoe, NM_ACT_STAGE_RETURN_FAILURE);
+
+            priv->ppp_data.ppp_mgr =
+                nm_ppp_mgr_start(&((const NMPppMgrConfig){
+                                     .netns         = nm_device_get_netns(device),
+                                     .parent_iface  = nm_device_get_iface(device),
+                                     .callback      = _ppp_mgr_callback,
+                                     .user_data     = self,
+                                     .act_req       = req,
+                                     .ppp_username  = nm_setting_pppoe_get_username(s_pppoe),
+                                     .timeout_secs  = 30,
+                                     .baud_override = 0,
+                                 }),
+                                 &error);
+            if (!priv->ppp_data.ppp_mgr) {
+                _LOGW(LOGD_DEVICE | LOGD_PPP, "PPPoE failed to start: %s", error->message);
+                *out_failure_reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
+                return NM_ACT_STAGE_RETURN_FAILURE;
+            }
+
+            return NM_ACT_STAGE_RETURN_POSTPONE;
+        }
+
+        if (nm_ppp_mgr_get_state(priv->ppp_data.ppp_mgr) < NM_PPP_MGR_STATE_HAVE_IFINDEX)
+            return NM_ACT_STAGE_RETURN_POSTPONE;
+    }
+
     /* 802.1x has to run before any IP configuration since the 802.1x auth
      * process opens the port up for normal traffic.
      */
-    connection_type = nm_setting_connection_get_connection_type(s_con);
     if (nm_streq(connection_type, NM_SETTING_WIRED_SETTING_NAME)) {
         NMSetting8021x *security;
 
         security = nm_device_get_applied_setting(device, NM_TYPE_SETTING_802_1X);
 
         if (security) {
-            /* FIXME: for now 802.1x is mutually exclusive with DCB */
+            /* FIXME: we always return from this. stage2 must be re-entrant, and
+             * process all the necessary steps. Just returning for 8021x is wrong. */
+
+            if (priv->supplicant.ready)
+                return NM_ACT_STAGE_RETURN_SUCCESS;
+
             if (!nm_device_has_carrier(NM_DEVICE(self))) {
                 _LOGD(LOGD_DEVICE | LOGD_ETHER,
                       "delay supplicant initialization until carrier goes up");
@@ -1450,7 +1497,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
 
     /* DCB and FCoE setup */
     s_dcb = nm_device_get_applied_setting(device, NM_TYPE_SETTING_DCB);
-    if (s_dcb) {
+    if (!priv->stage2_ready_dcb && s_dcb) {
         /* lldpad really really wants the carrier to be up */
         if (nm_platform_link_is_connected(nm_device_get_platform(device),
                                           nm_device_get_ifindex(device))) {
@@ -1465,100 +1512,66 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
         }
 
         priv->dcb_handle_carrier_changes = TRUE;
-        do_postpone                      = TRUE;
-    }
-
-    /* PPPoE setup */
-    if (nm_connection_is_type(nm_device_get_applied_connection(device),
-                              NM_SETTING_PPPOE_SETTING_NAME)) {
-        NMSettingPpp *s_ppp;
-
-        s_ppp = nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPP);
-        if (s_ppp) {
-            guint32 mtu;
-            guint32 mru;
-            guint32 mxu;
-
-            mtu = nm_setting_ppp_get_mtu(s_ppp);
-            mru = nm_setting_ppp_get_mru(s_ppp);
-            mxu = MAX(mru, mtu);
-            if (mxu) {
-                _LOGD(LOGD_PPP,
-                      "set MTU to %u (PPP interface MRU %u, MTU %u)",
-                      mxu + PPPOE_ENCAP_OVERHEAD,
-                      mru,
-                      mtu);
-                nm_platform_link_set_mtu(nm_device_get_platform(device),
-                                         nm_device_get_ifindex(device),
-                                         mxu + PPPOE_ENCAP_OVERHEAD);
-            }
-        }
+        return NM_ACT_STAGE_RETURN_POSTPONE;
     }
 
-    return do_postpone ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_SUCCESS;
+    return NM_ACT_STAGE_RETURN_SUCCESS;
 }
 
-static NMActStageReturn
-act_stage3_ip_config_start(NMDevice *           device,
-                           int                  addr_family,
-                           gpointer *           out_config,
-                           NMDeviceStateReason *out_failure_reason)
+static guint32
+get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force)
 {
-    NMSettingConnection *s_con;
-    const char *         connection_type;
-    int                  ifindex;
+    NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(device);
 
-    ifindex = nm_device_get_ifindex(device);
+    /* MTU only set for plain ethernet */
+    if (priv->ppp_data.ppp_mgr)
+        return 0;
 
-    if (ifindex <= 0)
-        return NM_ACT_STAGE_RETURN_FAILURE;
+    return nm_device_get_configured_mtu_for_wired(device, out_source, out_force);
+}
 
-    if (addr_family == AF_INET) {
-        s_con = nm_device_get_applied_setting(device, NM_TYPE_SETTING_CONNECTION);
+static void
+act_stage3_ip_config(NMDevice *device, int addr_family)
+{
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
+    NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
+    NMPppMgrState            ppp_state;
 
-        g_return_val_if_fail(s_con, NM_ACT_STAGE_RETURN_FAILURE);
+    if (!priv->ppp_data.ppp_mgr)
+        return;
 
-        connection_type = nm_setting_connection_get_connection_type(s_con);
-        if (!strcmp(connection_type, NM_SETTING_PPPOE_SETTING_NAME))
-            return pppoe_stage3_ip4_config_start(NM_DEVICE_ETHERNET(device), out_failure_reason);
-    }
+    ppp_state = nm_ppp_mgr_get_state(priv->ppp_data.ppp_mgr);
 
-    return NM_DEVICE_CLASS(nm_device_ethernet_parent_class)
-        ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason);
-}
+    nm_assert(NM_IN_SET(ppp_state, NM_PPP_MGR_STATE_HAVE_IFINDEX, NM_PPP_MGR_STATE_HAVE_IP_CONFIG));
 
-static guint32
-get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force)
-{
-    /* MTU only set for plain ethernet */
-    if (NM_DEVICE_ETHERNET_GET_PRIVATE(device)->ppp_manager)
-        return 0;
+    if (ppp_state < NM_PPP_MGR_STATE_HAVE_IP_CONFIG) {
+        nm_device_devip_set_state(device, AF_UNSPEC, NM_DEVICE_IP_STATE_PENDING, NULL);
+        return;
+    }
 
-    return nm_device_get_configured_mtu_for_wired(device, out_source, out_force);
+    _ppp_mgr_stage3_maybe_ready(self);
 }
 
 static void
 deactivate(NMDevice *device)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(device);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
-    NMSettingDcb *           s_dcb;
-    GError *                 error = NULL;
+    NMSettingDcb            *s_dcb;
+    GError                  *error = NULL;
     int                      ifindex;
 
-    nm_clear_g_source(&priv->pppoe_wait_id);
+    nm_clear_g_source_inst(&priv->ppp_data.wait_source);
     nm_clear_g_signal_handler(self, &priv->carrier_id);
 
-    if (priv->ppp_manager) {
-        nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL);
-        g_clear_object(&priv->ppp_manager);
-    }
+    _ppp_mgr_cleanup(self);
 
     supplicant_interface_release(self);
 
     priv->dcb_wait = DCB_WAIT_UNKNOWN;
     nm_clear_g_source(&priv->dcb_timeout_id);
     priv->dcb_handle_carrier_changes = FALSE;
+    priv->stage2_ready_dcb           = FALSE;
 
     /* Tear down DCB/FCoE if it was enabled */
     s_dcb = nm_device_get_applied_setting(device, NM_TYPE_SETTING_DCB);
@@ -1571,7 +1584,7 @@ deactivate(NMDevice *device)
 
     /* Set last PPPoE connection time */
     if (nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE))
-        priv->last_pppoe_time = nm_utils_get_monotonic_timestamp_sec();
+        priv->ppp_data.last_pppoe_time_msec = nm_utils_get_monotonic_timestamp_msec();
 
     ifindex = nm_device_get_ifindex(device);
     if (ifindex > 0 && priv->ethtool_prev_set) {
@@ -1594,19 +1607,19 @@ deactivate(NMDevice *device)
 }
 
 static gboolean
-complete_connection(NMDevice *           device,
-                    NMConnection *       connection,
-                    const char *         specific_object,
+complete_connection(NMDevice            *device,
+                    NMConnection        *connection,
+                    const char          *specific_object,
                     NMConnection *const *existing_connections,
-                    GError **            error)
+                    GError             **error)
 {
     NMSettingWired *s_wired;
     NMSettingPppoe *s_pppoe;
 
     if (nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_VETH_SETTING_NAME)) {
         NMSettingVeth *s_veth;
-        const char *   peer_name     = NULL;
-        const char *   con_peer_name = NULL;
+        const char    *peer_name     = NULL;
+        const char    *con_peer_name = NULL;
         int            ifindex;
 
         nm_utils_complete_generic(nm_device_get_platform(device),
@@ -1683,16 +1696,16 @@ complete_connection(NMDevice *           device,
 static NMConnection *
 new_default_connection(NMDevice *self)
 {
-    NMConnection *               connection;
-    NMSettingsConnection *const *connections;
-    NMSetting *                  setting;
+    NMConnection                  *connection;
+    NMSettingsConnection *const   *connections;
+    NMSetting                     *setting;
     gs_unref_hashtable GHashTable *existing_ids = NULL;
-    struct udev_device *           dev;
-    const char *                   perm_hw_addr;
-    const char *                   iface;
-    const char *                   uprop   = "0";
-    gs_free char *                 defname = NULL;
-    gs_free char *                 uuid    = NULL;
+    struct udev_device            *dev;
+    const char                    *perm_hw_addr;
+    const char                    *iface;
+    const char                    *uprop   = "0";
+    gs_free char                  *defname = NULL;
+    gs_free char                  *uuid    = NULL;
     guint                          i, n_connections;
 
     perm_hw_addr = nm_device_get_permanent_hw_address(self);
@@ -1778,12 +1791,12 @@ update_connection(NMDevice *device, NMConnection *connection)
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(device);
     NMSettingWired *s_wired = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIRED);
     gboolean        perm_hw_addr_is_fake;
-    const char *    perm_hw_addr;
-    const char *    mac      = nm_device_get_hw_address(device);
-    const char *    mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
+    const char     *perm_hw_addr;
+    const char     *mac      = nm_device_get_hw_address(device);
+    const char     *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
     GHashTableIter  iter;
-    const char *    key;
-    const char *    value;
+    const char     *key;
+    const char     *value;
 
     g_object_set(nm_connection_get_setting_connection(connection),
                  NM_SETTING_CONNECTION_TYPE,
@@ -1823,7 +1836,7 @@ update_connection(NMDevice *device, NMConnection *connection)
 static void
 link_speed_update(NMDevice *device)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(device);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
     guint32                  speed;
 
@@ -1844,7 +1857,7 @@ link_speed_update(NMDevice *device)
 static void
 carrier_changed_notify(NMDevice *device, gboolean carrier)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(device);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
 
     if (priv->dcb_handle_carrier_changes) {
@@ -1880,12 +1893,12 @@ is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
 }
 
 static gboolean
-can_reapply_change(NMDevice *  device,
+can_reapply_change(NMDevice   *device,
                    const char *setting_name,
-                   NMSetting * s_old,
-                   NMSetting * s_new,
+                   NMSetting  *s_old,
+                   NMSetting  *s_new,
                    GHashTable *diffs,
-                   GError **   error)
+                   GError    **error)
 {
     NMDeviceClass *device_class;
 
@@ -1926,14 +1939,14 @@ reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_ne
 static void
 dispose(GObject *object)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(object);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(object);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
 
     wired_secrets_cancel(self);
 
     supplicant_interface_release(self);
 
-    nm_clear_g_source(&priv->pppoe_wait_id);
+    nm_clear_g_source_inst(&priv->ppp_data.wait_source);
 
     nm_clear_g_source(&priv->dcb_timeout_id);
 
@@ -1945,7 +1958,7 @@ dispose(GObject *object)
 static void
 finalize(GObject *object)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(object);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(object);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
 
     g_clear_object(&priv->supplicant.mgr);
@@ -1963,7 +1976,7 @@ finalize(GObject *object)
 static void
 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
 {
-    NMDeviceEthernet *       self = NM_DEVICE_ETHERNET(object);
+    NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(object);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
 
     switch (prop_id) {
@@ -2007,9 +2020,9 @@ static const NMDBusInterfaceInfoExtended interface_info_device_wired = {
 static void
 nm_device_ethernet_class_init(NMDeviceEthernetClass *klass)
 {
-    GObjectClass *     object_class      = G_OBJECT_CLASS(klass);
+    GObjectClass      *object_class      = G_OBJECT_CLASS(klass);
     NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
-    NMDeviceClass *    device_class      = NM_DEVICE_CLASS(klass);
+    NMDeviceClass     *device_class      = NM_DEVICE_CLASS(klass);
 
     g_type_class_add_private(object_class, sizeof(NMDeviceEthernetPrivate));
 
@@ -2032,7 +2045,7 @@ nm_device_ethernet_class_init(NMDeviceEthernetClass *klass)
     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->act_stage3_ip_config                           = act_stage3_ip_config;
     device_class->get_configured_mtu                             = get_configured_mtu;
     device_class->deactivate                                     = deactivate;
     device_class->get_s390_subchannels                           = get_s390_subchannels;
@@ -2070,11 +2083,11 @@ nm_device_ethernet_class_init(NMDeviceEthernetClass *klass)
     (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_ETHERNET_DEVICE_FACTORY, NMEthernetDeviceFactory))
 
 static NMDevice *
-create_device(NMDeviceFactory *     factory,
-              const char *          iface,
+create_device(NMDeviceFactory      *factory,
+              const char           *iface,
               const NMPlatformLink *plink,
-              NMConnection *        connection,
-              gboolean *            out_ignore)
+              NMConnection         *connection,
+              gboolean             *out_ignore)
 {
     return g_object_new(NM_TYPE_DEVICE_ETHERNET,
                         NM_DEVICE_IFACE,
@@ -2091,7 +2104,7 @@ create_device(NMDeviceFactory *     factory,
 static gboolean
 match_connection(NMDeviceFactory *factory, NMConnection *connection)
 {
-    const char *    type = nm_connection_get_connection_type(connection);
+    const char     *type = nm_connection_get_connection_type(connection);
     NMSettingPppoe *s_pppoe;
 
     if (nm_streq(type, NM_SETTING_WIRED_SETTING_NAME))