Commit df30651b authored by Thomas Haller's avatar Thomas Haller
Browse files

libnm, cli, ifcfg-rh: add NMSettingEthtool setting

Note that in NetworkManager API (D-Bus, libnm, and nmcli),
the features are called "feature-xyz". The "feature-" prefix
is used, because NMSettingEthtool possibly will gain support
for options that are not only -K|--offload|--features, for
example -C|--coalesce.

The "xzy" suffix is either how ethtool utility calls the feature
("tso", "rx"). Or, if ethtool utility specifies no alias for that
feature, it's the name from kernel's ETH_SS_FEATURES ("tx-tcp6-segmentation").
If possible, we prefer ethtool utility's naming.

Also note, how the features "feature-sg", "feature-tso", and
"feature-tx" actually refer to multiple underlying kernel features
at once. This too follows what ethtool utility does.

The functionality is not yet implemented server-side.
parent 4e0f1b16
......@@ -453,6 +453,7 @@ libnm_core_lib_h_pub_real = \
libnm-core/nm-setting-connection.h \
libnm-core/nm-setting-dcb.h \
libnm-core/nm-setting-dummy.h \
libnm-core/nm-setting-ethtool.h \
libnm-core/nm-setting-generic.h \
libnm-core/nm-setting-gsm.h \
libnm-core/nm-setting-infiniband.h \
......@@ -502,6 +503,7 @@ libnm_core_lib_h_priv = \
shared/nm-utils/nm-shared-utils.h \
shared/nm-utils/nm-random-utils.h \
shared/nm-utils/nm-udev-utils.h \
shared/nm-ethtool-utils.h \
shared/nm-meta-setting.h \
libnm-core/crypto.h \
libnm-core/nm-connection-private.h \
......@@ -524,6 +526,7 @@ libnm_core_lib_c_settings_real = \
libnm-core/nm-setting-connection.c \
libnm-core/nm-setting-dcb.c \
libnm-core/nm-setting-dummy.c \
libnm-core/nm-setting-ethtool.c \
libnm-core/nm-setting-generic.c \
libnm-core/nm-setting-gsm.c \
libnm-core/nm-setting-infiniband.c \
......@@ -565,6 +568,7 @@ libnm_core_lib_c_real = \
shared/nm-utils/nm-shared-utils.c \
shared/nm-utils/nm-random-utils.c \
shared/nm-utils/nm-udev-utils.c \
shared/nm-ethtool-utils.c \
shared/nm-meta-setting.c \
libnm-core/crypto.c \
libnm-core/nm-connection.c \
......@@ -2390,6 +2394,7 @@ EXTRA_DIST += \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-3.expected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4 \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap \
src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap \
src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep \
......@@ -3425,6 +3430,9 @@ clients_common_libnmc_la_SOURCES = \
shared/nm-meta-setting.c \
shared/nm-meta-setting.h \
\
shared/nm-ethtool-utils.c \
shared/nm-ethtool-utils.h \
\
clients/common/nm-meta-setting-desc.c \
clients/common/nm-meta-setting-desc.h \
clients/common/nm-meta-setting-access.c \
......
......@@ -770,7 +770,8 @@ const NmcMetaGenericInfo *const metagen_con_active_vpn[_NMC_GENERIC_INFO_TYPE_CO
NM_SETTING_6LOWPAN_SETTING_NAME","\
NM_SETTING_PROXY_SETTING_NAME"," \
NM_SETTING_TC_CONFIG_SETTING_NAME"," \
NM_SETTING_SRIOV_SETTING_NAME
NM_SETTING_SRIOV_SETTING_NAME"," \
NM_SETTING_ETHTOOL_SETTING_NAME
// NM_SETTING_DUMMY_SETTING_NAME
// NM_SETTING_WIMAX_SETTING_NAME
......
......@@ -59,7 +59,7 @@ libnmc = static_library(
sources: files(
'nm-meta-setting-access.c',
'nm-meta-setting-desc.c'
) + shared_nm_meta_setting_c + [settings_docs_source],
) + shared_nm_meta_setting_c + shared_nm_ethtool_utils_c + [settings_docs_source],
dependencies: deps,
c_args: cflags,
link_with: libnmc_base,
......
......@@ -4823,6 +4823,84 @@ _validate_fcn_wireless_security_psk (const char *value, char **out_to_free, GErr
/*****************************************************************************/
static gconstpointer
_get_fcn_ethtool (ARGS_GET_FCN)
{
const char *s;
NMTernary val;
NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
RETURN_UNSUPPORTED_GET_TYPE ();
val = nm_setting_ethtool_get_feature (NM_SETTING_ETHTOOL (setting),
nm_ethtool_data[ethtool_id]->optname);
if (val == NM_TERNARY_TRUE)
s = N_("on");
else if (val == NM_TERNARY_FALSE)
s = N_("off");
else {
s = NULL;
NM_SET_OUT (out_is_default, TRUE);
}
if (s && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
s = gettext (s);
return s;
}
static gboolean
_set_fcn_ethtool (ARGS_SET_FCN)
{
gs_free char *value_clone = NULL;
NMTernary val;
NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
value = nm_strstrip_avoid_copy (value, &value_clone);
if (NM_IN_STRSET (value, "1", "yes", "true", "on"))
val = NM_TERNARY_TRUE;
else if (NM_IN_STRSET (value, "0", "no", "false", "off"))
val = NM_TERNARY_FALSE;
else if (NM_IN_STRSET (value, "", "ignore", "default"))
val = NM_TERNARY_DEFAULT;
else {
g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT,
_("'%s' is not valid; use 'on', 'off', or 'ignore'"),
value);
return FALSE;
}
nm_setting_ethtool_set_feature (NM_SETTING_ETHTOOL (setting),
nm_ethtool_data[ethtool_id]->optname,
val);
return TRUE;
}
static const char *const*
_complete_fcn_ethtool (ARGS_COMPLETE_FCN)
{
static const char *const v[] = {
"true",
"false",
"1",
"0",
"yes",
"no",
"default",
"on",
"off",
"ignore",
NULL,
};
if (!text || !text[0])
return &v[7];
return v;
}
/*****************************************************************************/
static const NMMetaPropertyInfo property_info_BOND_OPTIONS;
#define NESTED_PROPERTY_INFO_BOND(...) \
......@@ -4979,6 +5057,12 @@ static const NMMetaPropertyType _pt_gobject_devices = {
.complete_fcn = _complete_fcn_gobject_devices,
};
static const NMMetaPropertyType _pt_ethtool = {
.get_fcn = _get_fcn_ethtool,
.set_fcn = _set_fcn_ethtool,
.complete_fcn = _complete_fcn_ethtool,
};
/*****************************************************************************/
#include "settings-docs.h"
......@@ -5775,6 +5859,31 @@ static const NMMetaPropertyInfo *const property_infos_DCB[] = {
NULL
};
#define PROPERTY_INFO_ETHTOOL(xname) \
PROPERTY_INFO (NM_ETHTOOL_OPTNAME_##xname, NULL, \
.property_type = &_pt_ethtool, \
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (ethtool, \
.ethtool_id = NM_ETHTOOL_ID_##xname, \
), \
)
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_ETHTOOL
static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = {
PROPERTY_INFO_ETHTOOL (FEATURE_GRO),
PROPERTY_INFO_ETHTOOL (FEATURE_GSO),
PROPERTY_INFO_ETHTOOL (FEATURE_LRO),
PROPERTY_INFO_ETHTOOL (FEATURE_NTUPLE),
PROPERTY_INFO_ETHTOOL (FEATURE_RX),
PROPERTY_INFO_ETHTOOL (FEATURE_RXHASH),
PROPERTY_INFO_ETHTOOL (FEATURE_RXVLAN),
PROPERTY_INFO_ETHTOOL (FEATURE_SG),
PROPERTY_INFO_ETHTOOL (FEATURE_TSO),
PROPERTY_INFO_ETHTOOL (FEATURE_TX),
PROPERTY_INFO_ETHTOOL (FEATURE_TXVLAN),
NULL,
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_GSM
static const NMMetaPropertyInfo *const property_infos_GSM[] = {
......@@ -7740,6 +7849,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN)
#define SETTING_PRETTY_NAME_CONNECTION N_("General settings")
#define SETTING_PRETTY_NAME_DCB N_("DCB settings")
#define SETTING_PRETTY_NAME_DUMMY N_("Dummy settings")
#define SETTING_PRETTY_NAME_ETHTOOL N_("Ethtool settings")
#define SETTING_PRETTY_NAME_GENERIC N_("Generic settings")
#define SETTING_PRETTY_NAME_GSM N_("GSM mobile broadband connection")
#define SETTING_PRETTY_NAME_INFINIBAND N_("InfiniBand connection")
......@@ -7827,6 +7937,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (BOND, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (BRIDGE,
......@@ -7834,6 +7945,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (BRIDGE, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (BRIDGE_PORT),
......@@ -7848,11 +7960,13 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
),
SETTING_INFO (CONNECTION),
SETTING_INFO (DCB),
SETTING_INFO (ETHTOOL),
SETTING_INFO_EMPTY (DUMMY,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (DUMMY, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO_EMPTY (GENERIC,
......@@ -7875,6 +7989,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (INFINIBAND, TRUE),
NM_META_SETTING_VALID_PART_ITEM (SRIOV, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
.setting_init_fcn = _setting_init_fcn_infiniband,
),
......@@ -7889,6 +8004,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (IP_TUNNEL, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (MACSEC,
......@@ -7897,6 +8013,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (MACSEC, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (MACVLAN,
......@@ -7904,6 +8021,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (MACVLAN, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (OLPC_MESH,
......@@ -7928,6 +8046,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (IP4_CONFIG, FALSE),
NM_META_SETTING_VALID_PART_ITEM (IP6_CONFIG, FALSE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (OVS_PATCH),
......@@ -7947,6 +8066,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (WIRED, TRUE),
NM_META_SETTING_VALID_PART_ITEM (PPP, FALSE),
NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (PPP),
......@@ -7961,6 +8081,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (TEAM, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (TEAM_PORT),
......@@ -7969,6 +8090,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (TUN, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
.setting_init_fcn = _setting_init_fcn_tun,
),
......@@ -7978,6 +8100,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (VLAN, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
.setting_init_fcn = _setting_init_fcn_vlan,
),
......@@ -7992,6 +8115,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (VXLAN, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (WIMAX,
......@@ -8008,6 +8132,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE),
NM_META_SETTING_VALID_PART_ITEM (DCB, FALSE),
NM_META_SETTING_VALID_PART_ITEM (SRIOV, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
),
SETTING_INFO (WIRELESS,
......@@ -8017,6 +8142,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
NM_META_SETTING_VALID_PART_ITEM (WIRELESS, TRUE),
NM_META_SETTING_VALID_PART_ITEM (WIRELESS_SECURITY, FALSE),
NM_META_SETTING_VALID_PART_ITEM (802_1X, FALSE),
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
),
.setting_init_fcn = _setting_init_fcn_wireless,
),
......
......@@ -22,6 +22,7 @@
#include "nm-utils/nm-obj.h"
#include "nm-meta-setting.h"
#include "nm-ethtool-utils.h"
struct _NMDevice;
......@@ -263,6 +264,9 @@ struct _NMMetaPropertyTypData {
struct {
NMMetaPropertyTypeMacMode mode;
} mac;
struct {
NMEthtoolID ethtool_id;
} ethtool;
} subtype;
const char *const*values_static;
const NMMetaPropertyTypDataNested *nested;
......
......@@ -202,6 +202,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in
<xi:include href="xml/nm-setting-cdma.xml"/>
<xi:include href="xml/nm-setting-dcb.xml"/>
<xi:include href="xml/nm-setting-dummy.xml"/>
<xi:include href="xml/nm-setting-ethtool.xml"/>
<xi:include href="xml/nm-setting-generic.xml"/>
<xi:include href="xml/nm-setting-gsm.xml"/>
<xi:include href="xml/nm-setting-infiniband.xml"/>
......
......@@ -69,6 +69,7 @@ libnm_core_settings_sources = files(
'nm-setting-connection.c',
'nm-setting-dcb.c',
'nm-setting-dummy.c',
'nm-setting-ethtool.c',
'nm-setting-generic.c',
'nm-setting-gsm.c',
'nm-setting-infiniband.c',
......@@ -154,6 +155,7 @@ endif
libnm_core_sources_all = libnm_core_sources
libnm_core_sources_all += libnm_core_enum
libnm_core_sources_all += shared_nm_meta_setting_c
libnm_core_sources_all += shared_nm_ethtool_utils_c
libnm_core_sources_all += shared_files_libnm_core
libnm_core_sources_all += [version_header]
......
......@@ -201,6 +201,11 @@ GVariant *const*nm_setting_gendata_get_all_values (NMSetting *setting);
/*****************************************************************************/
guint nm_setting_ethtool_init_features (NMSettingEthtool *setting,
NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */);
/*****************************************************************************/
#define NM_UTILS_HWADDR_LEN_MAX_STR (NM_UTILS_HWADDR_LEN_MAX * 3)
guint8 *_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length);
......
......@@ -40,6 +40,7 @@ typedef struct _NMSettingCdma NMSettingCdma;
typedef struct _NMSettingConnection NMSettingConnection;
typedef struct _NMSettingDcb NMSettingDcb;
typedef struct _NMSettingDummy NMSettingDummy;
typedef struct _NMSettingEthtool NMSettingEthtool;
typedef struct _NMSettingGeneric NMSettingGeneric;
typedef struct _NMSettingGsm NMSettingGsm;
typedef struct _NMSettingInfiniband NMSettingInfiniband;
......
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2018 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-setting-ethtool.h"
#include "nm-setting-private.h"
#include "nm-ethtool-utils.h"
/*****************************************************************************/
/**
* SECTION:nm-setting-ethtool
* @short_description: Describes connection properties for ethtool related options
*
* The #NMSettingEthtool object is a #NMSetting subclass that describes properties
* to control network driver and hardware settings.
**/
/*****************************************************************************/
/**
* nm_ethtool_optname_is_feature:
* @optname: the option name to check
*
* Checks whether @optname is a valid option name for an offload feature.
*
* %Returns: %TRUE, if @optname is valid
*
* Since: 1.14
*/
gboolean
nm_ethtool_optname_is_feature (const char *optname)
{
return optname && nm_ethtool_id_is_feature (nm_ethtool_id_get_by_name (optname));
}
/*****************************************************************************/
/**
* NMSettingEthtool:
*
* Ethtool Ethernet Settings
*
* Since: 1.14
*/
struct _NMSettingEthtool {
NMSetting parent;
};
struct _NMSettingEthtoolClass {
NMSettingClass parent;
};
G_DEFINE_TYPE (NMSettingEthtool, nm_setting_ethtool, NM_TYPE_SETTING)
#define NM_SETTING_ETHTOOL_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSettingEthtool, NM_IS_SETTING_ETHTOOL, NMSetting)
/*****************************************************************************/
static void
_notify_attributes (NMSettingEthtool *self)
{
_nm_setting_gendata_notify (NM_SETTING (self), TRUE);
}
/*****************************************************************************/
/**
* nm_setting_ethtool_get_feature:
* @setting: the #NMSettingEthtool
* @optname: option name of the offload feature to get
*
* Gets and offload feature setting. Returns %NM_TERNARY_DEFAULT if the
* feature is not set.
*
* Returns: a #NMTernary value indicating whether the offload feature
* is enabled, disabled, or left untouched.
*
* Since: 1.14
*/
NMTernary
nm_setting_ethtool_get_feature (NMSettingEthtool *setting,
const char *optname)
{
GVariant *v;
g_return_val_if_fail (NM_IS_SETTING_ETHTOOL (setting), NM_TERNARY_DEFAULT);
g_return_val_if_fail (optname && nm_ethtool_optname_is_feature (optname), NM_TERNARY_DEFAULT);
v = nm_setting_gendata_get (NM_SETTING (setting), optname);
if ( v
&& g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) {
return g_variant_get_boolean (v)
? NM_TERNARY_TRUE
: NM_TERNARY_FALSE;
}
return NM_TERNARY_DEFAULT;
}
/**
* nm_setting_ethtool_set_feature:
* @setting: the #NMSettingEthtool
* @optname: option name of the offload feature to get
* @value: the new value to set. The special value %NM_TERNARY_DEFAULT
* means to clear the offload feature setting.
*
* Sets and offload feature setting.
*
* Since: 1.14
*/
void
nm_setting_ethtool_set_feature (NMSettingEthtool *setting,
const char *optname,
NMTernary value)
{
GHashTable *hash;
GVariant *v;
g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting));
g_return_if_fail (optname && nm_ethtool_optname_is_feature (optname));
g_return_if_fail (NM_IN_SET (value, NM_TERNARY_DEFAULT,
NM_TERNARY_FALSE,
NM_TERNARY_TRUE));
hash = _nm_setting_gendata_hash (NM_SETTING (setting),
value != NM_TERNARY_DEFAULT);
if (value == NM_TERNARY_DEFAULT) {
if (hash) {
if (g_hash_table_remove (hash, optname))
_notify_attributes (setting);
}
return;
}
v = g_hash_table_lookup (hash, optname);
if ( v
&& g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) {
if (g_variant_get_boolean (v)) {
if (value == NM_TERNARY_TRUE)
return;
} else {
if (value == NM_TERNARY_FALSE)
return;
}
}
v = g_variant_ref_sink (g_variant_new_boolean (value != NM_TERNARY_FALSE));
g_hash_table_insert (hash,
g_strdup (optname),
v);
_notify_attributes (setting);
}
/**
* nm_setting_ethtool_clear_features:
* @setting: the #NMSettingEthtool
*
* Clears all offload features settings
*
* Since: 1.14
*/
void
nm_setting_ethtool_clear_features (NMSettingEthtool *setting)
{
GHashTable *hash;
GHashTableIter iter;
const char *name;
gboolean changed = FALSE;
g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting));
hash = _nm_setting_gendata_hash (NM_SETTING (setting), FALSE);
if (!hash)
return;
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter, (gpointer *) &name, NULL)) {
if (nm_ethtool_optname_is_feature (name)) {
g_hash_table_iter_remove (&iter);
changed = TRUE;
}
}
if (changed)
_notify_attributes (setting);
}
guint
nm_setting_ethtool_init_features (NMSettingEthtool *setting,
NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */)
{
GHashTable *hash;
GHashTableIter iter;
guint i;
guint n_req = 0;
const char *name;
GVariant *variant;
nm_assert (NM_IS_SETTING_ETHTOOL (setting));
nm_assert (requested);
for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++)
requested[i] = NM_TERNARY_DEFAULT;
hash = _nm_setting_gendata_hash (NM_SETTING (setting), FALSE);
if (!hash)
return 0;