mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-22 10:46:59 +00:00
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.
This commit is contained in:
parent
4e0f1b16b9
commit
df30651b89
|
@ -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;
|
||||
|
|
342
libnm-core/nm-setting-ethtool.c
Normal file
342
libnm-core/nm-setting-ethtool.c
Normal file
|
@ -0,0 +1,342 @@
|
|||
/* -*- 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;
|
||||
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) {
|
||||
NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name (name);
|
||||
|
||||
if (!nm_ethtool_id_is_feature (ethtool_id))
|
||||
continue;
|
||||
if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
|
||||
continue;
|
||||
|
||||
requested[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST] = g_variant_get_boolean (variant)
|
||||
? NM_TERNARY_TRUE
|
||||
: NM_TERNARY_FALSE;
|
||||
n_req++;
|
||||
}
|
||||
|
||||
return n_req;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||
{
|
||||
GHashTable *hash;
|
||||
GHashTableIter iter;
|
||||
const char *optname;
|
||||
GVariant *variant;
|
||||
|
||||
hash = _nm_setting_gendata_hash (setting, FALSE);
|
||||
|
||||
if (!hash)
|
||||
goto out;
|
||||
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &optname, (gpointer *) &variant)) {
|
||||
if (!nm_ethtool_optname_is_feature (optname)) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("unsupported offload feature"));
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname);
|
||||
return FALSE;
|
||||
}
|
||||
if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("offload feature has invalid variant type"));
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const GVariantType *
|
||||
get_variant_type (const NMSettInfoSetting *sett_info,
|
||||
const char *name,
|
||||
GError **error)
|
||||
{
|
||||
if (nm_ethtool_optname_is_feature (name))
|
||||
return G_VARIANT_TYPE_BOOLEAN;
|
||||
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("unknown ethtool option '%s'"),
|
||||
name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_setting_ethtool_init (NMSettingEthtool *setting)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ethtool_new:
|
||||
*
|
||||
* Creates a new #NMSettingEthtool object with default values.
|
||||
*
|
||||
* Returns: (transfer full): the new empty #NMSettingEthtool object
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
NMSetting *
|
||||
nm_setting_ethtool_new (void)
|
||||
{
|
||||
return g_object_new (NM_TYPE_SETTING_ETHTOOL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_ethtool_class_init (NMSettingEthtoolClass *klass)
|
||||
{
|
||||
NMSettingClass *setting_class = NM_SETTING_CLASS (klass);
|
||||
|
||||
setting_class->verify = verify;
|
||||
|
||||
_nm_setting_class_commit_full (setting_class,
|
||||
NM_META_SETTING_TYPE_ETHTOOL,
|
||||
NM_SETT_INFO_SETT_DETAIL (
|
||||
.gendata_info = NM_SETT_INFO_SETT_GENDATA (
|
||||
.get_variant_type = get_variant_type,
|
||||
),
|
||||
),
|
||||
NULL);
|
||||
}
|
83
libnm-core/nm-setting-ethtool.h
Normal file
83
libnm-core/nm-setting-ethtool.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef __NM_SETTING_ETHTOOL_H__
|
||||
#define __NM_SETTING_ETHTOOL_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_ETHTOOL_OPTNAME_FEATURE_GRO "feature-gro"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_GSO "feature-gso"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_LRO "feature-lro"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_NTUPLE "feature-ntuple"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_RX "feature-rx"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_RXHASH "feature-rxhash"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN "feature-rxvlan"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_SG "feature-sg"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_TSO "feature-tso"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_TX "feature-tx"
|
||||
#define NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN "feature-txvlan"
|
||||
|
||||
gboolean nm_ethtool_optname_is_feature (const char *optname);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_TYPE_SETTING_ETHTOOL (nm_setting_ethtool_get_type ())
|
||||
#define NM_SETTING_ETHTOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtool))
|
||||
#define NM_SETTING_ETHTOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtoolClass))
|
||||
#define NM_IS_SETTING_ETHTOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_ETHTOOL))
|
||||
#define NM_IS_SETTING_ETHTOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_ETHTOOL))
|
||||
#define NM_SETTING_ETHTOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_ETHTOOL, NMSettingEthtoolClass))
|
||||
|
||||
#define NM_SETTING_ETHTOOL_SETTING_NAME "ethtool"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _NMSettingEthtoolClass NMSettingEthtoolClass;
|
||||
|
||||
NM_AVAILABLE_IN_1_14
|
||||
GType nm_setting_ethtool_get_type (void);
|
||||
|
||||
NM_AVAILABLE_IN_1_14
|
||||
NMSetting *nm_setting_ethtool_new (void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_AVAILABLE_IN_1_14
|
||||
NMTernary nm_setting_ethtool_get_feature (NMSettingEthtool *setting,
|
||||
const char *optname);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
void nm_setting_ethtool_set_feature (NMSettingEthtool *setting,
|
||||
const char *optname,
|
||||
NMTernary value);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
void nm_setting_ethtool_clear_features (NMSettingEthtool *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_SETTING_ETHTOOL_H__ */
|
|
@ -2095,6 +2095,20 @@ _nm_setting_gendata_notify (NMSetting *setting,
|
|||
* values cache. Otherwise, the names cache must be invalidated too. */
|
||||
nm_clear_g_free (&gendata->names);
|
||||
}
|
||||
|
||||
/* Note, that currently there is now way to notify the subclass when gendata changed.
|
||||
* gendata is only changed in two situations:
|
||||
* 1) from within NMSetting itself, for example when creating a NMSetting instance
|
||||
* from keyfile or a D-Bus GVariant.
|
||||
* 2) actively from the subclass itself
|
||||
* For 2), we don't need the notification, because the subclass knows that something
|
||||
* changed.
|
||||
* For 1), we currently don't need the notification either, because all that the subclass
|
||||
* currently would do, is emit a g_object_notify() signal. However, 1) only happens when
|
||||
* the setting instance is newly created, at that point, nobody listens to the signal.
|
||||
*
|
||||
* If we ever need it, then we would need to call a virtual function to notify the subclass
|
||||
* that gendata changed. */
|
||||
}
|
||||
|
||||
GVariant *
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nm-setting-bridge-port.h"
|
||||
#include "nm-setting-cdma.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-generic.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-infiniband.h"
|
||||
|
@ -65,6 +66,7 @@
|
|||
#include "nm-simple-connection.h"
|
||||
#include "nm-keyfile-internal.h"
|
||||
#include "nm-utils/nm-dedup-multi.h"
|
||||
#include "nm-ethtool-utils.h"
|
||||
|
||||
#include "test-general-enums.h"
|
||||
|
||||
|
@ -7058,6 +7060,22 @@ test_nm_va_args_macros (void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_ethtool_offload (void)
|
||||
{
|
||||
const NMEthtoolData *d;
|
||||
|
||||
g_assert_cmpint (nm_ethtool_id_get_by_name ("invalid"), ==, NM_ETHTOOL_ID_UNKNOWN);
|
||||
g_assert_cmpint (nm_ethtool_id_get_by_name ("feature-rx"), ==, NM_ETHTOOL_ID_FEATURE_RX);
|
||||
|
||||
d = nm_ethtool_data_get_by_optname (NM_ETHTOOL_OPTNAME_FEATURE_RXHASH);
|
||||
g_assert (d);
|
||||
g_assert_cmpint (d->id, ==, NM_ETHTOOL_ID_FEATURE_RXHASH);
|
||||
g_assert_cmpstr (d->optname, ==, NM_ETHTOOL_OPTNAME_FEATURE_RXHASH);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
@ -7212,8 +7230,8 @@ int main (int argc, char **argv)
|
|||
g_test_add_func ("/core/general/route_attributes/format", test_route_attributes_format);
|
||||
|
||||
g_test_add_func ("/core/general/get_start_time_for_pid", test_get_start_time_for_pid);
|
||||
|
||||
g_test_add_func ("/core/general/test_nm_va_args_macros", test_nm_va_args_macros);
|
||||
g_test_add_func ("/core/general/test_ethtool_offload", test_ethtool_offload);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nm-setting-8021x.h"
|
||||
#include "nm-setting-bond.h"
|
||||
#include "nm-setting-dcb.h"
|
||||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-team.h"
|
||||
#include "nm-setting-team-port.h"
|
||||
#include "nm-setting-tc-config.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include "nm-simple-connection.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-errors.h"
|
||||
#include "nm-keyfile-internal.h"
|
||||
|
||||
#include "nm-utils/nm-test-utils.h"
|
||||
|
||||
|
@ -1264,6 +1266,79 @@ test_team_port_full_config (void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_ethtool_1 (void)
|
||||
{
|
||||
gs_unref_object NMConnection *con = NULL;
|
||||
gs_unref_object NMConnection *con2 = NULL;
|
||||
gs_unref_object NMConnection *con3 = NULL;
|
||||
gs_unref_variant GVariant *variant = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_keyfile GKeyFile *keyfile = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingEthtool *s_ethtool;
|
||||
NMSettingEthtool *s_ethtool2;
|
||||
NMSettingEthtool *s_ethtool3;
|
||||
|
||||
con = nmtst_create_minimal_connection ("ethtool-1",
|
||||
NULL,
|
||||
NM_SETTING_WIRED_SETTING_NAME,
|
||||
&s_con);
|
||||
s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ());
|
||||
nm_connection_add_setting (con, NM_SETTING (s_ethtool));
|
||||
|
||||
nm_setting_ethtool_set_feature (s_ethtool,
|
||||
NM_ETHTOOL_OPTNAME_FEATURE_RX,
|
||||
NM_TERNARY_TRUE);
|
||||
nm_setting_ethtool_set_feature (s_ethtool,
|
||||
NM_ETHTOOL_OPTNAME_FEATURE_LRO,
|
||||
NM_TERNARY_FALSE);
|
||||
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RX), ==, NM_TERNARY_TRUE);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_SG), ==, NM_TERNARY_DEFAULT);
|
||||
|
||||
nmtst_connection_normalize (con);
|
||||
|
||||
variant = nm_connection_to_dbus (con, NM_CONNECTION_SERIALIZE_ALL);
|
||||
|
||||
con2 = nm_simple_connection_new_from_dbus (variant, &error);
|
||||
nmtst_assert_success (con2, error);
|
||||
|
||||
s_ethtool2 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con2, NM_TYPE_SETTING_ETHTOOL));
|
||||
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_RX), ==, NM_TERNARY_TRUE);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool2, NM_ETHTOOL_OPTNAME_FEATURE_SG), ==, NM_TERNARY_DEFAULT);
|
||||
|
||||
nmtst_assert_connection_verifies_without_normalization (con2);
|
||||
|
||||
nmtst_assert_connection_equals (con, FALSE, con2, FALSE);
|
||||
|
||||
keyfile = nm_keyfile_write (con, NULL, NULL, &error);
|
||||
nmtst_assert_success (keyfile, error);
|
||||
|
||||
con3 = nm_keyfile_read (keyfile,
|
||||
"ethtool-keyfile-name",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&error);
|
||||
nmtst_assert_success (con3, error);
|
||||
|
||||
nmtst_connection_normalize (con3);
|
||||
|
||||
nmtst_assert_connection_equals (con, FALSE, con3, FALSE);
|
||||
|
||||
s_ethtool3 = NM_SETTING_ETHTOOL (nm_connection_get_setting (con3, NM_TYPE_SETTING_ETHTOOL));
|
||||
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_RX), ==, NM_TERNARY_TRUE);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_LRO), ==, NM_TERNARY_FALSE);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool3, NM_ETHTOOL_OPTNAME_FEATURE_SG), ==, NM_TERNARY_DEFAULT);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_sriov_vf (void)
|
||||
{
|
||||
|
@ -1899,6 +1974,8 @@ main (int argc, char **argv)
|
|||
g_test_add_func ("/libnm/settings/dcb/priorities", test_dcb_priorities_valid);
|
||||
g_test_add_func ("/libnm/settings/dcb/bandwidth-sums", test_dcb_bandwidth_sums);
|
||||
|
||||
g_test_add_func ("/libnm/settings/ethtool/1", test_ethtool_1);
|
||||
|
||||
g_test_add_func ("/libnm/settings/sriov/vf", test_sriov_vf);
|
||||
g_test_add_func ("/libnm/settings/sriov/vf-dup", test_sriov_vf_dup);
|
||||
g_test_add_func ("/libnm/settings/sriov/vf-vlan", test_sriov_vf_vlan);
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-dcb.h"
|
||||
#include "nm-setting-dummy.h"
|
||||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-generic.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-infiniband.h"
|
||||
|
|
|
@ -1394,6 +1394,11 @@ global:
|
|||
nm_device_wpan_get_type;
|
||||
nm_setting_6lowpan_get_type;
|
||||
nm_setting_connection_get_multi_connect;
|
||||
nm_setting_ethtool_clear_features;
|
||||
nm_setting_ethtool_get_feature;
|
||||
nm_setting_ethtool_get_type;
|
||||
nm_setting_ethtool_new;
|
||||
nm_setting_ethtool_set_feature;
|
||||
nm_setting_sriov_add_vf;
|
||||
nm_setting_sriov_clear_vfs;
|
||||
nm_setting_sriov_get_autoprobe_drivers;
|
||||
|
|
|
@ -47,6 +47,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingCdma, g_object_unref)
|
|||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingConnection, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingDcb, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (NMSettingDummy, g_object_unref)
|
||||
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 (NMSettingInfiniband, g_object_unref)
|
||||
|
|
|
@ -67,6 +67,7 @@ libnm-core/nm-setting-bridge.c
|
|||
libnm-core/nm-setting-cdma.c
|
||||
libnm-core/nm-setting-connection.c
|
||||
libnm-core/nm-setting-dcb.c
|
||||
libnm-core/nm-setting-ethtool.c
|
||||
libnm-core/nm-setting-gsm.c
|
||||
libnm-core/nm-setting-infiniband.c
|
||||
libnm-core/nm-setting-ip-config.c
|
||||
|
|
|
@ -36,6 +36,8 @@ version_header = configure_file(
|
|||
configuration: version_conf,
|
||||
)
|
||||
|
||||
shared_nm_ethtool_utils_c = files('nm-ethtool-utils.c')
|
||||
|
||||
shared_nm_meta_setting_c = files('nm-meta-setting.c')
|
||||
|
||||
shared_nm_test_utils_impl_c = files('nm-test-utils-impl.c')
|
||||
|
|
143
shared/nm-ethtool-utils.c
Normal file
143
shared/nm-ethtool-utils.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/* -*- 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-ethtool-utils.h"
|
||||
|
||||
#include "nm-setting-ethtool.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define ETHT_DATA(xname) \
|
||||
[NM_ETHTOOL_ID_##xname] = (&((const NMEthtoolData) { \
|
||||
.optname = NM_ETHTOOL_OPTNAME_##xname, \
|
||||
.id = NM_ETHTOOL_ID_##xname, \
|
||||
}))
|
||||
|
||||
const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = {
|
||||
/* indexed by NMEthtoolID */
|
||||
ETHT_DATA (FEATURE_GRO),
|
||||
ETHT_DATA (FEATURE_GSO),
|
||||
ETHT_DATA (FEATURE_LRO),
|
||||
ETHT_DATA (FEATURE_NTUPLE),
|
||||
ETHT_DATA (FEATURE_RX),
|
||||
ETHT_DATA (FEATURE_RXHASH),
|
||||
ETHT_DATA (FEATURE_RXVLAN),
|
||||
ETHT_DATA (FEATURE_SG),
|
||||
ETHT_DATA (FEATURE_TSO),
|
||||
ETHT_DATA (FEATURE_TX),
|
||||
ETHT_DATA (FEATURE_TXVLAN),
|
||||
[_NM_ETHTOOL_ID_NUM] = NULL,
|
||||
};
|
||||
|
||||
const guint8 const _by_name[_NM_ETHTOOL_ID_NUM] = {
|
||||
/* sorted by optname. */
|
||||
NM_ETHTOOL_ID_FEATURE_GRO,
|
||||
NM_ETHTOOL_ID_FEATURE_GSO,
|
||||
NM_ETHTOOL_ID_FEATURE_LRO,
|
||||
NM_ETHTOOL_ID_FEATURE_NTUPLE,
|
||||
NM_ETHTOOL_ID_FEATURE_RX,
|
||||
NM_ETHTOOL_ID_FEATURE_RXHASH,
|
||||
NM_ETHTOOL_ID_FEATURE_RXVLAN,
|
||||
NM_ETHTOOL_ID_FEATURE_SG,
|
||||
NM_ETHTOOL_ID_FEATURE_TSO,
|
||||
NM_ETHTOOL_ID_FEATURE_TX,
|
||||
NM_ETHTOOL_ID_FEATURE_TXVLAN,
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_ASSERT_data (void)
|
||||
{
|
||||
#if NM_MORE_ASSERTS > 10
|
||||
int i;
|
||||
|
||||
G_STATIC_ASSERT_EXPR (_NM_ETHTOOL_ID_FIRST == 0);
|
||||
G_STATIC_ASSERT_EXPR (_NM_ETHTOOL_ID_LAST == _NM_ETHTOOL_ID_NUM - 1);
|
||||
G_STATIC_ASSERT_EXPR (_NM_ETHTOOL_ID_NUM > 0);
|
||||
|
||||
nm_assert (NM_PTRARRAY_LEN (nm_ethtool_data) == _NM_ETHTOOL_ID_NUM);
|
||||
nm_assert (G_N_ELEMENTS (_by_name) == _NM_ETHTOOL_ID_NUM);
|
||||
nm_assert (G_N_ELEMENTS (nm_ethtool_data) == _NM_ETHTOOL_ID_NUM + 1);
|
||||
|
||||
for (i = 0; i < _NM_ETHTOOL_ID_NUM; i++) {
|
||||
const NMEthtoolData *d = nm_ethtool_data[i];
|
||||
|
||||
nm_assert (d);
|
||||
nm_assert (d->id == (NMEthtoolID) i);
|
||||
nm_assert (d->optname && d->optname[0]);
|
||||
}
|
||||
|
||||
for (i = 0; i < _NM_ETHTOOL_ID_NUM; i++) {
|
||||
NMEthtoolID id = _by_name[i];
|
||||
const NMEthtoolData *d;
|
||||
|
||||
nm_assert (id >= 0);
|
||||
nm_assert (id < _NM_ETHTOOL_ID_NUM);
|
||||
|
||||
d = nm_ethtool_data[id];
|
||||
if (i > 0) {
|
||||
/* since we assert that all optnames are sorted strictly monotonically increasing,
|
||||
* it also follows that there are no duplicates in the _by_name.
|
||||
* It also follows, that all names in nm_ethtool_data are unique. */
|
||||
if (strcmp (nm_ethtool_data[_by_name[i - 1]]->optname, d->optname) >= 0) {
|
||||
g_error ("nm_ethtool_data is not sorted asciibetically: %u/%s should be after %u/%s",
|
||||
i - 1, nm_ethtool_data[_by_name[i - 1]]->optname,
|
||||
i, d->optname);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
_by_name_cmp (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
{
|
||||
const guint8 *p_id = a;
|
||||
const char *optname = b;
|
||||
|
||||
nm_assert (p_id && p_id >= _by_name && p_id <= &_by_name[_NM_ETHTOOL_ID_NUM]);
|
||||
nm_assert (*p_id < _NM_ETHTOOL_ID_NUM);
|
||||
|
||||
return strcmp (nm_ethtool_data[*p_id]->optname, optname);
|
||||
}
|
||||
|
||||
const NMEthtoolData *
|
||||
nm_ethtool_data_get_by_optname (const char *optname)
|
||||
{
|
||||
gssize idx;
|
||||
|
||||
nm_assert (optname);
|
||||
|
||||
_ASSERT_data ();
|
||||
|
||||
idx = nm_utils_array_find_binary_search ((gconstpointer *) _by_name,
|
||||
sizeof (_by_name[0]),
|
||||
_NM_ETHTOOL_ID_NUM,
|
||||
optname,
|
||||
_by_name_cmp,
|
||||
NULL);
|
||||
return (idx < 0) ? NULL : nm_ethtool_data[_by_name[idx]];
|
||||
}
|
79
shared/nm-ethtool-utils.h
Normal file
79
shared/nm-ethtool-utils.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef __NM_ETHTOOL_UTILS_H__
|
||||
#define __NM_ETHTOOL_UTILS_H__
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
NM_ETHTOOL_ID_UNKNOWN = -1,
|
||||
|
||||
_NM_ETHTOOL_ID_FIRST = 0,
|
||||
|
||||
_NM_ETHTOOL_ID_FEATURE_FIRST = _NM_ETHTOOL_ID_FIRST,
|
||||
NM_ETHTOOL_ID_FEATURE_GRO = _NM_ETHTOOL_ID_FEATURE_FIRST,
|
||||
NM_ETHTOOL_ID_FEATURE_GSO,
|
||||
NM_ETHTOOL_ID_FEATURE_LRO,
|
||||
NM_ETHTOOL_ID_FEATURE_NTUPLE,
|
||||
NM_ETHTOOL_ID_FEATURE_RX,
|
||||
NM_ETHTOOL_ID_FEATURE_RXHASH,
|
||||
NM_ETHTOOL_ID_FEATURE_RXVLAN,
|
||||
NM_ETHTOOL_ID_FEATURE_SG,
|
||||
NM_ETHTOOL_ID_FEATURE_TSO,
|
||||
NM_ETHTOOL_ID_FEATURE_TX,
|
||||
NM_ETHTOOL_ID_FEATURE_TXVLAN,
|
||||
_NM_ETHTOOL_ID_FEATURE_LAST = NM_ETHTOOL_ID_FEATURE_TXVLAN,
|
||||
_NM_ETHTOOL_ID_FEATURE_NUM = (_NM_ETHTOOL_ID_FEATURE_LAST - _NM_ETHTOOL_ID_FEATURE_FIRST + 1),
|
||||
|
||||
_NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_FEATURE_LAST,
|
||||
|
||||
_NM_ETHTOOL_ID_NUM = (_NM_ETHTOOL_ID_LAST - _NM_ETHTOOL_ID_FIRST + 1),
|
||||
} NMEthtoolID;
|
||||
|
||||
typedef struct {
|
||||
const char *optname;
|
||||
NMEthtoolID id;
|
||||
} NMEthtoolData;
|
||||
|
||||
extern const NMEthtoolData *const nm_ethtool_data[/*_NM_ETHTOOL_ID_NUM + NULL-terminated*/];
|
||||
|
||||
const NMEthtoolData *nm_ethtool_data_get_by_optname (const char *optname);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static inline NMEthtoolID
|
||||
nm_ethtool_id_get_by_name (const char *optname)
|
||||
{
|
||||
const NMEthtoolData *d;
|
||||
|
||||
d = nm_ethtool_data_get_by_optname (optname);
|
||||
return d ? d->id : NM_ETHTOOL_ID_UNKNOWN;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
nm_ethtool_id_is_feature (NMEthtoolID id)
|
||||
{
|
||||
return id >= _NM_ETHTOOL_ID_FEATURE_FIRST && id <= _NM_ETHTOOL_ID_FEATURE_LAST;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __NM_ETHTOOL_UTILS_H__ */
|
|
@ -34,6 +34,7 @@
|
|||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-dcb.h"
|
||||
#include "nm-setting-dummy.h"
|
||||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-generic.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-infiniband.h"
|
||||
|
@ -213,6 +214,12 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
|
|||
.setting_name = NM_SETTING_DUMMY_SETTING_NAME,
|
||||
.get_setting_gtype = nm_setting_dummy_get_type,
|
||||
},
|
||||
[NM_META_SETTING_TYPE_ETHTOOL] = {
|
||||
.meta_type = NM_META_SETTING_TYPE_ETHTOOL,
|
||||
.setting_priority = NM_SETTING_PRIORITY_AUX,
|
||||
.setting_name = NM_SETTING_ETHTOOL_SETTING_NAME,
|
||||
.get_setting_gtype = nm_setting_ethtool_get_type,
|
||||
},
|
||||
[NM_META_SETTING_TYPE_GENERIC] = {
|
||||
.meta_type = NM_META_SETTING_TYPE_GENERIC,
|
||||
.setting_priority = NM_SETTING_PRIORITY_HW_BASE,
|
||||
|
|
|
@ -118,6 +118,7 @@ typedef enum {
|
|||
NM_META_SETTING_TYPE_CONNECTION,
|
||||
NM_META_SETTING_TYPE_DCB,
|
||||
NM_META_SETTING_TYPE_DUMMY,
|
||||
NM_META_SETTING_TYPE_ETHTOOL,
|
||||
NM_META_SETTING_TYPE_GENERIC,
|
||||
NM_META_SETTING_TYPE_GSM,
|
||||
NM_META_SETTING_TYPE_INFINIBAND,
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-setting-wired.h"
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-8021x.h"
|
||||
#include "nm-setting-bond.h"
|
||||
#include "nm-setting-team.h"
|
||||
|
@ -53,6 +54,7 @@
|
|||
#include "nm-setting-generic.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-ethtool-utils.h"
|
||||
|
||||
#include "platform/nm-platform.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
@ -4051,15 +4053,66 @@ parse_ethtool_option (const char *value,
|
|||
char **out_password,
|
||||
gboolean *out_autoneg,
|
||||
guint32 *out_speed,
|
||||
const char **out_duplex)
|
||||
const char **out_duplex,
|
||||
NMSettingEthtool **out_s_ethtool)
|
||||
{
|
||||
gs_free const char **words = NULL;
|
||||
guint i;
|
||||
|
||||
words = nm_utils_strsplit_set (value, "\t \n");
|
||||
words = nm_utils_strsplit_set (value, NULL);
|
||||
if (!words)
|
||||
return;
|
||||
|
||||
if (words[0] && words[0][0] == '-') {
|
||||
/* /sbin/ethtool $opts */
|
||||
if (NM_IN_STRSET (words[0], "-K", "--features", "--offload")) {
|
||||
if (!words[1]) {
|
||||
/* first argument must be the interface name. This is invalid. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*out_s_ethtool)
|
||||
*out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ());
|
||||
|
||||
for (i = 2; words[i]; ) {
|
||||
const char *opt = words[i];
|
||||
const char *opt_val = words[++i];
|
||||
const NMEthtoolData *d = NULL;
|
||||
NMTernary onoff = NM_TERNARY_DEFAULT;
|
||||
|
||||
if (nm_streq0 (opt_val, "on"))
|
||||
onoff = NM_TERNARY_TRUE;
|
||||
else if (nm_streq0 (opt_val, "off"))
|
||||
onoff = NM_TERNARY_FALSE;
|
||||
|
||||
d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt);
|
||||
|
||||
if (!d) {
|
||||
if (onoff != NM_TERNARY_DEFAULT) {
|
||||
/* the next value is just the on/off argument. Skip it too. */
|
||||
i++;
|
||||
}
|
||||
|
||||
/* silently ignore unsupported offloading features. */
|
||||
continue;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (onoff == NM_TERNARY_DEFAULT) {
|
||||
PARSE_WARNING ("Expects on/off argument for feature '%s'", opt);
|
||||
continue;
|
||||
}
|
||||
|
||||
nm_setting_ethtool_set_feature (*out_s_ethtool,
|
||||
d->optname,
|
||||
onoff);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* /sbin/ethtool -s ${REALDEVICE} $opts */
|
||||
for (i = 0; words[i]; ) {
|
||||
const char *opt = words[i];
|
||||
const char *opt_val = words[++i];
|
||||
|
@ -4176,54 +4229,72 @@ parse_ethtool_option (const char *value,
|
|||
}
|
||||
|
||||
static void
|
||||
parse_ethtool_options (shvarFile *ifcfg, NMSettingWired *s_wired, const char *value)
|
||||
parse_ethtool_options (shvarFile *ifcfg, NMConnection *connection)
|
||||
{
|
||||
NMSettingWired *s_wired;
|
||||
gs_unref_object NMSettingEthtool *s_ethtool = NULL;
|
||||
NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT;
|
||||
gs_free char *ethtool_opts_free = NULL;
|
||||
const char *ethtool_opts;
|
||||
gs_free char *wol_password = NULL;
|
||||
gs_free char *wol_value = NULL;
|
||||
gboolean ignore_wol_password = FALSE;
|
||||
gs_free char *wol_value_free = NULL;
|
||||
const char *tmp;
|
||||
gboolean autoneg = FALSE;
|
||||
guint32 speed = 0;
|
||||
const char *duplex = NULL;
|
||||
|
||||
if (value) {
|
||||
gs_free const char **opts = NULL;
|
||||
const char *const *iter;
|
||||
|
||||
ethtool_opts = svGetValue (ifcfg, "ETHTOOL_OPTS", ðtool_opts_free);
|
||||
if (ethtool_opts) {
|
||||
/* WAKE_ON_LAN_IGNORE is inferred from a specified but empty ETHTOOL_OPTS */
|
||||
if (!value[0])
|
||||
if (!ethtool_opts[0])
|
||||
wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE;
|
||||
else {
|
||||
gs_free const char **opts = NULL;
|
||||
const char *const *iter;
|
||||
|
||||
opts = nm_utils_strsplit_set (value, ";");
|
||||
for (iter = opts; iter && iter[0]; iter++) {
|
||||
/* in case of repeated wol_passwords, parse_ethtool_option()
|
||||
* will do the right thing and clear wol_password before resetting. */
|
||||
parse_ethtool_option (iter[0], &wol_flags, &wol_password, &autoneg, &speed, &duplex);
|
||||
opts = nm_utils_strsplit_set (ethtool_opts, ";");
|
||||
for (iter = opts; iter && iter[0]; iter++) {
|
||||
/* in case of repeated wol_passwords, parse_ethtool_option()
|
||||
* will do the right thing and clear wol_password before resetting. */
|
||||
parse_ethtool_option (iter[0],
|
||||
&wol_flags,
|
||||
&wol_password,
|
||||
&autoneg,
|
||||
&speed,
|
||||
&duplex,
|
||||
&s_ethtool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ETHTOOL_WAKE_ON_LAN = ignore overrides WoL settings in ETHTOOL_OPTS */
|
||||
wol_value = svGetValueStr_cp (ifcfg, "ETHTOOL_WAKE_ON_LAN");
|
||||
if (wol_value) {
|
||||
if (strcmp (wol_value, "ignore") == 0)
|
||||
wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE;
|
||||
else
|
||||
PARSE_WARNING ("invalid ETHTOOL_WAKE_ON_LAN value '%s'", wol_value);
|
||||
}
|
||||
tmp = svGetValueStr (ifcfg, "ETHTOOL_WAKE_ON_LAN", &wol_value_free);
|
||||
if (nm_streq0 (tmp, "ignore"))
|
||||
wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE;
|
||||
else if (tmp)
|
||||
PARSE_WARNING ("invalid ETHTOOL_WAKE_ON_LAN value '%s'", tmp);
|
||||
|
||||
if ( wol_password
|
||||
&& !NM_FLAGS_HAS (wol_flags, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) {
|
||||
PARSE_WARNING ("Wake-on-LAN password not expected");
|
||||
ignore_wol_password = TRUE;
|
||||
nm_clear_g_free (&wol_password);
|
||||
}
|
||||
|
||||
g_object_set (s_wired,
|
||||
NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags,
|
||||
NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, ignore_wol_password ? NULL : wol_password,
|
||||
NM_SETTING_WIRED_AUTO_NEGOTIATE, autoneg,
|
||||
NM_SETTING_WIRED_SPEED, speed,
|
||||
NM_SETTING_WIRED_DUPLEX, duplex,
|
||||
NULL);
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
if (s_wired) {
|
||||
g_object_set (s_wired,
|
||||
NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags,
|
||||
NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, wol_password,
|
||||
NM_SETTING_WIRED_AUTO_NEGOTIATE, autoneg,
|
||||
NM_SETTING_WIRED_SPEED, speed,
|
||||
NM_SETTING_WIRED_DUPLEX, duplex,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (s_ethtool) {
|
||||
nm_connection_add_setting (connection,
|
||||
NM_SETTING (g_steal_pointer (&s_ethtool)));
|
||||
}
|
||||
}
|
||||
|
||||
static NMSetting *
|
||||
|
@ -4365,10 +4436,6 @@ make_wired_setting (shvarFile *ifcfg,
|
|||
nm_clear_g_free (&value);
|
||||
}
|
||||
|
||||
parse_ethtool_options (ifcfg, s_wired,
|
||||
svGetValue (ifcfg, "ETHTOOL_OPTS", &value));
|
||||
nm_clear_g_free (&value);
|
||||
|
||||
return (NMSetting *) g_steal_pointer (&s_wired);
|
||||
}
|
||||
|
||||
|
@ -5595,6 +5662,8 @@ connection_from_file_full (const char *filename,
|
|||
if (!connection)
|
||||
return NULL;
|
||||
|
||||
parse_ethtool_options (parsed, connection);
|
||||
|
||||
has_complex_routes_v4 = utils_has_complex_routes (filename, AF_INET);
|
||||
has_complex_routes_v6 = utils_has_complex_routes (filename, AF_INET6);
|
||||
|
||||
|
|
|
@ -470,3 +470,63 @@ nms_ifcfg_rh_utils_user_key_decode (const char *name, GString *str_buffer)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *const _nm_ethtool_ifcfg_names[] = {
|
||||
#define ETHT_NAME(eid, ename) \
|
||||
[eid - _NM_ETHTOOL_ID_FEATURE_FIRST] = ""ename""
|
||||
/* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GRO, "gro"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GSO, "gso"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LRO, "lro"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX, "rx"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_SG, "sg"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TSO, "tso"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX, "tx"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"),
|
||||
};
|
||||
|
||||
const NMEthtoolData *
|
||||
nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name)
|
||||
{
|
||||
static const struct {
|
||||
NMEthtoolID ethtool_id;
|
||||
const char *kernel_name;
|
||||
} kernel_names[] = {
|
||||
{ NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro" },
|
||||
{ NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation" },
|
||||
{ NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro" },
|
||||
{ NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter" },
|
||||
{ NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum" },
|
||||
{ NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing" },
|
||||
{ NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse" },
|
||||
{ NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert" },
|
||||
};
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (_nm_ethtool_ifcfg_names); i++) {
|
||||
if (nm_streq (name, _nm_ethtool_ifcfg_names[i]))
|
||||
return nm_ethtool_data[i];
|
||||
}
|
||||
|
||||
/* Option not found. Note that ethtool utility has built-in features and
|
||||
* NetworkManager's API follows the naming of these built-in features, whenever
|
||||
* they exist.
|
||||
* For example, NM's "ethtool.feature-ntuple" corresponds to ethtool utility's "ntuple"
|
||||
* feature. However the underlying kernel feature is called "rx-ntuple-filter" (as reported
|
||||
* for ETH_SS_FEATURES).
|
||||
*
|
||||
* With ethtool utility, whose command line we attempt to parse here, the user can also
|
||||
* specify the name of the underlying kernel feature directly. So, check whether that is
|
||||
* the case and if yes, map them to the corresponding NetworkManager's features. */
|
||||
for (i = 0; i < G_N_ELEMENTS (kernel_names); i++) {
|
||||
if (nm_streq (name, kernel_names[i].kernel_name))
|
||||
return nm_ethtool_data[kernel_names[i].ethtool_id];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define _UTILS_H_
|
||||
|
||||
#include "nm-connection.h"
|
||||
#include "nm-ethtool-utils.h"
|
||||
|
||||
#include "shvar.h"
|
||||
|
||||
|
@ -80,4 +81,20 @@ _nms_ifcfg_rh_utils_numbered_tag (char *buf, gsize buf_len, const char *tag_name
|
|||
_nms_ifcfg_rh_utils_numbered_tag (buf, sizeof (buf), ""tag_name"", (which)); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
extern const char *const _nm_ethtool_ifcfg_names[_NM_ETHTOOL_ID_FEATURE_NUM];
|
||||
|
||||
static inline const char *
|
||||
nms_ifcfg_rh_utils_get_ethtool_name (NMEthtoolID ethtool_id)
|
||||
{
|
||||
nm_assert (ethtool_id >= _NM_ETHTOOL_ID_FEATURE_FIRST && ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST);
|
||||
nm_assert ((ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST) < G_N_ELEMENTS (_nm_ethtool_ifcfg_names));
|
||||
nm_assert (_nm_ethtool_ifcfg_names[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]);
|
||||
|
||||
return _nm_ethtool_ifcfg_names[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST];
|
||||
}
|
||||
|
||||
const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name);
|
||||
|
||||
#endif /* _UTILS_H_ */
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-wired.h"
|
||||
#include "nm-setting-wireless.h"
|
||||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-8021x.h"
|
||||
#include "nm-setting-proxy.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
|
@ -50,6 +51,7 @@
|
|||
#include "nm-core-internal.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-meta-setting.h"
|
||||
#include "nm-ethtool-utils.h"
|
||||
|
||||
#include "nms-ifcfg-rh-common.h"
|
||||
#include "nms-ifcfg-rh-reader.h"
|
||||
|
@ -1135,6 +1137,7 @@ static gboolean
|
|||
write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
||||
{
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingEthtool *s_ethtool;
|
||||
const char *duplex;
|
||||
guint32 speed;
|
||||
GString *str = NULL;
|
||||
|
@ -1143,65 +1146,112 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro
|
|||
const char *wol_password;
|
||||
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (connection, NM_TYPE_SETTING_ETHTOOL));
|
||||
|
||||
if (!s_wired)
|
||||
if (!s_wired && !s_ethtool) {
|
||||
svUnsetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN");
|
||||
svUnsetValue (ifcfg, "ETHTOOL_OPTS");
|
||||
return TRUE;
|
||||
|
||||
auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired);
|
||||
speed = nm_setting_wired_get_speed (s_wired);
|
||||
duplex = nm_setting_wired_get_duplex (s_wired);
|
||||
|
||||
/* autoneg off + speed 0 + duplex NULL, means we want NM
|
||||
* to skip link configuration which is default. So write
|
||||
* down link config only if we have auto-negotiate true or
|
||||
* a valid value for one among speed and duplex.
|
||||
*/
|
||||
if (auto_negotiate) {
|
||||
str = g_string_sized_new (64);
|
||||
g_string_printf (str, "autoneg on");
|
||||
} else if (speed || duplex) {
|
||||
str = g_string_sized_new (64);
|
||||
g_string_printf (str, "autoneg off");
|
||||
}
|
||||
if (speed)
|
||||
g_string_append_printf (str, " speed %u", speed);
|
||||
if (duplex)
|
||||
g_string_append_printf (str, " duplex %s", duplex);
|
||||
|
||||
wol = nm_setting_wired_get_wake_on_lan (s_wired);
|
||||
wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired);
|
||||
if (s_wired) {
|
||||
auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired);
|
||||
speed = nm_setting_wired_get_speed (s_wired);
|
||||
duplex = nm_setting_wired_get_duplex (s_wired);
|
||||
|
||||
/* autoneg off + speed 0 + duplex NULL, means we want NM
|
||||
* to skip link configuration which is default. So write
|
||||
* down link config only if we have auto-negotiate true or
|
||||
* a valid value for one among speed and duplex.
|
||||
*/
|
||||
if (auto_negotiate) {
|
||||
str = g_string_sized_new (64);
|
||||
g_string_printf (str, "autoneg on");
|
||||
} else if (speed || duplex) {
|
||||
str = g_string_sized_new (64);
|
||||
g_string_printf (str, "autoneg off");
|
||||
}
|
||||
if (speed)
|
||||
g_string_append_printf (str, " speed %u", speed);
|
||||
if (duplex)
|
||||
g_string_append_printf (str, " duplex %s", duplex);
|
||||
|
||||
wol = nm_setting_wired_get_wake_on_lan (s_wired);
|
||||
wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired);
|
||||
|
||||
svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN",
|
||||
wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE
|
||||
? "ignore"
|
||||
: NULL);
|
||||
if (!NM_IN_SET (wol, NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE,
|
||||
NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)) {
|
||||
if (!str)
|
||||
str = g_string_sized_new (30);
|
||||
else
|
||||
g_string_append (str, " ");
|
||||
|
||||
g_string_append (str, "wol ");
|
||||
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_PHY))
|
||||
g_string_append (str, "p");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST))
|
||||
g_string_append (str, "u");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST))
|
||||
g_string_append (str, "m");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST))
|
||||
g_string_append (str, "b");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ARP))
|
||||
g_string_append (str, "a");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC))
|
||||
g_string_append (str, "g");
|
||||
|
||||
if (!NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ALL))
|
||||
g_string_append (str, "d");
|
||||
|
||||
if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC))
|
||||
g_string_append_printf (str, "s sopass %s", wol_password);
|
||||
}
|
||||
} else
|
||||
svUnsetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN");
|
||||
|
||||
if (s_ethtool) {
|
||||
NMEthtoolID ethtool_id;
|
||||
NMSettingConnection *s_con;
|
||||
const char *iface = NULL;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
if (s_con) {
|
||||
iface = nm_setting_connection_get_interface_name (s_con);
|
||||
if ( iface
|
||||
&& ( !iface[0]
|
||||
|| !NM_STRCHAR_ALL (iface, ch, (ch >= 'a' && ch <= 'z')
|
||||
|| (ch >= 'A' && ch <= 'Z')
|
||||
|| (ch >= '0' && ch <= '9')
|
||||
|| NM_IN_SET (ch, '_'))))
|
||||
iface = NULL;
|
||||
}
|
||||
|
||||
svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN",
|
||||
wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE
|
||||
? "ignore"
|
||||
: NULL);
|
||||
if (!NM_IN_SET (wol, NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE,
|
||||
NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)) {
|
||||
if (!str)
|
||||
str = g_string_sized_new (30);
|
||||
else
|
||||
g_string_append (str, " ");
|
||||
g_string_append (str, " ; ");
|
||||
g_string_append (str, "-K ");
|
||||
g_string_append (str, iface ?: "net0");
|
||||
|
||||
g_string_append (str, "wol ");
|
||||
for (ethtool_id = _NM_ETHTOOL_ID_FEATURE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST; ethtool_id++) {
|
||||
const NMEthtoolData *ed = nm_ethtool_data[ethtool_id];
|
||||
NMTernary val;
|
||||
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_PHY))
|
||||
g_string_append (str, "p");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST))
|
||||
g_string_append (str, "u");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST))
|
||||
g_string_append (str, "m");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST))
|
||||
g_string_append (str, "b");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ARP))
|
||||
g_string_append (str, "a");
|
||||
if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC))
|
||||
g_string_append (str, "g");
|
||||
nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id));
|
||||
|
||||
if (!NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ALL))
|
||||
g_string_append (str, "d");
|
||||
val = nm_setting_ethtool_get_feature (s_ethtool, ed->optname);
|
||||
if (val == NM_TERNARY_DEFAULT)
|
||||
continue;
|
||||
|
||||
if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC))
|
||||
g_string_append_printf (str, "s sopass %s", wol_password);
|
||||
g_string_append_c (str, ' ');
|
||||
g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id));
|
||||
g_string_append (str, val == NM_TERNARY_TRUE ? " on" : " off");
|
||||
}
|
||||
}
|
||||
|
||||
if (str) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
TYPE=Ethernet
|
||||
PROXY_METHOD=none
|
||||
BROWSER_ONLY=no
|
||||
ETHTOOL_OPTS="autoneg on ; -K net0 rxvlan off tx on"
|
||||
BOOTPROTO=dhcp
|
||||
DEFROUTE=yes
|
||||
IPV4_FAILURE_FATAL=no
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=yes
|
||||
IPV6_DEFROUTE=yes
|
||||
IPV6_FAILURE_FATAL=no
|
||||
IPV6_ADDR_GEN_MODE=stable-privacy
|
||||
NAME="Test Write Wired Auto-Negotiate"
|
||||
UUID=${UUID}
|
||||
ONBOOT=yes
|
|
@ -43,12 +43,14 @@
|
|||
#include "nm-setting-pppoe.h"
|
||||
#include "nm-setting-ppp.h"
|
||||
#include "nm-setting-vpn.h"
|
||||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-setting-gsm.h"
|
||||
#include "nm-setting-cdma.h"
|
||||
#include "nm-setting-serial.h"
|
||||
#include "nm-setting-vlan.h"
|
||||
#include "nm-setting-dcb.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-ethtool-utils.h"
|
||||
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
|
@ -3726,6 +3728,7 @@ test_write_wired_auto_negotiate_on (void)
|
|||
gs_unref_object NMConnection *connection = NULL;
|
||||
gs_unref_object NMConnection *reread = NULL;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingEthtool *s_ethtool;
|
||||
char *val;
|
||||
shvarFile *f;
|
||||
|
||||
|
@ -3735,8 +3738,14 @@ test_write_wired_auto_negotiate_on (void)
|
|||
NM_SETTING_WIRED_AUTO_NEGOTIATE, TRUE,
|
||||
NULL);
|
||||
|
||||
_writer_new_connection (connection,
|
||||
s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ());
|
||||
nm_setting_ethtool_set_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX, NM_TERNARY_TRUE);
|
||||
nm_setting_ethtool_set_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN, NM_TERNARY_FALSE);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ethtool));
|
||||
|
||||
_writer_new_connec_exp (connection,
|
||||
TEST_SCRATCH_DIR,
|
||||
TEST_IFCFG_DIR"/ifcfg-test_write_wired_auto_negotiate_on.cexpected",
|
||||
&testfile);
|
||||
|
||||
f = _svOpenFile (testfile);
|
||||
|
@ -3750,7 +3759,15 @@ test_write_wired_auto_negotiate_on (void)
|
|||
|
||||
reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL);
|
||||
|
||||
nmtst_assert_connection_verifies_without_normalization (reread);
|
||||
|
||||
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
|
||||
|
||||
s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (reread, NM_TYPE_SETTING_ETHTOOL));
|
||||
g_assert (s_ethtool);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX), ==, NM_TERNARY_TRUE);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN), ==, NM_TERNARY_FALSE);
|
||||
g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN), ==, NM_TERNARY_DEFAULT);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue