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 */