summary refs log tree commit diff
path: root/src/core/devices
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/devices')
-rw-r--r--src/core/devices/nm-device-ppp.c37
-rw-r--r--src/core/devices/nm-device.c41
-rw-r--r--src/core/devices/wifi/nm-device-wifi.c5
3 files changed, 50 insertions, 33 deletions
diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c
index 61e32348..6615b65e 100644
--- a/src/core/devices/nm-device-ppp.c
+++ b/src/core/devices/nm-device-ppp.c
@@ -23,6 +23,13 @@
 
 typedef struct _NMDevicePppPrivate {
     NMPppMgr *ppp_mgr;
+    union {
+        struct {
+            NML3CfgBlockHandle *l3cfg_block_handle_6;
+            NML3CfgBlockHandle *l3cfg_block_handle_4;
+        };
+        NML3CfgBlockHandle *l3cfg_block_handle_x[2];
+    };
 } NMDevicePppPrivate;
 
 struct _NMDevicePpp {
@@ -69,8 +76,10 @@ _ppp_mgr_stage3_maybe_ready(NMDevicePpp *self)
         const NMPppMgrIPData *ip_data;
 
         ip_data = nm_ppp_mgr_get_ip_data(priv->ppp_mgr, addr_family);
-        if (ip_data->ip_received)
+        if (ip_data->ip_received) {
+            nm_clear_pointer(&priv->l3cfg_block_handle_x[IS_IPv4], nm_l3cfg_unblock_obj_pruning);
             nm_device_devip_set_state(device, addr_family, NM_DEVICE_IP_STATE_READY, ip_data->l3cd);
+        }
     }
 
     if (nm_ppp_mgr_get_state(priv->ppp_mgr) >= NM_PPP_MGR_STATE_HAVE_IP_CONFIG)
@@ -80,9 +89,10 @@ _ppp_mgr_stage3_maybe_ready(NMDevicePpp *self)
 static void
 _ppp_mgr_callback(NMPppMgr *ppp_mgr, const NMPppMgrCallbackData *callback_data, gpointer user_data)
 {
-    NMDevicePpp  *self   = NM_DEVICE_PPP(user_data);
-    NMDevice     *device = NM_DEVICE(self);
-    NMDeviceState device_state;
+    NMDevicePpp        *self   = NM_DEVICE_PPP(user_data);
+    NMDevice           *device = NM_DEVICE(self);
+    NMDevicePppPrivate *priv   = NM_DEVICE_PPP_GET_PRIVATE(self);
+    NMDeviceState       device_state;
 
     if (callback_data->callback_type != NM_PPP_MGR_CALLBACK_TYPE_STATE_CHANGED)
         return;
@@ -112,6 +122,19 @@ _ppp_mgr_callback(NMPppMgr *ppp_mgr, const NMPppMgrCallbackData *callback_data,
                 return;
             }
 
+            /* pppd also tries to configure addresses by itself through some
+             * ioctls. If we remove between those calls an address that was added,
+             * pppd fails and quits. Temporarily block the removal of addresses
+             * and routes. */
+            if (!priv->l3cfg_block_handle_4) {
+                priv->l3cfg_block_handle_4 =
+                    nm_l3cfg_block_obj_pruning(nm_device_get_l3cfg(device), AF_INET);
+            }
+            if (!priv->l3cfg_block_handle_6) {
+                priv->l3cfg_block_handle_6 =
+                    nm_l3cfg_block_obj_pruning(nm_device_get_l3cfg(device), AF_INET6);
+            }
+
             if (old_name)
                 nm_manager_remove_device(NM_MANAGER_GET, old_name, NM_DEVICE_TYPE_PPP);
 
@@ -257,7 +280,11 @@ create_and_realize(NMDevice              *device,
 static void
 deactivate(NMDevice *device)
 {
-    NMDevicePpp *self = NM_DEVICE_PPP(device);
+    NMDevicePpp        *self = NM_DEVICE_PPP(device);
+    NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self);
+
+    nm_clear_pointer(&priv->l3cfg_block_handle_4, nm_l3cfg_unblock_obj_pruning);
+    nm_clear_pointer(&priv->l3cfg_block_handle_6, nm_l3cfg_unblock_obj_pruning);
 
     _ppp_mgr_cleanup(self);
 }
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 70b52b1a..82ce712a 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -4026,7 +4026,6 @@ _set_ifindex(NMDevice *self, int ifindex, gboolean is_ip_ifindex)
     NMDevicePrivate         *priv                  = NM_DEVICE_GET_PRIVATE(self);
     gs_unref_object NML3Cfg *l3cfg_old             = NULL;
     NML3CfgCommitTypeHandle *l3cfg_commit_type_old = NULL;
-    gboolean                 l3_changed;
     int                      ip_ifindex_new;
     int                     *p_ifindex;
     gboolean                 l3cfg_was_reset = FALSE;
@@ -4067,6 +4066,10 @@ _set_ifindex(NMDevice *self, int ifindex, gboolean is_ip_ifindex)
             l3cfg_was_reset       = TRUE;
         }
     }
