HSR: add support to HSR/PRP interface

This patch add support to HSR/PRP interface. Please notice that PRP
driver is represented as HSR too. They are different drivers but on
kernel they are integrated together.

HSR/PRP is a network protocol standard for Ethernet that provides
seamless failover against failure of any network component. It intends
to be transparent to the application. These protocols are useful for
applications that request high availability and short switchover time
e.g electrical substation or high power inverters.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1791
This commit is contained in:
Fernando Fernandez Mancera 2023-10-27 14:01:13 +02:00
parent f6bc12936f
commit 5426bdf4a1
46 changed files with 1439 additions and 3 deletions

View file

@ -1021,6 +1021,8 @@ introspection_sources = \
introspection/org.freedesktop.NetworkManager.Device.Dummy.h \
introspection/org.freedesktop.NetworkManager.Device.Generic.c \
introspection/org.freedesktop.NetworkManager.Device.Generic.h \
introspection/org.freedesktop.NetworkManager.Device.Hsr.c \
introspection/org.freedesktop.NetworkManager.Device.Hsr.h \
introspection/org.freedesktop.NetworkManager.Device.IPTunnel.c \
introspection/org.freedesktop.NetworkManager.Device.IPTunnel.h \
introspection/org.freedesktop.NetworkManager.Device.Infiniband.c \
@ -1112,6 +1114,7 @@ DBUS_INTERFACE_DOCS = \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Bridge.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Dummy.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Generic.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Hsr.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.IPTunnel.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Infiniband.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Loopback.xml \
@ -1181,6 +1184,7 @@ dbusinterfaces_DATA = \
introspection/org.freedesktop.NetworkManager.Device.Bridge.xml \
introspection/org.freedesktop.NetworkManager.Device.Dummy.xml \
introspection/org.freedesktop.NetworkManager.Device.Generic.xml \
introspection/org.freedesktop.NetworkManager.Device.Hsr.xml \
introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml \
introspection/org.freedesktop.NetworkManager.Device.Infiniband.xml \
introspection/org.freedesktop.NetworkManager.Device.Loopback.xml \
@ -1260,6 +1264,7 @@ src_libnm_core_impl_lib_h_pub_real = \
src/libnm-core-public/nm-setting-generic.h \
src/libnm-core-public/nm-setting-gsm.h \
src/libnm-core-public/nm-setting-hostname.h \
src/libnm-core-public/nm-setting-hsr.h \
src/libnm-core-public/nm-setting-infiniband.h \
src/libnm-core-public/nm-setting-ip-config.h \
src/libnm-core-public/nm-setting-ip-tunnel.h \
@ -1342,6 +1347,7 @@ src_libnm_core_impl_lib_c_settings_real = \
src/libnm-core-impl/nm-setting-generic.c \
src/libnm-core-impl/nm-setting-gsm.c \
src/libnm-core-impl/nm-setting-hostname.c \
src/libnm-core-impl/nm-setting-hsr.c \
src/libnm-core-impl/nm-setting-infiniband.c \
src/libnm-core-impl/nm-setting-ip-config.c \
src/libnm-core-impl/nm-setting-ip-tunnel.c \
@ -1741,6 +1747,7 @@ libnm_lib_h_pub_real = \
src/libnm-client-public/nm-device-dummy.h \
src/libnm-client-public/nm-device-ethernet.h \
src/libnm-client-public/nm-device-generic.h \
src/libnm-client-public/nm-device-hsr.h \
src/libnm-client-public/nm-device-infiniband.h \
src/libnm-client-public/nm-device-ip-tunnel.h \
src/libnm-client-public/nm-device-loopback.h \
@ -1812,6 +1819,7 @@ libnm_lib_c_real = \
src/libnm-client-impl/nm-device-dummy.c \
src/libnm-client-impl/nm-device-ethernet.c \
src/libnm-client-impl/nm-device-generic.c \
src/libnm-client-impl/nm-device-hsr.c \
src/libnm-client-impl/nm-device-infiniband.c \
src/libnm-client-impl/nm-device-ip-tunnel.c \
src/libnm-client-impl/nm-device-loopback.c \
@ -2656,6 +2664,8 @@ src_core_libNetworkManager_la_SOURCES = \
src/core/devices/nm-device-dummy.h \
src/core/devices/nm-device-ethernet.c \
src/core/devices/nm-device-ethernet.h \
src/core/devices/nm-device-hsr.c \
src/core/devices/nm-device-hsr.h \
src/core/devices/nm-device-infiniband.c \
src/core/devices/nm-device-infiniband.h \
src/core/devices/nm-device-ip-tunnel.c \

View file

@ -39,6 +39,7 @@ content_files = \
dbus-org.freedesktop.NetworkManager.Device.Bridge.xml \
dbus-org.freedesktop.NetworkManager.Device.Dummy.xml \
dbus-org.freedesktop.NetworkManager.Device.Generic.xml \
dbus-org.freedesktop.NetworkManager.Device.Hsr.xml \
dbus-org.freedesktop.NetworkManager.Device.IPTunnel.xml \
dbus-org.freedesktop.NetworkManager.Device.Infiniband.xml \
dbus-org.freedesktop.NetworkManager.Device.Loopback.xml \

View file

@ -183,6 +183,7 @@
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Bridge.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Dummy.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Generic.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Hsr.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.IPTunnel.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Infiniband.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Loopback.xml"/>

View file

@ -319,6 +319,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in
<xi:include href="xml/nm-setting-generic.xml"/>
<xi:include href="xml/nm-setting-gsm.xml"/>
<xi:include href="xml/nm-setting-hostname.xml"/>
<xi:include href="xml/nm-setting-hsr.xml"/>
<xi:include href="xml/nm-setting-infiniband.xml"/>
<xi:include href="xml/nm-setting-ip-config.xml"/>
<xi:include href="xml/nm-setting-ip-tunnel.xml"/>
@ -374,6 +375,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in
<xi:include href="xml/nm-device-dummy.xml"/>
<xi:include href="xml/nm-device-ethernet.xml"/>
<xi:include href="xml/nm-device-generic.xml"/>
<xi:include href="xml/nm-device-hsr.xml"/>
<xi:include href="xml/nm-device-infiniband.xml"/>
<xi:include href="xml/nm-device-ip-tunnel.xml"/>
<xi:include href="xml/nm-device-loopback.xml"/>

View file

