summary refs log tree commit diff
path: root/src/core/devices/nm-device-bond.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/devices/nm-device-bond.c')
-rw-r--r--src/core/devices/nm-device-bond.c99
1 files changed, 67 insertions, 32 deletions
diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c
index b208e2c0..f7d78f57 100644
--- a/src/core/devices/nm-device-bond.c
+++ b/src/core/devices/nm-device-bond.c
@@ -14,8 +14,10 @@
 #include "nm-device-private.h"
 #include "libnm-platform/nm-platform.h"
 #include "nm-device-factory.h"
+#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
 #include "libnm-core-intern/nm-core-internal.h"
 #include "nm-ip4-config.h"
+#include "nm-setting-bond-port.h"
 
 #define _NMLOG_DEVICE_TYPE NMDeviceBond
 #include "nm-device-logging.h"
@@ -79,8 +81,6 @@ complete_connection(NMDevice *           device,
                     NMConnection *const *existing_connections,
                     GError **            error)
 {
-    NMSettingBond *s_bond;
-
     nm_utils_complete_generic(nm_device_get_platform(device),
                               connection,
                               NM_SETTING_BOND_SETTING_NAME,
@@ -91,11 +91,7 @@ complete_connection(NMDevice *           device,
                               NULL,
                               TRUE);
 
-    s_bond = nm_connection_get_setting_bond(connection);
-    if (!s_bond) {
-        s_bond = (NMSettingBond *) nm_setting_bond_new();
-        nm_connection_add_setting(connection, NM_SETTING(s_bond));
-    }
+    _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND);
 
     return TRUE;
 }
@@ -168,16 +164,11 @@ static void
 update_connection(NMDevice *device, NMConnection *connection)
 {
     NMDeviceBond * self    = NM_DEVICE_BOND(device);
-    NMSettingBond *s_bond  = nm_connection_get_setting_bond(connection);
+    NMSettingBond *s_bond  = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND);
     int            ifindex = nm_device_get_ifindex(device);
     NMBondMode     mode    = NM_BOND_MODE_UNKNOWN;
     const char **  options;
 
-    if (!s_bond) {
-        s_bond = (NMSettingBond *) nm_setting_bond_new();
-        nm_connection_add_setting(connection, (NMSetting *) s_bond);
-    }
-
     /* Read bond options from sysfs and update the Bond setting to match */
     options = nm_setting_bond_get_valid_options(NULL);
     for (; options[0]; options++) {
@@ -225,11 +216,29 @@ update_connection(NMDevice *device, NMConnection *connection)
 }
 
 static gboolean
-master_update_slave_connection(NMDevice *    self,
-                               NMDevice *    slave,
-                               NMConnection *connection,
-                               GError **     error)
+controller_update_port_connection(NMDevice *    self,
+                                  NMDevice *    port,
+                                  NMConnection *connection,
+                                  GError **     error)
 {
+    NMSettingBondPort *s_port;
+    int                ifindex_port = nm_device_get_ifindex(port);
+    uint               queue_id     = NM_BOND_PORT_QUEUE_ID_DEF;
+    gs_free char *     queue_id_str = NULL;
+
+    g_return_val_if_fail(ifindex_port > 0, FALSE);
+
+    s_port = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND_PORT);
+
+    queue_id_str =
+        nm_platform_sysctl_slave_get_option(nm_device_get_platform(self), ifindex_port, "queue_id");
+    if (queue_id_str) {
+        queue_id =
+            _nm_utils_ascii_str_to_int64(queue_id_str, 10, 0, 65535, NM_BOND_PORT_QUEUE_ID_DEF);
+        g_object_set(s_port, NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL);
+    } else
+        _LOGW(LOGD_BOND, "failed to read bond port setting '%s'", NM_SETTING_BOND_PORT_QUEUE_ID);
+
     g_object_set(nm_connection_get_setting_connection(connection),
                  NM_SETTING_CONNECTION_MASTER,
                  nm_device_get_iface(self),
@@ -250,9 +259,8 @@ set_arp_targets(NMDevice *device, const char *cur_arp_ip_target, const char *new
     gsize                        i;
     gsize                        j;
 
-    cur_strv = nm_utils_strsplit_set_full(cur_arp_ip_target,
-                                          NM_ASCII_SPACES,
-                                          NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP);
+    cur_strv =
+        nm_strsplit_set_full(cur_arp_ip_target, NM_ASCII_SPACES, NM_STRSPLIT_SET_FLAGS_STRSTRIP);
     new_strv = nm_utils_bond_option_arp_ip_targets_split(new_arp_ip_target);
 
     cur_len = NM_PTRARRAY_LEN(cur_strv);
@@ -276,7 +284,7 @@ set_arp_targets(NMDevice *device, const char *cur_arp_ip_target, const char *new
                 }
             }
 
-            if (nm_utils_strv_find_first((char **) new_strv, i, s) < 0)
+            if (nm_strv_find_first(new_strv, i, s) < 0)
                 new_strv[j++] = s;
         }
         new_strv[j] = NULL;
