about 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-bridge.c3
-rw-r--r--src/core/devices/nm-device.c37
-rw-r--r--src/core/devices/nm-device.h2
-rw-r--r--src/core/devices/ovs/nm-device-ovs-bridge.c2
-rw-r--r--src/core/devices/ovs/nm-device-ovs-interface.c2
-rw-r--r--src/core/devices/ovs/nm-device-ovs-port.c2
-rw-r--r--src/core/devices/ovs/nm-ovs-factory.c6
-rw-r--r--src/core/devices/wifi/nm-device-wifi.c41
-rw-r--r--src/core/devices/wifi/nm-iwd-manager.c2
-rw-r--r--src/core/devices/wwan/nm-device-modem.c8
-rw-r--r--src/core/devices/wwan/nm-modem-broadband.c5
11 files changed, 86 insertions, 24 deletions
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c
index f11c172a..9bf7ac01 100644
--- a/src/core/devices/nm-device-bridge.c
+++ b/src/core/devices/nm-device-bridge.c
@@ -994,7 +994,8 @@ enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gbool
         nm_assert(s_bridge);
         s_port = nm_connection_get_setting_bridge_port(connection);
 
-        bridge_set_vlan_options(device, s_bridge);
+        if (!nm_device_sys_iface_state_is_external(device))
+            bridge_set_vlan_options(device, s_bridge);
 
         if (nm_setting_bridge_get_vlan_filtering(s_bridge)) {
             gs_free const NMPlatformBridgeVlan **plat_vlans = NULL;
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 82ce712a..6b854517 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -1286,7 +1286,7 @@ out_fail:
               duid,
               duid_error);
 
-        nm_utils_random_bytes(&uuid, sizeof(uuid));
+        nm_random_get_bytes(&uuid, sizeof(uuid));
         duid_out = nm_utils_generate_duid_uuid(&uuid);
     }
 
@@ -2022,7 +2022,7 @@ out_fail:
           fail_reason);
     client_id_buf    = g_malloc(1 + 15);
     client_id_buf[0] = 0;
-    nm_utils_random_bytes(&client_id_buf[1], 15);
+    nm_random_get_bytes(&client_id_buf[1], 15);
     result = g_bytes_new_take(client_id_buf, 1 + 15);
 
 out_good:
@@ -7857,7 +7857,8 @@ nm_device_slave_notify_release(NMDevice *self, NMDeviceStateReason reason)
 void
 nm_device_removed(NMDevice *self, gboolean unconfigure_ip_config)
 {
-    NMDevicePrivate *priv;
+    NMDevicePrivate      *priv;
+    const NML3ConfigData *l3cd_old;
 
     g_return_if_fail(NM_IS_DEVICE(self));
 
@@ -7875,6 +7876,18 @@ nm_device_removed(NMDevice *self, gboolean unconfigure_ip_config)
     }
 
     _dev_l3_register_l3cds(self, priv->l3cfg, FALSE, unconfigure_ip_config);
+
+    /* _dev_l3_register_l3cds() schedules a commit, but if the device has
+     * commit type NONE, that doesn't emit a l3cd-changed. Do it manually,
+     * to ensure that entries are removed from the DNS manager. */
+    if (priv->l3cfg
+        && NM_IN_SET(priv->sys_iface_state,
+                     NM_DEVICE_SYS_IFACE_STATE_REMOVED,
+                     NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)) {
+        l3cd_old = nm_l3cfg_get_combined_l3cd(priv->l3cfg, TRUE);
+        if (l3cd_old)
+            g_signal_emit(self, signals[L3CD_CHANGED], 0, l3cd_old, NULL);
+    }
 }
 
 static gboolean
@@ -11382,8 +11395,8 @@ _dev_ipac6_start(NMDevice *self)
 
     if (node_type == NM_NDISC_NODE_TYPE_ROUTER)
         _dev_ipac6_set_state(self, NM_DEVICE_IP_STATE_READY);
