summary refs log tree commit diff
path: root/src/nmtui
diff options
context:
space:
mode:
Diffstat (limited to 'src/nmtui')
-rw-r--r--src/nmtui/meson.build1
-rw-r--r--src/nmtui/nm-editor-utils.c8
-rw-r--r--src/nmtui/nmt-connect-connection-list.c1
-rw-r--r--src/nmtui/nmt-editor.c45
-rw-r--r--src/nmtui/nmt-page-loopback.c68
-rw-r--r--src/nmtui/nmt-page-loopback.h33
6 files changed, 137 insertions, 19 deletions
diff --git a/src/nmtui/meson.build b/src/nmtui/meson.build
index eecfaa99..40bb40b9 100644
--- a/src/nmtui/meson.build
+++ b/src/nmtui/meson.build
@@ -28,6 +28,7 @@ executable(
     'nmt-page-ip4.c',
     'nmt-page-ip6.c',
     'nmt-page-ip-tunnel.c',
+    'nmt-page-loopback.c',
     'nmt-page-macsec.c',
     'nmt-page-ppp.c',
     'nmt-page-team.c',
diff --git a/src/nmtui/nm-editor-utils.c b/src/nmtui/nm-editor-utils.c
index 73fad6d1..7997a8ce 100644
--- a/src/nmtui/nm-editor-utils.c
+++ b/src/nmtui/nm-editor-utils.c
@@ -156,6 +156,14 @@ nm_editor_utils_get_connection_type_list(void)
     item->id_format         = _("Veth connection %d");
     g_ptr_array_add(array, item);
 
+    item                    = g_new0(NMEditorConnectionTypeDataReal, 1);
+    item->data.name         = _("Loopback");
+    item->data.setting_type = NM_TYPE_SETTING_LOOPBACK;
+    item->data.device_type  = NM_TYPE_DEVICE_LOOPBACK;
+    item->data.virtual      = TRUE;
+    item->id_format         = _("Loopback connection %d");
+    g_ptr_array_add(array, item);
+
     item                        = g_new0(NMEditorConnectionTypeDataReal, 1);
     item->data.name             = _("Wi-Fi");
     item->data.setting_type     = NM_TYPE_SETTING_WIRELESS;
diff --git a/src/nmtui/nmt-connect-connection-list.c b/src/nmtui/nmt-connect-connection-list.c
index 1fd44b29..8e7dc807 100644
--- a/src/nmtui/nmt-connect-connection-list.c
+++ b/src/nmtui/nmt-connect-connection-list.c
@@ -95,6 +95,7 @@ static const char *device_sort_order[]   = {"NMDeviceEthernet",
                                             "NMDeviceVeth",
                                             "NMDeviceInfiniband",
                                             "NMDeviceWifi",
+                                            "NMDeviceLoopback",
                                             NM_SETTING_VLAN_SETTING_NAME,
                                             NM_SETTING_VETH_SETTING_NAME,
                                             NM_SETTING_BOND_SETTING_NAME,
diff --git a/src/nmtui/nmt-editor.c b/src/nmtui/nmt-editor.c
index 6205736a..474d08c2 100644
--- a/src/nmtui/nmt-editor.c
+++ b/src/nmtui/nmt-editor.c
@@ -35,6 +35,7 @@
 #include "nmt-page-ip-tunnel.h"
 #include "nmt-page-ip4.h"
 #include "nmt-page-ip6.h"
+#include "nmt-page-loopback.h"
 #include "nmt-page-macsec.h"
 #include "nmt-page-ppp.h"
 #include "nmt-page-team.h"
@@ -299,13 +300,13 @@ add_sections_for_page(NmtEditor *editor, NmtEditorGrid *grid, NmtEditorPage *pag
 static void
 nmt_editor_constructed(GObject *object)
 {
-    NmtEditor           *editor = NMT_EDITOR(object);
-    NmtEditorPrivate    *priv   = NMT_EDITOR_GET_PRIVATE(editor);
+    NmtEditor           *editor   = NMT_EDITOR(object);
+    NmtEditorPrivate    *priv     = NMT_EDITOR_GET_PRIVATE(editor);
+    NmtDeviceEntry      *deventry = NULL;
     NMSettingConnection *s_con;
     NmtNewtWidget       *vbox, *widget, *buttons;
     NmtEditorGrid       *grid;
     const char          *deventry_label;
-    NmtDeviceEntry      *deventry;
     GType                hardware_type;
     const char          *port_type;
     NmtEditorPage       *page;
@@ -337,22 +338,26 @@ nmt_editor_constructed(GObject *object)
     else
         hardware_type = priv->type_data->device_type;
 
-    /* For connections involving multiple network devices, clarify which one
-     * NMSettingConnection:interface-name refers to.
-     */
-    if (nm_connection_is_type(priv->edit_connection, NM_SETTING_PPPOE_SETTING_NAME))
-        deventry_label = _("Ethernet device");
-    else
-        deventry_label = _("Device");
-
-    widget = nmt_device_entry_new(deventry_label, 40, hardware_type);
-    nmt_editor_grid_append(grid, NULL, widget, NULL);
-    deventry = NMT_DEVICE_ENTRY(widget);
-    g_object_bind_property(s_con,
-                           NM_SETTING_CONNECTION_INTERFACE_NAME,
-                           deventry,
-                           "interface-name",
-                           G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+    if (nm_connection_is_type(priv->edit_connection, NM_SETTING_LOOPBACK_SETTING_NAME)) {
+        g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "lo", NULL);
+    } else {
+        /* For connections involving multiple network devices, clarify which one
+        * NMSettingConnection:interface-name refers to.
+        */
+        if (nm_connection_is_type(priv->edit_connection, NM_SETTING_PPPOE_SETTING_NAME))
+            deventry_label = _("Ethernet device");
+        else
+            deventry_label = _("Device");
+
+        widget = nmt_device_entry_new(deventry_label, 40, hardware_type);
+        nmt_editor_grid_append(grid, NULL, widget, NULL);
+        deventry = NMT_DEVICE_ENTRY(widget);
+        g_object_bind_property(s_con,
+                               NM_SETTING_CONNECTION_INTERFACE_NAME,
+                               deventry,
+                               "interface-name",
+                               G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+    }
 
     nmt_editor_grid_append(grid, NULL, nmt_newt_separator_new(), NULL);
 
@@ -376,6 +381,8 @@ nmt_editor_constructed(GObject *object)
         page = nmt_page_vlan_new(priv->edit_connection, deventry);
     else if (nm_connection_is_type(priv->edit_connection, NM_SETTING_WIRED_SETTING_NAME))
         page = nmt_page_ethernet_new(priv->edit_connection, deventry);
+    else if (nm_connection_is_type(priv->edit_connection, NM_SETTING_LOOPBACK_SETTING_NAME))
+        page = nmt_page_loopback_new(priv->edit_connection);
     else if (nm_connection_is_type(priv->edit_connection, NM_SETTING_WIRELESS_SETTING_NAME))
         page = nmt_page_wifi_new(priv->edit_connection, deventry);
     else if (nm_connection_is_type(priv->edit_connection, NM_SETTING_IP_TUNNEL_SETTING_NAME))
diff --git a/src/nmtui/nmt-page-loopback.c b/src/nmtui/nmt-page-loopback.c
new file mode 100644
index 00000000..e0800168
--- /dev/null
+++ b/src/nmtui/nmt-page-loopback.c
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2025 Red Hat, Inc.
+ */
+/**
+ * SECTION:nmt-page-loopback
+ * @short_description: The editor page for the loopback interface
+ */
+
+#include "libnm-client-aux-extern/nm-default-client.h"
+
+#include <linux/if_ether.h>
+
+#include "nmt-page-loopback.h"
+
+#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
+#include "nmt-mtu-entry.h"
+
+G_DEFINE_TYPE(NmtPageLoopback, nmt_page_loopback, NMT_TYPE_EDITOR_PAGE_DEVICE)
+
+#define NMT_PAGE_LOOPBACK_GET_PRIVATE(o) \
+    _NM_GET_PRIVATE(self, NmtPageLoopback, NMT_IS_PAGE_LOOPBACK)
+
+static void
+nmt_page_loopback_init(NmtPageLoopback *loopback)
+{}
+
+NmtEditorPage *
+nmt_page_loopback_new(NMConnection *conn)
+{
+    return g_object_new(NMT_TYPE_PAGE_LOOPBACK, "connection", conn, NULL);
+}
+
+static void
+nmt_page_loopback_constructed(GObject *object)
+{
+    NmtPageLoopback   *loopback = NMT_PAGE_LOOPBACK(object);
+    NmtEditorSection  *section;
+    NmtEditorGrid     *grid;
+    NMSettingLoopback *s_loopback;
+    NmtNewtWidget     *widget;
+    NMConnection      *conn;
+
+    conn       = nmt_editor_page_get_connection(NMT_EDITOR_PAGE(loopback));
+    s_loopback = _nm_connection_ensure_setting(conn, NM_TYPE_SETTING_LOOPBACK);
+
+    section = nmt_editor_section_new(_("LOOPBACK"), NULL, FALSE);
+    grid    = nmt_editor_section_get_body(section);
+
+    widget = nmt_mtu_entry_new();
+    g_object_bind_property(s_loopback,
+                           NM_SETTING_LOOPBACK_MTU,
+                           widget,
+                           "mtu",
+                           G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+    nmt_editor_grid_append(grid, _("MTU"), widget, NULL);
+
+    nmt_editor_page_add_section(NMT_EDITOR_PAGE(loopback), section);
+
+    G_OBJECT_CLASS(nmt_page_loopback_parent_class)->constructed(object);
+}
+
+static void
+nmt_page_loopback_class_init(NmtPageLoopbackClass *loopback_class)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(loopback_class);
+    object_class->constructed  = nmt_page_loopback_constructed;
+}
diff --git a/src/nmtui/nmt-page-loopback.h b/src/nmtui/nmt-page-loopback.h
new file mode 100644
index 00000000..12c38ef8
--- /dev/null
+++ b/src/nmtui/nmt-page-loopback.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2025 Red Hat, Inc.
+ */
+
+#ifndef NMT_PAGE_LOOPBACK_H
+#define NMT_PAGE_LOOPBACK_H
+
+#include "nmt-editor-page-device.h"
+
+#define NMT_TYPE_PAGE_LOOPBACK (nmt_page_loopback_get_type())
+#define NMT_PAGE_LOOPBACK(obj) \
+    (_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NMT_TYPE_PAGE_LOOPBACK, NmtPageLoopback))
+#define NMT_PAGE_LOOPBACK_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST((klass), NMT_TYPE_PAGE_LOOPBACK, NmtPageLoopbackClass))
+#define NMT_IS_PAGE_LOOPBACK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMT_TYPE_PAGE_LOOPBACK))
+#define NMT_IS_PAGE_LOOPBACK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NMT_TYPE_PAGE_LOOPBACK))
+#define NMT_PAGE_LOOPBACK_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS((obj), NMT_TYPE_PAGE_LOOPBACK, NmtPageLoopbackClass))
+
+typedef struct {
+    NmtEditorPageDevice parent;
+} NmtPageLoopback;
+
+typedef struct {
+    NmtEditorPageDeviceClass parent;
+} NmtPageLoopbackClass;
+
+GType nmt_page_loopback_get_type(void);
+
+NmtEditorPage *nmt_page_loopback_new(NMConnection *conn);
+
+#endif /* NMT_PAGE_LOOPBACK_H */