diff --git a/NEWS b/NEWS index 61a39c9d0e..0443da7082 100644 --- a/NEWS +++ b/NEWS @@ -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 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-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index 80f779c190..ca7a4c300e 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -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; 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 f584ee5d2c..c83deea9c1 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 @@ -1524,6 +1524,10 @@ + 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); diff --git a/src/libnm-core-public/nm-setting-hsr.h b/src/libnm-core-public/nm-setting-hsr.h index 17fccdfd56..3110bd9a09 100644 --- a/src/libnm-core-public/nm-setting-hsr.h +++ b/src/libnm-core-public/nm-setting-hsr.h @@ -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 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; diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c index e1658a4701..e2ab8dfafe 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.c +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -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 }; diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in index 0db894d17f..e4ed5f6ba9 100644 --- a/src/libnmc-setting/settings-docs.h.in +++ b/src/libnmc-setting/settings-docs.h.in @@ -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.") diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in index 01314e622a..9f3f0ef383 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in @@ -1246,6 +1246,9 @@ nmcli-description="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)." format="choice (NMSettingHsrProtocolVersion)" values="default (-1), hsr-2010 (0), hsr-2012 (1)" /> +