diff --git a/NEWS b/NEWS
index f2505251bf..db2282d655 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,8 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
* Add support for a new rd.net.dhcp.client-id option in
nm-initrd-generator.
* Add gsm device-uid setting to restrict the devices the connection applies to.
+* Support configuring the HSR protocol version via the
+ "hsr.protocol-version" property.
=============================================
NetworkManager-1.54
diff --git a/src/core/devices/nm-device-hsr.c b/src/core/devices/nm-device-hsr.c
index 59454ee341..5bc685729d 100644
--- a/src/core/devices/nm-device-hsr.c
+++ b/src/core/devices/nm-device-hsr.c
@@ -128,9 +128,13 @@ create_and_realize(NMDevice *device,
lnk.port1 = nm_platform_link_get_ifindex(NM_PLATFORM_GET, nm_setting_hsr_get_port1(s_hsr));
if (nm_setting_hsr_get_port2(s_hsr) != NULL)
lnk.port2 = nm_platform_link_get_ifindex(NM_PLATFORM_GET, nm_setting_hsr_get_port2(s_hsr));
- lnk.multicast_spec = nm_setting_hsr_get_multicast_spec(s_hsr);
- lnk.prp = nm_setting_hsr_get_prp(s_hsr);
+
+ lnk.multicast_spec = nm_setting_hsr_get_multicast_spec(s_hsr);
+ lnk.prp = nm_setting_hsr_get_prp(s_hsr);
+ lnk.protocol_version = nm_setting_hsr_get_protocol_version(s_hsr);
+
r = nm_platform_link_hsr_add(nm_device_get_platform(device), iface, &lnk, out_plink);
+
if (r < 0) {
g_set_error(error,
NM_DEVICE_ERROR,
diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver
index 3c956a36e1..bcc2ed8453 100644
--- a/src/libnm-client-impl/libnm.ver
+++ b/src/libnm-client-impl/libnm.ver
@@ -2081,4 +2081,6 @@ libnm_1_56_0 {
global:
nm_dns_server_validate;
nm_setting_gsm_get_device_uid;
+ nm_setting_hsr_get_protocol_version;
+ nm_setting_hsr_protocol_version_get_type;
} libnm_1_54_0;
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 b1670dc2dc..1836efd03f 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
@@ -1532,6 +1532,10 @@
dbus-type="s"
gprop-type="gchararray"
/>
+
prp;
}
+/**
+ * nm_setting_hsr_get_protocol_version:
+ * @setting: the #NMSettingHsr
+ *
+ * Returns: the #NMSettingHsr:protocol-version property of the setting
+ *
+ * Since: 1.56
+ **/
+NMSettingHsrProtocolVersion
+nm_setting_hsr_get_protocol_version(NMSettingHsr *setting)
+{
+ g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT);
+
+ return NM_SETTING_HSR_GET_PRIVATE(setting)->protocol_version;
+}
+
/*****************************************************************************/
static gboolean
@@ -160,6 +182,18 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
+ if (priv->prp && priv->protocol_version != NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT) {
+ g_set_error(error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("HSR protocol cannot be configured for PRP interfaces"));
+ g_prefix_error(error,
+ "%s.%s: ",
+ NM_SETTING_HSR_SETTING_NAME,
+ NM_SETTING_HSR_PROTOCOL_VERSION);
+ return FALSE;
+ }
+
return TRUE;
}
@@ -260,6 +294,27 @@ nm_setting_hsr_class_init(NMSettingHsrClass *klass)
NMSettingHsr,
_priv.prp);
+ /**
+ * NMSettingHsr:protocol-version:
+ *
+ * Configures the protocol version to be used for the HSR/PRP interface.
+ * %NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT sets the protocol version to the default version for the protocol.
+ * %NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010 sets the protocol version to HSRv0 (IEC 62439-3:2010).
+ * %NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012 sets the protocol version to HSRv1 (IEC 62439-3:2012).
+ *
+ * Since: 1.56
+ **/
+ _nm_setting_property_define_direct_enum(properties_override,
+ obj_properties,
+ NM_SETTING_HSR_PROTOCOL_VERSION,
+ PROP_PROTOCOL_VERSION,
+ NM_TYPE_SETTING_HSR_PROTOCOL_VERSION,
+ NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT,
+ NM_SETTING_PARAM_NONE,
+ NULL,
+ NMSettingHsr,
+ _priv.protocol_version);
+
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_HSR, NULL, properties_override, 0);
diff --git a/src/libnm-core-public/nm-setting-hsr.h b/src/libnm-core-public/nm-setting-hsr.h
index f7b0136fd1..17fccdfd56 100644
--- a/src/libnm-core-public/nm-setting-hsr.h
+++ b/src/libnm-core-public/nm-setting-hsr.h
@@ -23,10 +23,27 @@ G_BEGIN_DECLS
#define NM_SETTING_HSR_SETTING_NAME "hsr"
-#define NM_SETTING_HSR_PORT1 "port1"
-#define NM_SETTING_HSR_PORT2 "port2"
-#define NM_SETTING_HSR_MULTICAST_SPEC "multicast-spec"
-#define NM_SETTING_HSR_PRP "prp"
+#define NM_SETTING_HSR_PORT1 "port1"
+#define NM_SETTING_HSR_PORT2 "port2"
+#define NM_SETTING_HSR_MULTICAST_SPEC "multicast-spec"
+#define NM_SETTING_HSR_PRP "prp"
+#define NM_SETTING_HSR_PROTOCOL_VERSION "protocol-version"
+
+/**
+ * NMSettingHsrProtocolVersion:
+ * @NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT: Default version for the protocol
+ * @NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010: HSRv0, IEC 62439-3:2010
+ * @NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012: HSRv1, IEC 62439-3:2012
+ *
+ * #NMSettingHsrProtocolVersion values indicate the HSR protocol version.
+ *
+ * Since: 1.56
+ */
+typedef enum {
+ NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT = -1,
+ NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010 = 0,
+ NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012 = 1,
+} NMSettingHsrProtocolVersion;
typedef struct _NMSettingHsrClass NMSettingHsrClass;
@@ -43,6 +60,8 @@ NM_AVAILABLE_IN_1_46
guint32 nm_setting_hsr_get_multicast_spec(NMSettingHsr *setting);
NM_AVAILABLE_IN_1_46
gboolean nm_setting_hsr_get_prp(NMSettingHsr *setting);
+NM_AVAILABLE_IN_1_56
+NMSettingHsrProtocolVersion nm_setting_hsr_get_protocol_version(NMSettingHsr *setting);
G_END_DECLS
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index c7c78265c6..b6b622d376 100644
--- a/src/libnm-platform/nm-linux-platform.c
+++ b/src/libnm-platform/nm-linux-platform.c
@@ -5220,6 +5220,11 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo
NLA_PUT_U8(msg, IFLA_HSR_MULTICAST_SPEC, props->multicast_spec);
NLA_PUT_U8(msg, IFLA_HSR_PROTOCOL, props->prp);
+
+ if (!props->prp && props->protocol_version >= 0) {
+ NLA_PUT_U8(msg, IFLA_HSR_VERSION, props->protocol_version);
+ }
+
break;
}
case NM_LINK_TYPE_SIT:
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
index 559c7dc3a4..5c05de5a61 100644
--- a/src/libnm-platform/nm-platform.c
+++ b/src/libnm-platform/nm-platform.c
@@ -6569,12 +6569,14 @@ nm_platform_lnk_hsr_to_string(const NMPlatformLnkHsr *lnk, char *buf, gsize len)
"port1 %d "
"port2 %d "
"supervision_address " NM_ETHER_ADDR_FORMAT_STR " multicast_spec %u "
- "prp %s",
+ "prp %s "
+ "protocol_version %d",
lnk->port1,
lnk->port2,
NM_ETHER_ADDR_FORMAT_VAL(&lnk->supervision_address),
lnk->multicast_spec,
- lnk->prp ? "on" : "off");
+ lnk->prp ? "on" : "off",
+ lnk->protocol_version);
return buf;
}
@@ -8491,7 +8493,8 @@ nm_platform_lnk_hsr_hash_update(const NMPlatformLnkHsr *obj, NMHashState *h)
obj->port2,
obj->supervision_address,
obj->multicast_spec,
- NM_HASH_COMBINE_BOOLS(guint8, obj->prp));
+ NM_HASH_COMBINE_BOOLS(guint8, obj->prp),
+ obj->protocol_version);
}
int
@@ -8503,6 +8506,7 @@ nm_platform_lnk_hsr_cmp(const NMPlatformLnkHsr *a, const NMPlatformLnkHsr *b)
NM_CMP_FIELD_MEMCMP(a, b, supervision_address);
NM_CMP_FIELD(a, b, multicast_spec);
NM_CMP_FIELD_BOOL(a, b, prp);
+ NM_CMP_FIELD(a, b, protocol_version);
return 0;
}
diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
index 18204e39bc..8735a929d0 100644
--- a/src/libnm-platform/nm-platform.h
+++ b/src/libnm-platform/nm-platform.h
@@ -852,6 +852,7 @@ typedef struct {
int port1;
int port2;
NMEtherAddr supervision_address;
+ gint8 protocol_version;
guint8 multicast_spec;
bool prp : 1;
} _nm_alignas(NMPlatformObject) NMPlatformLnkHsr;
diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c
index c4b5b7f5b1..7ae2e2eeb8 100644
--- a/src/libnmc-setting/nm-meta-setting-desc.c
+++ b/src/libnmc-setting/nm-meta-setting-desc.c
@@ -6245,6 +6245,9 @@ static const NMMetaPropertyInfo *const property_infos_HSR[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_PRP,
.property_type = &_pt_gobject_bool,
),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_PROTOCOL_VERSION,
+ .property_type = &_pt_gobject_enum,
+ ),
NULL
};
diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in
index a49aee827c..3fd2966bce 100644
--- a/src/libnmc-setting/settings-docs.h.in
+++ b/src/libnmc-setting/settings-docs.h.in
@@ -175,6 +175,7 @@
#define DESCRIBE_DOC_NM_SETTING_HSR_MULTICAST_SPEC N_("The last byte of supervision address.")
#define DESCRIBE_DOC_NM_SETTING_HSR_PORT1 N_("The port1 interface name of the HSR. This property is mandatory.")
#define DESCRIBE_DOC_NM_SETTING_HSR_PORT2 N_("The port2 interface name of the HSR. This property is mandatory.")
+#define DESCRIBE_DOC_NM_SETTING_HSR_PROTOCOL_VERSION N_("Configures the protocol version to be used for the HSR/PRP interface. \"default\" (-1) sets the protocol version to the default version for the protocol. \"hsr-2010\" (0) sets the protocol version to HSRv0 (IEC 62439-3:2010). \"hsr-2012\" (1) sets the protocol version to HSRv1 (IEC 62439-3:2012).")
#define DESCRIBE_DOC_NM_SETTING_HSR_PRP N_("The protocol used by the interface, whether it is PRP or HSR.")
#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MAC_ADDRESS N_("If specified, this connection will only apply to the IPoIB device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).")
#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.")
diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
index 481aa4a280..1c99df9837 100644
--- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
+++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
@@ -1238,6 +1238,10 @@
nmcli-description="The protocol used by the interface, whether it is PRP or HSR."
format="boolean"
values="true/yes/on, false/no/off" />
+