diff --git a/Makefile.am b/Makefile.am
index a86bf9029d..02aaf6a816 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1172,6 +1172,7 @@ src_libnm_core_impl_lib_h_pub_real = \
src/libnm-core-public/nm-setting-8021x.h \
src/libnm-core-public/nm-setting-adsl.h \
src/libnm-core-public/nm-setting-bluetooth.h \
+ src/libnm-core-public/nm-setting-bond-port.h \
src/libnm-core-public/nm-setting-bond.h \
src/libnm-core-public/nm-setting-bridge-port.h \
src/libnm-core-public/nm-setting-bridge.h \
@@ -1253,6 +1254,7 @@ src_libnm_core_impl_lib_c_settings_real = \
src/libnm-core-impl/nm-setting-adsl.c \
src/libnm-core-impl/nm-setting-bluetooth.c \
src/libnm-core-impl/nm-setting-bond.c \
+ src/libnm-core-impl/nm-setting-bond-port.c \
src/libnm-core-impl/nm-setting-bridge-port.c \
src/libnm-core-impl/nm-setting-bridge.c \
src/libnm-core-impl/nm-setting-cdma.c \
@@ -3412,6 +3414,7 @@ EXTRA_DIST += \
src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-eth-type \
src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-main \
src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-mode-numeric \
+ src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-port \
src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave \
src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave-ib \
src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-component \
@@ -5086,6 +5089,8 @@ src_nmtui_nmtui_SOURCES = \
src/nmtui/nmt-mtu-entry.h \
src/nmtui/nmt-page-bond.c \
src/nmtui/nmt-page-bond.h \
+ src/nmtui/nmt-page-bond-port.c \
+ src/nmtui/nmt-page-bond-port.h \
src/nmtui/nmt-page-bridge.c \
src/nmtui/nmt-page-bridge.h \
src/nmtui/nmt-page-bridge-port.c \
diff --git a/docs/libnm/libnm-docs.xml b/docs/libnm/libnm-docs.xml
index fad9552283..cb66c17e6f 100644
--- a/docs/libnm/libnm-docs.xml
+++ b/docs/libnm/libnm-docs.xml
@@ -315,6 +315,7 @@ print ("NetworkManager version " + client.get_version())]]>
+
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 597035e6f6..3d8ccafd7a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -83,6 +83,7 @@ src/libnm-core-impl/nm-setting-6lowpan.c
src/libnm-core-impl/nm-setting-8021x.c
src/libnm-core-impl/nm-setting-adsl.c
src/libnm-core-impl/nm-setting-bluetooth.c
+src/libnm-core-impl/nm-setting-bond-port.c
src/libnm-core-impl/nm-setting-bond.c
src/libnm-core-impl/nm-setting-bridge-port.c
src/libnm-core-impl/nm-setting-bridge.c
@@ -159,6 +160,7 @@ src/nmtui/nmt-edit-connection-list.c
src/nmtui/nmt-editor-section.c
src/nmtui/nmt-editor.c
src/nmtui/nmt-mtu-entry.c
+src/nmtui/nmt-page-bond-port.c
src/nmtui/nmt-page-bond.c
src/nmtui/nmt-page-bridge-port.c
src/nmtui/nmt-page-bridge.c
diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c
index 5222381d3a..f2262054f4 100644
--- a/src/core/devices/nm-device-bond.c
+++ b/src/core/devices/nm-device-bond.c
@@ -17,6 +17,7 @@
#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"
@@ -215,11 +216,33 @@ 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_get_setting_bond_port(connection);
+ if (!s_port) {
+ s_port = NM_SETTING_BOND_PORT(nm_setting_bond_port_new());
+ nm_connection_add_setting(connection, NM_SETTING(s_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),
@@ -384,30 +407,63 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
return ret;
}
-static gboolean
-enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure)
-{
- NMDeviceBond *self = NM_DEVICE_BOND(device);
+/*
+ * The queue id format is '$interface_name:$queue_id'
+ * The max queue 65535 hold 5 chars.
+ */
+#define _MAX_QUEUE_ID_STR_LEN 5 + IFNAMSIZ + 1 + 1
- nm_device_master_check_slave_physical_port(device, slave, LOGD_BOND);
+static void
+commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *set_port)
+{
+ char queue_id_str[_MAX_QUEUE_ID_STR_LEN];
+
+ /*
+ * 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.
+ */
+ snprintf(queue_id_str,
+ _MAX_QUEUE_ID_STR_LEN,
+ "%s:%" G_GUINT32_FORMAT,
+ nm_device_get_iface(port),
+ set_port ? nm_setting_bond_port_get_queue_id(set_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 *port, NMConnection *connection, gboolean configure)
+{
+ NMDeviceBond * self = NM_DEVICE_BOND(device);
+ NMSettingBondPort *s_port;
+
+ 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_bond_port(connection);
+
+ 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;
}
@@ -613,7 +669,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;
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index aaf11777cd..200e9a588e 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -31,6 +31,7 @@
#include "nm-setting-ethtool.h"
#include "nm-setting-8021x.h"
#include "nm-setting-bond.h"
+#include "nm-setting-bond-port.h"
#include "nm-setting-team.h"
#include "nm-setting-team-port.h"
#include "nm-setting-bridge.h"
@@ -5493,6 +5494,37 @@ make_bond_setting(shvarFile *ifcfg, const char *file, GError **error)
return (NMSetting *) s_bond;
}
+static NMSetting *
+make_bond_port_setting(shvarFile *ifcfg)
+{
+ NMSetting * s_port = NULL;
+ gs_free char *value_to_free = NULL;
+ const char * value;
+ guint32 queue_id = 0;
+
+ g_return_val_if_fail(ifcfg != NULL, FALSE);
+
+ value = svGetValueStr(ifcfg, "BOND_PORT_QUEUE_ID", &value_to_free);
+ if (value) {
+ s_port = nm_setting_bond_port_new();
+ queue_id =
+ _nm_utils_ascii_str_to_uint64(value, 10, 0, G_MAXUINT16, NM_BOND_PORT_QUEUE_ID_DEF);
+ if (errno != 0) {
+ PARSE_WARNING("Invalid bond port queue_id value '%s': error %d", value, errno);
+ nm_clear_g_free(&value_to_free);
+ return s_port;
+ } else {
+ nm_clear_g_free(&value_to_free);
+ nm_g_object_set_property_uint(G_OBJECT(s_port),
+ NM_SETTING_BOND_PORT_QUEUE_ID,
+ queue_id,
+ NULL);
+ }
+ }
+
+ return s_port;
+}
+
static NMConnection *
bond_connection_from_ifcfg(const char *file, shvarFile *ifcfg, GError **error)
{
@@ -6660,6 +6692,10 @@ connection_from_file_full(const char *filename,
if (setting)
nm_connection_add_setting(connection, setting);
+ setting = make_bond_port_setting(main_ifcfg);
+ if (setting)
+ nm_connection_add_setting(connection, setting);
+
setting = make_team_port_setting(main_ifcfg);
if (setting)
nm_connection_add_setting(connection, setting);
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
index febfc120c1..7ae6a94555 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
@@ -827,6 +827,7 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = {
_KEY_TYPE("BAND", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("BONDING_MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("BONDING_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
+ _KEY_TYPE("BOND_PORT_QUEUE_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("BOOTPROTO", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("BRIDGE", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
_KEY_TYPE("BRIDGE_MACADDR", NMS_IFCFG_KEY_TYPE_IS_PLAIN),
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
index b7751ec96c..2b16668c75 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
@@ -33,7 +33,7 @@ typedef struct {
NMSIfcfgKeyTypeFlags key_flags;
} NMSIfcfgKeyTypeInfo;
-extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[251];
+extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[252];
const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx);
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 4510576811..9c5676f872 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -19,6 +19,7 @@
#include "libnm-glib-aux/nm-str-buf.h"
#include "libnm-glib-aux/nm-io-utils.h"
#include "nm-manager.h"
+#include "nm-setting-bond-port.h"
#include "nm-setting-connection.h"
#include "nm-setting-wired.h"
#include "nm-setting-wireless.h"
@@ -1888,6 +1889,26 @@ write_bridge_port_setting(NMConnection *connection, shvarFile *ifcfg, GError **e
return TRUE;
}
+static gboolean
+write_bond_port_setting(NMConnection *connection, shvarFile *ifcfg, GError **error)
+{
+ NMSettingBondPort *s_port = NULL;
+ guint16 queue_id = NM_BOND_PORT_QUEUE_ID_DEF;
+
+ s_port = _nm_connection_get_setting_bond_port(connection);
+ if (!s_port)
+ return TRUE;
+
+ queue_id = nm_setting_bond_port_get_queue_id(s_port);
+ if (queue_id
+ != get_setting_default_checked_uint(NM_BOND_PORT_QUEUE_ID_DEF,
+ s_port,
+ NM_SETTING_BOND_PORT_QUEUE_ID))
+ svSetValueInt64(ifcfg, "BOND_PORT_QUEUE_ID", queue_id);
+
+ return TRUE;
+}
+
static gboolean
write_team_port_setting(NMConnection *connection, shvarFile *ifcfg, GError **error)
{
@@ -3370,6 +3391,9 @@ do_write_construct(NMConnection * connection,
if (!write_bridge_port_setting(connection, ifcfg, error))
return FALSE;
+ if (!write_bond_port_setting(connection, ifcfg, error))
+ return FALSE;
+
if (!write_team_port_setting(connection, ifcfg, error))
return FALSE;
diff --git a/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-port b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-port
new file mode 100644
index 0000000000..111924c0b0
--- /dev/null
+++ b/src/core/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-port
@@ -0,0 +1,9 @@
+TYPE=Ethernet
+NAME=eth0
+UUID=43737e70-7c4f-4b67-9f4f-6d2d4747b1ff
+DEVICE=eth0
+ONBOOT=yes
+LLDP=no
+MASTER=bond99
+SLAVE=yes
+BOND_PORT_QUEUE_ID=1
diff --git a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index bc34ec124a..6052a3714d 100644
--- a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -9449,6 +9449,73 @@ test_write_bond_slave(void)
nmtst_assert_connection_equals(connection, TRUE, reread, FALSE);
}
+static void
+test_read_bond_port(void)
+{
+ gs_unref_object NMConnection *connection = NULL;
+ NMSettingConnection * s_con = NULL;
+ NMSettingBondPort * s_port = NULL;
+
+ connection =
+ _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-bond-port", NULL, TYPE_ETHERNET, NULL);
+
+ s_con = nm_connection_get_setting_connection(connection);
+ g_assert(s_con);
+ g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "bond99");
+ g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_BOND_SETTING_NAME);
+
+ s_port = _nm_connection_get_setting_bond_port(connection);
+ g_assert(s_port);
+ g_assert_cmpuint(nm_setting_bond_port_get_queue_id(s_port), ==, 1);
+}
+
+static void
+test_write_bond_port(void)
+{
+ nmtst_auto_unlinkfile char *testfile = NULL;
+ gs_unref_object NMConnection *connection = NULL;
+ gs_unref_object NMConnection *reread = NULL;
+ NMSettingConnection * s_con = NULL;
+ NMSettingWired * s_wired = NULL;
+ NMSettingBondPort * s_bond_port = NULL;
+
+ connection = nm_simple_connection_new();
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new();
+ nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+ g_object_set(s_con,
+ NM_SETTING_CONNECTION_ID,
+ "Test Write Bond Port",
+ NM_SETTING_CONNECTION_UUID,
+ nm_uuid_generate_random_str_a(),
+ NM_SETTING_CONNECTION_AUTOCONNECT,
+ TRUE,
+ NM_SETTING_CONNECTION_TYPE,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_CONNECTION_MASTER,
+ "bond0",
+ NM_SETTING_CONNECTION_SLAVE_TYPE,
+ NM_SETTING_BOND_SETTING_NAME,
+ NULL);
+
+ s_wired = (NMSettingWired *) nm_setting_wired_new();
+ nm_connection_add_setting(connection, NM_SETTING(s_wired));
+
+ s_bond_port = NM_SETTING_BOND_PORT(nm_setting_bond_port_new());
+ g_object_set(s_bond_port, NM_SETTING_BOND_PORT_QUEUE_ID, 1, NULL);
+ nm_connection_add_setting(connection, NM_SETTING(s_bond_port));
+
+ nmtst_assert_connection_verifies(connection);
+
+ _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile);
+
+ reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL);
+
+ nmtst_assert_connection_equals(connection, TRUE, reread, FALSE);
+}
+
static void
test_read_infiniband(void)
{
@@ -12064,6 +12131,8 @@ main(int argc, char **argv)
g_test_add_func(TPATH "bond/write-slave", test_write_bond_slave);
g_test_add_func(TPATH "bond/write-slave-ib", test_write_bond_slave_ib);
g_test_add_func(TPATH "bond/bonding-opts-numeric-mode", test_read_bond_opts_mode_numeric);
+ g_test_add_func(TPATH "bond/read-bond-port", test_read_bond_port);
+ g_test_add_func(TPATH "bond/write-bond-port", test_write_bond_port);
g_test_add_func(TPATH "bridge/read-master", test_read_bridge_main);
g_test_add_func(TPATH "bridge/write-master", test_write_bridge_main);
diff --git a/src/libnm-base/nm-base.h b/src/libnm-base/nm-base.h
index 3257b3f0a5..b3a57aa806 100644
--- a/src/libnm-base/nm-base.h
+++ b/src/libnm-base/nm-base.h
@@ -386,4 +386,6 @@ typedef struct {
/****************************************************************************/
+#define NM_BOND_PORT_QUEUE_ID_DEF 0
+
#endif /* __NM_LIBNM_BASE_H__ */
diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver
index f6836afb18..a7717ad65c 100644
--- a/src/libnm-client-impl/libnm.ver
+++ b/src/libnm-client-impl/libnm.ver
@@ -1803,4 +1803,7 @@ libnm_1_34_0 {
global:
nm_ip_routing_rule_get_uid_range;
nm_ip_routing_rule_set_uid_range;
+ nm_setting_bond_port_get_queue_id;
+ nm_setting_bond_port_get_type;
+ nm_setting_bond_port_new;
} libnm_1_32_4;
diff --git a/src/libnm-client-public/NetworkManager.h b/src/libnm-client-public/NetworkManager.h
index 97d3e649a1..3134562e61 100644
--- a/src/libnm-client-public/NetworkManager.h
+++ b/src/libnm-client-public/NetworkManager.h
@@ -55,6 +55,7 @@
#include "nm-setting-adsl.h"
#include "nm-setting-bluetooth.h"
#include "nm-setting-bond.h"
+#include "nm-setting-bond-port.h"
#include "nm-setting-bridge.h"
#include "nm-setting-bridge-port.h"
#include "nm-setting-cdma.h"
diff --git a/src/libnm-client-public/nm-autoptr.h b/src/libnm-client-public/nm-autoptr.h
index f37e2cfc44..6c34946ca7 100644
--- a/src/libnm-client-public/nm-autoptr.h
+++ b/src/libnm-client-public/nm-autoptr.h
@@ -67,6 +67,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSetting8021x, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingAdsl, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBluetooth, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBond, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBondPort, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBridge, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingBridgePort, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingCdma, g_object_unref)
diff --git a/src/libnm-core-impl/meson.build b/src/libnm-core-impl/meson.build
index f175ea3b29..2e1f175177 100644
--- a/src/libnm-core-impl/meson.build
+++ b/src/libnm-core-impl/meson.build
@@ -37,6 +37,7 @@ libnm_core_settings_sources = files(
'nm-setting-adsl.c',
'nm-setting-bluetooth.c',
'nm-setting-bond.c',
+ 'nm-setting-bond-port.c',
'nm-setting-bridge-port.c',
'nm-setting-bridge.c',
'nm-setting-cdma.c',
diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c
index 03fde1f9cf..d6efe918b8 100644
--- a/src/libnm-core-impl/nm-connection.c
+++ b/src/libnm-core-impl/nm-connection.c
@@ -1074,6 +1074,7 @@ _nm_connection_detect_slave_type(NMConnection *connection, NMSetting **out_s_por
const char * controller_type_name;
} infos[] = {
{NM_META_SETTING_TYPE_BRIDGE_PORT, NM_SETTING_BRIDGE_SETTING_NAME},
+ {NM_META_SETTING_TYPE_BOND_PORT, NM_SETTING_BOND_SETTING_NAME},
{NM_META_SETTING_TYPE_TEAM_PORT, NM_SETTING_TEAM_SETTING_NAME},
{NM_META_SETTING_TYPE_OVS_PORT, NM_SETTING_OVS_BRIDGE_SETTING_NAME},
{NM_META_SETTING_TYPE_OVS_INTERFACE, NM_SETTING_OVS_PORT_SETTING_NAME},
@@ -1679,6 +1680,10 @@ _normalize_invalid_slave_port_settings(NMConnection *self)
&& _nm_connection_remove_setting(self, NM_TYPE_SETTING_BRIDGE_PORT))
changed = TRUE;
+ if (!nm_streq0(slave_type, NM_SETTING_BOND_SETTING_NAME)
+ && _nm_connection_remove_setting(self, NM_TYPE_SETTING_BOND_PORT))
+ changed = TRUE;
+
if (!nm_streq0(slave_type, NM_SETTING_TEAM_SETTING_NAME)
&& _nm_connection_remove_setting(self, NM_TYPE_SETTING_TEAM_PORT))
changed = TRUE;
@@ -3766,3 +3771,9 @@ nm_connection_default_init(NMConnectionInterface *iface)
G_TYPE_NONE,
0);
}
+
+NMSettingBondPort *
+_nm_connection_get_setting_bond_port(NMConnection *connection)
+{
+ return _connection_get_setting_by_meta_type_check(connection, NM_META_SETTING_TYPE_BOND_PORT);
+}
diff --git a/src/libnm-core-impl/nm-meta-setting-base-impl.c b/src/libnm-core-impl/nm-meta-setting-base-impl.c
index d79f2529cb..8c1ad10ea8 100644
--- a/src/libnm-core-impl/nm-meta-setting-base-impl.c
+++ b/src/libnm-core-impl/nm-meta-setting-base-impl.c
@@ -16,6 +16,7 @@
#include "nm-setting-adsl.h"
#include "nm-setting-bluetooth.h"
#include "nm-setting-bond.h"
+#include "nm-setting-bond-port.h"
#include "nm-setting-bridge-port.h"
#include "nm-setting-bridge.h"
#include "nm-setting-cdma.h"
@@ -190,6 +191,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
.setting_name = NM_SETTING_BOND_SETTING_NAME,
.get_setting_gtype = nm_setting_bond_get_type,
},
+ [NM_META_SETTING_TYPE_BOND_PORT] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_BOND_PORT,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_BOND_PORT_SETTING_NAME,
+ .get_setting_gtype = nm_setting_bond_port_get_type,
+ },
[NM_META_SETTING_TYPE_BRIDGE] =
{
.meta_type = NM_META_SETTING_TYPE_BRIDGE,
@@ -568,6 +576,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = {
NM_META_SETTING_TYPE_SRIOV,
/* NM_SETTING_PRIORITY_AUX */
+ NM_META_SETTING_TYPE_BOND_PORT,
NM_META_SETTING_TYPE_BRIDGE_PORT,
NM_META_SETTING_TYPE_ETHTOOL,
NM_META_SETTING_TYPE_MATCH,
diff --git a/src/libnm-core-impl/nm-setting-bond-port.c b/src/libnm-core-impl/nm-setting-bond-port.c
new file mode 100644
index 0000000000..87a15462cc
--- /dev/null
+++ b/src/libnm-core-impl/nm-setting-bond-port.c
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021 Red Hat, Inc.
+ */
+
+#include "libnm-core-impl/nm-default-libnm-core.h"
+
+#include "nm-connection-private.h"
+#include "nm-setting-bond-port.h"
+#include "nm-setting-bond.h"
+#include "nm-setting-connection.h"
+#include "nm-utils-private.h"
+#include "nm-utils.h"
+
+/**
+ * SECTION:nm-setting-bond-port
+ * @short_description: Describes connection properties for bond ports
+ *
+ * The #NMSettingBondPort object is a #NMSetting subclass that describes
+ * optional properties that apply to bond ports.
+ **/
+
+/*****************************************************************************/
+
+NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBondPort, PROP_QUEUE_ID, );
+
+typedef struct {
+ guint32 queue_id;
+} NMSettingBondPortPrivate;
+
+/**
+ * NMSettingBondPort:
+ *
+ * Bond Port Settings
+ */
+struct _NMSettingBondPort {
+ NMSetting parent;
+ NMSettingBondPortPrivate _priv;
+};
+
+struct _NMSettingBondPortClass {
+ NMSettingClass parent;
+};
+
+G_DEFINE_TYPE(NMSettingBondPort, nm_setting_bond_port, NM_TYPE_SETTING)
+
+#define NM_SETTING_BOND_PORT_GET_PRIVATE(self) \
+ _NM_GET_PRIVATE(self, NMSettingBondPort, NM_IS_SETTING_BOND_PORT, NMSetting)
+
+/*****************************************************************************/
+
+/**
+ * nm_setting_bond_port_get_queue_id:
+ * @setting: the #NMSettingBondPort
+ *
+ * Returns: the #NMSettingBondPort:queue_id property of the setting
+ *
+ * Since: 1.34
+ **/
+guint32
+nm_setting_bond_port_get_queue_id(NMSettingBondPort *setting)
+{
+ g_return_val_if_fail(NM_IS_SETTING_BOND_PORT(setting), 0);
+
+ return NM_SETTING_BOND_PORT_GET_PRIVATE(setting)->queue_id;
+}
+
+/*****************************************************************************/
+
+static gboolean
+verify(NMSetting *setting, NMConnection *connection, GError **error)
+{
+ if (connection) {
+ NMSettingConnection *s_con;
+ const char * slave_type;
+
+ s_con = nm_connection_get_setting_connection(connection);
+ if (!s_con) {
+ g_set_error(error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_MISSING_SETTING,
+ _("missing setting"));
+ g_prefix_error(error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME);
+ return FALSE;
+ }
+
+ slave_type = nm_setting_connection_get_slave_type(s_con);
+ if (!nm_streq0(slave_type, NM_SETTING_BOND_SETTING_NAME)) {
+ g_set_error(error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("A connection with a '%s' setting must have the slave-type set to '%s'. "
+ "Instead it is '%s'"),
+ NM_SETTING_BOND_PORT_SETTING_NAME,
+ NM_SETTING_BOND_SETTING_NAME,
+ slave_type);
+ g_prefix_error(error,
+ "%s.%s: ",
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_SLAVE_TYPE);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+static void
+nm_setting_bond_port_init(NMSettingBondPort *setting)
+{}
+
+/**
+ * nm_setting_bond_port_new:
+ *
+ * Creates a new #NMSettingBondPort object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingBondPort object
+ *
+ * Since: 1.34
+ **/
+NMSetting *
+nm_setting_bond_port_new(void)
+{
+ return g_object_new(NM_TYPE_SETTING_BOND_PORT, NULL);
+}
+
+static void
+nm_setting_bond_port_class_init(NMSettingBondPortClass *klass)
+{
+ GObjectClass * object_class = G_OBJECT_CLASS(klass);
+ NMSettingClass *setting_class = NM_SETTING_CLASS(klass);
+ GArray * properties_override = _nm_sett_info_property_override_create_array();
+
+ object_class->get_property = _nm_setting_property_get_property_direct;
+ object_class->set_property = _nm_setting_property_set_property_direct;
+
+ setting_class->verify = verify;
+ setting_class->finalize_direct = TRUE;
+
+ /**
+ * NMSettingBondPort:queue-id:
+ *
+ * The queue ID of this bond port. The maximum value of queue ID is
+ * the number of TX queues currently active in device.
+ *
+ * Since: 1.34
+ **/
+ /* ---ifcfg-rh---
+ * property: queue-id
+ * variable: BONDING_OPTS: queue-id=
+ * values: 0 - 65535
+ * default: 0
+ * description: Queue ID.
+ * ---end---
+ */
+ _nm_setting_property_define_direct_uint32(properties_override,
+ obj_properties,
+ NM_SETTING_BOND_PORT_QUEUE_ID,
+ PROP_QUEUE_ID,
+ 0,
+ G_MAXUINT16,
+ NM_BOND_PORT_QUEUE_ID_DEF,
+ NM_SETTING_PARAM_INFERRABLE,
+ NMSettingBondPort,
+ _priv.queue_id);
+
+ g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+
+ _nm_setting_class_commit(setting_class,
+ NM_META_SETTING_TYPE_BOND_PORT,
+ NULL,
+ properties_override,
+ 0);
+}
diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c
index aece39a5c9..ccdd4b92a6 100644
--- a/src/libnm-core-impl/nm-utils.c
+++ b/src/libnm-core-impl/nm-utils.c
@@ -29,6 +29,7 @@
#include "nm-setting-private.h"
#include "nm-crypto.h"
#include "nm-setting-bond.h"
+#include "nm-setting-bond-port.h"
#include "nm-setting-bridge.h"
#include "nm-setting-bridge-port.h"
#include "nm-setting-infiniband.h"
diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c
index 02eb89666d..c84bee19d2 100644
--- a/src/libnm-core-impl/tests/test-setting.c
+++ b/src/libnm-core-impl/tests/test-setting.c
@@ -121,7 +121,7 @@ test_nm_meta_setting_types_by_priority(void)
G_STATIC_ASSERT_EXPR(_NM_META_SETTING_TYPE_NUM
== G_N_ELEMENTS(nm_meta_setting_types_by_priority));
- G_STATIC_ASSERT_EXPR(_NM_META_SETTING_TYPE_NUM == 51);
+ G_STATIC_ASSERT_EXPR(_NM_META_SETTING_TYPE_NUM == 52);
arr = g_ptr_array_new_with_free_func(g_object_unref);
diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h
index 3fed38d552..7d3593365d 100644
--- a/src/libnm-core-intern/nm-core-internal.h
+++ b/src/libnm-core-intern/nm-core-internal.h
@@ -29,6 +29,7 @@
#include "nm-setting-adsl.h"
#include "nm-setting-bluetooth.h"
#include "nm-setting-bond.h"
+#include "nm-setting-bond-port.h"
#include "nm-setting-bridge-port.h"
#include "nm-setting-bridge.h"
#include "nm-setting-cdma.h"
@@ -985,4 +986,6 @@ gboolean _nm_ip_tunnel_mode_is_layer2(NMIPTunnelMode mode);
GPtrArray *_nm_setting_ip_config_get_dns_array(NMSettingIPConfig *setting);
+NMSettingBondPort *_nm_connection_get_setting_bond_port(NMConnection *connection);
+
#endif
diff --git a/src/libnm-core-intern/nm-meta-setting-base-impl.h b/src/libnm-core-intern/nm-meta-setting-base-impl.h
index 8aec1e8756..eba1fb96f4 100644
--- a/src/libnm-core-intern/nm-meta-setting-base-impl.h
+++ b/src/libnm-core-intern/nm-meta-setting-base-impl.h
@@ -110,6 +110,7 @@ typedef enum _nm_packed {
NM_META_SETTING_TYPE_ADSL,
NM_META_SETTING_TYPE_BLUETOOTH,
NM_META_SETTING_TYPE_BOND,
+ NM_META_SETTING_TYPE_BOND_PORT,
NM_META_SETTING_TYPE_BRIDGE,
NM_META_SETTING_TYPE_BRIDGE_PORT,
NM_META_SETTING_TYPE_CDMA,
diff --git a/src/libnm-core-public/meson.build b/src/libnm-core-public/meson.build
index 6b8dad0f28..f1da4d023d 100644
--- a/src/libnm-core-public/meson.build
+++ b/src/libnm-core-public/meson.build
@@ -13,6 +13,7 @@ libnm_core_headers = files(
'nm-setting-adsl.h',
'nm-setting-bluetooth.h',
'nm-setting-bond.h',
+ 'nm-setting-bond-port.h',
'nm-setting-bridge-port.h',
'nm-setting-bridge.h',
'nm-setting-cdma.h',
diff --git a/src/libnm-core-public/nm-core-types.h b/src/libnm-core-public/nm-core-types.h
index bf0c2a9966..c86c28fa47 100644
--- a/src/libnm-core-public/nm-core-types.h
+++ b/src/libnm-core-public/nm-core-types.h
@@ -19,6 +19,7 @@ typedef struct _NMSetting8021x NMSetting8021x;
typedef struct _NMSettingAdsl NMSettingAdsl;
typedef struct _NMSettingBluetooth NMSettingBluetooth;
typedef struct _NMSettingBond NMSettingBond;
+typedef struct _NMSettingBondPort NMSettingBondPort;
typedef struct _NMSettingBridge NMSettingBridge;
typedef struct _NMSettingBridgePort NMSettingBridgePort;
typedef struct _NMSettingCdma NMSettingCdma;
diff --git a/src/libnm-core-public/nm-setting-bond-port.h b/src/libnm-core-public/nm-setting-bond-port.h
new file mode 100644
index 0000000000..0b20e4a8cb
--- /dev/null
+++ b/src/libnm-core-public/nm-setting-bond-port.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2012 Red Hat, Inc.
+ */
+
+#ifndef __NM_SETTING_BOND_PORT_H__
+#define __NM_SETTING_BOND_PORT_H__
+
+#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include "nm-setting.h"
+#include "nm-setting-bond.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_SETTING_BOND_PORT (nm_setting_bond_port_get_type())
+#define NM_SETTING_BOND_PORT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_BOND_PORT, NMSettingBondPort))
+#define NM_SETTING_BOND_PORT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SETTING_BOND_PORT, NMSettingBondPortClass))
+#define NM_IS_SETTING_BOND_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_BOND_PORT))
+#define NM_IS_SETTING_BOND_PORT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_BOND_PORT))
+#define NM_SETTING_BOND_PORT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_BOND_PORT, NMSettingBondPortClass))
+
+#define NM_SETTING_BOND_PORT_SETTING_NAME "bond-port"
+
+#define NM_SETTING_BOND_PORT_QUEUE_ID "queue-id"
+
+typedef struct _NMSettingBondPortClass NMSettingBondPortClass;
+
+NM_AVAILABLE_IN_1_34
+GType nm_setting_bond_port_get_type(void);
+
+NM_AVAILABLE_IN_1_34
+NMSetting *nm_setting_bond_port_new(void);
+
+NM_AVAILABLE_IN_1_34
+guint32 nm_setting_bond_port_get_queue_id(NMSettingBondPort *setting);
+
+G_END_DECLS
+
+#endif /* __NM_SETTING_BOND_PORT_H__ */
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
index ae9ee04e97..1301121f4c 100644
--- a/src/libnm-platform/nm-platform.c
+++ b/src/libnm-platform/nm-platform.c
@@ -2563,6 +2563,8 @@ slave_category(NMPlatform *self, int slave)
switch (nm_platform_link_get_type(self, master)) {
case NM_LINK_TYPE_BRIDGE:
return "brport";
+ case NM_LINK_TYPE_BOND:
+ return "bonding_slave";
default:
return NULL;
}
diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.c b/src/libnmc-setting/nm-meta-setting-base-impl.c
index d79f2529cb..8c1ad10ea8 100644
--- a/src/libnmc-setting/nm-meta-setting-base-impl.c
+++ b/src/libnmc-setting/nm-meta-setting-base-impl.c
@@ -16,6 +16,7 @@
#include "nm-setting-adsl.h"
#include "nm-setting-bluetooth.h"
#include "nm-setting-bond.h"
+#include "nm-setting-bond-port.h"
#include "nm-setting-bridge-port.h"
#include "nm-setting-bridge.h"
#include "nm-setting-cdma.h"
@@ -190,6 +191,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
.setting_name = NM_SETTING_BOND_SETTING_NAME,
.get_setting_gtype = nm_setting_bond_get_type,
},
+ [NM_META_SETTING_TYPE_BOND_PORT] =
+ {
+ .meta_type = NM_META_SETTING_TYPE_BOND_PORT,
+ .setting_priority = NM_SETTING_PRIORITY_AUX,
+ .setting_name = NM_SETTING_BOND_PORT_SETTING_NAME,
+ .get_setting_gtype = nm_setting_bond_port_get_type,
+ },
[NM_META_SETTING_TYPE_BRIDGE] =
{
.meta_type = NM_META_SETTING_TYPE_BRIDGE,
@@ -568,6 +576,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = {
NM_META_SETTING_TYPE_SRIOV,
/* NM_SETTING_PRIORITY_AUX */
+ NM_META_SETTING_TYPE_BOND_PORT,
NM_META_SETTING_TYPE_BRIDGE_PORT,
NM_META_SETTING_TYPE_ETHTOOL,
NM_META_SETTING_TYPE_MATCH,
diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.h b/src/libnmc-setting/nm-meta-setting-base-impl.h
index 8aec1e8756..eba1fb96f4 100644
--- a/src/libnmc-setting/nm-meta-setting-base-impl.h
+++ b/src/libnmc-setting/nm-meta-setting-base-impl.h
@@ -110,6 +110,7 @@ typedef enum _nm_packed {
NM_META_SETTING_TYPE_ADSL,
NM_META_SETTING_TYPE_BLUETOOTH,
NM_META_SETTING_TYPE_BOND,
+ NM_META_SETTING_TYPE_BOND_PORT,
NM_META_SETTING_TYPE_BRIDGE,
NM_META_SETTING_TYPE_BRIDGE_PORT,
NM_META_SETTING_TYPE_CDMA,
diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c
index 812ec3f044..ea260b4e9b 100644
--- a/src/libnmc-setting/nm-meta-setting-desc.c
+++ b/src/libnmc-setting/nm-meta-setting-desc.c
@@ -5048,6 +5048,18 @@ static const NMMetaPropertyInfo *const property_infos_BOND[] = {
NULL
};
+#undef _CURRENT_NM_META_SETTING_TYPE
+#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BOND_PORT
+static const NMMetaPropertyInfo *const property_infos_BOND_PORT[] = {
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BOND_PORT_QUEUE_ID,
+ .is_cli_option = TRUE,
+ .property_alias = "queue-id",
+ .prompt = N_("Queue ID [0]"),
+ .property_type = &_pt_gobject_int,
+ ),
+ NULL
+};
+
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_BRIDGE
static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = {
@@ -8113,6 +8125,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN)
#define SETTING_PRETTY_NAME_ADSL N_("ADSL connection")
#define SETTING_PRETTY_NAME_BLUETOOTH N_("bluetooth connection")
#define SETTING_PRETTY_NAME_BOND N_("Bond device")
+#define SETTING_PRETTY_NAME_BOND_PORT N_("Bond port")
#define SETTING_PRETTY_NAME_BRIDGE N_("Bridge device")
#define SETTING_PRETTY_NAME_BRIDGE_PORT N_("Bridge port")
#define SETTING_PRETTY_NAME_CDMA N_("CDMA mobile broadband connection")
@@ -8217,6 +8230,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
+ SETTING_INFO (BOND_PORT),
SETTING_INFO (BRIDGE,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
@@ -8497,6 +8511,11 @@ static const NMMetaSettingValidPartItem *const valid_settings_noslave[] = {
NULL,
};
+static const NMMetaSettingValidPartItem *const valid_settings_slave_bond[] = {
+ NM_META_SETTING_VALID_PART_ITEM(BOND_PORT, TRUE),
+ NULL,
+};
+
static const NMMetaSettingValidPartItem *const valid_settings_slave_bridge[] = {
NM_META_SETTING_VALID_PART_ITEM(BRIDGE_PORT, TRUE),
NULL,
@@ -8526,7 +8545,7 @@ nm_meta_setting_info_valid_parts_for_slave_type(const char *slave_type, const ch
}
if (nm_streq(slave_type, NM_SETTING_BOND_SETTING_NAME)) {
NM_SET_OUT(out_slave_name, "bond-slave");
- return NM_PTRARRAY_EMPTY(const NMMetaSettingValidPartItem *);
+ return valid_settings_slave_bond;
}
if (nm_streq(slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) {
NM_SET_OUT(out_slave_name, "bridge-slave");
diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in
index b7e2c1f7b2..3bad7cf810 100644
--- a/src/libnmc-setting/settings-docs.h.in
+++ b/src/libnmc-setting/settings-docs.h.in
@@ -114,6 +114,7 @@
#define DESCRIBE_DOC_NM_SETTING_BLUETOOTH_BDADDR N_("The Bluetooth address of the device.")
#define DESCRIBE_DOC_NM_SETTING_BLUETOOTH_TYPE N_("Either \"dun\" for Dial-Up Networking connections or \"panu\" for Personal Area Networking connections to devices supporting the NAP profile.")
#define DESCRIBE_DOC_NM_SETTING_BOND_OPTIONS N_("Dictionary of key/value pairs of bonding options. Both keys and values must be strings. Option names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).")
+#define DESCRIBE_DOC_NM_SETTING_BOND_PORT_QUEUE_ID N_("The queue ID of this bond port. The maximum value of queue ID is the number of TX queues currently active in device.")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_AGEING_TIME N_("The Ethernet MAC address aging time, in seconds.")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_FORWARD_DELAY N_("The Spanning Tree Protocol (STP) forwarding delay, in seconds.")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_GROUP_ADDRESS N_("If specified, The MAC address of the multicast group this bridge uses for STP. The address must be a link-local address in standard Ethernet MAC address format, ie an address of the form 01:80:C2:00:00:0X, with X in [0, 4..F]. If not specified the default value is 01:80:C2:00:00:00.")
diff --git a/src/nmcli/connections.c b/src/nmcli/connections.c
index 10bc224c19..bf274dee8f 100644
--- a/src/nmcli/connections.c
+++ b/src/nmcli/connections.c
@@ -874,18 +874,19 @@ const NmcMetaGenericInfo
"," NM_SETTING_CDMA_SETTING_NAME "," NM_SETTING_BLUETOOTH_SETTING_NAME \
"," NM_SETTING_OLPC_MESH_SETTING_NAME "," NM_SETTING_VPN_SETTING_NAME \
"," NM_SETTING_INFINIBAND_SETTING_NAME "," NM_SETTING_BOND_SETTING_NAME \
- "," NM_SETTING_VLAN_SETTING_NAME "," NM_SETTING_BRIDGE_SETTING_NAME \
- "," NM_SETTING_BRIDGE_PORT_SETTING_NAME "," NM_SETTING_TEAM_SETTING_NAME \
- "," NM_SETTING_TEAM_PORT_SETTING_NAME "," NM_SETTING_OVS_BRIDGE_SETTING_NAME \
- "," NM_SETTING_OVS_INTERFACE_SETTING_NAME "," NM_SETTING_OVS_PATCH_SETTING_NAME \
- "," NM_SETTING_OVS_PORT_SETTING_NAME "," NM_SETTING_DCB_SETTING_NAME \
- "," NM_SETTING_TUN_SETTING_NAME "," NM_SETTING_IP_TUNNEL_SETTING_NAME \
- "," NM_SETTING_MACSEC_SETTING_NAME "," NM_SETTING_MACVLAN_SETTING_NAME \
- "," NM_SETTING_VXLAN_SETTING_NAME "," NM_SETTING_VRF_SETTING_NAME \
- "," NM_SETTING_WPAN_SETTING_NAME "," NM_SETTING_6LOWPAN_SETTING_NAME \
- "," NM_SETTING_WIREGUARD_SETTING_NAME "," NM_SETTING_PROXY_SETTING_NAME \
- "," NM_SETTING_TC_CONFIG_SETTING_NAME "," NM_SETTING_SRIOV_SETTING_NAME \
- "," NM_SETTING_ETHTOOL_SETTING_NAME "," NM_SETTING_OVS_DPDK_SETTING_NAME \
+ "," NM_SETTING_BOND_PORT_SETTING_NAME "," NM_SETTING_VLAN_SETTING_NAME \
+ "," NM_SETTING_BRIDGE_SETTING_NAME "," NM_SETTING_BRIDGE_PORT_SETTING_NAME \
+ "," NM_SETTING_TEAM_SETTING_NAME "," NM_SETTING_TEAM_PORT_SETTING_NAME \
+ "," NM_SETTING_OVS_BRIDGE_SETTING_NAME "," NM_SETTING_OVS_INTERFACE_SETTING_NAME \
+ "," NM_SETTING_OVS_PATCH_SETTING_NAME "," NM_SETTING_OVS_PORT_SETTING_NAME \
+ "," NM_SETTING_DCB_SETTING_NAME "," NM_SETTING_TUN_SETTING_NAME \
+ "," NM_SETTING_IP_TUNNEL_SETTING_NAME "," NM_SETTING_MACSEC_SETTING_NAME \
+ "," NM_SETTING_MACVLAN_SETTING_NAME "," NM_SETTING_VXLAN_SETTING_NAME \
+ "," NM_SETTING_VRF_SETTING_NAME "," NM_SETTING_WPAN_SETTING_NAME \
+ "," NM_SETTING_6LOWPAN_SETTING_NAME "," NM_SETTING_WIREGUARD_SETTING_NAME \
+ "," NM_SETTING_PROXY_SETTING_NAME "," NM_SETTING_TC_CONFIG_SETTING_NAME \
+ "," NM_SETTING_SRIOV_SETTING_NAME "," NM_SETTING_ETHTOOL_SETTING_NAME \
+ "," NM_SETTING_OVS_DPDK_SETTING_NAME \
"," NM_SETTING_HOSTNAME_SETTING_NAME /* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */
const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = {
@@ -1062,7 +1063,8 @@ usage_connection_add(void)
" [arp-interval ]\n"
" [arp-ip-target ]\n"
" [lacp-rate slow (0) | fast (1)]\n\n"
- " bond-slave: master \n\n"
+ " bond-slave: master \n"
+ " [queue-id <0-65535>]\n\n"
" team: [config |]\n\n"
" team-slave: master \n"
" [config |]\n\n"
@@ -1125,6 +1127,7 @@ usage_connection_add(void)
" [path-cost <1-65535>]\n"
" [hairpin yes|no]\n\n"
" team: [config |]\n\n"
+ " bond: [queue-id <0-65535>]\n\n"
" IP_OPTIONS:\n"
" [ip4 ] [gw4 ]\n"
" [ip6 ] [gw6 ]\n\n"));
@@ -6007,6 +6010,8 @@ gen_property_names(const char *text, int state)
slv_type = NM_SETTING_TEAM_SETTING_NAME;
else if (nm_streq0(strv[0], NM_SETTING_BRIDGE_PORT_SETTING_NAME))
slv_type = NM_SETTING_BRIDGE_SETTING_NAME;
+ else if (nm_streq0(strv[0], NM_SETTING_BOND_PORT_SETTING_NAME))
+ slv_type = NM_SETTING_BOND_SETTING_NAME;
else
slv_type = NULL;
valid_settings_slave = nm_meta_setting_info_valid_parts_for_slave_type(slv_type, NULL);
diff --git a/src/nmcli/generate-docs-nm-settings-nmcli.xml.in b/src/nmcli/generate-docs-nm-settings-nmcli.xml.in
index b07e238290..a4f412f551 100644
--- a/src/nmcli/generate-docs-nm-settings-nmcli.xml.in
+++ b/src/nmcli/generate-docs-nm-settings-nmcli.xml.in
@@ -267,6 +267,11 @@
+
+
+
edit_connection));
else if (!strcmp(slave_type, NM_SETTING_TEAM_SETTING_NAME))
add_sections_for_page(editor, grid, nmt_page_team_port_new(priv->edit_connection));
+ else if (nm_streq(slave_type, NM_SETTING_BOND_SETTING_NAME))
+ add_sections_for_page(editor, grid, nmt_page_bond_port_new(priv->edit_connection));
} else {
NmtNewtWidget *section;
diff --git a/src/nmtui/nmt-editor.h b/src/nmtui/nmt-editor.h
index 49fe89d38f..602a61aeaf 100644
--- a/src/nmtui/nmt-editor.h
+++ b/src/nmtui/nmt-editor.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2013 Red Hat, Inc.
*/
diff --git a/src/nmtui/nmt-page-bond-port.c b/src/nmtui/nmt-page-bond-port.c
new file mode 100644
index 0000000000..ea64ff8013
--- /dev/null
+++ b/src/nmtui/nmt-page-bond-port.c
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021 Red Hat, Inc.
+ */
+
+/**
+ * SECTION:nmt-page-bond-port
+ * @short_description: The editor page for Bond ports
+ */
+
+#include "libnm-client-aux-extern/nm-default-client.h"
+#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
+
+#include "nmt-page-bond-port.h"
+
+G_DEFINE_TYPE(NmtPageBondPort, nmt_page_bond_port, NMT_TYPE_EDITOR_PAGE)
+
+static void
+nmt_page_bond_port_init(NmtPageBondPort *bond)
+{}
+
+NmtEditorPage *
+nmt_page_bond_port_new(NMConnection *conn)
+{
+ return g_object_new(NMT_TYPE_PAGE_BOND_PORT, "connection", conn, NULL);
+}
+
+static void
+nmt_page_bond_port_constructed(GObject *object)
+{
+ NmtPageBondPort * bond = NMT_PAGE_BOND_PORT(object);
+ NmtEditorSection * section;
+ NmtEditorGrid * grid;
+ NMSettingBondPort *s_port;
+ NmtNewtWidget * widget;
+ NMConnection * conn;
+
+ conn = nmt_editor_page_get_connection(NMT_EDITOR_PAGE(bond));
+ s_port = _nm_connection_ensure_setting(conn, NM_TYPE_SETTING_BOND_PORT);
+
+ section = nmt_editor_section_new(_("BOND PORT"), NULL, TRUE);
+ grid = nmt_editor_section_get_body(section);
+
+ widget = nmt_newt_entry_numeric_new(10, 0, 63);
+ g_object_bind_property(s_port,
+ NM_SETTING_BOND_PORT_QUEUE_ID,
+ widget,
+ "text",
+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+ nmt_editor_grid_append(grid, _("Queue ID"), widget, NULL);
+
+ nmt_editor_page_add_section(NMT_EDITOR_PAGE(bond), section);
+
+ G_OBJECT_CLASS(nmt_page_bond_port_parent_class)->constructed(object);
+}
+
+static void
+nmt_page_bond_port_class_init(NmtPageBondPortClass *bond_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(bond_class);
+
+ object_class->constructed = nmt_page_bond_port_constructed;
+}
diff --git a/src/nmtui/nmt-page-bond-port.h b/src/nmtui/nmt-page-bond-port.h
new file mode 100644
index 0000000000..387acf4cba
--- /dev/null
+++ b/src/nmtui/nmt-page-bond-port.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021 Red Hat, Inc.
+ */
+
+#ifndef NMT_PAGE_BOND_PORT_H
+#define NMT_PAGE_BOND_PORT_H
+
+#include "nmt-editor-page-device.h"
+
+#define NMT_TYPE_PAGE_BOND_PORT (nmt_page_bond_port_get_type())
+#define NMT_PAGE_BOND_PORT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), NMT_TYPE_PAGE_BOND_PORT, NmtPageBondPort))
+#define NMT_PAGE_BOND_PORT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), NMT_TYPE_PAGE_BOND_PORT, NmtPageBondPortClass))
+#define NMT_IS_PAGE_BOND_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMT_TYPE_PAGE_BOND_PORT))
+#define NMT_IS_PAGE_BOND_PORT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), NMT_TYPE_PAGE_BOND_PORT))
+#define NMT_PAGE_BOND_PORT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), NMT_TYPE_PAGE_BOND_PORT, NmtPageBondPortClass))
+
+typedef struct {
+ NmtEditorPage parent;
+
+} NmtPageBondPort;
+
+typedef struct {
+ NmtEditorPageClass parent;
+
+} NmtPageBondPortClass;
+
+GType nmt_page_bond_port_get_type(void);
+
+NmtEditorPage *nmt_page_bond_port_new(NMConnection *conn);
+
+#endif /* NMT_PAGE_BOND_PORT_H */