@ -15,6 +15,7 @@ ifaces = [
'org.freedesktop.NetworkManager.Device.Bridge',
'org.freedesktop.NetworkManager.Device.Dummy',
'org.freedesktop.NetworkManager.Device.Generic',
'org.freedesktop.NetworkManager.Device.Hsr',
'org.freedesktop.NetworkManager.Device.IPTunnel',
'org.freedesktop.NetworkManager.Device.Infiniband',
'org.freedesktop.NetworkManager.Device.Loopback',

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/">
<!--
org.freedesktop.NetworkManager.Device.Hsr:
@short_description: HSR Device.
-->
<interface name="org.freedesktop.NetworkManager.Device.Hsr">
<!--
Port1:
@since: 1.46
The device's port1 device.
-->
<property name="Port1" type="o" access="read"/>
<!--
Port2:
@since: 1.46
The device's port2 device.
-->
<property name="Port2" type="o" access="read"/>
<!--
SupervisionAddress:
@since: 1.46
The supervision MAC address.
-->
<property name="SupervisionAddress" type="s" access="read"/>
<!--
MulticastSpec:
@since: 1.46
The last byte of the supervision address.
-->
<property name="MulticastSpec" type="y" access="read"/>
<!--
Prp:
@since: 1.46
Whether the PRP protocol is used or not.
-->
<property name="Prp" type="b" access="read"/>
</interface>
</node>

View file

@ -396,6 +396,7 @@ nm_device_factory_manager_load_factories(NMDeviceFactoryManagerFactoryFunc callb
_ADD_INTERNAL(nm_bridge_device_factory_get_type);
_ADD_INTERNAL(nm_dummy_device_factory_get_type);
_ADD_INTERNAL(nm_ethernet_device_factory_get_type);
_ADD_INTERNAL(nm_hsr_device_factory_get_type);
_ADD_INTERNAL(nm_infiniband_device_factory_get_type);
_ADD_INTERNAL(nm_ip_tunnel_device_factory_get_type);
_ADD_INTERNAL(nm_loopback_device_factory_get_type);

View file

@ -0,0 +1,290 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2023 Red Hat, Inc.
*/
#include "src/core/nm-default-daemon.h"
#include "nm-manager.h"
#include "nm-device-hsr.h"
#include <linux/if_ether.h>
#include "libnm-core-intern/nm-core-internal.h"
#include "nm-act-request.h"
#include "nm-device-private.h"
#include "nm-setting-hsr.h"
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
#define _NMLOG_DEVICE_TYPE NMDeviceHsr
#include "nm-device-logging.h"
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceHsr,
PROP_PORT1,
PROP_PORT2,
PROP_SUPERVISION_ADDRESS,
PROP_MULTICAST_SPEC,
PROP_PRP, );
typedef struct {
NMPlatformLnkHsr props;
} NMDeviceHsrPrivate;
struct _NMDeviceHsr {
NMDevice parent;
NMDeviceHsrPrivate _priv;
};
struct _NMDeviceHsrClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE(NMDeviceHsr, nm_device_hsr, NM_TYPE_DEVICE)
#define NM_DEVICE_HSR_GET_PRIVATE(self) \
_NM_GET_PRIVATE(self, NMDeviceHsr, NM_IS_DEVICE_HSR, NMDevice)
/*****************************************************************************/
static NMDeviceCapabilities
get_generic_capabilities(NMDevice *dev)
{
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
static void
update_properties(NMDevice *device)
{
NMDeviceHsr *self;
NMDeviceHsrPrivate *priv;
const NMPlatformLink *plink;
const NMPlatformLnkHsr *props;
int ifindex;
g_return_if_fail(NM_IS_DEVICE_HSR(device));
self = NM_DEVICE_HSR(device);
priv = NM_DEVICE_HSR_GET_PRIVATE(self);
ifindex = nm_device_get_ifindex(device);
g_return_if_fail(ifindex > 0);
props = nm_platform_link_get_lnk_hsr(nm_device_get_platform(device), ifindex, &plink);
if (!props) {
_LOGW(LOGD_PLATFORM, "could not get HSR properties");
return;
}
g_object_freeze_notify((GObject *) device);
#define CHECK_PROPERTY_CHANGED(field, prop) \
G_STMT_START \
{ \
if (priv->props.field != props->field) { \
priv->props.field = props->field; \
_notify(self, prop); \
} \
} \
G_STMT_END
CHECK_PROPERTY_CHANGED(port1, PROP_PORT1);
CHECK_PROPERTY_CHANGED(port2, PROP_PORT2);
CHECK_PROPERTY_CHANGED(multicast_spec, PROP_MULTICAST_SPEC);
CHECK_PROPERTY_CHANGED(prp, PROP_PRP);
if (!nm_ether_addr_equal(&priv->props.supervision_address, &props->supervision_address))
_notify(self, PROP_SUPERVISION_ADDRESS);
g_object_thaw_notify((GObject *) device);
}
static void
link_changed(NMDevice *device, const NMPlatformLink *pllink)
{
NM_DEVICE_CLASS(nm_device_hsr_parent_class)->link_changed(device, pllink);
update_properties(device);
}
static gboolean
create_and_realize(NMDevice *device,
NMConnection *connection,
NMDevice *parent,
const NMPlatformLink **out_plink,
GError **error)
{
const char *iface = nm_device_get_iface(device);
NMSettingHsr *s_hsr;
NMPlatformLnkHsr lnk = {};
int r;
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_supervision_address(s_hsr) != NULL)
nm_ether_addr_from_string(&lnk.supervision_address,
nm_setting_hsr_get_supervision_address(s_hsr));
lnk.multicast_spec = nm_setting_hsr_get_multicast_spec(s_hsr);
lnk.prp = nm_setting_hsr_get_prp(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,
NM_DEVICE_ERROR_CREATION_FAILED,
"Failed to create HSR interface '%s' for '%s': %s",
iface,
nm_connection_get_id(connection),
nm_strerror(r));
return FALSE;
}
return TRUE;
}
/*****************************************************************************/
static void
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
NMDeviceHsr *self = NM_DEVICE_HSR(object);
NMDeviceHsrPrivate *priv = NM_DEVICE_HSR_GET_PRIVATE(self);
NMDevice *port;
switch (prop_id) {
case PROP_PORT1:
port = nm_manager_get_device_by_ifindex(NM_MANAGER_GET, priv->props.port1);
nm_dbus_utils_g_value_set_object_path(value, port);
break;
case PROP_PORT2:
port = nm_manager_get_device_by_ifindex(NM_MANAGER_GET, priv->props.port2);
nm_dbus_utils_g_value_set_object_path(value, port);
break;
case PROP_SUPERVISION_ADDRESS:
g_value_take_string(value, nm_ether_addr_to_string_dup(&priv->props.supervision_address));
break;
case PROP_MULTICAST_SPEC:
g_value_set_uchar(value, priv->props.multicast_spec);
break;
case PROP_PRP:
g_value_set_boolean(value, priv->props.prp);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
nm_device_hsr_init(NMDeviceHsr *self)
{}
/*****************************************************************************/
static const NMDBusInterfaceInfoExtended interface_info_device_hsr = {
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
NM_DBUS_INTERFACE_DEVICE_HSR,
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Port1", "o", NM_DEVICE_HSR_PORT1),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Port2", "o", NM_DEVICE_HSR_PORT2),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("SupervisionAddress",
"s",
NM_DEVICE_HSR_SUPERVISION_ADDRESS),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("MulticastSpec",
"y",
NM_DEVICE_HSR_MULTICAST_SPEC),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Prp", "b", NM_DEVICE_HSR_PRP), ), ),
};
static void
nm_device_hsr_class_init(NMDeviceHsrClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
NMDeviceClass *device_class = NM_DEVICE_CLASS(klass);
object_class->get_property = get_property;
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_hsr);
device_class->connection_type_supported = NM_SETTING_HSR_SETTING_NAME;
device_class->connection_type_check_compatible = NM_SETTING_HSR_SETTING_NAME;
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_HSR);
device_class->link_changed = link_changed;
device_class->create_and_realize = create_and_realize;
device_class->get_generic_capabilities = get_generic_capabilities;
obj_properties[PROP_PORT1] = g_param_spec_string(NM_DEVICE_HSR_PORT1,
"",
"",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_PORT2] = g_param_spec_string(NM_DEVICE_HSR_PORT2,
"",
"",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_SUPERVISION_ADDRESS] =
g_param_spec_string(NM_DEVICE_HSR_SUPERVISION_ADDRESS,
"",
"",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_MULTICAST_SPEC] =
g_param_spec_uchar(NM_DEVICE_HSR_MULTICAST_SPEC,
"",
"",
0,
G_MAXUINT8,
0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_PRP] = g_param_spec_boolean(NM_DEVICE_HSR_PRP,
"",
"",
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
}
/*****************************************************************************/
#define NM_TYPE_HSR_DEVICE_FACTORY (nm_hsr_device_factory_get_type())
#define NM_HSR_DEVICE_FACTORY(obj) \
(_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_HSR_DEVICE_FACTORY, NMHsrDeviceFactory))
static NMDevice *
create_device(NMDeviceFactory *factory,
const char *iface,
const NMPlatformLink *plink,
NMConnection *connection,
gboolean *out_ignore)
{
return g_object_new(NM_TYPE_DEVICE_HSR,
NM_DEVICE_IFACE,
iface,
NM_DEVICE_TYPE_DESC,
"hsr",
NM_DEVICE_DEVICE_TYPE,
NM_DEVICE_TYPE_HSR,
NM_DEVICE_LINK_TYPE,
NM_LINK_TYPE_HSR,
NULL);
}
NM_DEVICE_FACTORY_DEFINE_INTERNAL(
HSR,
Hsr,
hsr,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_HSR)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_HSR_SETTING_NAME),
factory_class->create_device = create_device;)

View file

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2023 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_DEVICE_HSR_H__
#define __NETWORKMANAGER_DEVICE_HSR_H__
#include "nm-device.h"
#define NM_TYPE_DEVICE_HSR (nm_device_hsr_get_type())
#define NM_DEVICE_HSR(obj) (_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_HSR, NMDeviceHsr))
#define NM_DEVICE_HSR_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_HSR, NMDeviceHsrClass))
#define NM_IS_DEVICE_HSR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_HSR))
#define NM_IS_DEVICE_HSR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_HSR))
#define NM_DEVICE_HSR_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_HSR, NMDeviceHsrClass))
#define NM_DEVICE_HSR_PORT1 "port1"
#define NM_DEVICE_HSR_PORT2 "port2"
#define NM_DEVICE_HSR_SUPERVISION_ADDRESS "supervision-address"
#define NM_DEVICE_HSR_MULTICAST_SPEC "multicast-spec"
#define NM_DEVICE_HSR_PRP "prp"
typedef struct _NMDeviceHsr NMDeviceHsr;
typedef struct _NMDeviceHsrClass NMDeviceHsrClass;
GType nm_device_hsr_get_type(void);
#endif /* __NETWORKMANAGER_DEVICE_HSR_H__ */

View file

@ -5450,6 +5450,8 @@ nm_device_get_route_metric_default(NMDeviceType device_type)
return 200;
case NM_DEVICE_TYPE_WIMAX:
return 250;
case NM_DEVICE_TYPE_HSR:
return 275;
case NM_DEVICE_TYPE_BOND:
return 300;
case NM_DEVICE_TYPE_TEAM:
@ -18310,7 +18312,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
nm_assert(priv->type == NM_DEVICE_TYPE_UNKNOWN);
priv->type = g_value_get_uint(value);
nm_assert(priv->type > NM_DEVICE_TYPE_UNKNOWN);
nm_assert(priv->type <= NM_DEVICE_TYPE_LOOPBACK);
nm_assert(priv->type <= NM_DEVICE_TYPE_HSR);
break;
case PROP_LINK_TYPE:
/* construct-only */

View file

