merge: branch 'jv/hsr-interlink'

libnm: introduce `hsr.interlink` property

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2285
This commit is contained in:
Jan Vaclav 2025-10-13 10:42:51 +00:00
commit 86b67233bf
12 changed files with 91 additions and 10 deletions

2
NEWS
View file

@ -27,6 +27,8 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
as a recoverable error.
* Add support for configuring systemd-resolved's DNSSEC option
per-connection via the "connection.dnssec" connection property.
* Support configuring the HSR interlink port via the
"hsr.interlink" property.
=============================================
NetworkManager-1.54

View file

@ -116,18 +116,31 @@ create_and_realize(NMDevice *device,
const NMPlatformLink **out_plink,
GError **error)
{
const char *iface = nm_device_get_iface(device);
NMSettingHsr *s_hsr;
NMPlatformLnkHsr lnk = {};
int r;
const char *iface = nm_device_get_iface(device);
nm_auto_free char *err_msg = NULL;
NMSettingHsr *s_hsr;
NMPlatformLnkHsr lnk = {};
int r = 0;
s_hsr = _nm_connection_get_setting(connection, NM_TYPE_SETTING_HSR);
nm_assert(s_hsr);
if (nm_setting_hsr_get_port1(s_hsr) != NULL)
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));
if (nm_setting_hsr_get_interlink(s_hsr) != NULL) {
const char *ifname = nm_setting_hsr_get_interlink(s_hsr);
int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, ifname);
if (ifindex <= 0) {
err_msg = g_strdup_printf("interlink port '%s' does not exist", ifname);
goto out;
}
lnk.interlink = ifindex;
}
lnk.multicast_spec = nm_setting_hsr_get_multicast_spec(s_hsr);
lnk.prp = nm_setting_hsr_get_prp(s_hsr);
@ -136,13 +149,18 @@ create_and_realize(NMDevice *device,
r = nm_platform_link_hsr_add(nm_device_get_platform(device), iface, &lnk, out_plink);
if (r < 0) {
err_msg = g_strdup(nm_strerror(r) ?: "unknown");
}
out:
if (err_msg) {
g_set_error(error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_CREATION_FAILED,
"Failed to create HSR interface '%s' for '%s': %s",
iface,
nm_connection_get_id(connection),
nm_strerror(r));
err_msg);
return FALSE;
}

View file

@ -2081,6 +2081,7 @@ libnm_1_56_0 {
global:
nm_dns_server_validate;
nm_setting_gsm_get_device_uid;
nm_setting_hsr_get_interlink;
nm_setting_hsr_get_protocol_version;
nm_setting_hsr_protocol_version_get_type;
nm_setting_connection_get_dnssec;

View file

@ -1524,6 +1524,10 @@
<setting name="hsr"
gtype="NMSettingHsr"
>
<property name="interlink"
dbus-type="s"
gprop-type="gchararray"
/>
<property name="multicast-spec"
dbus-type="u"
gprop-type="guint"

View file

@ -28,11 +28,13 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHsr,
PROP_PORT2,
PROP_MULTICAST_SPEC,
PROP_PRP,
PROP_PROTOCOL_VERSION, );
PROP_PROTOCOL_VERSION,
PROP_INTERLINK, );
typedef struct {
char *port1;
char *port2;
char *interlink;
guint32 multicast_spec;
int protocol_version;
bool prp;
@ -139,6 +141,22 @@ nm_setting_hsr_get_protocol_version(NMSettingHsr *setting)
return NM_SETTING_HSR_GET_PRIVATE(setting)->protocol_version;
}
/**
* nm_setting_hsr_get_interlink:
* @setting: the #NMSettingHsr
*
* Returns: the #NMSettingHsr:interlink property of the setting
*
* Since: 1.56
**/
const char *
nm_setting_hsr_get_interlink(NMSettingHsr *setting)
{
g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NULL);
return NM_SETTING_HSR_GET_PRIVATE(setting)->interlink;
}
/*****************************************************************************/
static gboolean
@ -315,6 +333,21 @@ nm_setting_hsr_class_init(NMSettingHsrClass *klass)
NMSettingHsr,
_priv.protocol_version);
/**
* NMSettingHsr:interlink:
*
* The optional interlink port name of the HSR interface.
*
* Since: 1.56
**/
_nm_setting_property_define_direct_string(properties_override,
obj_properties,
NM_SETTING_HSR_INTERLINK,
PROP_INTERLINK,
NM_SETTING_PARAM_INFERRABLE,
NMSettingHsr,
_priv.interlink);
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);

View file