@@ -286,7 +294,7 @@ set_arp_targets(NMDevice *device, const char *cur_arp_ip_target, const char *new
     if (cur_len == 0 && new_len == 0)
         return;
 
-    if (nm_utils_strv_equal(cur_strv, new_strv))
+    if (nm_strv_equal(cur_strv, new_strv))
         return;
 
     for (i = 0; i < cur_len; i++)
@@ -395,30 +403,57 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
     return ret;
 }
 
+static void
+commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *s_port)
+{
+    char queue_id_str[IFNAMSIZ + NM_STRLEN(":") + 5 + 100];
+
+    /*
+     * The queue-id of bond port is read only, we should modify bond interface using:
+     *    echo "eth1:2" > /sys/class/net/bond0/bonding/queue_id
+     * Kernel allows parital editing, so no need to care about other bond ports.
+     */
+    g_snprintf(queue_id_str,
+               sizeof(queue_id_str),
+               "%s:%" G_GUINT32_FORMAT,
+               nm_device_get_iface(port),
+               s_port ? nm_setting_bond_port_get_queue_id(s_port) : NM_BOND_PORT_QUEUE_ID_DEF);
+
+    nm_platform_sysctl_master_set_option(nm_device_get_platform(bond_device),
+                                         nm_device_get_ifindex(bond_device),
+                                         "queue_id",
+                                         queue_id_str);
+}
+
 static gboolean
-enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure)
+enslave_slave(NMDevice *device, NMDevice *port, NMConnection *connection, gboolean configure)
 {
-    NMDeviceBond *self = NM_DEVICE_BOND(device);
+    NMDeviceBond *     self = NM_DEVICE_BOND(device);
+    NMSettingBondPort *s_port;
 
-    nm_device_master_check_slave_physical_port(device, slave, LOGD_BOND);
+    nm_device_master_check_slave_physical_port(device, port, LOGD_BOND);
 
     if (configure) {
         gboolean success;
 
-        nm_device_take_down(slave, TRUE);
+        nm_device_take_down(port, TRUE);
         success = nm_platform_link_enslave(nm_device_get_platform(device),
                                            nm_device_get_ip_ifindex(device),
-                                           nm_device_get_ip_ifindex(slave));
-        nm_device_bring_up(slave, TRUE, NULL);
+                                           nm_device_get_ip_ifindex(port));
+        nm_device_bring_up(port, TRUE, NULL);
 
         if (!success) {
-            _LOGI(LOGD_BOND, "enslaved bond slave %s: failed", nm_device_get_ip_iface(slave));
+            _LOGI(LOGD_BOND, "assigning bond port %s: failed", nm_device_get_ip_iface(port));
             return FALSE;
         }
 
-        _LOGI(LOGD_BOND, "enslaved bond slave %s", nm_device_get_ip_iface(slave));
+        s_port = _nm_connection_get_setting(connection, NM_TYPE_SETTING_BOND_PORT);
+
+        commit_port_options(device, port, s_port);
+
+        _LOGI(LOGD_BOND, "assigned bond port %s", nm_device_get_ip_iface(port));
     } else
-        _LOGI(LOGD_BOND, "bond slave %s was enslaved", nm_device_get_ip_iface(slave));
+        _LOGI(LOGD_BOND, "bond port %s was assigned", nm_device_get_ip_iface(port));
 
     return TRUE;
 }
@@ -624,7 +659,7 @@ nm_device_bond_class_init(NMDeviceBondClass *klass)
     device_class->complete_connection      = complete_connection;
 
     device_class->update_connection              = update_connection;
-    device_class->master_update_slave_connection = master_update_slave_connection;
+    device_class->master_update_slave_connection = controller_update_port_connection;
 
     device_class->create_and_realize = create_and_realize;
     device_class->act_stage1_prepare = act_stage1_prepare;