-    else
-        _dev_ipac6_grace_period_start(self, ra_timeout, TRUE);
+
+    _dev_ipac6_grace_period_start(self, ra_timeout, TRUE);
 
     nm_ndisc_start(priv->ipac6_data.ndisc);
 }
@@ -11623,7 +11636,7 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family, const
         priv->ip_data_x[IS_IPv4].wait_for_ports = FALSE;
     }
 
-    if (klass->ready_for_ip_config && !klass->ready_for_ip_config(self))
+    if (klass->ready_for_ip_config && !klass->ready_for_ip_config(self, FALSE))
         goto out_devip;
 
     if (IS_IPv4) {
@@ -11887,7 +11900,7 @@ activate_stage3_ip_config(NMDevice *self)
     }
 
     if (!nm_device_sys_iface_state_is_external(self)
-        && (!klass->ready_for_ip_config || klass->ready_for_ip_config(self))) {
+        && (!klass->ready_for_ip_config || klass->ready_for_ip_config(self, TRUE))) {
         if (priv->ipmanual_data.state_6 == NM_DEVICE_IP_STATE_NONE
             && !NM_IN_STRSET(ipv6_method,
                              NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
@@ -12682,6 +12695,16 @@ check_and_reapply_connection(NMDevice     *self,
         if (nm_g_hash_table_lookup(diffs, NM_SETTING_IP6_CONFIG_SETTING_NAME))
             priv->ip_data_6.do_reapply = TRUE;
 
+        if (nm_g_hash_table_contains_any(
+                nm_g_hash_table_lookup(diffs, NM_SETTING_CONNECTION_SETTING_NAME),
+                NM_SETTING_CONNECTION_LLDP,
+                NM_SETTING_CONNECTION_MDNS,
+                NM_SETTING_CONNECTION_LLMNR,
+                NM_SETTING_CONNECTION_DNS_OVER_TLS)) {
+            priv->ip_data_4.do_reapply = TRUE;
+            priv->ip_data_6.do_reapply = TRUE;
+        }
+
         nm_device_activate_schedule_stage3_ip_config(self, FALSE);
 
         _routing_rules_sync(self, NM_TERNARY_TRUE);
diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
index 80def125..d59aecb2 100644
--- a/src/core/devices/nm-device.h
+++ b/src/core/devices/nm-device.h
@@ -346,7 +346,7 @@ typedef struct _NMDeviceClass {
     NMActStageReturn (*act_stage1_prepare)(NMDevice *self, NMDeviceStateReason *out_failure_reason);
     NMActStageReturn (*act_stage2_config)(NMDevice *self, NMDeviceStateReason *out_failure_reason);
     void (*act_stage3_ip_config)(NMDevice *self, int addr_family);
-    gboolean (*ready_for_ip_config)(NMDevice *self);
+    gboolean (*ready_for_ip_config)(NMDevice *self, gboolean is_manual);
 
     const char *(*get_ip_method_auto)(NMDevice *self, int addr_family);
 
diff --git a/src/core/devices/ovs/nm-device-ovs-bridge.c b/src/core/devices/ovs/nm-device-ovs-bridge.c
index 683ada13..ea77dd18 100644
--- a/src/core/devices/ovs/nm-device-ovs-bridge.c
+++ b/src/core/devices/ovs/nm-device-ovs-bridge.c
@@ -67,7 +67,7 @@ get_generic_capabilities(NMDevice *device)
 }
 
 static gboolean
-ready_for_ip_config(NMDevice *device)
+ready_for_ip_config(NMDevice *device, gboolean is_manual)
 {
     return FALSE;
 }
diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c
index 6b9d3d7e..1f531a6f 100644
--- a/src/core/devices/ovs/nm-device-ovs-interface.c
+++ b/src/core/devices/ovs/nm-device-ovs-interface.c
@@ -198,7 +198,7 @@ set_platform_mtu(NMDevice *device, guint32 mtu)
 }
 
 static gboolean
-ready_for_ip_config(NMDevice *device)
+ready_for_ip_config(NMDevice *device, gboolean is_manual)
 {
     return nm_device_get_ip_ifindex(device) > 0;
 }
diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c
index 116f58c4..6ba52f40 100644
--- a/src/core/devices/ovs/nm-device-ovs-port.c
+++ b/src/core/devices/ovs/nm-device-ovs-port.c
@@ -61,7 +61,7 @@ get_generic_capabilities(NMDevice *device)
 }
 
 static gboolean
-ready_for_ip_config(NMDevice *device)
+ready_for_ip_config(NMDevice *device, gboolean is_manual)
 {
     return FALSE;
 }
diff --git a/src/core/devices/ovs/nm-ovs-factory.c b/src/core/devices/ovs/nm-ovs-factory.c
index 3ff0abf8..5aaa5c01 100644
--- a/src/core/devices/ovs/nm-ovs-factory.c
+++ b/src/core/devices/ovs/nm-ovs-factory.c
@@ -244,7 +244,11 @@ ovsdb_interface_failed(NMOvsdb         *ovsdb,
             TRUE);
     }
 
-    nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_OVSDB_FAILED);
+    if (nm_device_is_activating(device)) {
+        nm_device_state_changed(device,
+                                NM_DEVICE_STATE_FAILED,
+                                NM_DEVICE_STATE_REASON_OVSDB_FAILED);
+    }
 }
 
 static void
diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c
index 2572213c..04608d14 100644
--- a/src/core/devices/wifi/nm-device-wifi.c
+++ b/src/core/devices/wifi/nm-device-wifi.c
@@ -86,6 +86,7 @@ typedef struct {
     GCancellable *scan_request_cancellable;
 
     GSource *scan_request_delay_source;
+    GSource *roam_supplicant_wait_source;
 
     NMWifiAP *current_ap;
 
@@ -939,6 +940,7 @@ deactivate(NMDevice *device)
     int                  ifindex = nm_device_get_ifindex(device);
 
     nm_clear_g_source(&priv->periodic_update_id);
+    nm_clear_g_source_inst(&priv->roam_supplicant_wait_source);
 
     cleanup_association_attempt(self, TRUE);
 
@@ -2512,8 +2514,15 @@ supplicant_iface_state(NMDeviceWifi              *self,
                                                    : "Connected to wireless network",
                   (ssid_str = _nm_utils_ssid_to_string_gbytes(ssid)));
             nm_device_activate_schedule_stage3_ip_config(device, FALSE);
-        } else if (devstate == NM_DEVICE_STATE_ACTIVATED)
+        } else if (devstate == NM_DEVICE_STATE_ACTIVATED) {
             periodic_update(self);
+            if (priv->roam_supplicant_wait_source) {
+                _LOGD(LOGD_WIFI,
+                      "supplicant state settled after roaming, renew dynamic IP configuration");
+                nm_clear_g_source_inst(&priv->roam_supplicant_wait_source);
+                nm_device_update_dynamic_ip_setup(device);
+            }
+        }
         break;
     case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
         if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating(device)) {
@@ -2584,6 +2593,21 @@ supplicant_iface_assoc_cb(NMSupplicantInterface *iface, GError *error, gpointer
     }
 }
 