@ -28,6 +28,7 @@ G_BEGIN_DECLS
#define NM_SETTING_HSR_MULTICAST_SPEC "multicast-spec"
#define NM_SETTING_HSR_PRP "prp"
#define NM_SETTING_HSR_PROTOCOL_VERSION "protocol-version"
#define NM_SETTING_HSR_INTERLINK "interlink"
/**
* NMSettingHsrProtocolVersion:
@ -62,6 +63,8 @@ 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);
NM_AVAILABLE_IN_1_56
const char *nm_setting_hsr_get_interlink(NMSettingHsr *setting);
G_END_DECLS

View file

@ -253,7 +253,8 @@ G_STATIC_ASSERT(RTA_MAX == (__RTA_MAX - 1));
#define IFLA_HSR_SEQ_NR 5
#define IFLA_HSR_VERSION 6
#define IFLA_HSR_PROTOCOL 7
#define __IFLA_HSR_MAX 8
#define IFLA_HSR_INTERLINK 8
#define __IFLA_HSR_MAX 9
/*****************************************************************************/
@ -5225,6 +5226,10 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo
NLA_PUT_U8(msg, IFLA_HSR_VERSION, props->protocol_version);
}
if (props->interlink > 0) {
NLA_PUT_U32(msg, IFLA_HSR_INTERLINK, props->interlink);
}
break;
}
case NM_LINK_TYPE_SIT:

View file

@ -6560,6 +6560,8 @@ nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len)
const char *
nm_platform_lnk_hsr_to_string(const NMPlatformLnkHsr *lnk, char *buf, gsize len)
{
char interlink_buf[30];
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
return buf;
@ -6570,13 +6572,16 @@ nm_platform_lnk_hsr_to_string(const NMPlatformLnkHsr *lnk, char *buf, gsize len)
"port2 %d "
"supervision_address " NM_ETHER_ADDR_FORMAT_STR " multicast_spec %u "
"prp %s "
"protocol_version %d",
"protocol_version %d"
"%s", /* interlink */
lnk->port1,
lnk->port2,
NM_ETHER_ADDR_FORMAT_VAL(&lnk->supervision_address),
lnk->multicast_spec,
lnk->prp ? "on" : "off",
lnk->protocol_version);
lnk->protocol_version,
lnk->interlink ? nm_sprintf_buf(interlink_buf, " interlink %d", lnk->interlink)
: "");
return buf;
}
@ -8494,7 +8499,8 @@ nm_platform_lnk_hsr_hash_update(const NMPlatformLnkHsr *obj, NMHashState *h)
obj->supervision_address,
obj->multicast_spec,
NM_HASH_COMBINE_BOOLS(guint8, obj->prp),
obj->protocol_version);
obj->protocol_version,
obj->interlink);
}
int
@ -8507,6 +8513,7 @@ nm_platform_lnk_hsr_cmp(const NMPlatformLnkHsr *a, const NMPlatformLnkHsr *b)
NM_CMP_FIELD(a, b, multicast_spec);
NM_CMP_FIELD_BOOL(a, b, prp);
NM_CMP_FIELD(a, b, protocol_version);
NM_CMP_FIELD(a, b, interlink);
return 0;
}

View file

@ -851,6 +851,7 @@ typedef struct {
typedef struct {
int port1;
int port2;
int interlink;
NMEtherAddr supervision_address;
gint8 protocol_version;
guint8 multicast_spec;

View file

@ -6251,6 +6251,9 @@ static const NMMetaPropertyInfo *const property_infos_HSR[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_PROTOCOL_VERSION,
.property_type = &_pt_gobject_enum,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_INTERLINK,
.property_type = &_pt_gobject_string,
),
NULL
};

View file

@ -173,6 +173,7 @@
#define DESCRIBE_DOC_NM_SETTING_GSM_SIM_ID N_("The SIM card unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will apply to any device also allowed by \"device-id\" which contains a SIM card matching the given identifier.")
#define DESCRIBE_DOC_NM_SETTING_GSM_SIM_OPERATOR_ID N_("A MCC/MNC string like \"310260\" or \"21601\" identifying the specific mobile network operator which this connection applies to. If given, the connection will apply to any device also allowed by \"device-id\" and \"sim-id\" which contains a SIM card provisioned by the given operator.")
#define DESCRIBE_DOC_NM_SETTING_GSM_USERNAME N_("The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.")
#define DESCRIBE_DOC_NM_SETTING_HSR_INTERLINK N_("The optional interlink port name of the HSR interface.")
#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.")

View file

@ -1246,6 +1246,9 @@
nmcli-description="Configures the protocol version to be used for the HSR/PRP interface. &quot;default&quot; (-1) sets the protocol version to the default version for the protocol. &quot;hsr-2010&quot; (0) sets the protocol version to HSRv0 (IEC 62439-3:2010). &quot;hsr-2012&quot; (1) sets the protocol version to HSRv1 (IEC 62439-3:2012)."
format="choice (NMSettingHsrProtocolVersion)"
values="default (-1), hsr-2010 (0), hsr-2012 (1)" />
<property name="interlink"
nmcli-description="The optional interlink port name of the HSR interface."
format="string" />
</setting>
<setting name="infiniband" >
<property name="mac-address"