diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 442c7140b6..69cfdb0713 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -1021,6 +1021,9 @@ ipv6.ip6-privacy=0
loopback.mtu
If configured explicitly to 0, the MTU is not reconfigured during device activation unless it is required due to IPv6 constraints. If left unspecified, a DHCP/IPv6 SLAAC provided value is used or the MTU is left unspecified on activation.
+
+ macsec.offload
+
sriov.autoprobe-drivers
If left unspecified, drivers are autoprobed when the SR-IOV VF gets created.
diff --git a/src/core/devices/nm-device-macsec.c b/src/core/devices/nm-device-macsec.c
index 130708bb23..32fab5be63 100644
--- a/src/core/devices/nm-device-macsec.c
+++ b/src/core/devices/nm-device-macsec.c
@@ -10,6 +10,7 @@
#include
#include "nm-act-request.h"
+#include "nm-config.h"
#include "nm-device-private.h"
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
@@ -190,6 +191,7 @@ build_supplicant_config(NMDeviceMacsec *self, GError **error)
NMConnection *connection;
const char *con_uuid;
guint32 mtu;
+ int offload;
connection = nm_device_get_applied_connection(NM_DEVICE(self));
@@ -205,7 +207,20 @@ build_supplicant_config(NMDeviceMacsec *self, GError **error)
g_return_val_if_fail(s_macsec, NULL);
- if (!nm_supplicant_config_add_setting_macsec(config, s_macsec, error)) {
+ offload = nm_setting_macsec_get_offload(s_macsec);
+ if (offload == NM_SETTING_MACSEC_OFFLOAD_DEFAULT) {
+ offload = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
+ NM_CON_DEFAULT("macsec.offload"),
+ NM_DEVICE(self),
+ NM_SETTING_MACSEC_OFFLOAD_OFF,
+ NM_SETTING_MACSEC_OFFLOAD_MAC,
+ NM_SETTING_MACSEC_OFFLOAD_OFF);
+ }
+
+ if (!nm_supplicant_config_add_setting_macsec(config,
+ s_macsec,
+ (NMSettingMacsecOffload) offload,
+ error)) {
g_prefix_error(error, "macsec-setting: ");
return NULL;
}
diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c
index 1d9372e09f..9ad4a8f950 100644
--- a/src/core/supplicant/nm-supplicant-config.c
+++ b/src/core/supplicant/nm-supplicant-config.c
@@ -396,14 +396,16 @@ again:
}
gboolean
-nm_supplicant_config_add_setting_macsec(NMSupplicantConfig *self,
- NMSettingMacsec *setting,
- GError **error)
+nm_supplicant_config_add_setting_macsec(NMSupplicantConfig *self,
+ NMSettingMacsec *setting,
+ NMSettingMacsecOffload offload,
+ GError **error)
{
const char *value;
char buf[32];
int port;
gsize key_len;
+ const char *offload_str = NULL;
g_return_val_if_fail(NM_IS_SUPPLICANT_CONFIG(self), FALSE);
g_return_val_if_fail(setting != NULL, FALSE);
@@ -472,6 +474,28 @@ nm_supplicant_config_add_setting_macsec(NMSupplicantConfig *self,
return FALSE;
}
+ switch (offload) {
+ case NM_SETTING_MACSEC_OFFLOAD_OFF:
+ /* This is the default in wpa_supplicant. Don't set the option,
+ * so that if user doesn't enable offload, the connection still
+ * works with previous versions of the supplicant.
+ */
+ break;
+ case NM_SETTING_MACSEC_OFFLOAD_PHY:
+ offload_str = "1";
+ break;
+ case NM_SETTING_MACSEC_OFFLOAD_MAC:
+ offload_str = "2";
+ break;
+ case NM_SETTING_MACSEC_OFFLOAD_DEFAULT:
+ nm_assert_not_reached();
+ break;
+ }
+ if (offload_str
+ && !nm_supplicant_config_add_option(self, "macsec_offload", offload_str, -1, NULL, error)) {
+ return FALSE;
+ }
+
return TRUE;
}
diff --git a/src/core/supplicant/nm-supplicant-config.h b/src/core/supplicant/nm-supplicant-config.h
index 585cf9588d..c52b756e78 100644
--- a/src/core/supplicant/nm-supplicant-config.h
+++ b/src/core/supplicant/nm-supplicant-config.h
@@ -68,9 +68,10 @@ gboolean nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
gboolean wired,
GError **error);
-gboolean nm_supplicant_config_add_setting_macsec(NMSupplicantConfig *self,
- NMSettingMacsec *setting,
- GError **error);
+gboolean nm_supplicant_config_add_setting_macsec(NMSupplicantConfig *self,
+ NMSettingMacsec *setting,
+ NMSettingMacsecOffload offload,
+ GError **error);
gboolean nm_supplicant_config_enable_pmf_akm(NMSupplicantConfig *self, GError **error);
diff --git a/src/core/supplicant/nm-supplicant-settings-verify.c b/src/core/supplicant/nm-supplicant-settings-verify.c
index 8f2561a6a9..7842365c3c 100644
--- a/src/core/supplicant/nm-supplicant-settings-verify.c
+++ b/src/core/supplicant/nm-supplicant-settings-verify.c
@@ -87,6 +87,7 @@ static const struct Opt opt_table[] = {
"OWE",
"NONE", )),
OPT_INT("macsec_integ_only", 0, 1),
+ OPT_INT("macsec_offload", 0, 2),
OPT_INT("macsec_policy", 0, 1),
OPT_INT("macsec_port", 1, 65534),
OPT_BYTES("mka_cak", 65536),
diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver
index 73fdec5bad..0655d2dea4 100644
--- a/src/libnm-client-impl/libnm.ver
+++ b/src/libnm-client-impl/libnm.ver
@@ -1959,6 +1959,7 @@ global:
nm_setting_connection_get_autoconnect_ports;
nm_setting_connection_get_controller;
nm_setting_connection_get_port_type;
+ nm_setting_get_enum_property_type;
nm_setting_hsr_get_multicast_spec;
nm_setting_hsr_get_port1;
nm_setting_hsr_get_port2;
@@ -1966,11 +1967,12 @@ global:
nm_setting_hsr_get_type;
nm_setting_hsr_new;
nm_setting_ip_config_get_dhcp_dscp;
- nm_setting_get_enum_property_type;
- nm_setting_sriov_get_eswitch_mode;
- nm_sriov_eswitch_mode_get_type;
- nm_setting_sriov_get_eswitch_inline_mode;
- nm_sriov_eswitch_inline_mode_get_type;
+ nm_setting_macsec_get_offload;
+ nm_setting_macsec_offload_get_type;
nm_setting_sriov_get_eswitch_encap_mode;
+ nm_setting_sriov_get_eswitch_inline_mode;
+ nm_setting_sriov_get_eswitch_mode;
nm_sriov_eswitch_encap_mode_get_type;
+ nm_sriov_eswitch_inline_mode_get_type;
+ nm_sriov_eswitch_mode_get_type;
} libnm_1_44_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 b2748beb1e..57337c6069 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
@@ -1876,6 +1876,10 @@
dbus-type="i"
gprop-type="gint"
/>
+
send_sci;
}
+/**
+ * nm_setting_macsec_get_offload:
+ * @setting: the #NMSettingMacsec
+ *
+ * Returns: the #NMSettingMacsec:offload property of the setting
+ *
+ * Since: 1.46
+ **/
+NMSettingMacsecOffload
+nm_setting_macsec_get_offload(NMSettingMacsec *setting)
+{
+ g_return_val_if_fail(NM_IS_SETTING_MACSEC(setting), NM_SETTING_MACSEC_OFFLOAD_DEFAULT);
+
+ return NM_SETTING_MACSEC_GET_PRIVATE(setting)->offload;
+}
+
static GPtrArray *
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
@@ -597,6 +615,35 @@ nm_setting_macsec_class_init(NMSettingMacsecClass *klass)
NMSettingMacsecPrivate,
send_sci);
+ /**
+ * NMSettingMacsec:offload:
+ *
+ * Specifies the MACsec offload mode.
+ *
+ * %NM_SETTING_MACSEC_OFFLOAD_OFF disables MACsec offload.
+ *
+ * %NM_SETTING_MACSEC_OFFLOAD_PHY and %NM_SETTING_MACSEC_OFFLOAD_MAC request offload
+ * respectively to the PHY or to the MAC; if the selected mode is not available, the
+ * connection will fail.
+ *
+ * %NM_SETTING_MACSEC_OFFLOAD_DEFAULT uses the global default value specified in
+ * NetworkManager configuration; if no global default is defined, the built-in
+ * default is %NM_SETTING_MACSEC_OFFLOAD_OFF.
+ *
+ * Since: 1.46
+ **/
+ _nm_setting_property_define_direct_enum(properties_override,
+ obj_properties,
+ NM_SETTING_MACSEC_OFFLOAD,
+ PROP_OFFLOAD,
+ NM_TYPE_SETTING_MACSEC_OFFLOAD,
+ NM_SETTING_MACSEC_OFFLOAD_DEFAULT,
+ NM_SETTING_PARAM_INFERRABLE
+ | NM_SETTING_PARAM_FUZZY_IGNORE,
+ NULL,
+ NMSettingMacsecPrivate,
+ offload);
+
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit(setting_class,
diff --git a/src/libnm-core-public/nm-setting-macsec.h b/src/libnm-core-public/nm-setting-macsec.h
index c2662b1f5e..27b7311e4f 100644
--- a/src/libnm-core-public/nm-setting-macsec.h
+++ b/src/libnm-core-public/nm-setting-macsec.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
#define NM_SETTING_MACSEC_PORT "port"
#define NM_SETTING_MACSEC_VALIDATION "validation"
#define NM_SETTING_MACSEC_SEND_SCI "send-sci"
+#define NM_SETTING_MACSEC_OFFLOAD "offload"
typedef struct _NMSettingMacsecClass NMSettingMacsecClass;
@@ -77,6 +78,24 @@ typedef enum {
/* Deprecated. The CKN can be between 2 and 64 characters. */
#define NM_SETTING_MACSEC_MKA_CKN_LENGTH 64
+/**
+ * NMSettingMacsecOffload:
+ * @NM_SETTING_MACSEC_OFFLOAD_DEFAULT: use the global default; disable if not defined
+ * @NM_SETTING_MACSEC_OFFLOAD_OFF: disable offload
+ * @NM_SETTING_MACSEC_OFFLOAD_PHY: request offload to the PHY
+ * @NM_SETTING_MACSEC_OFFLOAD_MAC: request offload to the MAC
+ *
+ * These flags control the MACsec offload mode.
+ *
+ * Since: 1.46
+ **/
+typedef enum {
+ NM_SETTING_MACSEC_OFFLOAD_DEFAULT = -1,
+ NM_SETTING_MACSEC_OFFLOAD_OFF = 0,
+ NM_SETTING_MACSEC_OFFLOAD_PHY = 1,
+ NM_SETTING_MACSEC_OFFLOAD_MAC = 2,
+} NMSettingMacsecOffload;
+
NM_AVAILABLE_IN_1_6
GType nm_setting_macsec_get_type(void);
NM_AVAILABLE_IN_1_6
@@ -100,6 +119,8 @@ NM_AVAILABLE_IN_1_6
NMSettingMacsecValidation nm_setting_macsec_get_validation(NMSettingMacsec *setting);
NM_AVAILABLE_IN_1_12
gboolean nm_setting_macsec_get_send_sci(NMSettingMacsec *setting);
+NM_AVAILABLE_IN_1_46
+NMSettingMacsecOffload nm_setting_macsec_get_offload(NMSettingMacsec *setting);
G_END_DECLS
diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c
index 4876acc2e9..16cc003a93 100644
--- a/src/libnmc-setting/nm-meta-setting-desc.c
+++ b/src/libnmc-setting/nm-meta-setting-desc.c
@@ -6909,6 +6909,9 @@ static const NMMetaPropertyInfo *const property_infos_MACSEC[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_SEND_SCI,
.property_type = &_pt_gobject_bool,
),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_MACSEC_OFFLOAD,
+ .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 841cfc8574..d56a3d8ab5 100644
--- a/src/libnmc-setting/settings-docs.h.in
+++ b/src/libnmc-setting/settings-docs.h.in
@@ -243,6 +243,7 @@
#define DESCRIBE_DOC_NM_SETTING_MACSEC_MKA_CAK_FLAGS N_("Flags indicating how to handle the \"mka-cak\" property.")
#define DESCRIBE_DOC_NM_SETTING_MACSEC_MKA_CKN N_("The pre-shared CKN (Connectivity-association Key Name) for MACsec Key Agreement. Must be a string of hexadecimal characters with a even length between 2 and 64.")
#define DESCRIBE_DOC_NM_SETTING_MACSEC_MODE N_("Specifies how the CAK (Connectivity Association Key) for MKA (MACsec Key Agreement) is obtained.")
+#define DESCRIBE_DOC_NM_SETTING_MACSEC_OFFLOAD N_("Specifies the MACsec offload mode. \"off\" (0) disables MACsec offload. \"phy\" (1) and \"mac\" (2) request offload respectively to the PHY or to the MAC; if the selected mode is not available, the connection will fail. \"default\" (-1) uses the global default value specified in NetworkManager configuration; if no global default is defined, the built-in default is \"off\" (0).")
#define DESCRIBE_DOC_NM_SETTING_MACSEC_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this MACSEC interface should be created. If this property is not specified, the connection must contain an \"802-3-ethernet\" setting with a \"mac-address\" property.")
#define DESCRIBE_DOC_NM_SETTING_MACSEC_PORT N_("The port component of the SCI (Secure Channel Identifier), between 1 and 65534.")
#define DESCRIBE_DOC_NM_SETTING_MACSEC_SEND_SCI N_("Specifies whether the SCI (Secure Channel Identifier) is included in every packet.")
diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
index 1329a9c7fa..2c71865fca 100644
--- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
+++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
@@ -1548,6 +1548,10 @@
nmcli-description="Specifies whether the SCI (Secure Channel Identifier) is included in every packet."
format="boolean"
values="true/yes/on, false/no/off" />
+