@ -102,6 +102,7 @@ libNetworkManager = static_library(
'devices/nm-device-ethernet-utils.c',
'devices/nm-device-factory.c',
'devices/nm-device-generic.c',
'devices/nm-device-hsr.c',
'devices/nm-device-infiniband.c',
'devices/nm-device-ip-tunnel.c',
'devices/nm-device-loopback.c',

View file

@ -1947,7 +1947,20 @@ global:
libnm_1_46_0 {
global:
nm_access_point_get_bandwidth;
nm_device_hsr_get_multicast_spec;
nm_device_hsr_get_port1;
nm_device_hsr_get_port2;
nm_device_hsr_get_prp;
nm_device_hsr_get_supervision_address;
nm_device_hsr_get_type;
nm_device_ip_tunnel_get_fwmark;
nm_ethtool_optname_is_channels;
nm_ethtool_optname_is_eee;
nm_setting_hsr_get_multicast_spec;
nm_setting_hsr_get_port1;
nm_setting_hsr_get_port2;
nm_setting_hsr_get_prp;
nm_setting_hsr_get_supervision_address;
nm_setting_hsr_get_type;
nm_setting_hsr_new;
} libnm_1_44_0;

View file

@ -17,6 +17,7 @@ libnm_client_impl_sources = files(
'nm-device-dummy.c',
'nm-device-ethernet.c',
'nm-device-generic.c',
'nm-device-hsr.c',
'nm-device-infiniband.c',
'nm-device-ip-tunnel.c',
'nm-device-loopback.c',

View file

@ -29,6 +29,7 @@
#include "nm-device-dummy.h"
#include "nm-device-ethernet.h"
#include "nm-device-generic.h"
#include "nm-device-hsr.h"
#include "nm-device-infiniband.h"
#include "nm-device-ip-tunnel.h"
#include "nm-device-loopback.h"

View file

@ -0,0 +1,279 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2023 Red Hat, Inc.
*/
#include "libnm-client-impl/nm-default-libnm.h"
#include "nm-device-hsr.h"
#include "nm-setting-connection.h"
#include "nm-setting-hsr.h"
#include "nm-utils.h"
#include "nm-object-private.h"
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PORT1,
PROP_PORT2,
PROP_SUPERVISION_ADDRESS,
PROP_MULTICAST_SPEC,
PROP_PRP, );
typedef struct {
char *supervision_address;
NMLDBusPropertyO port1;
NMLDBusPropertyO port2;
guint8 multicast_spec;
bool prp;
} NMDeviceHsrPrivate;
struct _NMDeviceHsr {
NMDevice parent;
NMDeviceHsrPrivate _priv;
};
struct _NMDeviceHsrClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE(NMDeviceHsr, nm_device_hsr, NM_TYPE_DEVICE)
#define NM_DEVICE_HSR_GET_PRIVATE(self) \
_NM_GET_PRIVATE(self, NMDeviceHsr, NM_IS_DEVICE_HSR, NMObject, NMDevice)
/*****************************************************************************/
/**
* nm_device_hsr_get_port1:
* @device: a #NMDeviceHsr
*
* Returns: (transfer none): the device's port1 device
*
* Since: 1.46
**/
NMDevice *
nm_device_hsr_get_port1(NMDeviceHsr *device)
{
g_return_val_if_fail(NM_IS_DEVICE_HSR(device), NULL);
return nml_dbus_property_o_get_obj(&NM_DEVICE_HSR_GET_PRIVATE(device)->port1);
}
/**
* nm_device_hsr_get_port2:
* @device: a #NMDeviceHsr
*
* Returns: (transfer none): the device's port2 device
*
* Since: 1.46
**/
NMDevice *
nm_device_hsr_get_port2(NMDeviceHsr *device)
{
g_return_val_if_fail(NM_IS_DEVICE_HSR(device), NULL);
return nml_dbus_property_o_get_obj(&NM_DEVICE_HSR_GET_PRIVATE(device)->port2);
}
/**
* nm_device_hsr_get_supervision_address:
* @device: a #NMDeviceHsr
*
* Returns: the supervision MAC adddress
*
* Since: 1.46
**/
const char *
nm_device_hsr_get_supervision_address(NMDeviceHsr *device)
{
g_return_val_if_fail(NM_IS_DEVICE_HSR(device), NULL);
return NM_DEVICE_HSR_GET_PRIVATE(device)->supervision_address;
}
/**
* nm_device_hsr_get_multicast_spec:
* @device: a #NMDeviceHsr
*
* Returns: the last byte of the supervision address
*
* Since: 1.46
**/
guint8
nm_device_hsr_get_multicast_spec(NMDeviceHsr *device)
{
g_return_val_if_fail(NM_IS_DEVICE_HSR(device), 0);
return NM_DEVICE_HSR_GET_PRIVATE(device)->multicast_spec;
}
/**
* nm_device_hsr_get_prp:
* @device: a #NMDeviceHsr
*
* Returns: whether PRP protocol is used or not
*
* Since: 1.46
**/
gboolean
nm_device_hsr_get_prp(NMDeviceHsr *device)
{
g_return_val_if_fail(NM_IS_DEVICE_HSR(device), FALSE);
return NM_DEVICE_HSR_GET_PRIVATE(device)->prp;
}
/*****************************************************************************/
static void
nm_device_hsr_init(NMDeviceHsr *device)
{}
static void
finalize(GObject *object)
{
NMDeviceHsrPrivate *priv = NM_DEVICE_HSR_GET_PRIVATE(object);
g_free(priv->supervision_address);
G_OBJECT_CLASS(nm_device_hsr_parent_class)->finalize(object);
}
static void
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
NMDeviceHsr *device = NM_DEVICE_HSR(object);
switch (prop_id) {
case PROP_PORT1:
g_value_set_object(value, nm_device_hsr_get_port1(device));
break;
case PROP_PORT2:
g_value_set_object(value, nm_device_hsr_get_port2(device));
break;
case PROP_SUPERVISION_ADDRESS:
g_value_set_string(value, nm_device_hsr_get_supervision_address(device));
break;
case PROP_MULTICAST_SPEC:
g_value_set_uchar(value, nm_device_hsr_get_multicast_spec(device));
break;
case PROP_PRP:
g_value_set_boolean(value, nm_device_hsr_get_prp(device));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_hsr = NML_DBUS_META_IFACE_INIT_PROP(
NM_DBUS_INTERFACE_DEVICE_HSR,
nm_device_hsr_get_type,
NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30,
NML_DBUS_META_IFACE_DBUS_PROPERTIES(
NML_DBUS_META_PROPERTY_INIT_Y("MulticastSpec",
PROP_MULTICAST_SPEC,
NMDeviceHsr,
_priv.multicast_spec),
NML_DBUS_META_PROPERTY_INIT_O_PROP("Port1",
PROP_PORT1,
NMDeviceHsr,
_priv.port1,
nm_device_get_type),
NML_DBUS_META_PROPERTY_INIT_O_PROP("Port2",
PROP_PORT2,
NMDeviceHsr,
_priv.port2,
nm_device_get_type),
NML_DBUS_META_PROPERTY_INIT_B("Prp", PROP_PRP, NMDeviceHsr, _priv.prp),
NML_DBUS_META_PROPERTY_INIT_S("SupervisionAddress",
PROP_SUPERVISION_ADDRESS,
NMDeviceHsr,
_priv.supervision_address), ), );
static void
nm_device_hsr_class_init(NMDeviceHsrClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
_NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceHsr);
_NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceHsrPrivate, port1);
_NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceHsrPrivate, port2);
/**
* NMDeviceHsr:port1:
*
* The device's port1 device.
*
* Since: 1.46
**/
obj_properties[PROP_PORT1] = g_param_spec_object(NM_DEVICE_HSR_PORT1,
"",
"",
NM_TYPE_DEVICE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* NMDeviceHsr:port2:
*
* The device's port2 device.
*
* Since: 1.46
**/
obj_properties[PROP_PORT2] = g_param_spec_object(NM_DEVICE_HSR_PORT2,
"",
"",
NM_TYPE_DEVICE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* NMDeviceHsr:supervision-address:
*
* The device supervision MAC adddress.
*
* Since: 1.46
**/
obj_properties[PROP_SUPERVISION_ADDRESS] =
g_param_spec_string(NM_DEVICE_HSR_SUPERVISION_ADDRESS,
"",
"",
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* NMDeviceHsr:multicast-spec:
*
* The device last byte of the supervision address.
*
* Since: 1.46
**/
obj_properties[PROP_MULTICAST_SPEC] =
g_param_spec_uchar(NM_DEVICE_HSR_MULTICAST_SPEC,
"",
"",
0,
G_MAXUINT8,
0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* NMDeviceHsr:prp:
*
* Whether the PRP protocol is used or not.
*
* Since: 1.46
**/
obj_properties[PROP_PRP] = g_param_spec_boolean(NM_DEVICE_HSR_PRP,
"",
"",
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
_nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_hsr);
}

View file

@ -313,6 +313,7 @@ coerce_type(NMDeviceType type)
case NM_DEVICE_TYPE_WIFI_P2P:
case NM_DEVICE_TYPE_VRF:
case NM_DEVICE_TYPE_LOOPBACK:
case NM_DEVICE_TYPE_HSR:
return type;
}
return NM_DEVICE_TYPE_UNKNOWN;
@ -1814,6 +1815,8 @@ get_type_name(NMDevice *device)
return _("VRF");
case NM_DEVICE_TYPE_LOOPBACK:
return _("Loopback");
case NM_DEVICE_TYPE_HSR:
return _("HSR");
case NM_DEVICE_TYPE_GENERIC:
case NM_DEVICE_TYPE_UNUSED1:
case NM_DEVICE_TYPE_UNUSED2:

View file

@ -39,6 +39,7 @@
#include "nm-setting-generic.h"
#include "nm-setting-gsm.h"
#include "nm-setting-hostname.h"
#include "nm-setting-hsr.h"
#include "nm-setting-infiniband.h"
#include "nm-setting-ip4-config.h"
#include "nm-setting-ip6-config.h"
@ -111,6 +112,7 @@
#include "nm-device-dummy.h"
#include "nm-device-ethernet.h"
#include "nm-device-generic.h"
#include "nm-device-hsr.h"
#include "nm-device-infiniband.h"
#include "nm-device-ip-tunnel.h"
#include "nm-device-loopback.h"

View file

@ -18,6 +18,7 @@ libnm_client_headers = files(
'nm-device-dummy.h',
'nm-device-ethernet.h',
'nm-device-generic.h',
'nm-device-hsr.h',
'nm-device-infiniband.h',
'nm-device-ip-tunnel.h',
'nm-device-loopback.h',

View file

@ -41,6 +41,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceBt, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceDummy, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceEthernet, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceGeneric, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceHsr, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceIPTunnel, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceInfiniband, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceLoopback, g_object_unref)
@ -80,6 +81,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingEthtool, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingGeneric, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingGsm, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingHostname, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingHsr, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIP4Config, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIP6Config, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIPConfig, g_object_unref)

View file

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2023 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_HSR_H__
#define __NM_DEVICE_HSR_H__
#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-device.h"
G_BEGIN_DECLS
#define NM_TYPE_DEVICE_HSR (nm_device_hsr_get_type())
#define NM_DEVICE_HSR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_HSR, NMDeviceHsr))
#define NM_DEVICE_HSR_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_HSR, NMDeviceHsClass))
#define NM_IS_DEVICE_HSR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_HSR))
#define NM_IS_DEVICE_HSR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_HSR))
#define NM_DEVICE_HSR_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_HSR, NMDeviceHsrClass))
#define NM_DEVICE_HSR_PORT1 "port1"
#define NM_DEVICE_HSR_PORT2 "port2"
#define NM_DEVICE_HSR_SUPERVISION_ADDRESS "supervision-address"
#define NM_DEVICE_HSR_MULTICAST_SPEC "multicast-spec"
#define NM_DEVICE_HSR_PRP "prp"
/**
* NMDeviceHsr:
*
* Since: 1.46
*/
typedef struct _NMDeviceHsr NMDeviceHsr;
typedef struct _NMDeviceHsrClass NMDeviceHsrClass;
NM_AVAILABLE_IN_1_46
GType nm_device_hsr_get_type(void);
NM_AVAILABLE_IN_1_46
NMDevice *nm_device_hsr_get_port1(NMDeviceHsr *device);
NM_AVAILABLE_IN_1_46
NMDevice *nm_device_hsr_get_port2(NMDeviceHsr *device);
NM_AVAILABLE_IN_1_46
const char *nm_device_hsr_get_supervision_address(NMDeviceHsr *device);
NM_AVAILABLE_IN_1_46
guint8 nm_device_hsr_get_multicast_spec(NMDeviceHsr *device);
NM_AVAILABLE_IN_1_46
gboolean nm_device_hsr_get_prp(NMDeviceHsr *device);
G_END_DECLS
#endif /* __NM_DEVICE_HSR_H__ */

View file

@ -1418,6 +1418,30 @@
gprop-type="gint"
/>
</setting>
<setting name="hsr"
gtype="NMSettingHsr"
>
<property name="multicast-spec"
dbus-type="u"
gprop-type="guint"
/>
<property name="port1"
dbus-type="s"
gprop-type="gchararray"
/>
<property name="port2"
dbus-type="s"
gprop-type="gchararray"
/>
<property name="prp"
dbus-type="b"
gprop-type="gboolean"
/>
<property name="supervision-address"
dbus-type="s"
gprop-type="gchararray"
/>
</setting>
<setting name="infiniband"
gtype="NMSettingInfiniband"
>

View file

@ -19,6 +19,7 @@ libnm_core_settings_sources = files(
'nm-setting-generic.c',
'nm-setting-gsm.c',
'nm-setting-hostname.c',
'nm-setting-hsr.c',
'nm-setting-infiniband.c',
'nm-setting-ip-config.c',
'nm-setting-ip-tunnel.c',

View file

@ -3182,6 +3182,7 @@ nm_connection_is_virtual(NMConnection *connection)
NM_SETTING_BOND_SETTING_NAME,
NM_SETTING_BRIDGE_SETTING_NAME,
NM_SETTING_DUMMY_SETTING_NAME,
NM_SETTING_HSR_SETTING_NAME,
NM_SETTING_IP_TUNNEL_SETTING_NAME,
NM_SETTING_MACSEC_SETTING_NAME,
NM_SETTING_MACVLAN_SETTING_NAME,

View file

@ -3044,6 +3044,10 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
PARSE_INFO_PROPERTY(NM_SETTING_CONNECTION_TYPE,
.parser = setting_alias_parser,
.writer = setting_alias_writer, ), ), ),
PARSE_INFO_SETTING(
NM_META_SETTING_TYPE_HSR,
PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_HSR_SUPERVISION_ADDRESS,
.parser = mac_address_parser_ETHER, ), ), ),
PARSE_INFO_SETTING(
NM_META_SETTING_TYPE_INFINIBAND,
PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_INFINIBAND_MAC_ADDRESS,

View file

@ -29,6 +29,7 @@
#include "nm-setting-generic.h"
#include "nm-setting-gsm.h"
#include "nm-setting-hostname.h"
#include "nm-setting-hsr.h"
#include "nm-setting-infiniband.h"
#include "nm-setting-ip-config.h"
#include "nm-setting-ip-tunnel.h"
@ -335,6 +336,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
.setting_name = NM_SETTING_HOSTNAME_SETTING_NAME,
.get_setting_gtype = nm_setting_hostname_get_type,
},
[NM_META_SETTING_TYPE_HSR] =
{
.meta_type = NM_META_SETTING_TYPE_HSR,
.setting_priority = NM_SETTING_PRIORITY_HW_BASE,
.setting_name = NM_SETTING_HSR_SETTING_NAME,
.get_setting_gtype = nm_setting_hsr_get_type,
},
[NM_META_SETTING_TYPE_INFINIBAND] =
{
.meta_type = NM_META_SETTING_TYPE_INFINIBAND,
@ -632,6 +640,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = {
NM_META_SETTING_TYPE_DUMMY,
NM_META_SETTING_TYPE_GENERIC,
NM_META_SETTING_TYPE_GSM,
NM_META_SETTING_TYPE_HSR,
NM_META_SETTING_TYPE_INFINIBAND,
NM_META_SETTING_TYPE_IP_TUNNEL,
NM_META_SETTING_TYPE_LOOPBACK,

View file

@ -0,0 +1,316 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2023 Red Hat, Inc.
*/
#include "libnm-core-impl/nm-default-libnm-core.h"
#include "nm-setting-hsr.h"
#include <linux/if_ether.h>
#include "nm-connection-private.h"
#include "nm-utils.h"
#include "nm-utils-private.h"
/**
* SECTION:nm-setting-hsr
* @short_description: Describes connection properties for HSR/PRP interfaces
*
* The #NMSettingHsr object is a #NMSetting subclass that describes properties
* necessary for HSR/PRP connections.
**/
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHsr,
PROP_PORT1,
PROP_PORT2,
PROP_SUPERVISION_ADDRESS,
PROP_MULTICAST_SPEC,
PROP_PRP, );
typedef struct {
char *port1;
char *port2;
char *supervision_address;
guint32 multicast_spec;
bool prp;
} NMSettingHsrPrivate;
/**
* NMSettingHsr:
*
* HSR/PRP Settings
*/
struct _NMSettingHsr {
NMSetting parent;
NMSettingHsrPrivate _priv;
};
struct _NMSettingHsrClass {
NMSettingClass parent;
};
G_DEFINE_TYPE(NMSettingHsr, nm_setting_hsr, NM_TYPE_SETTING)
#define NM_SETTING_HSR_GET_PRIVATE(self) \
_NM_GET_PRIVATE(self, NMSettingHsr, NM_IS_SETTING_HSR, NMSetting)
/*****************************************************************************/
/**
* nm_setting_hsr_get_port1:
* @setting: the #NMSettingHsr
*
* Returns: the #NMSettingHsr:port1 property of the setting
*
* Since: 1.46
**/
const char *
nm_setting_hsr_get_port1(NMSettingHsr *setting)
{
g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NULL);
return NM_SETTING_HSR_GET_PRIVATE(setting)->port1;
}
/**
* nm_setting_hsr_get_port2:
* @setting: the #NMSettingHsr
*
* Returns: the #NMSettingHsr:port2 property of the setting
*
* Since: 1.46
**/
const char *
nm_setting_hsr_get_port2(NMSettingHsr *setting)
{
g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NULL);
return NM_SETTING_HSR_GET_PRIVATE(setting)->port2;
}
/**
* nm_setting_hsr_get_supervision_address:
* @setting: the #NMSettingHsr
*
* Returns: the #NMSettingHsr:supervision_address property of the setting
*
* Since: 1.46
**/
const char *
nm_setting_hsr_get_supervision_address(NMSettingHsr *setting)
{
g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NULL);
return NM_SETTING_HSR_GET_PRIVATE(setting)->supervision_address;
}
/**
* nm_setting_hsr_get_multicast_spec:
* @setting: the #NMSettingHsr
*
* Returns: the #NMSettingHsr:multicast_spec property of the setting
*
* Since: 1.46
**/
guint32
nm_setting_hsr_get_multicast_spec(NMSettingHsr *setting)
{
g_return_val_if_fail(NM_IS_SETTING_HSR(setting), 0);
return NM_SETTING_HSR_GET_PRIVATE(setting)->multicast_spec;
}
/**
* nm_setting_hsr_get_prp:
* @setting: the #NMSettingHsr
*
* Returns: the #NMSettingHsr:prp property of the setting
*
* Since: 1.46
**/
gboolean
nm_setting_hsr_get_prp(NMSettingHsr *setting)
{
g_return_val_if_fail(NM_IS_SETTING_HSR(setting), FALSE);
return NM_SETTING_HSR_GET_PRIVATE(setting)->prp;
}
/*****************************************************************************/
static gboolean
verify(NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingHsrPrivate *priv = NM_SETTING_HSR_GET_PRIVATE(setting);
if (!priv->port1) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is not specified"));
g_prefix_error(error, "%s.%s: ", NM_SETTING_HSR_SETTING_NAME, NM_SETTING_HSR_PORT1);
return FALSE;
}
if (!nm_utils_ifname_valid(priv->port1, NMU_IFACE_KERNEL, NULL)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid interface name"),
priv->port1);
g_prefix_error(error, "%s.%s: ", NM_SETTING_HSR_SETTING_NAME, NM_SETTING_HSR_PORT1);
return FALSE;
}
if (!priv->port2) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is not specified"));
g_prefix_error(error, "%s.%s: ", NM_SETTING_HSR_SETTING_NAME, NM_SETTING_HSR_PORT2);
return FALSE;
}
if (!nm_utils_ifname_valid(priv->port2, NMU_IFACE_KERNEL, NULL)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid interface name"),
priv->port2);
g_prefix_error(error, "%s.%s: ", NM_SETTING_HSR_SETTING_NAME, NM_SETTING_HSR_PORT2);
return FALSE;
}
if (priv->supervision_address && !nm_utils_hwaddr_valid(priv->supervision_address, ETH_ALEN)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid MAC address"),
priv->supervision_address);
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_HSR_SETTING_NAME,
NM_SETTING_HSR_SUPERVISION_ADDRESS);
return FALSE;
}
return TRUE;
}
/*****************************************************************************/
static void
nm_setting_hsr_init(NMSettingHsr *setting)
{}
/**
* nm_setting_hsr_new:
*
* Creates a new #NMSettingHsr object with default values.
*
* Returns: (transfer full): the new empty #NMSettingHsr object
*
* Since: 1.46
**/
NMSetting *
nm_setting_hsr_new(void)
{
return g_object_new(NM_TYPE_SETTING_HSR, NULL);
}
static void
nm_setting_hsr_class_init(NMSettingHsrClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
NMSettingClass *setting_class = NM_SETTING_CLASS(klass);
GArray *properties_override = _nm_sett_info_property_override_create_array();
object_class->get_property = _nm_setting_property_get_property_direct;
object_class->set_property = _nm_setting_property_set_property_direct;
setting_class->verify = verify;
/**
* NMSettingHsr:port1:
*
* The port1 interface name of the HSR. This property is mandatory.
*
* Since: 1.46
**/
_nm_setting_property_define_direct_string(properties_override,
obj_properties,
NM_SETTING_HSR_PORT1,
PROP_PORT1,
NM_SETTING_PARAM_INFERRABLE,
NMSettingHsr,
_priv.port1);
/**
* NMSettingHsr:port2:
*
* The port2 interface name of the HSR. This property is mandatory.
*
* Since: 1.46
**/
_nm_setting_property_define_direct_string(properties_override,
obj_properties,
NM_SETTING_HSR_PORT2,
PROP_PORT2,
NM_SETTING_PARAM_INFERRABLE,
NMSettingHsr,
_priv.port2);
/**
* NMSettingHsr:supervision-address:
*
* The supervision MAC address.
*
* Since: 1.46
**/
_nm_setting_property_define_direct_string(properties_override,
obj_properties,
NM_SETTING_HSR_SUPERVISION_ADDRESS,
PROP_SUPERVISION_ADDRESS,
NM_SETTING_PARAM_INFERRABLE,
NMSettingHsr,
_priv.supervision_address);
/**
* NMSettingHsr:multicast-spec:
*
* The last byte of supervision address.
*
* Since: 1.46
**/
_nm_setting_property_define_direct_uint32(properties_override,
obj_properties,
NM_SETTING_HSR_MULTICAST_SPEC,
PROP_MULTICAST_SPEC,
0,
G_MAXUINT8,
0,
NM_SETTING_PARAM_INFERRABLE,
NMSettingHsr,
_priv.multicast_spec);
/**
* NMSettingHsr:prp:
*
* The protocol used by the interface, whether it is PRP or HSR.
*
* Since: 1.46
**/
_nm_setting_property_define_direct_boolean(properties_override,
obj_properties,
NM_SETTING_HSR_PRP,
PROP_PRP,
FALSE,
NM_SETTING_PARAM_INFERRABLE,
NMSettingHsr,
_priv.prp);
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

@ -38,6 +38,7 @@
#include "nm-setting-dummy.h"
#include "nm-setting-generic.h"
#include "nm-setting-gsm.h"
#include "nm-setting-hsr.h"
#include "nm-setting-hostname.h"
#include "nm-setting-infiniband.h"
#include "nm-setting-ip-tunnel.h"

View file

@ -123,6 +123,7 @@ typedef enum _nm_packed {
NM_META_SETTING_TYPE_GENERIC,
NM_META_SETTING_TYPE_GSM,
NM_META_SETTING_TYPE_HOSTNAME,
NM_META_SETTING_TYPE_HSR,
NM_META_SETTING_TYPE_INFINIBAND,
NM_META_SETTING_TYPE_IP_TUNNEL,
NM_META_SETTING_TYPE_IP4_CONFIG,

View file

@ -23,6 +23,7 @@ libnm_core_headers = files(
'nm-setting-ethtool.h',
'nm-setting-generic.h',
'nm-setting-gsm.h',
'nm-setting-hsr.h',
'nm-setting-hostname.h',
'nm-setting-infiniband.h',
'nm-setting-ip-config.h',

View file

@ -30,6 +30,7 @@ typedef struct _NMSettingEthtool NMSettingEthtool;
typedef struct _NMSettingGeneric NMSettingGeneric;
typedef struct _NMSettingGsm NMSettingGsm;
typedef struct _NMSettingHostname NMSettingHostname;
typedef struct _NMSettingHsr NMSettingHsr;
typedef struct _NMSettingIP4Config NMSettingIP4Config;
typedef struct _NMSettingIP6Config NMSettingIP6Config;
typedef struct _NMSettingIPConfig NMSettingIPConfig;

View file

@ -37,6 +37,7 @@
#define NM_DBUS_INTERFACE_DEVICE_DUMMY NM_DBUS_INTERFACE_DEVICE ".Dummy"
#define NM_DBUS_INTERFACE_DEVICE_GENERIC NM_DBUS_INTERFACE_DEVICE ".Generic"
#define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre"
#define NM_DBUS_INTERFACE_DEVICE_HSR NM_DBUS_INTERFACE_DEVICE ".Hsr"
#define NM_DBUS_INTERFACE_DEVICE_INFINIBAND NM_DBUS_INTERFACE_DEVICE ".Infiniband"
#define NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL NM_DBUS_INTERFACE_DEVICE ".IPTunnel"
#define NM_DBUS_INTERFACE_DEVICE_LOOPBACK NM_DBUS_INTERFACE_DEVICE ".Loopback"
@ -234,6 +235,7 @@ typedef enum {
* @NM_DEVICE_TYPE_WIFI_P2P: an 802.11 Wi-Fi P2P device. Since: 1.16.
* @NM_DEVICE_TYPE_VRF: A VRF (Virtual Routing and Forwarding) interface. Since: 1.24.
* @NM_DEVICE_TYPE_LOOPBACK: a loopback interface. Since: 1.42.
* @NM_DEVICE_TYPE_HSR: A HSR/PRP device. Since: 1.46.
*
* #NMDeviceType values indicate the type of hardware represented by a
* device object.
@ -272,6 +274,7 @@ typedef enum {
NM_DEVICE_TYPE_WIFI_P2P = 30,
NM_DEVICE_TYPE_VRF = 31,
NM_DEVICE_TYPE_LOOPBACK = 32,
NM_DEVICE_TYPE_HSR = 33,
} NMDeviceType;
/**

View file

@ -0,0 +1,52 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2023 Red Hat, Inc.
*/
#ifndef __NM_SETTING_HSR_H__
#define __NM_SETTING_HSR_H__
#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-setting.h"
G_BEGIN_DECLS
#define NM_TYPE_SETTING_HSR (nm_setting_hsr_get_type())
#define NM_SETTING_HSR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_HSR, NMSettingHsr))
#define NM_IS_SETTING_HSR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_HSR))
#define NM_IS_SETTING_HSR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_HSR))
#define NM_SETTING_HSR_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_HSR, NMSettingHsrClass))
#define NM_SETTING_HSR_SETTING_NAME "hsr"
#define NM_SETTING_HSR_PORT1 "port1"
#define NM_SETTING_HSR_PORT2 "port2"
#define NM_SETTING_HSR_SUPERVISION_ADDRESS "supervision-address"
#define NM_SETTING_HSR_MULTICAST_SPEC "multicast-spec"
#define NM_SETTING_HSR_PRP "prp"
typedef struct _NMSettingHsrClass NMSettingHsrClass;
NM_AVAILABLE_IN_1_46
GType nm_setting_hsr_get_type(void);
NM_AVAILABLE_IN_1_46
NMSetting *nm_setting_hsr_new(void);
NM_AVAILABLE_IN_1_46
const char *nm_setting_hsr_get_port1(NMSettingHsr *setting);
NM_AVAILABLE_IN_1_46
const char *nm_setting_hsr_get_port2(NMSettingHsr *setting);
NM_AVAILABLE_IN_1_46
const char *nm_setting_hsr_get_supervision_address(NMSettingHsr *setting);
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);
G_END_DECLS
#endif /* __NM_SETTING_HSR_H__ */

View file

@ -158,6 +158,7 @@ typedef enum {
#define _NM_LINK_TYPE_SW_MASTER_FIRST NM_LINK_TYPE_BRIDGE
NM_LINK_TYPE_BRIDGE,
NM_LINK_TYPE_BOND,
NM_LINK_TYPE_HSR,
NM_LINK_TYPE_TEAM,
#define _NM_LINK_TYPE_SW_MASTER_LAST NM_LINK_TYPE_TEAM

View file

@ -229,6 +229,18 @@ G_STATIC_ASSERT(RTA_MAX == (__RTA_MAX - 1));
/*****************************************************************************/
#define IFLA_HSR_UNSPEC 0
#define IFLA_HSR_PORT1 1
#define IFLA_HSR_PORT2 2
#define IFLA_HSR_MULTICAST_SPEC 3
#define IFLA_HSR_SUPERVISION_ADDR 4
#define IFLA_HSR_SEQ_NR 5
#define IFLA_HSR_VERSION 6
#define IFLA_HSR_PROTOCOL 7
#define __IFLA_HSR_MAX 8
/*****************************************************************************/
#define IFLA_VTI_UNSPEC 0
#define IFLA_VTI_LINK 1
#define IFLA_VTI_IKEY 2
@ -847,6 +859,7 @@ static const LinkDesc link_descs[] = {
[NM_LINK_TYPE_BRIDGE] = {"bridge", "bridge", "bridge"},
[NM_LINK_TYPE_BOND] = {"bond", "bond", "bond"},
[NM_LINK_TYPE_HSR] = {"hsr", "hsr", "hsr"},
[NM_LINK_TYPE_TEAM] = {"team", "team", NULL},
};
@ -869,6 +882,7 @@ _link_type_from_rtnl_type(const char *name)
NM_LINK_TYPE_DUMMY, /* "dummy" */
NM_LINK_TYPE_GRE, /* "gre" */
NM_LINK_TYPE_GRETAP, /* "gretap" */
NM_LINK_TYPE_HSR, /* "hsr" */
NM_LINK_TYPE_IFB, /* "ifb" */
NM_LINK_TYPE_IP6GRE, /* "ip6gre" */
NM_LINK_TYPE_IP6GRETAP, /* "ip6gretap" */
@ -943,6 +957,7 @@ _link_type_from_devtype(const char *name)
NM_LINK_TYPE_BNEP, /* "bluetooth" */
NM_LINK_TYPE_BOND, /* "bond" */
NM_LINK_TYPE_BRIDGE, /* "bridge" */
NM_LINK_TYPE_HSR, /* "hsr" */
NM_LINK_TYPE_PPP, /* "ppp" */
NM_LINK_TYPE_VLAN, /* "vlan" */
NM_LINK_TYPE_VRF, /* "vrf" */
@ -1805,6 +1820,51 @@ _parse_lnk_gre(const char *kind, struct nlattr *info_data)
/*****************************************************************************/
static NMPObject *
_parse_lnk_hsr(const char *kind, struct nlattr *info_data)
{
static const struct nla_policy policy[] = {
[IFLA_HSR_PORT1] = {.type = NLA_U32},
[IFLA_HSR_PORT2] = {.type = NLA_U32},
[IFLA_HSR_MULTICAST_SPEC] = {.type = NLA_U8},
[IFLA_HSR_SUPERVISION_ADDR] = {.minlen = sizeof(NMEtherAddr)},
[IFLA_HSR_PROTOCOL] = {.type = NLA_U8},
};
NMPlatformLnkHsr *props;
struct nlattr *tb[G_N_ELEMENTS(policy)];
NMPObject *obj;
guint32 v_u32;
if (!info_data || !kind)
return NULL;
if (nla_parse_nested_arr(tb, info_data, policy) < 0)
return NULL;
obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_HSR, NULL);
props = &obj->lnk_hsr;
if (tb[IFLA_HSR_PORT1]) {
v_u32 = nla_get_u32(tb[IFLA_HSR_PORT1]);
if (v_u32 <= (unsigned) G_MAXINT)
props->port1 = v_u32;
}
if (tb[IFLA_HSR_PORT2]) {
v_u32 = nla_get_u32(tb[IFLA_HSR_PORT2]);
if (v_u32 <= (unsigned) G_MAXINT)
props->port2 = v_u32;
}
if (tb[IFLA_HSR_MULTICAST_SPEC])
props->multicast_spec = nla_get_u8(tb[IFLA_HSR_MULTICAST_SPEC]);
if (tb[IFLA_HSR_SUPERVISION_ADDR])
nla_memcpy(&props->supervision_address, tb[IFLA_HSR_SUPERVISION_ADDR], sizeof(NMEtherAddr));
if (tb[IFLA_HSR_PROTOCOL])
props->prp = nla_get_u8(tb[IFLA_HSR_PROTOCOL]);
return obj;
}
/*****************************************************************************/
/* IFLA_IPOIB_* were introduced in the 3.7 kernel, but the kernel headers
* we're building against might not have those properties even though the
* running kernel might.
@ -3568,6 +3628,9 @@ _new_from_nl_link(NMPlatform *platform,
case NM_LINK_TYPE_GRETAP:
lnk_data = _parse_lnk_gre(nl_info_kind, nl_info_data);
break;
case NM_LINK_TYPE_HSR:
lnk_data = _parse_lnk_hsr(nl_info_kind, nl_info_data);
break;
case NM_LINK_TYPE_INFINIBAND:
lnk_data = _parse_lnk_infiniband(nl_info_kind, nl_info_data);
break;
@ -4998,6 +5061,29 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo
NLA_PUT_U16(msg, IFLA_GRE_OFLAGS, htons(props->output_flags));
break;
}
case NM_LINK_TYPE_HSR:
{
const NMPlatformLnkHsr *props = extra_data;
nm_assert(props);
if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
goto nla_put_failure;
NLA_PUT_U32(msg, IFLA_HSR_PORT1, props->port1);
NLA_PUT_U32(msg, IFLA_HSR_PORT2, props->port2);
if (props->multicast_spec)
NLA_PUT_U8(msg, IFLA_HSR_MULTICAST_SPEC, props->multicast_spec);
if (!nm_ether_addr_is_zero(&props->supervision_address))
NLA_PUT(msg,
IFLA_HSR_SUPERVISION_ADDR,
sizeof(props->supervision_address),
&props->supervision_address);
NLA_PUT_U8(msg, IFLA_HSR_PROTOCOL, props->prp);
break;
}
case NM_LINK_TYPE_SIT:
{
const NMPlatformLnkSit *props = extra_data;

View file

@ -1391,6 +1391,12 @@ nm_platform_link_add(NMPlatform *self,
buf_p,
buf_len);
break;
case NM_LINK_TYPE_HSR:
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
nm_platform_lnk_hsr_to_string((const NMPlatformLnkHsr *) extra_data,
buf_p,
buf_len);
break;
case NM_LINK_TYPE_IP6TNL:
case NM_LINK_TYPE_IP6GRE:
case NM_LINK_TYPE_IP6GRETAP:
@ -2515,6 +2521,12 @@ nm_platform_link_get_lnk_gretap(NMPlatform *self, int ifindex, const NMPlatformL
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_GRETAP, out_link);
}
const NMPlatformLnkHsr *
nm_platform_link_get_lnk_hsr(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_HSR, out_link);
}
const NMPlatformLnkInfiniband *
nm_platform_link_get_lnk_infiniband(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
@ -6427,6 +6439,27 @@ nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len)
return buf;
}
const char *
nm_platform_lnk_hsr_to_string(const NMPlatformLnkHsr *lnk, char *buf, gsize len)
{
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
return buf;
g_snprintf(buf,
len,
"hsr "
"port1 %d "
"port2 %d "
"supervision_address " NM_ETHER_ADDR_FORMAT_STR " multicast_spec %u "
"prp %s",
lnk->port1,
lnk->port2,
NM_ETHER_ADDR_FORMAT_VAL(&lnk->supervision_address),
lnk->multicast_spec,
lnk->prp ? "on" : "off");
return buf;
}
const char *
nm_platform_lnk_infiniband_to_string(const NMPlatformLnkInfiniband *lnk, char *buf, gsize len)
{
@ -8308,6 +8341,29 @@ nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b)
return 0;
}
void
nm_platform_lnk_hsr_hash_update(const NMPlatformLnkHsr *obj, NMHashState *h)
{
nm_hash_update_vals(h,
obj->port1,
obj->port2,
obj->supervision_address,
obj->multicast_spec,
NM_HASH_COMBINE_BOOLS(guint8, obj->prp));
}
int
nm_platform_lnk_hsr_cmp(const NMPlatformLnkHsr *a, const NMPlatformLnkHsr *b)
{
NM_CMP_SELF(a, b);
NM_CMP_FIELD(a, b, port1);
NM_CMP_FIELD(a, b, port2);
NM_CMP_FIELD_MEMCMP(a, b, supervision_address);
NM_CMP_FIELD(a, b, multicast_spec);
NM_CMP_FIELD_BOOL(a, b, prp);
return 0;
}
void
nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h)
{

View file

@ -842,6 +842,14 @@ typedef struct {
bool is_tap : 1;
} _nm_alignas(NMPlatformObject) NMPlatformLnkGre;
typedef struct {
int port1;
int port2;
NMEtherAddr supervision_address;
guint8 multicast_spec;
bool prp : 1;
} _nm_alignas(NMPlatformObject) NMPlatformLnkHsr;
typedef struct {
int p_key;
const char *mode;
@ -1749,6 +1757,17 @@ nm_platform_link_gre_add(NMPlatform *self,
out_link);
}
static inline int
nm_platform_link_hsr_add(NMPlatform *self,
const char *name,
const NMPlatformLnkHsr *props,
const NMPlatformLink **out_link)
{
g_return_val_if_fail(props, -NME_BUG);
return nm_platform_link_add(self, NM_LINK_TYPE_HSR, name, 0, NULL, 0, 0, props, out_link);
}
static inline int
nm_platform_link_sit_add(NMPlatform *self,
const char *name,
@ -2068,6 +2087,8 @@ const NMPlatformLnkGre *
nm_platform_link_get_lnk_gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkGre *
nm_platform_link_get_lnk_gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkHsr *
nm_platform_link_get_lnk_hsr(NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkIp6Tnl *
nm_platform_link_get_lnk_ip6tnl(NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkIp6Tnl *
@ -2390,6 +2411,7 @@ const char *nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gs
const char *nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize len);
const char *nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsize len);
const char *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);
const char *
nm_platform_lnk_infiniband_to_string(const NMPlatformLnkInfiniband *lnk, char *buf, gsize len);
const char *nm_platform_lnk_ip6tnl_to_string(const NMPlatformLnkIp6Tnl *lnk, char *buf, gsize len);
@ -2443,6 +2465,7 @@ int nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b);
int nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b);
int nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b);
int nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b);
int nm_platform_lnk_hsr_cmp(const NMPlatformLnkHsr *a, const NMPlatformLnkHsr *b);
int nm_platform_lnk_infiniband_cmp(const NMPlatformLnkInfiniband *a,
const NMPlatformLnkInfiniband *b);
int nm_platform_lnk_ip6tnl_cmp(const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b);
@ -2514,6 +2537,7 @@ void nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj,
void nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h);
void nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *h);
void nm_platform_lnk_gre_hash_update(const NMPlatformLnkGre *obj, NMHashState *h);
void nm_platform_lnk_hsr_hash_update(const NMPlatformLnkHsr *obj, NMHashState *h);
void nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h);
void nm_platform_lnk_ip6tnl_hash_update(const NMPlatformLnkIp6Tnl *obj, NMHashState *h);
void nm_platform_lnk_ipip_hash_update(const NMPlatformLnkIpIp *obj, NMHashState *h);

View file

@ -159,6 +159,7 @@ typedef enum _nm_packed {
NMP_OBJECT_TYPE_LNK_BRIDGE,
NMP_OBJECT_TYPE_LNK_GRE,
NMP_OBJECT_TYPE_LNK_GRETAP,
NMP_OBJECT_TYPE_LNK_HSR,
NMP_OBJECT_TYPE_LNK_INFINIBAND,
NMP_OBJECT_TYPE_LNK_IP6TNL,
NMP_OBJECT_TYPE_LNK_IP6GRE,

View file

@ -3485,6 +3485,18 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_gre_hash_update,
.cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_gre_cmp,
},
[NMP_OBJECT_TYPE_LNK_HSR - 1] =
{
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
.obj_type = NMP_OBJECT_TYPE_LNK_HSR,
.sizeof_data = sizeof(NMPObjectLnkHsr),
.sizeof_public = sizeof(NMPlatformLnkHsr),
.obj_type_name = "hsr",
.lnk_link_type = NM_LINK_TYPE_HSR,
.cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_hsr_to_string,
.cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_hsr_hash_update,
.cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_hsr_cmp,
},
[NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] =
{
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),

View file

@ -253,6 +253,10 @@ typedef struct {
NMPlatformLnkGre _public;
} NMPObjectLnkGre;
typedef struct {
NMPlatformLnkHsr _public;
} NMPObjectLnkHsr;
typedef struct {
NMPlatformLnkInfiniband _public;
} NMPObjectLnkInfiniband;
@ -377,6 +381,9 @@ struct _NMPObject {
NMPlatformLnkGre lnk_gre;
NMPObjectLnkGre _lnk_gre;
NMPlatformLnkHsr lnk_hsr;
NMPObjectLnkHsr _lnk_hsr;
NMPlatformLnkInfiniband lnk_infiniband;
NMPObjectLnkInfiniband _lnk_infiniband;
@ -530,6 +537,7 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type)
case NMP_OBJECT_TYPE_LNK_BOND:
case NMP_OBJECT_TYPE_LNK_GRE:
case NMP_OBJECT_TYPE_LNK_GRETAP:
case NMP_OBJECT_TYPE_LNK_HSR:
case NMP_OBJECT_TYPE_LNK_INFINIBAND:
case NMP_OBJECT_TYPE_LNK_IP6TNL:
case NMP_OBJECT_TYPE_LNK_IP6GRE:

View file

@ -29,6 +29,7 @@
#include "nm-setting-generic.h"
#include "nm-setting-gsm.h"
#include "nm-setting-hostname.h"
#include "nm-setting-hsr.h"
#include "nm-setting-infiniband.h"
#include "nm-setting-ip-config.h"
#include "nm-setting-ip-tunnel.h"
@ -335,6 +336,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
.setting_name = NM_SETTING_HOSTNAME_SETTING_NAME,
.get_setting_gtype = nm_setting_hostname_get_type,
},
[NM_META_SETTING_TYPE_HSR] =
{
.meta_type = NM_META_SETTING_TYPE_HSR,
.setting_priority = NM_SETTING_PRIORITY_HW_BASE,
.setting_name = NM_SETTING_HSR_SETTING_NAME,
.get_setting_gtype = nm_setting_hsr_get_type,
},
[NM_META_SETTING_TYPE_INFINIBAND] =
{
.meta_type = NM_META_SETTING_TYPE_INFINIBAND,
@ -632,6 +640,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = {
NM_META_SETTING_TYPE_DUMMY,
NM_META_SETTING_TYPE_GENERIC,
NM_META_SETTING_TYPE_GSM,
NM_META_SETTING_TYPE_HSR,
NM_META_SETTING_TYPE_INFINIBAND,
NM_META_SETTING_TYPE_IP_TUNNEL,
NM_META_SETTING_TYPE_LOOPBACK,

View file

@ -123,6 +123,7 @@ typedef enum _nm_packed {
NM_META_SETTING_TYPE_GENERIC,
NM_META_SETTING_TYPE_GSM,
NM_META_SETTING_TYPE_HOSTNAME,
NM_META_SETTING_TYPE_HSR,
NM_META_SETTING_TYPE_INFINIBAND,
NM_META_SETTING_TYPE_IP_TUNNEL,
NM_META_SETTING_TYPE_IP4_CONFIG,

View file

@ -6024,6 +6024,42 @@ static const NMMetaPropertyInfo *const property_infos_GSM[] = {
NULL
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_HSR
static const NMMetaPropertyInfo *const property_infos_HSR[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_PORT1,
.is_cli_option = TRUE,
.property_alias = "port1",
.inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
.prompt = N_("hsr port1"),
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_PORT2,
.is_cli_option = TRUE,
.property_alias = "port2",
.inf_flags = NM_META_PROPERTY_INF_FLAG_REQD,
.prompt = N_("hsr port2"),
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_SUPERVISION_ADDRESS,
.is_cli_option = TRUE,
.property_alias = "supervision-address",
.prompt = N_("hsr supervision address"),
.property_type = &_pt_gobject_mac,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_MULTICAST_SPEC,
.is_cli_option = TRUE,
.property_alias = "multicast-spec",
.prompt = N_("hsr multicast spec"),
.property_type = &_pt_gobject_int,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_PRP,
.property_type = &_pt_gobject_bool,
),
NULL
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_HOSTNAME
static const NMMetaPropertyInfo *const property_infos_HOSTNAME[] = {
@ -8559,6 +8595,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN)
#define SETTING_PRETTY_NAME_GENERIC N_("Generic settings")
#define SETTING_PRETTY_NAME_GSM N_("GSM mobile broadband connection")
#define SETTING_PRETTY_NAME_HOSTNAME N_("Hostname settings")
#define SETTING_PRETTY_NAME_HSR N_("HSR settings")
#define SETTING_PRETTY_NAME_INFINIBAND N_("InfiniBand connection")
#define SETTING_PRETTY_NAME_IP4_CONFIG N_("IPv4 protocol")
#define SETTING_PRETTY_NAME_IP6_CONFIG N_("IPv6 protocol")
@ -8702,6 +8739,12 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
.setting_init_fcn = _setting_init_fcn_gsm,
),
SETTING_INFO (HOSTNAME),
SETTING_INFO (HSR,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (HSR, TRUE),
),
),
SETTING_INFO (INFINIBAND,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),

View file

@ -445,6 +445,11 @@
#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 \"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 \"true\" (1).")
#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_ONLY_FROM_DEFAULT N_("If set to \"true\" (1), NetworkManager attempts to get the hostname via DHCPv4/DHCPv6 or reverse DNS lookup on this device only when the device has the default route for the given address family (IPv4/IPv6). If set to \"false\" (0), the hostname can be set from this device even if it doesn't have the default route. When set to \"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 \"false\" (0).")
#define DESCRIBE_DOC_NM_SETTING_HOSTNAME_PRIORITY N_("The relative priority of this connection to determine the system hostname. A lower numerical value is better (higher priority). A connection with higher priority is considered before connections with lower priority. If the value is zero, it can be overridden by a global value from NetworkManager configuration. If the property doesn't have a value in the global configuration, the value is assumed to be 100. Negative values have the special effect of excluding other connections with a greater numerical priority value; so in presence of at least one negative priority, only connections with the lowest priority value will be used to determine the hostname.")
#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_PRP N_("The protocol used by the interface, whether it is PRP or HSR.")
#define DESCRIBE_DOC_NM_SETTING_HSR_SUPERVISION_ADDRESS N_("The supervision MAC address.")
#define DESCRIBE_DOC_NM_SETTING_LINK_GRO_MAX_SIZE N_("The maximum size of a packet built by the Generic Receive Offload stack for this device. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved.")
#define DESCRIBE_DOC_NM_SETTING_LINK_GSO_MAX_SEGMENTS N_("The maximum segments of a Generic Segment Offload packet the device should accept. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved.")
#define DESCRIBE_DOC_NM_SETTING_LINK_GSO_MAX_SIZE N_("The maximum size of a Generic Segment Offload packet the device should accept. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved.")

View file

@ -1075,7 +1075,8 @@ const NmcMetaGenericInfo
"," NM_SETTING_LINK_SETTING_NAME "," NM_SETTING_PROXY_SETTING_NAME \
"," NM_SETTING_TC_CONFIG_SETTING_NAME "," NM_SETTING_SRIOV_SETTING_NAME \
"," NM_SETTING_ETHTOOL_SETTING_NAME "," NM_SETTING_OVS_DPDK_SETTING_NAME \
"," NM_SETTING_HOSTNAME_SETTING_NAME /* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */
"," NM_SETTING_HOSTNAME_SETTING_NAME "," NM_SETTING_HSR_SETTING_NAME
/* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */
const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = {
NMC_META_GENERIC_WITH_NESTED("GENERAL", metagen_con_active_general), /* 0 */
@ -4561,6 +4562,7 @@ enable_type_settings_and_options(NmCli *nmc, NMConnection *con, GError **error)
NM_SETTING_BOND_SETTING_NAME,
NM_SETTING_BRIDGE_SETTING_NAME,
NM_SETTING_DUMMY_SETTING_NAME,
NM_SETTING_HSR_SETTING_NAME,
NM_SETTING_OVS_BRIDGE_SETTING_NAME,
NM_SETTING_OVS_PATCH_SETTING_NAME,
NM_SETTING_OVS_PORT_SETTING_NAME,

View file

@ -616,7 +616,7 @@
alias="type"
nmcli-description="Base type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, &quot;802-3-ethernet&quot; or &quot;802-11-wireless&quot; or &quot;bluetooth&quot;, etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, &quot;vpn&quot; or &quot;bridge&quot;, etc)."
format="string"
values="6lowpan, 802-11-olpc-mesh, 802-11-wireless, 802-3-ethernet, adsl, bluetooth, bond, bridge, cdma, dummy, generic, gsm, infiniband, ip-tunnel, loopback, macsec, macvlan, ovs-bridge, ovs-dpdk, ovs-interface, ovs-patch, ovs-port, pppoe, team, tun, veth, vlan, vpn, vrf, vxlan, wifi-p2p, wimax, wireguard, wpan" />
values="6lowpan, 802-11-olpc-mesh, 802-11-wireless, 802-3-ethernet, adsl, bluetooth, bond, bridge, cdma, dummy, generic, gsm, hsr, infiniband, ip-tunnel, loopback, macsec, macvlan, ovs-bridge, ovs-dpdk, ovs-interface, ovs-patch, ovs-port, pppoe, team, tun, veth, vlan, vpn, vrf, vxlan, wifi-p2p, wimax, wireguard, wpan" />
<property name="interface-name"
alias="ifname"
nmcli-description="The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface."
@ -1135,6 +1135,29 @@
format="ternary"
values="true/yes/on, false/no/off, default/unknown" />
</setting>
<setting name="hsr" >
<property name="port1"
alias="port1"
nmcli-description="The port1 interface name of the HSR. This property is mandatory."
format="string" />
<property name="port2"
alias="port2"
nmcli-description="The port2 interface name of the HSR. This property is mandatory."
format="string" />
<property name="supervision-address"
alias="supervision-address"
nmcli-description="The supervision MAC address."
format="MAC address" />
<property name="multicast-spec"
alias="multicast-spec"
nmcli-description="The last byte of supervision address."
format="integer"
values="0 - 255" />
<property name="prp"
nmcli-description="The protocol used by the interface, whether it is PRP or HSR."
format="boolean"
values="true/yes/on, false/no/off" />
</setting>
<setting name="infiniband" >
<property name="mac-address"
alias="mac"

View file

@ -31,6 +31,7 @@ SETTING_ETHTOOL_* parent="NM.SettingEthtool" name="SETTIN
SETTING_GENERIC_* parent="NM.SettingGeneric" name="SETTING_GENERIC_(.+)"
SETTING_GSM_* parent="NM.SettingGsm" name="SETTING_GSM_(.+)"
SETTING_HOSTNAME_* parent="NM.SettingHostname" name="SETTING_HOSTNAME_(.+)"
SETTING_HSR_* parent="NM.SettingHsr" name="SETTING_HSR_(.+)"
SETTING_INFINIBAND_* parent="NM.SettingInfiniband" name="SETTING_INFINIBAND_(.+)"
SETTING_IP4_CONFIG_* parent="NM.SettingIP4Config" name="SETTING_IP4_CONFIG_(.+)"
SETTING_IP6_CONFIG_* parent="NM.SettingIP6Config" name="SETTING_IP6_CONFIG_(.+)"
@ -111,6 +112,7 @@ DEVICE_BT_* parent="NM.DeviceBt" name="DEVICE
DEVICE_DUMMY_* parent="NM.DeviceDummy" name="DEVICE_DUMMY_(.+)"
DEVICE_ETHERNET_* parent="NM.DeviceEthernet" name="DEVICE_ETHERNET_(.+)"
DEVICE_GENERIC_* parent="NM.DeviceGeneric" name="DEVICE_GENERIC_(.+)"
DEVICE_HSR_* parent="NM.DeviceHsr" name="DEVICE_HSR_(.+)"
DEVICE_INFINIBAND_* parent="NM.DeviceInfiniband" name="DEVICE_INFINIBAND_(.+)"
DEVICE_IP_TUNNEL_* parent="NM.DeviceIPTunnel" name="DEVICE_IP_TUNNEL_(.+)"
DEVICE_LOOPBACK_* parent="NM.DeviceLoopback" name="DEVICE_LOOPBACK_(.+)"