diff options
author | Fernando Fernandez Mancera <ffmancera@riseup.net> | 2023-03-09 12:18:14 +0100 |
---|---|---|
committer | Fernando Fernandez Mancera <ffmancera@riseup.net> | 2023-05-03 10:44:06 +0200 |
commit | 2f0571f1930ff2c11de4f48b4433ca5fe6c897a0 (patch) | |
tree | f803c1aac7608fd14c83d72b24024eb6c52082aa | |
parent | e200b162914d3bda4c03a19652124330a99bb3ae (diff) | |
download | NetworkManager-2f0571f1930ff2c11de4f48b4433ca5fe6c897a0.tar.gz |
bonding: add support to prio property in bond portsff/bond_port_options
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.c | 62 | ||||
-rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 23 | ||||
-rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c | 1 | ||||
-rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h | 2 | ||||
-rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 4 | ||||
-rw-r--r-- | src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 1 | ||||
-rw-r--r-- | src/libnm-base/nm-base.h | 1 | ||||
-rw-r--r-- | src/libnm-client-impl/libnm.ver | 1 | ||||
-rw-r--r-- | src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in | 4 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-bond-port.c | 48 | ||||
-rw-r--r-- | src/libnm-core-public/nm-setting-bond-port.h | 4 | ||||
-rw-r--r-- | src/libnmc-setting/nm-meta-setting-desc.c | 6 | ||||
-rw-r--r-- | src/libnmc-setting/settings-docs.h.in | 1 | ||||
-rw-r--r-- | src/nmcli/gen-metadata-nm-settings-nmcli.xml.in | 3 |
14 files changed, 145 insertions, 16 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..4009574472 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); @@ -5598,11 +5599,23 @@ make_bond_port_setting(shvarFile *ifcfg) 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'", value); - return s_port; - } - g_object_set(G_OBJECT(s_port), NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL); + if (errno != 0) + PARSE_WARNING("Invalid bond port queue_id value BOND_PORT_QUEUE_ID '%s'", value); + else + g_object_set(G_OBJECT(s_port), NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL); + } + + nm_clear_g_free(&value_to_free); + 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_MAXINT32, NM_BOND_PORT_PRIO_DEF); + if (errno != 0) + PARSE_WARNING("Invalid bond port prio value BOND_PORT_PRIO '%s'", value); + else + 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" |