+static gboolean
+roam_supplicant_wait_timeout(gpointer user_data)
+{
+    NMDeviceWifi        *self = NM_DEVICE_WIFI(user_data);
+    NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self);
+
+    _LOGD(LOGD_WIFI, "timeout waiting for supplicant to settle after roaming");
+
+    /* Eventually we still want to restart DHCP when the supplicant
+     * becomes ready */
+    nm_clear_g_source_inst(&priv->roam_supplicant_wait_source);
+    priv->roam_supplicant_wait_source = g_source_ref(nm_g_source_sentinel_get(0));
+    return G_SOURCE_CONTINUE;
+}
+
 static void
 supplicant_iface_notify_current_bss(NMSupplicantInterface *iface,
                                     GParamSpec            *pspec,
@@ -2636,7 +2660,19 @@ supplicant_iface_notify_current_bss(NMSupplicantInterface *iface,
              * Also, some APs (e.g. Cisco) can be configured to drop
              * all traffic until DHCP completes. To support such
              * cases, renew the lease when roaming to a new AP. */
-            nm_device_update_dynamic_ip_setup(NM_DEVICE(self));
+
+            if (nm_supplicant_interface_get_state(priv->sup_iface)
+                == NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) {
+                nm_device_update_dynamic_ip_setup(NM_DEVICE(self));
+            } else {
+                /* Wait that the authentication to new the AP completes before
+                 * trying to renew, otherwise the DHCP REQUEST could be lost
+                 * and the client will fall back to a DISCOVER, potentially
+                 * getting a different address. */
+                nm_clear_g_source_inst(&priv->roam_supplicant_wait_source);
+                priv->roam_supplicant_wait_source =
+                    nm_g_timeout_add_source(10000, roam_supplicant_wait_timeout, self);
+            }
         }
 
         set_current_ap(self, new_ap, TRUE);
@@ -3743,6 +3779,7 @@ dispose(GObject *object)
     nm_assert(c_list_is_empty(&priv->scanning_prohibited_lst_head));
 
     nm_clear_g_source(&priv->periodic_update_id);
+    nm_clear_g_source_inst(&priv->roam_supplicant_wait_source);
 
     wifi_secrets_cancel(self);
 
diff --git a/src/core/devices/wifi/nm-iwd-manager.c b/src/core/devices/wifi/nm-iwd-manager.c
index 27222aae..2e0d51e5 100644
--- a/src/core/devices/wifi/nm-iwd-manager.c
+++ b/src/core/devices/wifi/nm-iwd-manager.c
@@ -306,7 +306,7 @@ iwd_agent_export(GDBusConnection *connection, gpointer user_data, char **agent_p
     unsigned int rnd;
     guint        id;
 
-    nm_utils_random_bytes(&rnd, sizeof(rnd));
+    nm_random_get_bytes(&rnd, sizeof(rnd));
 
     nm_sprintf_buf(path, "/agent/%u", rnd);
 
diff --git a/src/core/devices/wwan/nm-device-modem.c b/src/core/devices/wwan/nm-device-modem.c
index 77ba1b24..e0209aff 100644
--- a/src/core/devices/wwan/nm-device-modem.c
+++ b/src/core/devices/wwan/nm-device-modem.c
@@ -621,13 +621,13 @@ is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
 }
 
 static gboolean
-ready_for_ip_config(NMDevice *device)
+ready_for_ip_config(NMDevice *device, gboolean is_manual)
 {
-    /* Tell NMDevice to only run device-specific IP
+    /* Tell NMDevice to only run manual and device-specific IP
      * configuration (devip) and skip other methods
-     * (manual, dhcp, etc).
+     * (dhcp, link-local, shared, etc).
      */
-    return FALSE;
+    return is_manual;
 }
 
 /*****************************************************************************/
diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c
index cbf30f56..997fe727 100644
--- a/src/core/devices/wwan/nm-modem-broadband.c
+++ b/src/core/devices/wwan/nm-modem-broadband.c
@@ -1032,7 +1032,6 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho
         l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET),
                                      ifindex,
                                      NM_IP_CONFIG_SOURCE_WWAN);
-        nm_l3_config_data_set_dns_priority(l3cd, AF_INET, 0);
 
         address = (NMPlatformIP4Address){
             .address      = address_network,
@@ -1116,11 +1115,9 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho
 
         _LOGI("IPv6 base configuration:");
 
-        l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET),
+        l3cd    = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET),
                                      ifindex,
                                      NM_IP_CONFIG_SOURCE_WWAN);
-        nm_l3_config_data_set_dns_priority(l3cd, AF_INET6, 0);
-
         do_auto = TRUE;
 
         address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv6_config);