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-veth.c32
-rw-r--r--src/core/devices/nm-device.c128
-rw-r--r--src/core/devices/nm-device.h5
3 files changed, 69 insertions, 96 deletions
diff --git a/src/core/devices/nm-device-veth.c b/src/core/devices/nm-device-veth.c
index c3482e78..17115d33 100644
--- a/src/core/devices/nm-device-veth.c
+++ b/src/core/devices/nm-device-veth.c
@@ -81,11 +81,13 @@ create_and_realize(NMDevice              *device,
                    const NMPlatformLink **out_plink,
                    GError               **error)
 {
-    const char    *iface = nm_device_get_iface(device);
-    const char    *peer;
-    NMDevice      *peer_device;
-    NMSettingVeth *s_veth;
-    int            r;
+    NMPlatform           *platform = nm_device_get_platform(device);
+    const char           *iface    = nm_device_get_iface(device);
+    NMSettingVeth        *s_veth;
+    const NMPlatformLink *plink;
+    const NMPlatformLink *peer_plink;
+    int                   peer_ifindex;
+    int                   r;
 
     s_veth = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VETH);
     if (!s_veth) {
@@ -98,15 +100,23 @@ create_and_realize(NMDevice              *device,
         return FALSE;
     }
 
-    peer        = nm_setting_veth_get_peer(s_veth);
-    peer_device = nm_manager_get_device(NM_MANAGER_GET, peer, NM_DEVICE_TYPE_VETH);
-    if (peer_device) {
-        if (nm_device_parent_get_device(peer_device))
-            /* The veth device and its peer already exist. No need to create it again. */
+    /* For veths, users can define two connection profiles referencing each
+     * other as 'veth.peer'. Only the first to be activated will actually
+     * create the veth pair; the other must detect that interfaces already
+     * exist and proceed. */
+    plink = nm_platform_link_get_by_ifname(platform, iface);
+    if (plink && nm_platform_link_veth_get_properties(platform, plink->ifindex, &peer_ifindex)) {
+        peer_plink = nm_platform_link_get(platform, peer_ifindex);
+        if (peer_plink && peer_plink->type == NM_LINK_TYPE_VETH
+            && nm_streq0(peer_plink->name, nm_setting_veth_get_peer(s_veth))) {
             return TRUE;
+        }
     }
 
-    r = nm_platform_link_veth_add(nm_device_get_platform(device), iface, peer, out_plink);
+    r = nm_platform_link_veth_add(nm_device_get_platform(device),
+                                  iface,
+                                  nm_setting_veth_get_peer(s_veth),
+                                  out_plink);
     if (r < 0) {
         g_set_error(error,
                     NM_DEVICE_ERROR,
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 059e31f2..a723bf7f 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -96,8 +96,6 @@
 #define NM_DEVICE_AUTH_RETRIES_INFINITY -2
 #define NM_DEVICE_AUTH_RETRIES_DEFAULT  3
 
-#define AUTOCONNECT_RESET_RETRIES_TIMER 300
-
 /*****************************************************************************/
 
 typedef void (*ActivationHandleFunc)(NMDevice *self);
@@ -763,9 +761,6 @@ typedef struct _NMDevicePrivate {
 
     GVariant *ports_variant; /* Array of port devices D-Bus path */
     char     *prop_ip_iface; /* IP interface D-Bus property */
-
-    int    autoconnect_retries;
-    gint32 autoconnect_retries_blocked_until;
 } NMDevicePrivate;
 
 G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT)
@@ -6397,7 +6392,8 @@ carrier_changed(NMDevice *self, gboolean carrier)
         if (carrier) {
             /* If needed, also resume IP configuration that is
              * waiting for carrier. */
-            if (priv->state == NM_DEVICE_STATE_IP_CONFIG)
+            if (priv->state >= NM_DEVICE_STATE_IP_CONFIG
+                && priv->state <= NM_DEVICE_STATE_ACTIVATED)
                 nm_device_activate_schedule_stage3_ip_config(self, FALSE);
             return;
         }
@@ -12791,6 +12787,7 @@ reapply_connection(NMDevice *self, NMConnection *con_old, NMConnection *con_new)
  *   the current settings connection
  * @version_id: either zero, or the current version id for the applied
  *   connection.
+ * @reapply_flags: the #NMDeviceReapplyFlags.
  * @audit_args: on return, a string representing the changes
  * @error: the error if %FALSE is returned
  *
@@ -12800,11 +12797,12 @@ reapply_connection(NMDevice *self, NMConnection *con_old, NMConnection *con_new)
  * Return: %FALSE if the new configuration can not be reapplied.
  */
 static gboolean
-check_and_reapply_connection(NMDevice     *self,
-                             NMConnection *connection,
-                             guint64       version_id,
-                             char        **audit_args,
-                             GError      **error)
+check_and_reapply_connection(NMDevice            *self,
+                             NMConnection        *connection,
+                             guint64              version_id,
+                             NMDeviceReapplyFlags reapply_flags,
+                             char               **audit_args,
+                             GError             **error)
 {
     NMDeviceClass                 *klass         = NM_DEVICE_GET_CLASS(self);
     NMDevicePrivate               *priv          = NM_DEVICE_GET_PRIVATE(self);
@@ -12972,7 +12970,12 @@ check_and_reapply_connection(NMDevice     *self,
 
         reactivate_proxy_config(self);
 
-        nm_device_l3cfg_commit(self, NM_L3_CFG_COMMIT_TYPE_REAPPLY, FALSE);
+        nm_device_l3cfg_commit(
+            self,
+            NM_FLAGS_HAS(reapply_flags, NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP)
+                ? NM_L3_CFG_COMMIT_TYPE_UPDATE
+                : NM_L3_CFG_COMMIT_TYPE_REAPPLY,
+            FALSE);
     }
 
     if (priv->state >= NM_DEVICE_STATE_IP_CHECK)
@@ -12989,12 +12992,18 @@ nm_device_reapply(NMDevice *self, NMConnection *connection, GError **error)
 {
     g_return_val_if_fail(NM_IS_DEVICE(self), FALSE);
 
-    return check_and_reapply_connection(self, connection, 0, NULL, error);
+    return check_and_reapply_connection(self,
+                                        connection,
+                                        0,
+                                        NM_DEVICE_REAPPLY_FLAGS_NONE,
+                                        NULL,
+                                        error);
 }
 
 typedef struct {
-    NMConnection *connection;
-    guint64       version_id;
+    NMConnection        *connection;
+    guint64              version_id;
+    NMDeviceReapplyFlags reapply_flags;
 } ReapplyData;
 
 static void
@@ -13005,16 +13014,16 @@ reapply_cb(NMDevice              *self,
            gpointer               user_data)
 {
     ReapplyData                  *reapply_data = user_data;
-    guint64                       version_id   = 0;
-    gs_unref_object NMConnection *connection   = NULL;
-    GError                       *local        = NULL;
-    gs_free char                 *audit_args   = NULL;
+    guint64                       version_id;
+    gs_unref_object NMConnection *connection = NULL;
+    NMDeviceReapplyFlags          reapply_flags;
+    GError                       *local      = NULL;
+    gs_free char                 *audit_args = NULL;
 
-    if (reapply_data) {
-        connection = reapply_data->connection;
-        version_id = reapply_data->version_id;
-        g_slice_free(ReapplyData, reapply_data);
-    }
+    connection    = reapply_data->connection;
+    version_id    = reapply_data->version_id;
+    reapply_flags = reapply_data->reapply_flags;
+    nm_g_slice_free(reapply_data);
 
     if (error) {
         nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY,
@@ -13034,6 +13043,7 @@ reapply_cb(NMDevice              *self,
                                       connection
                                           ?: nm_device_get_settings_connection_get_connection(self),
                                       version_id,
+                                      reapply_flags,
                                       &audit_args,
                                       &local)) {
         nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY,
@@ -13067,12 +13077,12 @@ impl_device_reapply(NMDBusObject                      *obj,
     ReapplyData               *reapply_data;
     gs_unref_variant GVariant *settings = NULL;
     guint64                    version_id;
-    guint32                    flags;
+    guint32                    reapply_flags_u;
+    NMDeviceReapplyFlags       reapply_flags;
 
-    g_variant_get(parameters, "(@a{sa{sv}}tu)", &settings, &version_id, &flags);
+    g_variant_get(parameters, "(@a{sa{sv}}tu)", &settings, &version_id, &reapply_flags_u);
 
-    /* No flags supported as of now. */
-    if (flags != 0) {
+    if (NM_FLAGS_ANY(reapply_flags_u, ~((guint32) NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP))) {
         error =
             g_error_new_literal(NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "Invalid flags specified");
         nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY,
@@ -13085,6 +13095,9 @@ impl_device_reapply(NMDBusObject                      *obj,
         return;
     }
 
+    reapply_flags = reapply_flags_u;
+    nm_assert(reapply_flags_u == reapply_flags);
+
     if (priv->state < NM_DEVICE_STATE_PREPARE || priv->state > NM_DEVICE_STATE_ACTIVATED) {
         error = g_error_new_literal(NM_DEVICE_ERROR,
                                     NM_DEVICE_ERROR_NOT_ACTIVE,
@@ -13122,12 +13135,12 @@ impl_device_reapply(NMDBusObject                      *obj,
         nm_connection_clear_secrets(connection);
     }
 
-    if (connection || version_id) {
-        reapply_data             = g_slice_new(ReapplyData);
-        reapply_data->connection = connection;
-        reapply_data->version_id = version_id;
-    } else
-        reapply_data = NULL;
+    reapply_data  = g_slice_new(ReapplyData);
+    *reapply_data = (ReapplyData){
+        .connection    = connection,
+        .version_id    = version_id,
+        .reapply_flags = reapply_flags,
+    };
 
     nm_device_auth_request(self,
                            invocation,
@@ -13163,7 +13176,7 @@ impl_device_get_applied_connection(NMDBusObject                      *obj,
     if (flags != 0) {
         g_dbus_method_invocation_return_error_literal(invocation,
                                                       NM_DEVICE_ERROR,
-                                                      NM_DEVICE_ERROR_FAILED,
+                                                      NM_DEVICE_ERROR_INVALID_ARGUMENT,
                                                       "Invalid flags specified");
         return;
     }
@@ -16881,49 +16894,6 @@ nm_device_get_initial_hw_address(NMDevice *self)
     return NM_DEVICE_GET_PRIVATE(self)->hw_addr_initial;
 }
 
-void
-nm_device_set_autoconnect_retries(NMDevice *self, int tries)
-{
-    NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
-    if (priv->autoconnect_retries != tries) {
-        _LOGT(LOGD_DEVICE, "autoconnect: retries set %d", tries);
-        priv->autoconnect_retries = tries;
-    }
-
-    if (tries)
-        priv->autoconnect_retries_blocked_until = 0; /* we are not blocked anymore */
-    else
-        priv->autoconnect_retries_blocked_until =
-            nm_utils_get_monotonic_timestamp_sec() + AUTOCONNECT_RESET_RETRIES_TIMER;
-}
-
-int
-nm_device_get_autoconnect_retries(NMDevice *self)
-{
-    NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
-    return priv->autoconnect_retries;
-}
-
-gint32
-nm_device_autoconnect_retries_blocked_until(NMDevice *self)
-{
-    NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
-    return priv->autoconnect_retries_blocked_until;
-}
-
-void
-nm_device_autoconnect_retries_reset(NMDevice *self)
-{
-    NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
-    /* default value, we will sync. with connection value when needed */
-    priv->autoconnect_retries               = -2;
-    priv->autoconnect_retries_blocked_until = 0;
-}
-
 /**
  * nm_device_spec_match_list:
  * @self: an #NMDevice
@@ -17675,8 +17645,6 @@ nm_device_init(NMDevice *self)
     priv->sys_iface_state_      = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL;
 
     priv->promisc_reset = NM_OPTION_BOOL_DEFAULT;
-
-    priv->autoconnect_retries = -2;
 }
 
 static GObject *
diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
index fea46bb7..de850e68 100644
--- a/src/core/devices/nm-device.h
+++ b/src/core/devices/nm-device.h
@@ -464,11 +464,6 @@ const char *nm_device_get_permanent_hw_address_full(NMDevice *self,
                                                     gboolean *out_is_fake);
 const char *nm_device_get_initial_hw_address(NMDevice *dev);
 
-void   nm_device_set_autoconnect_retries(NMDevice *self, int tries);
-int    nm_device_get_autoconnect_retries(NMDevice *self);
-gint32 nm_device_autoconnect_retries_blocked_until(NMDevice *self);
-void   nm_device_autoconnect_retries_reset(NMDevice *self);
-
 NMDhcpConfig *nm_device_get_dhcp_config(NMDevice *dev, int addr_family);
 
 NML3Cfg *nm_device_get_l3cfg(NMDevice *self);