From 17efec8b06f8b29db31f6ca24e226d60029be5c5 Mon Sep 17 00:00:00 2001 From: Jan Vaclav Date: Tue, 16 Sep 2025 17:54:22 +0200 Subject: [PATCH] platform: configure HSR interlink from property Uses the `hsr.interlink` property defined in the previous commit to configure the property in the kernel. --- src/core/devices/nm-device-hsr.c | 28 +++++++++++++++++++++----- src/libnm-platform/nm-linux-platform.c | 7 ++++++- src/libnm-platform/nm-platform.c | 13 +++++++++--- src/libnm-platform/nm-platform.h | 1 + 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/core/devices/nm-device-hsr.c b/src/core/devices/nm-device-hsr.c index 5bc685729d..e3368a5be6 100644 --- a/src/core/devices/nm-device-hsr.c +++ b/src/core/devices/nm-device-hsr.c @@ -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; } diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index b6b622d376..e703774388 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -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: diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 5c05de5a61..d7fb59b079 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -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; } diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 8735a929d0..9c8425b883 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -851,6 +851,7 @@ typedef struct { typedef struct { int port1; int port2; + int interlink; NMEtherAddr supervision_address; gint8 protocol_version; guint8 multicast_spec;