+
+    if (!priv->l3cfg && l3cfg_old)
+        _dev_l3_register_l3cds(self, l3cfg_old, FALSE, FALSE);
+
     if (!priv->l3cfg && ip_ifindex_new > 0) {
         priv->l3cfg_ = nm_netns_l3cfg_acquire(priv->netns, ip_ifindex_new);
 
@@ -4078,6 +4081,7 @@ _set_ifindex(NMDevice *self, int ifindex, gboolean is_ip_ifindex)
         _dev_l3_cfg_commit_type_reset(self);
         l3cfg_was_reset = TRUE;
     }
+
     if (!priv->l3cfg) {
         _cleanup_ip_pre(self, AF_INET, CLEANUP_TYPE_KEEP, FALSE);
         _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_KEEP, FALSE);
@@ -4118,11 +4122,7 @@ _set_ifindex(NMDevice *self, int ifindex, gboolean is_ip_ifindex)
         _notify(self, PROP_IP6_CONFIG);
     }
 
-    if (l3cfg_old != priv->l3cfg) {
-        l3_changed = FALSE;
-        if (_dev_l3_register_l3cds(self, l3cfg_old, FALSE, FALSE))
-            l3_changed = TRUE;
-
+    if (priv->l3cfg && l3cfg_old != priv->l3cfg) {
         /* Now it gets ugly. We changed the ip-ifindex, which determines the NML3Cfg instance.
          * But all the NML3ConfigData we currently track are still for the old ifindex. We
          * need to update them.
@@ -4131,12 +4131,10 @@ _set_ifindex(NMDevice *self, int ifindex, gboolean is_ip_ifindex)
          * associated with one ifindex (and not the ifindex/ip-ifindex split). Or it
          * is not at all associated with an ifindex, but only a controlling device for
          * a real NMDevice (that has the ifindex). */
+
         _dev_l3_update_l3cds_ifindex(self);
 
         if (_dev_l3_register_l3cds(self, priv->l3cfg, TRUE, FALSE))
-            l3_changed = TRUE;
-
-        if (l3_changed)
             _dev_l3_cfg_commit(self, TRUE);
     }
 
@@ -6164,10 +6162,6 @@ carrier_changed(NMDevice *self, gboolean carrier)
 
     if (nm_device_is_master(self)) {
         if (carrier) {
-            /* Force master to retry getting ip addresses when carrier
-             * is restored. */
-            if (priv->state == NM_DEVICE_STATE_ACTIVATED)
-                nm_device_update_dynamic_ip_setup(self);
             /* If needed, also resume IP configuration that is
              * waiting for carrier. */
             if (priv->state == NM_DEVICE_STATE_IP_CONFIG)
@@ -6195,12 +6189,6 @@ carrier_changed(NMDevice *self, gboolean carrier)
              * the device.
              */
             nm_device_emit_recheck_auto_activate(self);
-        } else if (priv->state == NM_DEVICE_STATE_ACTIVATED) {
-            /* If the device is active without a carrier (probably because it is
-             * tagged for carrier ignore) ensure that when the carrier appears we
-             * renew DHCP leases and such.
-             */
-            nm_device_update_dynamic_ip_setup(self);
         }
     } else {
         if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
@@ -6588,6 +6576,14 @@ device_link_changed(gpointer user_data)
         if (priv->state >= NM_DEVICE_STATE_IP_CONFIG && priv->state <= NM_DEVICE_STATE_ACTIVATED
             && !nm_device_sys_iface_state_is_external(self))
             nm_device_l3cfg_commit(self, NM_L3_CFG_COMMIT_TYPE_REAPPLY, FALSE);
+
+        /* If the device is active without a carrier (probably because it is
+         * tagged for carrier ignore) ensure that when the carrier appears we
+         * renew DHCP leases and such.
+         */
+        if (priv->state == NM_DEVICE_STATE_ACTIVATED) {
+            nm_device_update_dynamic_ip_setup(self);
+        }
     }
 
     if (update_unmanaged_specs)
@@ -10117,13 +10113,6 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family)
 
     hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address);
 
-    if (!IS_IPv4) {
-        if (!hwaddr) {
-            fail_reason = "interface has no MAC address to start DHCPv6";
-            goto out_fail;
-        }
-    }
-
     request_broadcast = FALSE;
     if (pllink) {
         str = nmp_object_link_udev_device_get_property_value(NMP_OBJECT_UP_CAST(pllink),
diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c
index d83b1f35..2572213c 100644
--- a/src/core/devices/wifi/nm-device-wifi.c
+++ b/src/core/devices/wifi/nm-device-wifi.c
@@ -1076,8 +1076,9 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError *
     if (s_wsec) {
         key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec);
 
-        if (nm_supplicant_interface_get_capability(priv->sup_iface, NM_SUPPL_CAP_TYPE_WEP)
-                == NM_TERNARY_FALSE
+        if (priv->sup_iface
+            && nm_supplicant_interface_get_capability(priv->sup_iface, NM_SUPPL_CAP_TYPE_WEP)
+                   == NM_TERNARY_FALSE
             && NM_IN_STRSET(key_mgmt, "ieee8021x", "none")) {
             nm_utils_error_set_literal(error,
                                        NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,