summary refs log tree commit diff
path: root/src/devices
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/nm-device-bridge.c14
-rw-r--r--src/devices/nm-device.c16
-rw-r--r--src/devices/nm-device.h11
-rw-r--r--src/devices/ovs/nm-ovsdb.c50
-rw-r--r--src/devices/wifi/nm-device-wifi.c10
-rw-r--r--src/devices/wifi/nm-iwd-manager.c5
-rw-r--r--src/devices/wifi/nm-wifi-ap.c18
-rw-r--r--src/devices/wwan/nm-modem-broadband.c7
8 files changed, 100 insertions, 31 deletions
diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c
index 3c27b349..48dcec1b 100644
--- a/src/devices/nm-device-bridge.c
+++ b/src/devices/nm-device-bridge.c
@@ -1027,6 +1027,7 @@ create_and_realize(NMDevice *             device,
                    const NMPlatformLink **out_plink,
                    GError **              error)
 {
+    NMSettingWired *    s_wired;
     NMSettingBridge *   s_bridge;
     const char *        iface = nm_device_get_iface(device);
     const char *        hwaddr;
@@ -1034,12 +1035,17 @@ create_and_realize(NMDevice *             device,
     guint8              mac_address[NM_UTILS_HWADDR_LEN_MAX];
     NMPlatformLnkBridge props;
     int                 r;
+    guint32             mtu = 0;
 
     nm_assert(iface);
 
     s_bridge = nm_connection_get_setting_bridge(connection);
     nm_assert(s_bridge);
 
+    s_wired = nm_connection_get_setting_wired(connection);
+    if (s_wired)
+        mtu = nm_setting_wired_get_mtu(s_wired);
+
     hwaddr = nm_setting_bridge_get_mac_address(s_bridge);
     if (!hwaddr
         && nm_device_hw_addr_get_cloned(device, connection, FALSE, &hwaddr_cloned, NULL, NULL)) {
@@ -1097,10 +1103,17 @@ create_and_realize(NMDevice *             device,
 
     to_sysfs_group_address_sys(nm_setting_bridge_get_group_address(s_bridge), &props.group_addr);
 
+    /* If mtu != 0, we set the MTU of the new bridge at creation time. However, kernel will still
+     * automatically adjust the MTU of the bridge based on the minimum of the slave's MTU.
+     * We don't want this automatism as the user asked for a fixed MTU.
+     *
+     * To workaround this behavior of kernel, we will later toggle the MTU twice. See
+     * NMDeviceClass.mtu_force_set. */
     r = nm_platform_link_bridge_add(nm_device_get_platform(device),
                                     iface,
                                     hwaddr ? mac_address : NULL,
                                     hwaddr ? ETH_ALEN : 0,
+                                    mtu,
                                     &props,
                                     out_plink);
     if (r < 0) {
@@ -1152,6 +1165,7 @@ nm_device_bridge_class_init(NMDeviceBridgeClass *klass)
     device_class->link_types                = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_BRIDGE);
 
     device_class->is_master                   = TRUE;
+    device_class->mtu_force_set               = TRUE;
     device_class->get_generic_capabilities    = get_generic_capabilities;
     device_class->check_connection_compatible = check_connection_compatible;
     device_class->check_connection_available  = check_connection_available;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 2dab5075..0be05f23 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -659,6 +659,8 @@ typedef struct _NMDevicePrivate {
         guint64 tx_bytes;
         guint64 rx_bytes;
     } stats;
+
+    bool mtu_force_set_done : 1;
 } NMDevicePrivate;
 
 G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT)
@@ -10433,6 +10435,18 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config)
         }
     }
 
