summary refs log tree commit diff
path: root/src/nmtui/nmt-page-bond.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nmtui/nmt-page-bond.c')
-rw-r--r--src/nmtui/nmt-page-bond.c112
1 files changed, 101 insertions, 11 deletions
diff --git a/src/nmtui/nmt-page-bond.c b/src/nmtui/nmt-page-bond.c
index f74bac27..eeea0b0b 100644
--- a/src/nmtui/nmt-page-bond.c
+++ b/src/nmtui/nmt-page-bond.c
@@ -21,7 +21,7 @@
 
 #include "libnm-core-aux-intern/nm-libnm-core-utils.h"
 #include "nmt-mac-entry.h"
-#include "nmt-address-list.h"
+#include "nmt-list.h"
 #include "nmt-port-list.h"
 
 G_DEFINE_TYPE(NmtPageBond, nmt_page_bond, NMT_TYPE_EDITOR_PAGE_DEVICE)
@@ -41,14 +41,15 @@ typedef struct {
     /* Note: when adding new options to the UI also ensure they are
      * initialized in bond_connection_setup_func()
      */
-    NmtNewtPopup   *mode;
-    NmtNewtEntry   *primary;
-    NmtNewtPopup   *monitoring;
-    NmtNewtEntry   *miimon;
-    NmtNewtEntry   *updelay;
-    NmtNewtEntry   *downdelay;
-    NmtNewtEntry   *arp_interval;
-    NmtAddressList *arp_ip_target;
+    NmtNewtPopup *mode;
+    NmtNewtEntry *primary;
+    NmtNewtPopup *monitoring;
+    NmtNewtEntry *miimon;
+    NmtNewtEntry *updelay;
+    NmtNewtEntry *downdelay;
+    NmtNewtEntry *arp_interval;
+    NmtList      *arp_ip_target;
+    NmtList      *other_options;
 
     NmtPageBondMonitoringMode monitoring_mode;
 
@@ -63,6 +64,45 @@ static void arp_ip_target_widget_changed(GObject *object, GParamSpec *pspec, gpo
 
 /*****************************************************************************/
 
+static gboolean
+_is_other_option(const char *option)
+{
+    return !NM_IN_STRSET(option,
+                         NM_SETTING_BOND_OPTION_MODE,
+                         NM_SETTING_BOND_OPTION_PRIMARY,
+                         NM_SETTING_BOND_OPTION_MIIMON,
+                         NM_SETTING_BOND_OPTION_UPDELAY,
+                         NM_SETTING_BOND_OPTION_DOWNDELAY,
+                         NM_SETTING_BOND_OPTION_ARP_INTERVAL,
+                         NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
+}
+
+static void
+_bond_update_other_options(NMSettingBond *s_bond, NmtList *list)
+{
+    gs_unref_ptrarray GPtrArray *arr      = g_ptr_array_new_with_free_func(g_free);
+    guint                        num_opts = nm_setting_bond_get_num_options(s_bond);
+    guint                        i;
+
+    for (i = 0; i < num_opts; i++) {
+        const char *opt_name;
+        const char *opt_value;
+        gboolean    ret;
+
+        ret = nm_setting_bond_get_option(s_bond, i, &opt_name, &opt_value);
+        nm_assert(ret);
+
+        if (_is_other_option(opt_name)) {
+            g_ptr_array_add(arr, g_strdup_printf("%s=%s", opt_name, opt_value));
+        }
+    }
+
+    g_ptr_array_add(arr, NULL);
+    g_object_set(G_OBJECT(list), "strings", arr->pdata, NULL);
+}
+
+/*****************************************************************************/
+
 NmtEditorPage *
 nmt_page_bond_new(NMConnection *conn, NmtDeviceEntry *deventry)
 {
@@ -155,6 +195,8 @@ bond_options_changed(GObject *object, GParamSpec *pspec, gpointer user_data)
     nmt_newt_widget_set_visible(NMT_NEWT_WIDGET(priv->arp_interval), !visible_mii);
     nmt_newt_widget_set_visible(NMT_NEWT_WIDGET(priv->arp_ip_target), !visible_mii);
 
+    _bond_update_other_options(s_bond, priv->other_options);
+
     priv->updating = FALSE;
 }
 
@@ -308,6 +350,49 @@ arp_ip_target_widget_changed(GObject *object, GParamSpec *pspec, gpointer user_d
     g_strfreev(ips);
 }
 
+static void
+other_options_widget_changed(GObject *object, GParamSpec *pspec, gpointer user_data)
+{
+    NmtPageBond        *bond          = NMT_PAGE_BOND(user_data);
+    NmtPageBondPrivate *priv          = NMT_PAGE_BOND_GET_PRIVATE(bond);
+    gs_strfreev char  **other_options = NULL;
+    const char         *name;
+    gboolean            ret;
+    guint               num;
+    guint               i;
+
+    if (priv->updating)
+        return;
+
+    priv->updating = TRUE;
+
+    g_object_get(G_OBJECT(priv->other_options), "strings", &other_options, NULL);
+
+again:
+    num = nm_setting_bond_get_num_options(priv->s_bond);
+    for (i = 0; i < num; i++) {
+        ret = nm_setting_bond_get_option(priv->s_bond, i, &name, NULL);
+        nm_assert(ret);
+
+        if (_is_other_option(name)) {
+            nm_setting_bond_remove_option(priv->s_bond, name);
+            goto again;
+        }
+    }
+
+    for (i = 0; other_options && other_options[i]; i++) {
+        char *val = strchr(other_options[i], '=');
+
+        if (val && val != other_options[i] && val[1]) {
+            *val = '\0';
+            if (_is_other_option(other_options[i]))
+                nm_setting_bond_add_option(priv->s_bond, other_options[i], val + 1);
+        }
+    }
+
+    priv->updating = FALSE;
+}
+
 static gboolean
 bond_connection_type_filter(GType connection_type, gpointer user_data)
 {
@@ -390,10 +475,15 @@ nmt_page_bond_constructed(GObject *object)
     nmt_editor_grid_append(grid, _("Monitoring frequency"), widget, label);
     priv->arp_interval = NMT_NEWT_ENTRY(widget);
 
-    widget = nmt_address_list_new(NMT_ADDRESS_LIST_IP4);
+    widget = nmt_list_new(NMT_LIST_IP4);
     g_signal_connect(widget, "notify::strings", G_CALLBACK(arp_ip_target_widget_changed), bond);
     nmt_editor_grid_append(grid, _("ARP targets"), widget, NULL);
-    priv->arp_ip_target = NMT_ADDRESS_LIST(widget);
+    priv->arp_ip_target = NMT_LIST(widget);
+
+    widget = nmt_list_new(NMT_LIST_KEY_VALUE);
+    g_signal_connect(widget, "notify::strings", G_CALLBACK(other_options_widget_changed), bond);
+    nmt_editor_grid_append(grid, _("Other options (key=value)"), widget, NULL);
+    priv->other_options = NMT_LIST(widget);
 
     widget = nmt_mac_entry_new(40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_CLONED_ETHERNET);
     g_object_bind_property(s_wired,