summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFernando Fernandez Mancera <ffmancera@riseup.net>2023-03-09 12:18:14 +0100
committerThomas Haller <thaller@redhat.com>2023-05-02 19:14:04 +0200
commit9800bd172354f8b6db394814b9ddf7f98ad666d2 (patch)
treed949f9efe2ffe6f106f4d37843873b1bbef65eb9
parentcdd2de2692789ea26703b7f8b35ff1b5c21fdb4d (diff)
bonding: add support to prio property in bond portsth/pr/1564
Add per port priority support for bond active port re-selection during failover. A higher number means a higher priority in selection. The primary port still has the highest priority. This option is only compatible with active-backup, balance-tlb and balance-alb modes.
-rw-r--r--src/core/devices/nm-device-bond.c62
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c14
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c1
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h2
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c4
-rw-r--r--src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c1
-rw-r--r--src/libnm-base/nm-base.h1
-rw-r--r--src/libnm-client-impl/libnm.ver1
-rw-r--r--src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in4
-rw-r--r--src/libnm-core-impl/nm-setting-bond-port.c48
-rw-r--r--src/libnm-core-public/nm-setting-bond-port.h4
-rw-r--r--src/libnmc-setting/nm-meta-setting-desc.c6
-rw-r--r--src/libnmc-setting/settings-docs.h.in1
-rw-r--r--src/nmcli/gen-metadata-nm-settings-nmcli.xml.in3
14 files changed, 141 insertions, 11 deletions
diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c
index 4b48db3344..10fe809204 100644
--- a/src/core/devices/nm-device-bond.c
+++ b/src/core/devices/nm-device-bond.c
@@ -240,7 +240,12 @@ controller_update_port_connection(NMDevice *self,
pllink = nm_platform_link_get(nm_device_get_platform(port), ifindex_port);
if (pllink && pllink->port_kind == NM_PORT_KIND_BOND)
- g_object_set(s_port, NM_SETTING_BOND_PORT_QUEUE_ID, pllink->port_data.bond.queue_id, NULL);
+ g_object_set(s_port,
+ NM_SETTING_BOND_PORT_QUEUE_ID,
+ pllink->port_data.bond.queue_id,
+ NM_SETTING_BOND_PORT_PRIO,
+ pllink->port_data.bond.prio,
+ NULL);
g_object_set(nm_connection_get_setting_connection(connection),
NM_SETTING_CONNECTION_MASTER,
@@ -631,13 +636,54 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
static void
commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *s_port)
{
- nm_platform_link_change(
- nm_device_get_platform(port),
- nm_device_get_ifindex(port),
- NULL,
- &((NMPlatformLinkBondPort){.queue_id = s_port ? nm_setting_bond_port_get_queue_id(s_port)
- : NM_BOND_PORT_QUEUE_ID_DEF}),
- 0);
+ NMBondMode mode = NM_BOND_MODE_UNKNOWN;
+ const char *value;
+ NMSettingBond *s_bond;
+ gint32 prio;
+ gboolean prio_has;
+
+ s_bond = nm_device_get_applied_setting(bond_device, NM_TYPE_SETTING_BOND);
+ if (s_bond) {
+ value = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_MODE);
+ mode = _nm_setting_bond_mode_from_string(value);
+ }
+
+ prio = s_port ? nm_setting_bond_port_get_prio(s_port) : NM_BOND_PORT_PRIO_DEF;
+
+ if (prio != 0) {
+ /* The profile explicitly sets the priority. No matter what, we try to set it
+ * in netlink. */
+ prio_has = TRUE;
+ } else if (!NM_IN_SET(mode, NM_BOND_MODE_ACTIVEBACKUP, NM_BOND_MODE_TLB, NM_BOND_MODE_ALB)) {
+ /* The priority only is configurable with certain modes. If we don't have
+ * one of those modes, don't try to set the priority explicitly to zero. */
+ prio_has = FALSE;
+ } else if (nm_platform_kernel_support_get_full(
+ NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BOND_SLAVE_PRIO,
+ FALSE)
+ == NM_OPTION_BOOL_TRUE) {
+ /* We can only detect support if we have it. We cannot detect lack of support if
+ * we don't have it.
+ *
+ * But we did explicitly detect support, so explicitly set the prio to zero. */
+ prio_has = TRUE;
+ } else {
+ /* We either have an unsuitable mode or didn't detect kernel support for the
+ * priority. Don't explicitly set priority to zero. It is already the default,
+ * so it shouldn't be necessary. */
+ prio_has = FALSE;
+ }
+
+ nm_platform_link_change(nm_device_get_platform(port),
+ nm_device_get_ifindex(port),
+ NULL,
+ &((NMPlatformLinkBondPort){
+ .queue_id = s_port ? nm_setting_bond_port_get_queue_id(s_port)
+ : NM_BOND_PORT_QUEUE_ID_DEF,
+ .prio = prio_has ? prio : 0,
+ .prio_has = prio_has,
+ }),
+ 0);
}
static NMTernary
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 cf2a030f22..1646fa7aef 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
@@ -5590,6 +5590,7 @@ make_bond_port_setting(shvarFile *ifcfg)
gs_free char *value_to_free = NULL;
const char *value;
guint queue_id;
+ gint32 prio;
g_return_val_if_fail(ifcfg != NULL, FALSE);
@@ -5605,6 +5606,19 @@ make_bond_port_setting(shvarFile *ifcfg)
g_object_set(G_OBJECT(s_port), NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL);
}
+ value = svGetValue(ifcfg, "BOND_PORT_PRIO", &value_to_free);
+ if (value) {
+ if (!s_port)
+ s_port = nm_setting_bond_port_new();
+ prio =
+ _nm_utils_ascii_str_to_int64(value, 10, G_MININT32, G_MAXUINT32, NM_BOND_PORT_PRIO_DEF);
+ if (errno != 0) {
+ PARSE_WARNING("Invalid bond port prio value '%s'", value);
+ return s_port;
+ }
+ g_object_set(G_OBJECT(s_port), NM_SETTING_BOND_PORT_PRIO, prio, NULL);
+ }
+
return s_port;
}
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 f9cce442df..d46d71f99a 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_PRIO", 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),
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 ffc3679aee..51b118e3d3 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[262];
+extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[263];
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 3cf93e0656..acee4b215e 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
@@ -1911,8 +1911,10 @@ write_bond_port_setting(NMConnection *connection, shvarFile *ifcfg)
NMSettingBondPort *s_port;
s_port = _nm_connection_get_setting(connection, NM_TYPE_SETTING_BOND_PORT);
- if (s_port)
+ if (s_port) {
svSetValueInt64(ifcfg, "BOND_PORT_QUEUE_ID", nm_setting_bond_port_get_queue_id(s_port));
+ svSetValueInt64(ifcfg, "BOND_PORT_PRIO", nm_setting_bond_port_get_prio(s_port));
+ }
}
static gboolean
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 40ff7c670e..0172747481 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
@@ -8352,6 +8352,7 @@ test_write_bond_port(void)
s_bond_port = _nm_connection_new_setting(connection, NM_TYPE_SETTING_BOND_PORT);
g_object_set(s_bond_port, NM_SETTING_BOND_PORT_QUEUE_ID, 1, NULL);
+ g_object_set(s_bond_port, NM_SETTING_BOND_PORT_PRIO, 10, NULL);
nmtst_assert_connection_verifies(connection);
diff --git a/src/libnm-base/nm-base.h b/src/libnm-base/nm-base.h
index 77d2ef0a16..440fbc90c7 100644
--- a/src/libnm-base/nm-base.h
+++ b/src/libnm-base/nm-base.h
@@ -392,6 +392,7 @@ typedef struct {
/****************************************************************************/
#define NM_BOND_PORT_QUEUE_ID_DEF 0
+#define NM_BOND_PORT_PRIO_DEF 0
/****************************************************************************/
diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver
index d0745e2515..f473da2041 100644
--- a/src/libnm-client-impl/libnm.ver
+++ b/src/libnm-client-impl/libnm.ver
@@ -1928,6 +1928,7 @@ global:
libnm_1_44_0 {
global:
+ nm_setting_bond_port_get_prio;
nm_setting_gsm_get_initial_eps_apn;
nm_setting_gsm_get_initial_eps_config;
nm_setting_ip6_config_get_dhcp_pd_hint;
diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
index bbb4906af7..4e17a45baa 100644
--- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
+++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
@@ -584,6 +584,10 @@
<setting name="bond-port"
gtype="NMSettingBondPort"
>
+ <property name="prio"
+ dbus-type="i"
+ gprop-type="gint"
+ />
<property name="queue-id"
dbus-type="u"
gprop-type="guint"
diff --git a/src/libnm-core-impl/nm-setting-bond-port.c b/src/libnm-core-impl/nm-setting-bond-port.c
index d1656a31ac..e89179023d 100644
--- a/src/libnm-core-impl/nm-setting-bond-port.c
+++ b/src/libnm-core-impl/nm-setting-bond-port.c
@@ -22,9 +22,10 @@
/*****************************************************************************/
-NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBondPort, PROP_QUEUE_ID, );
+NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBondPort, PROP_QUEUE_ID, PROP_PRIO, );
typedef struct {
+ gint32 prio;
guint32 queue_id;
} NMSettingBondPortPrivate;
@@ -65,6 +66,22 @@ nm_setting_bond_port_get_queue_id(NMSettingBondPort *setting)
return NM_SETTING_BOND_PORT_GET_PRIVATE(setting)->queue_id;
}
+/**
+ * nm_setting_bond_port_get_prio:
+ * @setting: the #NMSettingBondPort
+ *
+ * Returns: the #NMSettingBondPort:prio property of the setting
+ *
+ * Since: 1.44
+ **/
+gint32
+nm_setting_bond_port_get_prio(NMSettingBondPort *setting)
+{
+ g_return_val_if_fail(NM_IS_SETTING_BOND_PORT(setting), 0);
+
+ return NM_SETTING_BOND_PORT_GET_PRIVATE(setting)->prio;
+}
+
/*****************************************************************************/
static gboolean
@@ -165,6 +182,35 @@ nm_setting_bond_port_class_init(NMSettingBondPortClass *klass)
NMSettingBondPort,
_priv.queue_id);
+ /**
+ * NMSettingBondPort:prio:
+ *
+ * The port priority for bond active port re-selection during failover. A
+ * higher number means a higher priority in selection. The primary port has
+ * the highest priority. This option is only compatible with active-backup,
+ * balance-tlb and balance-alb modes.
+ *
+ * Since: 1.44
+ **/
+ /* ---ifcfg-rh---
+ * property: prio
+ * variable: BOND_PORT_PRIO(+)
+ * values: -2147483648 - 2147483647
+ * default: 0
+ * description: Port priority.
+ * ---end---
+ */
+ _nm_setting_property_define_direct_int32(properties_override,
+ obj_properties,
+ NM_SETTING_BOND_PORT_PRIO,
+ PROP_PRIO,
+ G_MININT32,
+ G_MAXINT32,
+ NM_BOND_PORT_PRIO_DEF,
+ NM_SETTING_PARAM_INFERRABLE,
+ NMSettingBondPort,
+ _priv.prio);
+
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit(setting_class,
diff --git a/src/libnm-core-public/nm-setting-bond-port.h b/src/libnm-core-public/nm-setting-bond-port.h
index 0b20e4a8cb..033c59b492 100644
--- a/src/libnm-core-public/nm-setting-bond-port.h
+++ b/src/libnm-core-public/nm-setting-bond-port.h
@@ -29,6 +29,7 @@ G_BEGIN_DECLS
#define NM_SETTING_BOND_PORT_SETTING_NAME "bond-port"
#define NM_SETTING_BOND_PORT_QUEUE_ID "queue-id"
+#define NM_SETTING_BOND_PORT_PRIO "prio"
typedef struct _NMSettingBondPortClass NMSettingBondPortClass;
@@ -41,6 +42,9 @@ NMSetting *nm_setting_bond_port_new(void);
NM_AVAILABLE_IN_1_34
guint32 nm_setting_bond_port_get_queue_id(NMSettingBondPort *setting);
+NM_AVAILABLE_IN_1_44
+gint32 nm_setting_bond_port_get_prio(NMSettingBondPort *setting);
+
G_END_DECLS
#endif /* __NM_SETTING_BOND_PORT_H__ */
diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c
index fddee2aacd..b03d9ecdc2 100644
--- a/src/libnmc-setting/nm-meta-setting-desc.c
+++ b/src/libnmc-setting/nm-meta-setting-desc.c
@@ -5238,6 +5238,12 @@ static const NMMetaPropertyInfo *const property_infos_BOND_PORT[] = {
.prompt = N_("Queue ID"),
.property_type = &_pt_gobject_int,
),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_BOND_PORT_PRIO,
+ .is_cli_option = TRUE,
+ .property_alias = "prio",
+ .prompt = N_("Port Priority"),
+ .property_type= &_pt_gobject_int,
+ ),
NULL
};
diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in
index 8aba737378..9f16a7ffec 100644
--- a/src/libnmc-setting/settings-docs.h.in
+++ b/src/libnmc-setting/settings-docs.h.in
@@ -439,6 +439,7 @@
#define DESCRIBE_DOC_NM_SETTING_WPAN_PAGE N_("IEEE 802.15.4 channel page. A positive integer or -1, meaning \"do not set, use whatever the device is already set to\".")
#define DESCRIBE_DOC_NM_SETTING_WPAN_PAN_ID N_("IEEE 802.15.4 Personal Area Network (PAN) identifier.")
#define DESCRIBE_DOC_NM_SETTING_WPAN_SHORT_ADDRESS N_("Short IEEE 802.15.4 address to be used within a restricted environment.")
+#define DESCRIBE_DOC_NM_SETTING_BOND_PORT_PRIO N_("The port priority for bond active port re-selection during failover. A higher number means a higher priority in selection. The primary port has the highest priority. This option is only compatible with active-backup, balance-tlb and balance-alb modes.")
#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_HOSTNAME_FROM_DHCP N_("Whether the system hostname can be determined from DHCP on this connection. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).")
#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP N_("Whether the system hostname can be determined from reverse DNS lookup of addresses on this device. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).")
diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
index 1a86b591a7..720b257d20 100644
--- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
+++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
@@ -267,6 +267,9 @@
<property name="queue-id"
alias="queue-id"
description="The queue ID of this bond port. The maximum value of queue ID is the number of TX queues currently active in device." />
+ <property name="prio"
+ alias="prio"
+ description="The port priority for bond active port re-selection during failover. A higher number means a higher priority in selection. The primary port has the highest priority. This option is only compatible with active-backup, balance-tlb and balance-alb modes." />
</setting>
<setting name="bridge" >
<property name="mac-address"