+    if (mtu_desired && NM_DEVICE_GET_CLASS(self)->mtu_force_set && !priv->mtu_force_set_done) {
+        priv->mtu_force_set_done = TRUE;
+
+        if (mtu_desired == mtu_plat) {
+            mtu_plat--;
+            if (NM_DEVICE_GET_CLASS(self)->set_platform_mtu(self, mtu_desired - 1)) {
+                _LOGD(LOGD_DEVICE, "mtu: force-set MTU to %u", mtu_desired - 1);
+            } else
+                _LOGW(LOGD_DEVICE, "mtu: failure to force-set MTU to %u", mtu_desired - 1);
+        }
+    }
+
     _LOGT(LOGD_DEVICE,
           "mtu: device-mtu: %u%s, ipv6-mtu: %u%s, ifindex: %d",
           (guint) mtu_desired,
@@ -15773,6 +15787,8 @@ _cleanup_generic_post(NMDevice *self, CleanupType cleanup_type)
 
     priv->linklocal6_dad_counter = 0;
 
+    priv->mtu_force_set_done = FALSE;
+
     /* Clean up IP configs; this does not actually deconfigure the
      * interface; the caller must flush routes and addresses explicitly.
      */
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 13782417..3eae9318 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -232,6 +232,17 @@ typedef struct _NMDeviceClass {
      * type (NMDeviceClass), not the actual device instance. */
     bool is_master : 1;
 
+    /* Force setting the MTU actually means first setting the MTU
+     * to (desired_MTU-1) and then setting the desired_MTU
+     * so that kernel actually applies the MTU, otherwise
+     * kernel will ignore the request if the link's MTU is the
+     * same as the desired one.
+     *
+     * This is just a workaround made for bridges (ATM) that employ
+     * a auto-MTU adjust mechanism if no MTU is manually set.
+     */
+    bool mtu_force_set : 1;
+
     void (*state_changed)(NMDevice *          device,
                           NMDeviceState       new_state,
                           NMDeviceState       old_state,
diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c
index 9826c1b7..27ef789f 100644
--- a/src/devices/ovs/nm-ovsdb.c
+++ b/src/devices/ovs/nm-ovsdb.c
@@ -707,7 +707,7 @@ _add_interface(NMOvsdb *     self,
     nm_auto_decref_json json_t *interfaces     = NULL;
     nm_auto_decref_json json_t *new_interfaces = NULL;
     gboolean                    has_interface  = FALSE;
-    gboolean                    interface_is_internal;
+    gboolean                    interface_is_local;
     gs_free char *              bridge_cloned_mac    = NULL;
     gs_free char *              interface_cloned_mac = NULL;
     GError *                    error                = NULL;
@@ -721,10 +721,10 @@ _add_interface(NMOvsdb *     self,
     new_ports      = json_array();
     new_interfaces = json_array();
 
-    bridge_name           = nm_connection_get_interface_name(bridge);
-    port_name             = nm_connection_get_interface_name(port);
-    interface_name        = nm_connection_get_interface_name(interface);
-    interface_is_internal = nm_streq0(bridge_name, interface_name);
+    bridge_name        = nm_connection_get_interface_name(bridge);
+    port_name          = nm_connection_get_interface_name(port);
+    interface_name     = nm_connection_get_interface_name(interface);
+    interface_is_local = nm_streq0(bridge_name, interface_name);
 
     /* Determine cloned MAC addresses */
     if (!nm_device_hw_addr_get_cloned(bridge_device,
@@ -733,7 +733,7 @@ _add_interface(NMOvsdb *     self,
                                       &bridge_cloned_mac,
                                       NULL,
                                       &error)) {
-        _LOGW("Cannot determine cloned mac for OVS %s '%s': %s",
+        _LOGW("Cannot determine cloned MAC for OVS %s '%s': %s",
               "bridge",
               bridge_name,
               error->message);
@@ -746,18 +746,34 @@ _add_interface(NMOvsdb *     self,
                                       &interface_cloned_mac,
                                       NULL,
                                       &error)) {
-        _LOGW("Cannot determine cloned mac for OVS %s '%s': %s",
+        _LOGW("Cannot determine cloned MAC for OVS %s '%s': %s",
               "interface",
               interface_name,
               error->message);
         g_clear_error(&error);
     }
 
-    if (interface_is_internal && !bridge_cloned_mac && interface_cloned_mac) {
-        _LOGT("'%s' is a local ovs-interface, the MAC will be set on ovs-bridge '%s'",
-              interface_name,
-              bridge_name);
-        bridge_cloned_mac = g_steal_pointer(&interface_cloned_mac);
+    /* For local interfaces, ovs complains if it finds a
+     * MAC address in the Interface table because it only takes
+     * the MAC from the Bridge table.
+     * Set any cloned MAC present in a local interface connection
+     * into the Bridge table, unless conflicting with the bridge MAC. */
+    if (interface_is_local && interface_cloned_mac) {
+        if (bridge_cloned_mac && !nm_streq(interface_cloned_mac, bridge_cloned_mac)) {
+            _LOGW("Cloned MAC '%s' of local ovs-interface '%s' conflicts with MAC '%s' of bridge "
+                  "'%s'",
+                  interface_cloned_mac,
+                  interface_name,
+                  bridge_cloned_mac,
+                  bridge_name);
+            nm_clear_g_free(&interface_cloned_mac);
+        } else {
+            nm_clear_g_free(&bridge_cloned_mac);
+            bridge_cloned_mac = g_steal_pointer(&interface_cloned_mac);
+            _LOGT("'%s' is a local ovs-interface, the MAC will be set on ovs-bridge '%s'",
+                  interface_name,
+                  bridge_name);
+        }
     }
 
     g_hash_table_iter_init(&iter, priv->bridges);
@@ -823,7 +839,7 @@ _add_interface(NMOvsdb *     self,
             g_return_if_fail(ovs_bridge);
             _expect_bridge_ports(params, ovs_bridge->name, ports);
             _set_bridge_ports(params, bridge_name, new_ports);
-            if (bridge_cloned_mac && interface_is_internal)
+            if (bridge_cloned_mac && interface_is_local)
                 _set_bridge_mac(params, bridge_name, bridge_cloned_mac);
         }
 
@@ -1175,8 +1191,12 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
     }
 
     if (ovs) {
-        iter          = json_object_iter(ovs);
-        priv->db_uuid = iter ? g_strdup(json_object_iter_key(iter)) : NULL;
+        const char *s;
+
+        iter = json_object_iter(ovs);
+        s    = json_object_iter_key(iter);
+        if (s)
+            nm_utils_strdup_reset(&priv->db_uuid, s);
     }
 
     /* Interfaces */
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 55062644..980916dd 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -1390,11 +1390,11 @@ _hw_addr_set_scanning(NMDeviceWifi *self, gboolean do_reset)
          * a new one.*/
         priv->hw_addr_scan_expire = now + SCAN_RAND_MAC_ADDRESS_EXPIRE_SEC;
 
-        generate_mac_address_mask =
-            nm_config_data_get_device_config(NM_CONFIG_GET_DATA,
-                                             "wifi.scan-generate-mac-address-mask",
-                                             device,
-                                             NULL);
+        generate_mac_address_mask = nm_config_data_get_device_config(
+            NM_CONFIG_GET_DATA,
+            NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_GENERATE_MAC_ADDRESS_MASK,
+            device,
+            NULL);
 
         priv->scan_last_request_started_at_msec = G_MININT64;
         priv->scan_periodic_next_msec           = 0;
diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c
index 6a562014..c7e99e0b 100644
--- a/src/devices/wifi/nm-iwd-manager.c
+++ b/src/devices/wifi/nm-iwd-manager.c
@@ -673,15 +673,16 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint
     gboolean             mapped;
     KnownNetworkData *   data;
     KnownNetworkId       id;
+    gs_free char *       ssid_str = NULL;
 
     id.security = nm_wifi_connection_get_iwd_security(conn, &mapped);
     if (!mapped)
         return;
 
     s_wireless = nm_connection_get_setting_wireless(conn);
-    id.name    = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wireless));
+    ssid_str   = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wireless));
+    id.name    = ssid_str;
     data       = g_hash_table_lookup(priv->known_networks, &id);
-    g_free((char *) id.name);
     if (!data)
         return;
 
diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
index fe26421d..55438a53 100644
--- a/src/devices/wifi/nm-wifi-ap.c
+++ b/src/devices/wifi/nm-wifi-ap.c
@@ -113,22 +113,26 @@ nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid)
 
     g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE);
 
-    if (ssid) {
-        l = g_bytes_get_size(ssid);
-        if (l == 0 || l > 32)
-            g_return_val_if_reached(FALSE);
+    if (!ssid) {
+        /* we don't clear the SSID, once we have it. We can only update
+         * it by a better value. */
+        return FALSE;
     }
 
+    l = g_bytes_get_size(ssid);
+    if (l == 0 || l > 32)
+        g_return_val_if_reached(FALSE);
+
     priv = NM_WIFI_AP_GET_PRIVATE(ap);
 
     if (ssid == priv->ssid)
         return FALSE;
-    if (ssid && priv->ssid && g_bytes_equal(ssid, priv->ssid))
+    if (priv->ssid && g_bytes_equal(ssid, priv->ssid))
         return FALSE;
 
+    g_bytes_ref(ssid);
     nm_clear_pointer(&priv->ssid, g_bytes_unref);
-    if (ssid)
-        priv->ssid = g_bytes_ref(ssid);
+    priv->ssid = ssid;
 
     _notify(ap, PROP_SSID);
     return TRUE;
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c
index 633878ce..7b3a13a3 100644
--- a/src/devices/wwan/nm-modem-broadband.c
+++ b/src/devices/wwan/nm-modem-broadband.c
@@ -39,8 +39,11 @@ MODEM_CAPS_3GPP(MMModemCapability caps)
 
 #define MODEM_CAPS_3GPP2(caps) (caps & (MM_MODEM_CAPABILITY_CDMA_EVDO))
 
-/* Maximum time to keep the DBus call waiting for a connection result */
-#define MODEM_CONNECT_TIMEOUT_SECS 120
+/* Maximum time to keep the DBus call waiting for a connection result.
+ * This value is greater than the default timeout in ModemManager (180s since
+ * 1.16), so that whenever possible the timeout happens first there instead of
+ * in NetworkManager. */
+#define MODEM_CONNECT_TIMEOUT_SECS 200
 
 /*****************************************************************************/