mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-06 10:18:03 +02:00
ethtool: merge branch 'ac/ethtool_opts_ring'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/508
This commit is contained in:
commit
2eccd19b91
20 changed files with 1084 additions and 299 deletions
|
|
@ -4132,6 +4132,16 @@ _get_fcn_ethtool (ARGS_GET_FCN)
|
|||
if (s && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
|
||||
s = gettext (s);
|
||||
return s;
|
||||
} else if (nm_ethtool_id_is_ring (ethtool_id)) {
|
||||
if (!nm_setting_ethtool_get_ring (NM_SETTING_ETHTOOL (setting),
|
||||
nm_ethtool_data[ethtool_id]->optname,
|
||||
&u32)) {
|
||||
NM_SET_OUT (out_is_default, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return_str = g_strdup_printf ("%"G_GUINT32_FORMAT, u32);
|
||||
RETURN_STR_TO_FREE (return_str);
|
||||
}
|
||||
nm_assert_not_reached();
|
||||
return NULL;
|
||||
|
|
@ -4142,12 +4152,18 @@ _set_fcn_ethtool (ARGS_SET_FCN)
|
|||
{
|
||||
gint64 i64;
|
||||
NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
|
||||
NMEthtoolType ethtool_type = nm_ethtool_id_to_type (ethtool_id);
|
||||
|
||||
if (nm_ethtool_id_is_coalesce (ethtool_id)) {
|
||||
|
||||
if (NM_IN_SET (ethtool_type,
|
||||
NM_ETHTOOL_TYPE_COALESCE,
|
||||
NM_ETHTOOL_TYPE_RING)) {
|
||||
if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) {
|
||||
nm_setting_ethtool_clear_coalesce (NM_SETTING_ETHTOOL (setting),
|
||||
nm_ethtool_data[ethtool_id]->optname);
|
||||
if (ethtool_type == NM_ETHTOOL_TYPE_COALESCE)
|
||||
nm_setting_ethtool_clear_coalesce (NM_SETTING_ETHTOOL (setting),
|
||||
nm_ethtool_data[ethtool_id]->optname);
|
||||
else
|
||||
nm_setting_ethtool_clear_ring (NM_SETTING_ETHTOOL (setting),
|
||||
nm_ethtool_data[ethtool_id]->optname);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -4160,13 +4176,18 @@ _set_fcn_ethtool (ARGS_SET_FCN)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
nm_setting_ethtool_set_coalesce (NM_SETTING_ETHTOOL (setting),
|
||||
nm_ethtool_data[ethtool_id]->optname,
|
||||
(guint32) i64);
|
||||
if (ethtool_type == NM_ETHTOOL_TYPE_COALESCE)
|
||||
nm_setting_ethtool_set_coalesce (NM_SETTING_ETHTOOL (setting),
|
||||
nm_ethtool_data[ethtool_id]->optname,
|
||||
(guint32) i64);
|
||||
else
|
||||
nm_setting_ethtool_set_ring (NM_SETTING_ETHTOOL (setting),
|
||||
nm_ethtool_data[ethtool_id]->optname,
|
||||
(guint32) i64);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (nm_ethtool_id_is_feature (ethtool_id)) {
|
||||
if (ethtool_type == NM_ETHTOOL_TYPE_FEATURE) {
|
||||
gs_free char *value_to_free = NULL;
|
||||
NMTernary val;
|
||||
|
||||
|
|
@ -5507,6 +5528,10 @@ static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = {
|
|||
PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_IRQ),
|
||||
PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_HIGH),
|
||||
PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_LOW),
|
||||
PROPERTY_INFO_ETHTOOL (RING_RX),
|
||||
PROPERTY_INFO_ETHTOOL (RING_RX_JUMBO),
|
||||
PROPERTY_INFO_ETHTOOL (RING_RX_MINI),
|
||||
PROPERTY_INFO_ETHTOOL (RING_TX),
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -310,6 +310,8 @@ gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef gboolean (*nm_setting_gendata_filter_fcn)(const char *name);
|
||||
|
||||
GHashTable *_nm_setting_gendata_hash (NMSetting *setting,
|
||||
gboolean create_if_necessary);
|
||||
|
||||
|
|
@ -334,6 +336,20 @@ const char *const*nm_setting_gendata_get_all_names (NMSetting *setting,
|
|||
|
||||
GVariant *const*nm_setting_gendata_get_all_values (NMSetting *setting);
|
||||
|
||||
gboolean nm_setting_gendata_clear (NMSetting *setting,
|
||||
const char *optname);
|
||||
|
||||
gboolean nm_setting_gendata_clear_all (NMSetting *setting,
|
||||
nm_setting_gendata_filter_fcn filter);
|
||||
|
||||
gboolean nm_setting_gendata_get_uint32 (NMSetting *setting,
|
||||
const char *optname,
|
||||
guint32 *out_value);
|
||||
|
||||
void nm_setting_gendata_set_uint32 (NMSetting *setting,
|
||||
const char *optname,
|
||||
guint32 value);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint nm_setting_ethtool_init_features (NMSettingEthtool *setting,
|
||||
|
|
|
|||
|
|
@ -58,6 +58,22 @@ nm_ethtool_optname_is_coalesce (const char *optname)
|
|||
return optname && nm_ethtool_id_is_coalesce (nm_ethtool_id_get_by_name (optname));
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_ethtool_optname_is_ring:
|
||||
* @optname: (allow-none): the option name to check
|
||||
*
|
||||
* Checks whether @optname is a valid option name for a ring setting.
|
||||
*
|
||||
* %Returns: %TRUE, if @optname is valid
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
gboolean
|
||||
nm_ethtool_optname_is_ring (const char *optname)
|
||||
{
|
||||
return optname && nm_ethtool_id_is_ring (nm_ethtool_id_get_by_name (optname));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
|
|
@ -193,26 +209,10 @@ nm_setting_ethtool_set_feature (NMSettingEthtool *setting,
|
|||
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)
|
||||
if (nm_setting_gendata_clear_all (NM_SETTING (setting),
|
||||
&nm_ethtool_optname_is_feature))
|
||||
_notify_attributes (setting);
|
||||
}
|
||||
|
||||
|
|
@ -276,19 +276,12 @@ nm_setting_ethtool_get_coalesce (NMSettingEthtool *setting,
|
|||
const char *optname,
|
||||
guint32 *out_value)
|
||||
{
|
||||
GVariant *v;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_ETHTOOL (setting), FALSE);
|
||||
g_return_val_if_fail (nm_ethtool_optname_is_coalesce (optname), FALSE);
|
||||
|
||||
v = nm_setting_gendata_get (NM_SETTING (setting), optname);
|
||||
if ( v
|
||||
&& g_variant_is_of_type (v, G_VARIANT_TYPE_UINT32)) {
|
||||
NM_SET_OUT (out_value, g_variant_get_uint32 (v));
|
||||
return TRUE;
|
||||
}
|
||||
NM_SET_OUT (out_value, 0);
|
||||
return FALSE;
|
||||
return nm_setting_gendata_get_uint32 (NM_SETTING (setting),
|
||||
optname,
|
||||
out_value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -309,7 +302,6 @@ nm_setting_ethtool_set_coalesce (NMSettingEthtool *setting,
|
|||
const char *optname,
|
||||
guint32 value)
|
||||
{
|
||||
GHashTable *ht;
|
||||
NMEthtoolID ethtool_id;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting));
|
||||
|
|
@ -318,17 +310,14 @@ nm_setting_ethtool_set_coalesce (NMSettingEthtool *setting,
|
|||
|
||||
g_return_if_fail (nm_ethtool_id_is_coalesce (ethtool_id));
|
||||
|
||||
ht = _nm_setting_gendata_hash (NM_SETTING (setting),
|
||||
TRUE);
|
||||
|
||||
if (NM_IN_SET (ethtool_id,
|
||||
NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX,
|
||||
NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX))
|
||||
value = !!value;
|
||||
|
||||
g_hash_table_insert (ht,
|
||||
g_strdup (optname),
|
||||
g_variant_ref_sink (g_variant_new_uint32 (value)));
|
||||
nm_setting_gendata_set_uint32 (NM_SETTING (setting),
|
||||
optname,
|
||||
value);
|
||||
_notify_attributes (setting);
|
||||
}
|
||||
|
||||
|
|
@ -345,16 +334,10 @@ void
|
|||
nm_setting_ethtool_clear_coalesce (NMSettingEthtool *setting,
|
||||
const char *optname)
|
||||
{
|
||||
GHashTable *hash;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting));
|
||||
g_return_if_fail (nm_str_not_empty (optname));
|
||||
|
||||
hash = _nm_setting_gendata_hash (NM_SETTING (setting), FALSE);
|
||||
if (!hash)
|
||||
return;
|
||||
|
||||
if (g_hash_table_remove (hash, optname))
|
||||
if (nm_setting_gendata_clear (NM_SETTING (setting), optname))
|
||||
_notify_attributes (setting);
|
||||
}
|
||||
|
||||
|
|
@ -369,26 +352,109 @@ nm_setting_ethtool_clear_coalesce (NMSettingEthtool *setting,
|
|||
void
|
||||
nm_setting_ethtool_clear_coalesce_all (NMSettingEthtool *setting)
|
||||
{
|
||||
GHashTable *hash;
|
||||
GHashTableIter iter;
|
||||
const char *name;
|
||||
gboolean changed = FALSE;
|
||||
g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting));
|
||||
|
||||
if (nm_setting_gendata_clear_all (NM_SETTING (setting),
|
||||
&nm_ethtool_optname_is_coalesce))
|
||||
_notify_attributes (setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ethtool_get_ring:
|
||||
* @setting: the #NMSettingEthtool
|
||||
* @optname: option name of the ring setting to get
|
||||
* @out_value (out) (allow-none): value of the ring setting
|
||||
*
|
||||
* Gets the value of ring setting.
|
||||
*
|
||||
* Note that @optname must be a valid name for a setting, according to
|
||||
* nm_ethtool_optname_is_ring().
|
||||
*
|
||||
*
|
||||
* Returns: %TRUE and places the ring setting value in @out_value or %FALSE if unset.
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
gboolean
|
||||
nm_setting_ethtool_get_ring (NMSettingEthtool *setting,
|
||||
const char *optname,
|
||||
guint32 *out_value)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_ETHTOOL (setting), FALSE);
|
||||
g_return_val_if_fail (nm_ethtool_optname_is_ring (optname), FALSE);
|
||||
|
||||
return nm_setting_gendata_get_uint32 (NM_SETTING (setting),
|
||||
optname,
|
||||
out_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ethtool_set_ring:
|
||||
* @setting: the #NMSettingEthtool
|
||||
* @optname: option name of the ring setting
|
||||
* @value: the new value to set.
|
||||
*
|
||||
* Sets a ring setting.
|
||||
*
|
||||
* Note that @optname must be a valid name for a ring setting, according to
|
||||
* nm_ethtool_optname_is_ring().
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
void
|
||||
nm_setting_ethtool_set_ring (NMSettingEthtool *setting,
|
||||
const char *optname,
|
||||
guint32 value)
|
||||
{
|
||||
NMEthtoolID ethtool_id;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting));
|
||||
|
||||
hash = _nm_setting_gendata_hash (NM_SETTING (setting), FALSE);
|
||||
if (!hash)
|
||||
return;
|
||||
ethtool_id = nm_ethtool_id_get_by_name (optname);
|
||||
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, NULL)) {
|
||||
if (nm_ethtool_optname_is_coalesce (name)) {
|
||||
g_hash_table_iter_remove (&iter);
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
g_return_if_fail (nm_ethtool_id_is_ring (ethtool_id));
|
||||
|
||||
if (changed)
|
||||
nm_setting_gendata_set_uint32 (NM_SETTING (setting),
|
||||
optname,
|
||||
value);
|
||||
_notify_attributes (setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ethtool_clear_ring:
|
||||
* @setting: the #NMSettingEthtool
|
||||
* @optname: option name of the ring setting
|
||||
*
|
||||
* Clear a ring setting
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
void
|
||||
nm_setting_ethtool_clear_ring (NMSettingEthtool *setting,
|
||||
const char *optname)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting));
|
||||
g_return_if_fail (nm_str_not_empty (optname));
|
||||
|
||||
if (nm_setting_gendata_clear (NM_SETTING (setting), optname))
|
||||
_notify_attributes (setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ethtool_clear_ring_all:
|
||||
* @setting: the #NMSettingEthtool
|
||||
*
|
||||
* Clears all ring settings
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
void
|
||||
nm_setting_ethtool_clear_ring_all (NMSettingEthtool *setting)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTING_ETHTOOL (setting));
|
||||
|
||||
if (nm_setting_gendata_clear_all (NM_SETTING (setting),
|
||||
&nm_ethtool_optname_is_ring))
|
||||
_notify_attributes (setting);
|
||||
}
|
||||
|
||||
|
|
@ -446,12 +512,13 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
g_prefix_error (error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname);
|
||||
return FALSE;
|
||||
}
|
||||
} else if (nm_ethtool_optname_is_coalesce (optname)) {
|
||||
} else if ( nm_ethtool_optname_is_coalesce (optname)
|
||||
|| nm_ethtool_optname_is_ring (optname)) {
|
||||
if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("coalesce setting has invalid variant type"));
|
||||
_("setting has invalid variant type"));
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_ETHTOOL_SETTING_NAME, optname);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -476,10 +543,13 @@ get_variant_type (const NMSettInfoSetting *sett_info,
|
|||
const char *name,
|
||||
GError **error)
|
||||
{
|
||||
if (nm_ethtool_optname_is_feature (name))
|
||||
NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name (name);
|
||||
|
||||
if (nm_ethtool_id_is_feature (ethtool_id))
|
||||
return G_VARIANT_TYPE_BOOLEAN;
|
||||
|
||||
if (nm_ethtool_optname_is_coalesce (name))
|
||||
if ( nm_ethtool_id_is_coalesce (ethtool_id)
|
||||
|| nm_ethtool_id_is_ring (ethtool_id))
|
||||
return G_VARIANT_TYPE_UINT32;
|
||||
|
||||
g_set_error (error,
|
||||
|
|
|
|||
|
|
@ -92,12 +92,20 @@ G_BEGIN_DECLS
|
|||
#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_IRQ "coalesce-tx-usecs-irq"
|
||||
#define NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS_LOW "coalesce-tx-usecs-low"
|
||||
|
||||
#define NM_ETHTOOL_OPTNAME_RING_RX "ring-rx"
|
||||
#define NM_ETHTOOL_OPTNAME_RING_RX_JUMBO "ring-rx-jumbo"
|
||||
#define NM_ETHTOOL_OPTNAME_RING_RX_MINI "ring-rx-mini"
|
||||
#define NM_ETHTOOL_OPTNAME_RING_TX "ring-tx"
|
||||
|
||||
NM_AVAILABLE_IN_1_20
|
||||
gboolean nm_ethtool_optname_is_feature (const char *optname);
|
||||
|
||||
NM_AVAILABLE_IN_1_26
|
||||
gboolean nm_ethtool_optname_is_coalesce (const char *optname);
|
||||
|
||||
NM_AVAILABLE_IN_1_26
|
||||
gboolean nm_ethtool_optname_is_ring (const char *optname);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_TYPE_SETTING_ETHTOOL (nm_setting_ethtool_get_type ())
|
||||
|
|
@ -152,6 +160,23 @@ void nm_setting_ethtool_clear_coalesce (NMSettingEthtool *setting,
|
|||
NM_AVAILABLE_IN_1_26
|
||||
void nm_setting_ethtool_clear_coalesce_all (NMSettingEthtool *setting);
|
||||
|
||||
NM_AVAILABLE_IN_1_26
|
||||
gboolean nm_setting_ethtool_get_ring (NMSettingEthtool *setting,
|
||||
const char *optname,
|
||||
guint32 *out_value);
|
||||
|
||||
NM_AVAILABLE_IN_1_26
|
||||
void nm_setting_ethtool_set_ring (NMSettingEthtool *setting,
|
||||
const char *optname,
|
||||
guint32 value);
|
||||
|
||||
NM_AVAILABLE_IN_1_26
|
||||
void nm_setting_ethtool_clear_ring (NMSettingEthtool *setting,
|
||||
const char *optname);
|
||||
|
||||
NM_AVAILABLE_IN_1_26
|
||||
void nm_setting_ethtool_clear_ring_all (NMSettingEthtool *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_SETTING_ETHTOOL_H__ */
|
||||
|
|
|
|||
|
|
@ -2616,6 +2616,81 @@ _nm_setting_gendata_reset_from_hash (NMSetting *setting,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_setting_gendata_get_uint32 (NMSetting *setting,
|
||||
const char *optname,
|
||||
guint32 *out_value)
|
||||
{
|
||||
GVariant *v;
|
||||
|
||||
nm_assert (NM_IS_SETTING (setting));
|
||||
nm_assert (nm_str_not_empty (optname));
|
||||
|
||||
v = nm_setting_gendata_get (setting, optname);
|
||||
if ( v
|
||||
&& g_variant_is_of_type (v, G_VARIANT_TYPE_UINT32)) {
|
||||
NM_SET_OUT (out_value, g_variant_get_uint32 (v));
|
||||
return TRUE;
|
||||
}
|
||||
NM_SET_OUT (out_value, 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nm_setting_gendata_set_uint32 (NMSetting *setting,
|
||||
const char *optname,
|
||||
guint32 value)
|
||||
{
|
||||
nm_assert (NM_IS_SETTING (setting));
|
||||
nm_assert (nm_str_not_empty (optname));
|
||||
|
||||
g_hash_table_insert (_nm_setting_gendata_hash (setting, TRUE),
|
||||
g_strdup (optname),
|
||||
g_variant_ref_sink (g_variant_new_uint32 (value)));
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_setting_gendata_clear (NMSetting *setting,
|
||||
const char *optname)
|
||||
{
|
||||
GHashTable *ht;
|
||||
|
||||
nm_assert (NM_IS_SETTING (setting));
|
||||
nm_assert (nm_str_not_empty (optname));
|
||||
|
||||
ht = _nm_setting_gendata_hash (setting, FALSE);
|
||||
if (!ht)
|
||||
return FALSE;
|
||||
|
||||
return g_hash_table_remove (ht, optname);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_setting_gendata_clear_all (NMSetting *setting,
|
||||
nm_setting_gendata_filter_fcn filter)
|
||||
{
|
||||
GHashTable *ht;
|
||||
const char *name;
|
||||
GHashTableIter iter;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
nm_assert (NM_IS_SETTING (setting));
|
||||
|
||||
ht = _nm_setting_gendata_hash (setting, FALSE);
|
||||
if (!ht)
|
||||
return FALSE;
|
||||
|
||||
g_hash_table_iter_init (&iter, ht);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, NULL)) {
|
||||
if (!filter || filter (name)) {
|
||||
g_hash_table_iter_remove (&iter);
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -1499,7 +1499,7 @@ test_team_setting (void)
|
|||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_ethtool_1 (void)
|
||||
test_ethtool_features (void)
|
||||
{
|
||||
gs_unref_object NMConnection *con = NULL;
|
||||
gs_unref_object NMConnection *con2 = NULL;
|
||||
|
|
@ -1655,6 +1655,90 @@ test_ethtool_coalesce (void)
|
|||
g_assert_false (nm_setting_ethtool_get_coalesce (s_ethtool, NM_ETHTOOL_OPTNAME_COALESCE_TX_USECS, NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
test_ethtool_ring (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;
|
||||
guint32 out_value;
|
||||
|
||||
con = nmtst_create_minimal_connection ("ethtool-ring",
|
||||
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_ring (s_ethtool,
|
||||
NM_ETHTOOL_OPTNAME_RING_RX_JUMBO,
|
||||
4);
|
||||
|
||||
g_assert_true (nm_setting_ethtool_get_ring (s_ethtool, NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, &out_value));
|
||||
g_assert_cmpuint (out_value, ==, 4);
|
||||
|
||||
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_true (nm_setting_ethtool_get_ring (s_ethtool2, NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, &out_value));
|
||||
g_assert_cmpuint (out_value, ==, 4);
|
||||
|
||||
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,
|
||||
"/ignored/current/working/directory/for/loading/relative/paths",
|
||||
NULL,
|
||||
NULL,
|
||||
&error);
|
||||
nmtst_assert_success (con3, error);
|
||||
|
||||
nm_keyfile_read_ensure_id (con3, "unused-because-already-has-id");
|
||||
nm_keyfile_read_ensure_uuid (con3, "unused-because-already-has-uuid");
|
||||
|
||||
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_true (nm_setting_ethtool_get_ring (s_ethtool3, NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, &out_value));
|
||||
g_assert_cmpuint (out_value, ==, 4);
|
||||
|
||||
|
||||
nm_setting_ethtool_clear_ring (s_ethtool, NM_ETHTOOL_OPTNAME_RING_RX_JUMBO);
|
||||
g_assert_false (nm_setting_ethtool_get_ring (s_ethtool, NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, NULL));
|
||||
|
||||
nm_setting_ethtool_set_ring (s_ethtool,
|
||||
NM_ETHTOOL_OPTNAME_RING_RX_JUMBO,
|
||||
8);
|
||||
|
||||
g_assert_true (nm_setting_ethtool_get_ring (s_ethtool, NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, &out_value));
|
||||
g_assert_cmpuint (out_value, ==, 8);
|
||||
|
||||
nm_setting_ethtool_clear_ring_all (s_ethtool);
|
||||
g_assert_false (nm_setting_ethtool_get_ring (s_ethtool, NM_ETHTOOL_OPTNAME_RING_RX_JUMBO, NULL));
|
||||
g_assert_false (nm_setting_ethtool_get_ring (s_ethtool, NM_ETHTOOL_OPTNAME_RING_RX, NULL));
|
||||
g_assert_false (nm_setting_ethtool_get_ring (s_ethtool, NM_ETHTOOL_OPTNAME_RING_TX, NULL));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -3854,8 +3938,9 @@ 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/ethtool/features", test_ethtool_features);
|
||||
g_test_add_func ("/libnm/settings/ethtool/coalesce", test_ethtool_coalesce);
|
||||
g_test_add_func ("/libnm/settings/ethtool/ring", test_ethtool_ring);
|
||||
|
||||
g_test_add_func ("/libnm/settings/sriov/vf", test_sriov_vf);
|
||||
g_test_add_func ("/libnm/settings/sriov/vf-dup", test_sriov_vf_dup);
|
||||
|
|
|
|||
|
|
@ -1699,6 +1699,7 @@ global:
|
|||
libnm_1_26_0 {
|
||||
global:
|
||||
nm_ethtool_optname_is_coalesce;
|
||||
nm_ethtool_optname_is_ring;
|
||||
nm_setting_bridge_get_multicast_hash_max;
|
||||
nm_setting_bridge_get_multicast_last_member_count;
|
||||
nm_setting_bridge_get_multicast_last_member_interval;
|
||||
|
|
@ -1711,8 +1712,12 @@ global:
|
|||
nm_setting_connection_get_mud_url;
|
||||
nm_setting_ethtool_clear_coalesce;
|
||||
nm_setting_ethtool_clear_coalesce_all;
|
||||
nm_setting_ethtool_clear_ring;
|
||||
nm_setting_ethtool_clear_ring_all;
|
||||
nm_setting_ethtool_get_coalesce;
|
||||
nm_setting_ethtool_get_ring;
|
||||
nm_setting_ethtool_set_coalesce;
|
||||
nm_setting_ethtool_set_ring;
|
||||
nm_setting_match_add_driver;
|
||||
nm_setting_match_add_kernel_command_line;
|
||||
nm_setting_match_clear_drivers;
|
||||
|
|
|
|||
|
|
@ -93,6 +93,10 @@ const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = {
|
|||
ETHT_DATA (FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION),
|
||||
ETHT_DATA (FEATURE_TX_UDP_TNL_SEGMENTATION),
|
||||
ETHT_DATA (FEATURE_TX_VLAN_STAG_HW_INSERT),
|
||||
ETHT_DATA (RING_RX),
|
||||
ETHT_DATA (RING_RX_JUMBO),
|
||||
ETHT_DATA (RING_RX_MINI),
|
||||
ETHT_DATA (RING_TX),
|
||||
[_NM_ETHTOOL_ID_NUM] = NULL,
|
||||
};
|
||||
|
||||
|
|
@ -172,6 +176,10 @@ static const guint8 _by_name[_NM_ETHTOOL_ID_NUM] = {
|
|||
NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION,
|
||||
NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT,
|
||||
NM_ETHTOOL_ID_FEATURE_TXVLAN,
|
||||
NM_ETHTOOL_ID_RING_RX,
|
||||
NM_ETHTOOL_ID_RING_RX_JUMBO,
|
||||
NM_ETHTOOL_ID_RING_RX_MINI,
|
||||
NM_ETHTOOL_ID_RING_TX,
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -253,3 +261,16 @@ nm_ethtool_data_get_by_optname (const char *optname)
|
|||
NULL);
|
||||
return (idx < 0) ? NULL : nm_ethtool_data[_by_name[idx]];
|
||||
}
|
||||
|
||||
NMEthtoolType
|
||||
nm_ethtool_id_to_type (NMEthtoolID id)
|
||||
{
|
||||
if (nm_ethtool_id_is_coalesce (id))
|
||||
return NM_ETHTOOL_TYPE_COALESCE;
|
||||
if (nm_ethtool_id_is_feature (id))
|
||||
return NM_ETHTOOL_TYPE_FEATURE;
|
||||
if (nm_ethtool_id_is_ring (id))
|
||||
return NM_ETHTOOL_TYPE_RING;
|
||||
|
||||
return NM_ETHTOOL_TYPE_UNKNOWN;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,13 +93,28 @@ typedef enum {
|
|||
NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT,
|
||||
_NM_ETHTOOL_ID_FEATURE_LAST = NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT,
|
||||
|
||||
_NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_FEATURE_LAST,
|
||||
_NM_ETHTOOL_ID_RING_FIRST = _NM_ETHTOOL_ID_FEATURE_LAST + 1,
|
||||
NM_ETHTOOL_ID_RING_RX = _NM_ETHTOOL_ID_RING_FIRST,
|
||||
NM_ETHTOOL_ID_RING_RX_JUMBO,
|
||||
NM_ETHTOOL_ID_RING_RX_MINI,
|
||||
NM_ETHTOOL_ID_RING_TX,
|
||||
_NM_ETHTOOL_ID_RING_LAST = NM_ETHTOOL_ID_RING_TX,
|
||||
|
||||
_NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_RING_LAST,
|
||||
|
||||
_NM_ETHTOOL_ID_COALESCE_NUM = (_NM_ETHTOOL_ID_COALESCE_LAST - _NM_ETHTOOL_ID_COALESCE_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_FEATURE_NUM = (_NM_ETHTOOL_ID_FEATURE_LAST - _NM_ETHTOOL_ID_FEATURE_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_RING_NUM = (_NM_ETHTOOL_ID_RING_LAST - _NM_ETHTOOL_ID_RING_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_NUM = (_NM_ETHTOOL_ID_LAST - _NM_ETHTOOL_ID_FIRST + 1),
|
||||
} NMEthtoolID;
|
||||
|
||||
typedef enum {
|
||||
NM_ETHTOOL_TYPE_UNKNOWN,
|
||||
NM_ETHTOOL_TYPE_COALESCE,
|
||||
NM_ETHTOOL_TYPE_FEATURE,
|
||||
NM_ETHTOOL_TYPE_RING,
|
||||
} NMEthtoolType;
|
||||
|
||||
typedef struct {
|
||||
const char *optname;
|
||||
NMEthtoolID id;
|
||||
|
|
@ -109,6 +124,8 @@ extern const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1];
|
|||
|
||||
const NMEthtoolData *nm_ethtool_data_get_by_optname (const char *optname);
|
||||
|
||||
NMEthtoolType nm_ethtool_id_to_type (NMEthtoolID id);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static inline NMEthtoolID
|
||||
|
|
@ -132,6 +149,12 @@ nm_ethtool_id_is_coalesce (NMEthtoolID id)
|
|||
return id >= _NM_ETHTOOL_ID_COALESCE_FIRST && id <= _NM_ETHTOOL_ID_COALESCE_LAST;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
nm_ethtool_id_is_ring (NMEthtoolID id)
|
||||
{
|
||||
return id >= _NM_ETHTOOL_ID_RING_FIRST && id <= _NM_ETHTOOL_ID_RING_LAST;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __NM_ETHTOOL_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-manager.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "platform/nm-platform-utils.h"
|
||||
#include "platform/nmp-object.h"
|
||||
#include "platform/nmp-rules-manager.h"
|
||||
#include "ndisc/nm-ndisc.h"
|
||||
|
|
@ -185,7 +186,8 @@ typedef struct {
|
|||
int ifindex;
|
||||
NMEthtoolFeatureStates *features;
|
||||
NMTernary requested[_NM_ETHTOOL_ID_FEATURE_NUM];
|
||||
NMEthtoolCoalesceStates *coalesce;
|
||||
NMEthtoolCoalesceState *coalesce;
|
||||
NMEthtoolRingState *ring;
|
||||
} EthtoolState;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -868,7 +870,7 @@ static gboolean
|
|||
_ethtool_init_coalesce (NMDevice *self,
|
||||
NMPlatform *platform,
|
||||
NMSettingEthtool *s_ethtool,
|
||||
NMEthtoolCoalesceStates *coalesce)
|
||||
NMEthtoolCoalesceState *coalesce)
|
||||
{
|
||||
GHashTable *hash;
|
||||
GHashTableIter iter;
|
||||
|
|
@ -889,6 +891,8 @@ _ethtool_init_coalesce (NMDevice *self,
|
|||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) {
|
||||
if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32))
|
||||
continue;
|
||||
if (!nm_ethtool_optname_is_coalesce (name))
|
||||
continue;
|
||||
|
||||
if (!nm_platform_ethtool_init_coalesce (platform,
|
||||
coalesce,
|
||||
|
|
@ -901,28 +905,27 @@ _ethtool_init_coalesce (NMDevice *self,
|
|||
|
||||
}
|
||||
|
||||
return (!!n_coalesce_set);
|
||||
return !!n_coalesce_set;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
_ethtool_coalesce_reset (NMDevice *self,
|
||||
NMPlatform *platform,
|
||||
EthtoolState *ethtool_state)
|
||||
{
|
||||
gs_free NMEthtoolCoalesceStates *coalesce = NULL;
|
||||
gs_free NMEthtoolCoalesceState *coalesce = NULL;
|
||||
|
||||
nm_assert (NM_IS_DEVICE (self));
|
||||
nm_assert (NM_IS_PLATFORM (platform));
|
||||
nm_assert (ethtool_state);
|
||||
|
||||
coalesce = g_steal_pointer (ðtool_state->coalesce);
|
||||
if (!coalesce)
|
||||
return;
|
||||
|
||||
if (!nm_platform_ethtool_set_coalesce (platform,
|
||||
ethtool_state->ifindex,
|
||||
coalesce,
|
||||
FALSE))
|
||||
coalesce))
|
||||
_LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more coalesce settings");
|
||||
else
|
||||
_LOGD (LOGD_DEVICE, "ethtool: coalesce settings successfully reset");
|
||||
|
|
@ -934,37 +937,147 @@ _ethtool_coalesce_set (NMDevice *self,
|
|||
EthtoolState *ethtool_state,
|
||||
NMSettingEthtool *s_ethtool)
|
||||
{
|
||||
gs_free NMEthtoolCoalesceStates *coalesce = NULL;
|
||||
NMEthtoolCoalesceState coalesce_old;
|
||||
NMEthtoolCoalesceState coalesce_new;
|
||||
|
||||
nm_assert (ethtool_state);
|
||||
nm_assert (NM_IS_DEVICE (self));
|
||||
nm_assert (NM_IS_PLATFORM (platform));
|
||||
nm_assert (NM_IS_SETTING_ETHTOOL (s_ethtool));
|
||||
|
||||
coalesce = nm_platform_ethtool_get_link_coalesce (platform,
|
||||
ethtool_state->ifindex);
|
||||
|
||||
if (!coalesce) {
|
||||
if (!nm_platform_ethtool_get_link_coalesce (platform,
|
||||
ethtool_state->ifindex,
|
||||
&coalesce_old)) {
|
||||
_LOGW (LOGD_DEVICE, "ethtool: failure getting coalesce settings (cannot read)");
|
||||
return;
|
||||
}
|
||||
|
||||
coalesce_new = coalesce_old;
|
||||
|
||||
if (!_ethtool_init_coalesce (self,
|
||||
platform,
|
||||
s_ethtool,
|
||||
coalesce))
|
||||
&coalesce_new))
|
||||
return;
|
||||
|
||||
ethtool_state->coalesce = nm_memdup (&coalesce_old, sizeof (coalesce_old));
|
||||
|
||||
if (!nm_platform_ethtool_set_coalesce (platform,
|
||||
ethtool_state->ifindex,
|
||||
coalesce,
|
||||
TRUE)) {
|
||||
&coalesce_new)) {
|
||||
_LOGW (LOGD_DEVICE, "ethtool: failure setting coalesce settings");
|
||||
return;
|
||||
}
|
||||
_LOGD (LOGD_DEVICE, "ethtool: coalesce settings successfully set");
|
||||
|
||||
ethtool_state->coalesce = g_steal_pointer (&coalesce);
|
||||
_LOGD (LOGD_DEVICE, "ethtool: coalesce settings successfully set");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_ethtool_init_ring (NMDevice *self,
|
||||
NMPlatform *platform,
|
||||
NMSettingEthtool *s_ethtool,
|
||||
NMEthtoolRingState *ring)
|
||||
{
|
||||
GHashTable *hash;
|
||||
GHashTableIter iter;
|
||||
const char *name;
|
||||
GVariant *variant;
|
||||
gsize n_ring_set = 0;
|
||||
|
||||
nm_assert (self);
|
||||
nm_assert (platform);
|
||||
nm_assert (ring);
|
||||
nm_assert (NM_IS_SETTING_ETHTOOL (s_ethtool));
|
||||
|
||||
hash = _nm_setting_gendata_hash (NM_SETTING (s_ethtool), FALSE);
|
||||
if (!hash)
|
||||
return FALSE;
|
||||
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) {
|
||||
if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32))
|
||||
continue;
|
||||
if (!nm_ethtool_optname_is_ring (name))
|
||||
continue;
|
||||
|
||||
if (!nm_platform_ethtool_init_ring (platform,
|
||||
ring,
|
||||
name,
|
||||
g_variant_get_uint32(variant))) {
|
||||
_LOGW (LOGD_DEVICE, "ethtool: invalid ring setting %s", name);
|
||||
return FALSE;
|
||||
}
|
||||
++n_ring_set;
|
||||
|
||||
}
|
||||
|
||||
return !!n_ring_set;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
_ethtool_ring_reset (NMDevice *self,
|
||||
NMPlatform *platform,
|
||||
EthtoolState *ethtool_state)
|
||||
{
|
||||
gs_free NMEthtoolRingState *ring = NULL;
|
||||
|
||||
nm_assert (NM_IS_DEVICE (self));
|
||||
nm_assert (NM_IS_PLATFORM (platform));
|
||||
nm_assert (ethtool_state);
|
||||
|
||||
ring = g_steal_pointer (ðtool_state->ring);
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
if (!nm_platform_ethtool_set_ring (platform,
|
||||
ethtool_state->ifindex,
|
||||
ring))
|
||||
_LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more ring settings");
|
||||
else
|
||||
_LOGD (LOGD_DEVICE, "ethtool: ring settings successfully reset");
|
||||
}
|
||||
|
||||
static void
|
||||
_ethtool_ring_set (NMDevice *self,
|
||||
NMPlatform *platform,
|
||||
EthtoolState *ethtool_state,
|
||||
NMSettingEthtool *s_ethtool)
|
||||
{
|
||||
NMEthtoolRingState ring_old;
|
||||
NMEthtoolRingState ring_new;
|
||||
|
||||
nm_assert (ethtool_state);
|
||||
nm_assert (NM_IS_DEVICE (self));
|
||||
nm_assert (NM_IS_PLATFORM (platform));
|
||||
nm_assert (NM_IS_SETTING_ETHTOOL (s_ethtool));
|
||||
|
||||
if (!nm_platform_ethtool_get_link_ring (platform,
|
||||
ethtool_state->ifindex,
|
||||
&ring_old)) {
|
||||
_LOGW (LOGD_DEVICE, "ethtool: failure getting ring settings (cannot read)");
|
||||
return;
|
||||
}
|
||||
|
||||
ring_new = ring_old;
|
||||
|
||||
if (!_ethtool_init_ring (self,
|
||||
platform,
|
||||
s_ethtool,
|
||||
&ring_new))
|
||||
return;
|
||||
|
||||
ethtool_state->ring = nm_memdup (&ring_old, sizeof (ring_old));
|
||||
|
||||
if (!nm_platform_ethtool_set_ring (platform,
|
||||
ethtool_state->ifindex,
|
||||
&ring_new)) {
|
||||
_LOGW (LOGD_DEVICE, "ethtool: failure setting ring settings");
|
||||
return;
|
||||
}
|
||||
|
||||
_LOGD (LOGD_DEVICE, "ethtool: ring settings successfully set");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -981,6 +1094,8 @@ _ethtool_state_reset (NMDevice *self)
|
|||
_ethtool_features_reset (self, platform, ethtool_state);
|
||||
if (ethtool_state->coalesce)
|
||||
_ethtool_coalesce_reset (self, platform, ethtool_state);
|
||||
if (ethtool_state->ring)
|
||||
_ethtool_ring_reset (self, platform, ethtool_state);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1021,9 +1136,14 @@ _ethtool_state_set (NMDevice *self)
|
|||
platform,
|
||||
ethtool_state,
|
||||
s_ethtool);
|
||||
_ethtool_ring_set (self,
|
||||
platform,
|
||||
ethtool_state,
|
||||
s_ethtool);
|
||||
|
||||
if ( ethtool_state->features
|
||||
|| ethtool_state->coalesce)
|
||||
|| ethtool_state->coalesce
|
||||
|| ethtool_state->ring)
|
||||
priv->ethtool_state = g_steal_pointer (ðtool_state);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ NM_UTILS_ENUM2STR_DEFINE (_ethtool_cmd_to_string, guint32,
|
|||
NM_UTILS_ENUM2STR (ETHTOOL_GFEATURES, "ETHTOOL_GFEATURES"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_GLINK, "ETHTOOL_GLINK"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_GPERMADDR, "ETHTOOL_GPERMADDR"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_GRINGPARAM, "ETHTOOL_GRINGPARAM"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_GSET, "ETHTOOL_GSET"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_GSSET_INFO, "ETHTOOL_GSSET_INFO"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_GSTATS, "ETHTOOL_GSTATS"),
|
||||
|
|
@ -276,6 +277,7 @@ NM_UTILS_ENUM2STR_DEFINE (_ethtool_cmd_to_string, guint32,
|
|||
NM_UTILS_ENUM2STR (ETHTOOL_GWOL, "ETHTOOL_GWOL"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_SCOALESCE, "ETHTOOL_SCOALESCE"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_SFEATURES, "ETHTOOL_SFEATURES"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_SRINGPARAM, "ETHTOOL_SRINGPARAM"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_SSET, "ETHTOOL_SSET"),
|
||||
NM_UTILS_ENUM2STR (ETHTOOL_SWOL, "ETHTOOL_SWOL"),
|
||||
);
|
||||
|
|
@ -845,31 +847,26 @@ ethtool_get_coalesce (SocketHandle *shandle,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
NMEthtoolCoalesceStates *
|
||||
nmp_utils_ethtool_get_coalesce (int ifindex)
|
||||
gboolean
|
||||
nmp_utils_ethtool_get_coalesce (int ifindex,
|
||||
NMEthtoolCoalesceState *coalesce)
|
||||
{
|
||||
gs_free NMEthtoolCoalesceStates *coalesce = NULL;
|
||||
nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT (ifindex);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, NULL);
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (coalesce, FALSE);
|
||||
|
||||
coalesce = g_new0 (NMEthtoolCoalesceStates, 1);
|
||||
|
||||
if (!ethtool_get_coalesce (&shandle, &coalesce->old_state)) {
|
||||
if (!ethtool_get_coalesce (&shandle, coalesce)) {
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure getting coalesce settings",
|
||||
ifindex,
|
||||
"get-coalesce");
|
||||
return NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* copy into requested as well, so that they're merged when applying */
|
||||
coalesce->requested_state = coalesce->old_state;
|
||||
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: retrieved kernel coalesce settings",
|
||||
ifindex,
|
||||
"get-coalesce");
|
||||
return g_steal_pointer (&coalesce);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -916,32 +913,112 @@ ethtool_set_coalesce (SocketHandle *shandle,
|
|||
|
||||
gboolean
|
||||
nmp_utils_ethtool_set_coalesce (int ifindex,
|
||||
const NMEthtoolCoalesceStates *coalesce,
|
||||
gboolean do_set)
|
||||
const NMEthtoolCoalesceState *coalesce)
|
||||
{
|
||||
gboolean success;
|
||||
nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT (ifindex);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (coalesce, FALSE);
|
||||
|
||||
if (do_set)
|
||||
success = ethtool_set_coalesce (&shandle, &coalesce->requested_state);
|
||||
else
|
||||
success = ethtool_set_coalesce (&shandle, &coalesce->old_state);
|
||||
|
||||
if (!success) {
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure %s coalesce settings",
|
||||
if (!ethtool_set_coalesce (&shandle, coalesce)) {
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure setting coalesce settings",
|
||||
ifindex,
|
||||
"set-coalesce",
|
||||
do_set ? "setting" : "resetting");
|
||||
"set-coalesce");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s kernel coalesce settings",
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: set kernel coalesce settings",
|
||||
ifindex,
|
||||
"set-coalesce",
|
||||
do_set ? "set" : "reset");
|
||||
"set-coalesce");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ethtool_get_ring (SocketHandle *shandle,
|
||||
NMEthtoolRingState *ring)
|
||||
{
|
||||
struct ethtool_ringparam eth_data;
|
||||
|
||||
eth_data.cmd = ETHTOOL_GRINGPARAM;
|
||||
|
||||
if (_ethtool_call_handle (shandle,
|
||||
ð_data,
|
||||
sizeof (struct ethtool_ringparam)) != 0)
|
||||
return FALSE;
|
||||
|
||||
ring->rx_pending = eth_data.rx_pending;
|
||||
ring->rx_jumbo_pending = eth_data.rx_jumbo_pending;
|
||||
ring->rx_mini_pending = eth_data.rx_mini_pending;
|
||||
ring->tx_pending = eth_data.tx_pending;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmp_utils_ethtool_get_ring (int ifindex,
|
||||
NMEthtoolRingState *ring)
|
||||
{
|
||||
nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT (ifindex);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (ring, FALSE);
|
||||
|
||||
if (!ethtool_get_ring (&shandle, ring)) {
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure getting ring settings",
|
||||
ifindex,
|
||||
"get-ring");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: retrieved kernel ring settings",
|
||||
ifindex,
|
||||
"get-ring");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ethtool_set_ring (SocketHandle *shandle,
|
||||
const NMEthtoolRingState *ring)
|
||||
{
|
||||
gboolean success;
|
||||
struct ethtool_ringparam eth_data;
|
||||
|
||||
g_return_val_if_fail (shandle, FALSE);
|
||||
g_return_val_if_fail (ring, FALSE);
|
||||
|
||||
eth_data = (struct ethtool_ringparam) {
|
||||
.cmd = ETHTOOL_SRINGPARAM,
|
||||
.rx_pending = ring->rx_pending,
|
||||
.rx_jumbo_pending = ring->rx_jumbo_pending,
|
||||
.rx_mini_pending = ring->rx_mini_pending,
|
||||
.tx_pending = ring->tx_pending,
|
||||
};
|
||||
|
||||
success = (_ethtool_call_handle (shandle,
|
||||
ð_data,
|
||||
sizeof (struct ethtool_ringparam)) == 0);
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmp_utils_ethtool_set_ring (int ifindex,
|
||||
const NMEthtoolRingState *ring)
|
||||
{
|
||||
nm_auto_socket_handle SocketHandle shandle = SOCKET_HANDLE_INIT (ifindex);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (ring, FALSE);
|
||||
|
||||
if (!ethtool_set_ring (&shandle, ring)) {
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure setting ring settings",
|
||||
ifindex,
|
||||
"set-ring");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: set kernel ring settings",
|
||||
ifindex,
|
||||
"set-ring");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ gboolean nmp_utils_ethtool_set_features (int ifindex,
|
|||
const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */,
|
||||
gboolean do_set /* or reset */);
|
||||
|
||||
typedef struct {
|
||||
struct _NMEthtoolCoalesceState {
|
||||
guint32 rx_coalesce_usecs;
|
||||
guint32 rx_max_coalesced_frames;
|
||||
guint32 rx_coalesce_usecs_irq;
|
||||
|
|
@ -115,18 +115,26 @@ typedef struct {
|
|||
guint32 tx_coalesce_usecs_high;
|
||||
guint32 tx_max_coalesced_frames_high;
|
||||
guint32 rate_sample_interval;
|
||||
} NMEthtoolCoalesceState;
|
||||
|
||||
struct _NMEthtoolCoalesceStates {
|
||||
NMEthtoolCoalesceState old_state;
|
||||
NMEthtoolCoalesceState requested_state;
|
||||
};
|
||||
|
||||
NMEthtoolCoalesceStates * nmp_utils_ethtool_get_coalesce (int ifindex);
|
||||
gboolean nmp_utils_ethtool_get_coalesce (int ifindex,
|
||||
NMEthtoolCoalesceState *coalesce);
|
||||
|
||||
gboolean nmp_utils_ethtool_set_coalesce (int ifindex,
|
||||
const NMEthtoolCoalesceStates *coalesce,
|
||||
gboolean do_set);
|
||||
const NMEthtoolCoalesceState *coalesce);
|
||||
|
||||
struct _NMEthtoolRingState {
|
||||
guint32 rx_pending;
|
||||
guint32 rx_mini_pending;
|
||||
guint32 rx_jumbo_pending;
|
||||
guint32 tx_pending;
|
||||
};
|
||||
|
||||
gboolean nmp_utils_ethtool_get_ring (int ifindex,
|
||||
NMEthtoolRingState *ring);
|
||||
|
||||
gboolean nmp_utils_ethtool_set_ring (int ifindex,
|
||||
const NMEthtoolRingState *ring);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -3214,100 +3214,100 @@ nm_platform_ethtool_set_features (NMPlatform *self,
|
|||
return nmp_utils_ethtool_set_features (ifindex, features, requested, do_set);
|
||||
}
|
||||
|
||||
NMEthtoolCoalesceStates *
|
||||
nm_platform_ethtool_get_link_coalesce (NMPlatform *self, int ifindex)
|
||||
gboolean
|
||||
nm_platform_ethtool_get_link_coalesce (NMPlatform *self,
|
||||
int ifindex,
|
||||
NMEthtoolCoalesceState *coalesce)
|
||||
{
|
||||
_CHECK_SELF_NETNS (self, klass, netns, NULL);
|
||||
_CHECK_SELF_NETNS (self, klass, netns, FALSE);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, NULL);
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (coalesce, FALSE);
|
||||
|
||||
return nmp_utils_ethtool_get_coalesce (ifindex);
|
||||
return nmp_utils_ethtool_get_coalesce (ifindex, coalesce);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ethtool_init_coalesce (NMPlatform *self,
|
||||
NMEthtoolCoalesceStates *coalesce,
|
||||
NMEthtoolCoalesceState *coalesce,
|
||||
const char *option_name,
|
||||
guint32 value)
|
||||
{
|
||||
NMEthtoolID ethtool_id;
|
||||
NMEthtoolCoalesceState *state;
|
||||
|
||||
g_return_val_if_fail (coalesce, FALSE);
|
||||
g_return_val_if_fail (option_name, FALSE);
|
||||
|
||||
state = &coalesce->requested_state;
|
||||
ethtool_id = nm_ethtool_id_get_by_name (option_name);
|
||||
|
||||
if (!nm_ethtool_id_is_coalesce (ethtool_id))
|
||||
return FALSE;
|
||||
g_return_val_if_fail (nm_ethtool_id_is_coalesce (ethtool_id), FALSE);
|
||||
|
||||
switch (ethtool_id) {
|
||||
case NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX:
|
||||
state->use_adaptive_rx_coalesce = value;
|
||||
coalesce->use_adaptive_rx_coalesce = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX:
|
||||
state->use_adaptive_tx_coalesce = value;
|
||||
coalesce->use_adaptive_tx_coalesce = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH:
|
||||
state->pkt_rate_high = value;
|
||||
coalesce->pkt_rate_high = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW:
|
||||
state->pkt_rate_low = value;
|
||||
coalesce->pkt_rate_low = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_RX_FRAMES:
|
||||
state->rx_max_coalesced_frames = value;
|
||||
coalesce->rx_max_coalesced_frames = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH:
|
||||
state->rx_max_coalesced_frames_high = value;
|
||||
coalesce->rx_max_coalesced_frames_high = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ:
|
||||
state->rx_max_coalesced_frames_irq = value;
|
||||
coalesce->rx_max_coalesced_frames_irq = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW:
|
||||
state->rx_max_coalesced_frames_low = value;
|
||||
coalesce->rx_max_coalesced_frames_low = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_RX_USECS:
|
||||
state->rx_coalesce_usecs = value;
|
||||
coalesce->rx_coalesce_usecs = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH:
|
||||
state->rx_coalesce_usecs_high = value;
|
||||
coalesce->rx_coalesce_usecs_high = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ:
|
||||
state->rx_coalesce_usecs_irq = value;
|
||||
coalesce->rx_coalesce_usecs_irq = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW:
|
||||
state->rx_coalesce_usecs_low = value;
|
||||
coalesce->rx_coalesce_usecs_low = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL:
|
||||
state->rate_sample_interval = value;
|
||||
coalesce->rate_sample_interval = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS:
|
||||
state->stats_block_coalesce_usecs = value;
|
||||
coalesce->stats_block_coalesce_usecs = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_TX_FRAMES:
|
||||
state->tx_max_coalesced_frames = value;
|
||||
coalesce->tx_max_coalesced_frames = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH:
|
||||
state->tx_max_coalesced_frames_high = value;
|
||||
coalesce->tx_max_coalesced_frames_high = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ:
|
||||
state->tx_max_coalesced_frames_irq = value;
|
||||
coalesce->tx_max_coalesced_frames_irq = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW:
|
||||
state->tx_max_coalesced_frames_low = value;
|
||||
coalesce->tx_max_coalesced_frames_low = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_TX_USECS:
|
||||
state->tx_coalesce_usecs = value;
|
||||
coalesce->tx_coalesce_usecs = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH:
|
||||
state->tx_coalesce_usecs_high = value;
|
||||
coalesce->tx_coalesce_usecs_high = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ:
|
||||
state->tx_coalesce_usecs_irq = value;
|
||||
coalesce->tx_coalesce_usecs_irq = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW:
|
||||
state->tx_coalesce_usecs_low = value;
|
||||
coalesce->tx_coalesce_usecs_low = value;
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
|
@ -3319,14 +3319,73 @@ nm_platform_ethtool_init_coalesce (NMPlatform *self,
|
|||
gboolean
|
||||
nm_platform_ethtool_set_coalesce (NMPlatform *self,
|
||||
int ifindex,
|
||||
const NMEthtoolCoalesceStates *coalesce,
|
||||
gboolean do_set)
|
||||
const NMEthtoolCoalesceState *coalesce)
|
||||
{
|
||||
_CHECK_SELF_NETNS (self, klass, netns, FALSE);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
|
||||
return nmp_utils_ethtool_set_coalesce (ifindex, coalesce, do_set);
|
||||
return nmp_utils_ethtool_set_coalesce (ifindex, coalesce);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ethtool_get_link_ring (NMPlatform *self,
|
||||
int ifindex,
|
||||
NMEthtoolRingState *ring)
|
||||
{
|
||||
_CHECK_SELF_NETNS (self, klass, netns, FALSE);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (ring, FALSE);
|
||||
|
||||
return nmp_utils_ethtool_get_ring (ifindex, ring);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ethtool_init_ring (NMPlatform *self,
|
||||
NMEthtoolRingState *ring,
|
||||
const char *option_name,
|
||||
guint32 value)
|
||||
{
|
||||
NMEthtoolID ethtool_id;
|
||||
|
||||
g_return_val_if_fail (ring, FALSE);
|
||||
g_return_val_if_fail (option_name, FALSE);
|
||||
|
||||
ethtool_id = nm_ethtool_id_get_by_name (option_name);
|
||||
|
||||
g_return_val_if_fail (nm_ethtool_id_is_ring (ethtool_id), FALSE);
|
||||
|
||||
switch (ethtool_id) {
|
||||
case NM_ETHTOOL_ID_RING_RX:
|
||||
ring->rx_pending = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_RING_RX_JUMBO:
|
||||
ring->rx_jumbo_pending = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_RING_RX_MINI:
|
||||
ring->rx_mini_pending = value;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_RING_TX:
|
||||
ring->tx_pending = value;
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ethtool_set_ring (NMPlatform *self,
|
||||
int ifindex,
|
||||
const NMEthtoolRingState *ring)
|
||||
{
|
||||
_CHECK_SELF_NETNS (self, klass, netns, FALSE);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
|
||||
return nmp_utils_ethtool_set_ring (ifindex, ring);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1954,20 +1954,35 @@ gboolean nm_platform_ethtool_set_features (NMPlatform *self,
|
|||
const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */,
|
||||
gboolean do_set /* or reset */);
|
||||
|
||||
typedef struct _NMEthtoolCoalesceStates NMEthtoolCoalesceStates;
|
||||
typedef struct _NMEthtoolCoalesceState NMEthtoolCoalesceState;
|
||||
|
||||
NMEthtoolCoalesceStates *nm_platform_ethtool_get_link_coalesce (NMPlatform *self,
|
||||
int ifindex);
|
||||
gboolean nm_platform_ethtool_get_link_coalesce (NMPlatform *self,
|
||||
int ifindex,
|
||||
NMEthtoolCoalesceState *coalesce);
|
||||
|
||||
gboolean nm_platform_ethtool_init_coalesce (NMPlatform *self,
|
||||
NMEthtoolCoalesceStates *coalesce,
|
||||
NMEthtoolCoalesceState *coalesce,
|
||||
const char *option_name,
|
||||
guint32 value);
|
||||
|
||||
gboolean nm_platform_ethtool_set_coalesce (NMPlatform *self,
|
||||
int ifindex,
|
||||
const NMEthtoolCoalesceStates *coalesce,
|
||||
gboolean do_set);
|
||||
const NMEthtoolCoalesceState *coalesce);
|
||||
|
||||
typedef struct _NMEthtoolRingState NMEthtoolRingState;
|
||||
|
||||
gboolean nm_platform_ethtool_get_link_ring (NMPlatform *self,
|
||||
int ifindex,
|
||||
NMEthtoolRingState *ring);
|
||||
|
||||
gboolean nm_platform_ethtool_init_ring (NMPlatform *self,
|
||||
NMEthtoolRingState *ring,
|
||||
const char *option_name,
|
||||
guint32 value);
|
||||
|
||||
gboolean nm_platform_ethtool_set_ring (NMPlatform *self,
|
||||
int ifindex,
|
||||
const NMEthtoolRingState *ring);
|
||||
|
||||
const char * nm_platform_link_duplex_type_to_string (NMPlatformLinkDuplexType duplex);
|
||||
|
||||
|
|
|
|||
|
|
@ -4248,6 +4248,130 @@ wireless_connection_from_ifcfg (const char *file,
|
|||
return connection;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *optname;
|
||||
union {
|
||||
guint32 u32;
|
||||
NMTernary nmternary;
|
||||
} v;
|
||||
gboolean has_value;
|
||||
} NMEthtoolIfcfgOption;
|
||||
|
||||
/* returns an 'iterator' to words
|
||||
* pointing to the next unprocessed option or NULL
|
||||
* in case of failure */
|
||||
static const char **
|
||||
_next_ethtool_options_nmternary (const char **words,
|
||||
NMEthtoolType ethtool_type,
|
||||
NMEthtoolIfcfgOption *out_value)
|
||||
{
|
||||
const char *opt;
|
||||
const char *opt_val;
|
||||
const NMEthtoolData *d = NULL;
|
||||
NMTernary onoff = NM_TERNARY_DEFAULT;
|
||||
|
||||
nm_assert (out_value);
|
||||
|
||||
out_value->has_value = FALSE;
|
||||
out_value->optname = NULL;
|
||||
|
||||
if ( !words
|
||||
|| !words[0]
|
||||
|| !words[1])
|
||||
return NULL;
|
||||
|
||||
opt = *words;
|
||||
opt_val = *(++words);
|
||||
|
||||
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, ethtool_type);
|
||||
if (!d) {
|
||||
if (onoff != NM_TERNARY_DEFAULT) {
|
||||
/* the next value is just the on/off argument. Skip it too. */
|
||||
++words;
|
||||
}
|
||||
|
||||
/* silently ignore unsupported offloading features. */
|
||||
return words;
|
||||
}
|
||||
|
||||
if (onoff == NM_TERNARY_DEFAULT) {
|
||||
PARSE_WARNING ("Expects on/off argument for feature '%s'", opt);
|
||||
return words;
|
||||
}
|
||||
|
||||
out_value->has_value = TRUE;
|
||||
out_value->optname = d->optname;
|
||||
out_value->v.nmternary = onoff;
|
||||
|
||||
return ++words;
|
||||
}
|
||||
|
||||
/* returns an 'iterator' to words
|
||||
* pointing to the next unprocessed option or NULL
|
||||
* in case of failure */
|
||||
static const char **
|
||||
_next_ethtool_options_uint32 (const char **words,
|
||||
NMEthtoolType ethtool_type,
|
||||
NMEthtoolIfcfgOption *out_value)
|
||||
{
|
||||
gint64 i64;
|
||||
const char *opt;
|
||||
const char *opt_val;
|
||||
const NMEthtoolData *d = NULL;
|
||||
|
||||
nm_assert (out_value);
|
||||
|
||||
out_value->has_value = FALSE;
|
||||
out_value->optname = NULL;
|
||||
|
||||
if ( !words
|
||||
|| !words[0]
|
||||
|| !words[1])
|
||||
return NULL;
|
||||
|
||||
opt = *words;
|
||||
opt_val = *(++words);
|
||||
|
||||
i64 = _nm_utils_ascii_str_to_int64 (opt_val, 10, 0, G_MAXUINT32, -1);
|
||||
|
||||
d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt, ethtool_type);
|
||||
if (!d) {
|
||||
if (i64 != -1) {
|
||||
/* the next value is just the on/off argument. Skip it too. */
|
||||
++words;
|
||||
}
|
||||
|
||||
/* silently ignore unsupported offloading features. */
|
||||
return words;
|
||||
}
|
||||
|
||||
out_value->has_value = TRUE;
|
||||
out_value->optname = d->optname;
|
||||
out_value->v.u32 = (guint32) i64;
|
||||
|
||||
return ++words;
|
||||
}
|
||||
|
||||
static
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
|
||||
_get_ethtool_type_by_name,
|
||||
NMEthtoolType,
|
||||
{ nm_assert (name); },
|
||||
{ return NM_ETHTOOL_TYPE_UNKNOWN; },
|
||||
{ "--coalesce", NM_ETHTOOL_TYPE_COALESCE },
|
||||
{ "--features", NM_ETHTOOL_TYPE_FEATURE },
|
||||
{ "--offload", NM_ETHTOOL_TYPE_FEATURE },
|
||||
{ "--set-ring", NM_ETHTOOL_TYPE_RING },
|
||||
{ "-C", NM_ETHTOOL_TYPE_COALESCE },
|
||||
{ "-G", NM_ETHTOOL_TYPE_RING },
|
||||
{ "-K", NM_ETHTOOL_TYPE_FEATURE },
|
||||
);
|
||||
|
||||
static void
|
||||
parse_ethtool_option (const char *value,
|
||||
NMSettingWiredWakeOnLan *out_flags,
|
||||
|
|
@ -4257,100 +4381,67 @@ parse_ethtool_option (const char *value,
|
|||
const char **out_duplex,
|
||||
NMSettingEthtool **out_s_ethtool)
|
||||
{
|
||||
gs_free const char **words = NULL;
|
||||
guint i;
|
||||
const char **w_iter;
|
||||
NMEthtoolIfcfgOption ifcfg_option;
|
||||
gs_free const char **words = NULL;
|
||||
NMEthtoolType ethtool_type = NM_ETHTOOL_TYPE_UNKNOWN;
|
||||
|
||||
words = nm_utils_strsplit_set (value, " \t\n");
|
||||
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 (words[0])
|
||||
ethtool_type = _get_ethtool_type_by_name (words[0]);
|
||||
|
||||
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
|
||||
|| !nm_ethtool_id_is_feature (d->id)) {
|
||||
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);
|
||||
}
|
||||
} else if (NM_IN_STRSET (words[0], "-C", "--coalesce")) {
|
||||
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;
|
||||
gint64 i64;
|
||||
|
||||
i64 = _nm_utils_ascii_str_to_int64 (opt_val, 10, 0, G_MAXUINT32, -1);
|
||||
d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt);
|
||||
|
||||
if ( !d
|
||||
|| !nm_ethtool_id_is_coalesce (d->id)) {
|
||||
if (i64 != -1) {
|
||||
/* the next value is just the argument. Skip it too. */
|
||||
i++;
|
||||
}
|
||||
/* silently ignore unsupported coalesce settings. */
|
||||
continue;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (i64 == -1) {
|
||||
PARSE_WARNING ("Expects integer argument for setting '%s'", opt);
|
||||
continue;
|
||||
}
|
||||
|
||||
nm_setting_ethtool_set_coalesce (*out_s_ethtool,
|
||||
d->optname,
|
||||
(guint32) i64);
|
||||
}
|
||||
if (ethtool_type != NM_ETHTOOL_TYPE_UNKNOWN) {
|
||||
if (!words[1]) {
|
||||
/* first argument must be the interface name. This is invalid. */
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
if (!*out_s_ethtool)
|
||||
*out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ());
|
||||
|
||||
/* skip ethtool type && interface name */
|
||||
w_iter = &words[2];
|
||||
|
||||
if (ethtool_type == NM_ETHTOOL_TYPE_FEATURE) {
|
||||
while (w_iter && *w_iter) {
|
||||
w_iter = _next_ethtool_options_nmternary (w_iter,
|
||||
ethtool_type,
|
||||
&ifcfg_option);
|
||||
|
||||
if (ifcfg_option.has_value)
|
||||
nm_setting_ethtool_set_feature (*out_s_ethtool,
|
||||
ifcfg_option.optname,
|
||||
ifcfg_option.v.nmternary);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (NM_IN_SET (ethtool_type,
|
||||
NM_ETHTOOL_TYPE_COALESCE,
|
||||
NM_ETHTOOL_TYPE_RING)) {
|
||||
while (w_iter && *w_iter) {
|
||||
w_iter = _next_ethtool_options_uint32 (w_iter,
|
||||
ethtool_type,
|
||||
&ifcfg_option);
|
||||
|
||||
if (ifcfg_option.has_value) {
|
||||
if (ethtool_type == NM_ETHTOOL_TYPE_COALESCE)
|
||||
nm_setting_ethtool_set_coalesce (*out_s_ethtool,
|
||||
ifcfg_option.optname,
|
||||
ifcfg_option.v.u32);
|
||||
else
|
||||
nm_setting_ethtool_set_ring (*out_s_ethtool,
|
||||
ifcfg_option.optname,
|
||||
ifcfg_option.v.u32);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* unsupported ethtool type */
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
|
||||
/* /sbin/ethtool -s ${REALDEVICE} $opts */
|
||||
|
|
|
|||
|
|
@ -598,11 +598,45 @@ const char *const _nm_ethtool_ifcfg_names[] = {
|
|||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_RING_RX, "rx"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_RING_RX_JUMBO, "rx-jumbo"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_RING_RX_MINI, "rx-mini"),
|
||||
ETHT_NAME (NM_ETHTOOL_ID_RING_TX, "tx"),
|
||||
};
|
||||
|
||||
static
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
|
||||
_get_ethtoolid_by_name,
|
||||
_get_ethtoolid_coalesce_by_name,
|
||||
NMEthtoolID,
|
||||
{ nm_assert (name); },
|
||||
{ return NM_ETHTOOL_ID_UNKNOWN; },
|
||||
{ "adaptive-rx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX },
|
||||
{ "adaptive-tx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX },
|
||||
{ "pkt-rate-high", NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH },
|
||||
{ "pkt-rate-low", NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW },
|
||||
{ "rx-frames", NM_ETHTOOL_ID_COALESCE_RX_FRAMES },
|
||||
{ "rx-frames-high", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH },
|
||||
{ "rx-frames-irq", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ },
|
||||
{ "rx-frames-low", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW },
|
||||
{ "rx-usecs", NM_ETHTOOL_ID_COALESCE_RX_USECS },
|
||||
{ "rx-usecs-high", NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH },
|
||||
{ "rx-usecs-irq", NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ },
|
||||
{ "rx-usecs-low", NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW },
|
||||
{ "sample-interval", NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL },
|
||||
{ "stats-block-usecs", NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS },
|
||||
{ "tx-frames", NM_ETHTOOL_ID_COALESCE_TX_FRAMES },
|
||||
{ "tx-frames-high", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH },
|
||||
{ "tx-frames-irq", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ },
|
||||
{ "tx-frames-low", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW },
|
||||
{ "tx-usecs", NM_ETHTOOL_ID_COALESCE_TX_USECS },
|
||||
{ "tx-usecs-high", NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH },
|
||||
{ "tx-usecs-irq", NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ },
|
||||
{ "tx-usecs-low", NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW },
|
||||
);
|
||||
|
||||
static
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
|
||||
_get_ethtoolid_feature_by_name,
|
||||
NMEthtoolID,
|
||||
{ nm_assert (name); },
|
||||
{ return NM_ETHTOOL_ID_UNKNOWN; },
|
||||
|
|
@ -619,8 +653,6 @@ NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
|
|||
* the case and if yes, map them to the corresponding NetworkManager's features.
|
||||
*
|
||||
* That is why there are duplicate IDs in this list. */
|
||||
{ "adaptive-rx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX },
|
||||
{ "adaptive-tx", NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX },
|
||||
{ "esp-hw-offload", NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD },
|
||||
{ "esp-tx-csum-hw-offload", NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD },
|
||||
{ "fcoe-mtu", NM_ETHTOOL_ID_FEATURE_FCOE_MTU },
|
||||
|
|
@ -632,35 +664,23 @@ NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
|
|||
{ "loopback", NM_ETHTOOL_ID_FEATURE_LOOPBACK },
|
||||
{ "lro", NM_ETHTOOL_ID_FEATURE_LRO },
|
||||
{ "ntuple", NM_ETHTOOL_ID_FEATURE_NTUPLE },
|
||||
{ "pkt-rate-high", NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH },
|
||||
{ "pkt-rate-low", NM_ETHTOOL_ID_COALESCE_PKT_RATE_LOW },
|
||||
{ "rx", NM_ETHTOOL_ID_FEATURE_RX },
|
||||
{ "rx-all", NM_ETHTOOL_ID_FEATURE_RX_ALL },
|
||||
{ "rx-checksum", NM_ETHTOOL_ID_FEATURE_RX }, // kernel-only name
|
||||
{ "rx-fcs", NM_ETHTOOL_ID_FEATURE_RX_FCS },
|
||||
{ "rx-frames", NM_ETHTOOL_ID_COALESCE_RX_FRAMES },
|
||||
{ "rx-frames-high", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_HIGH },
|
||||
{ "rx-frames-irq", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_IRQ },
|
||||
{ "rx-frames-low", NM_ETHTOOL_ID_COALESCE_RX_FRAMES_LOW },
|
||||
{ "rx-gro", NM_ETHTOOL_ID_FEATURE_GRO }, // kernel-only name
|
||||
{ "rx-gro-hw", NM_ETHTOOL_ID_FEATURE_RX_GRO_HW },
|
||||
{ "rx-hashing", NM_ETHTOOL_ID_FEATURE_RXHASH }, // kernel-only name
|
||||
{ "rx-lro", NM_ETHTOOL_ID_FEATURE_LRO }, // kernel-only name
|
||||
{ "rx-ntuple-filter", NM_ETHTOOL_ID_FEATURE_NTUPLE }, // kernel-only name
|
||||
{ "rx-udp_tunnel-port-offload", NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD },
|
||||
{ "rx-usecs", NM_ETHTOOL_ID_COALESCE_RX_USECS },
|
||||
{ "rx-usecs-high", NM_ETHTOOL_ID_COALESCE_RX_USECS_HIGH },
|
||||
{ "rx-usecs-irq", NM_ETHTOOL_ID_COALESCE_RX_USECS_IRQ },
|
||||
{ "rx-usecs-low", NM_ETHTOOL_ID_COALESCE_RX_USECS_LOW },
|
||||
{ "rx-vlan-filter", NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER },
|
||||
{ "rx-vlan-hw-parse", NM_ETHTOOL_ID_FEATURE_RXVLAN }, // kernel-only name
|
||||
{ "rx-vlan-stag-filter", NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER },
|
||||
{ "rx-vlan-stag-hw-parse", NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE },
|
||||
{ "rxhash", NM_ETHTOOL_ID_FEATURE_RXHASH },
|
||||
{ "rxvlan", NM_ETHTOOL_ID_FEATURE_RXVLAN },
|
||||
{ "sample-interval", NM_ETHTOOL_ID_COALESCE_SAMPLE_INTERVAL },
|
||||
{ "sg", NM_ETHTOOL_ID_FEATURE_SG },
|
||||
{ "stats-block-usecs", NM_ETHTOOL_ID_COALESCE_STATS_BLOCK_USECS },
|
||||
{ "tls-hw-record", NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD },
|
||||
{ "tls-hw-tx-offload", NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD },
|
||||
{ "tso", NM_ETHTOOL_ID_FEATURE_TSO },
|
||||
|
|
@ -672,10 +692,6 @@ NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
|
|||
{ "tx-checksum-sctp", NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP },
|
||||
{ "tx-esp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION },
|
||||
{ "tx-fcoe-segmentation", NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION },
|
||||
{ "tx-frames", NM_ETHTOOL_ID_COALESCE_TX_FRAMES },
|
||||
{ "tx-frames-high", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_HIGH },
|
||||
{ "tx-frames-irq", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_IRQ },
|
||||
{ "tx-frames-low", NM_ETHTOOL_ID_COALESCE_TX_FRAMES_LOW },
|
||||
{ "tx-generic-segmentation", NM_ETHTOOL_ID_FEATURE_GSO }, // kernel-only name
|
||||
{ "tx-gre-csum-segmentation", NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION },
|
||||
{ "tx-gre-segmentation", NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION },
|
||||
|
|
@ -694,21 +710,44 @@ NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
|
|||
{ "tx-udp-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION },
|
||||
{ "tx-udp_tnl-csum-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION },
|
||||
{ "tx-udp_tnl-segmentation", NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION },
|
||||
{ "tx-usecs", NM_ETHTOOL_ID_COALESCE_TX_USECS },
|
||||
{ "tx-usecs-high", NM_ETHTOOL_ID_COALESCE_TX_USECS_HIGH },
|
||||
{ "tx-usecs-irq", NM_ETHTOOL_ID_COALESCE_TX_USECS_IRQ },
|
||||
{ "tx-usecs-low", NM_ETHTOOL_ID_COALESCE_TX_USECS_LOW },
|
||||
{ "tx-vlan-hw-insert", NM_ETHTOOL_ID_FEATURE_TXVLAN }, // kernel-only name
|
||||
{ "tx-vlan-stag-hw-insert", NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT },
|
||||
{ "txvlan", NM_ETHTOOL_ID_FEATURE_TXVLAN },
|
||||
);
|
||||
|
||||
static
|
||||
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
|
||||
_get_ethtoolid_ring_by_name,
|
||||
NMEthtoolID,
|
||||
{ nm_assert (name); },
|
||||
{ return NM_ETHTOOL_ID_UNKNOWN; },
|
||||
{ "rx", NM_ETHTOOL_ID_RING_RX },
|
||||
{ "rx-jumbo", NM_ETHTOOL_ID_RING_RX_JUMBO },
|
||||
{ "rx-mini", NM_ETHTOOL_ID_RING_RX_MINI },
|
||||
{ "tx", NM_ETHTOOL_ID_RING_TX },
|
||||
);
|
||||
|
||||
const NMEthtoolData *
|
||||
nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name)
|
||||
nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name,
|
||||
NMEthtoolType ethtool_type)
|
||||
{
|
||||
NMEthtoolID id;
|
||||
|
||||
id = _get_ethtoolid_by_name (name);
|
||||
switch (ethtool_type) {
|
||||
case NM_ETHTOOL_TYPE_COALESCE:
|
||||
id = _get_ethtoolid_coalesce_by_name (name);
|
||||
break;
|
||||
case NM_ETHTOOL_TYPE_FEATURE:
|
||||
id = _get_ethtoolid_feature_by_name (name);
|
||||
break;
|
||||
case NM_ETHTOOL_TYPE_RING:
|
||||
id = _get_ethtoolid_ring_by_name (name);
|
||||
break;
|
||||
default:
|
||||
nm_assert_not_reached();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (id == NM_ETHTOOL_ID_UNKNOWN)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ nms_ifcfg_rh_utils_get_ethtool_name (NMEthtoolID ethtool_id)
|
|||
return _nm_ethtool_ifcfg_names[ethtool_id];
|
||||
}
|
||||
|
||||
const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name);
|
||||
const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name,
|
||||
NMEthtoolType ethtool_type);
|
||||
|
||||
#endif /* _UTILS_H_ */
|
||||
|
|
|
|||
|
|
@ -1212,6 +1212,23 @@ write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro
|
|||
g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id));
|
||||
g_string_append_printf (str, " %"G_GUINT32_FORMAT, val);
|
||||
}
|
||||
|
||||
g_string_append (str, " ; -G ");
|
||||
g_string_append (str, iface ?: "net0");
|
||||
|
||||
for (ethtool_id = _NM_ETHTOOL_ID_RING_FIRST; ethtool_id <= _NM_ETHTOOL_ID_RING_LAST; ethtool_id++) {
|
||||
const NMEthtoolData *ed = nm_ethtool_data[ethtool_id];
|
||||
guint32 val;
|
||||
|
||||
nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id));
|
||||
|
||||
if (!nm_setting_ethtool_get_ring (s_ethtool, ed->optname, &val))
|
||||
continue;
|
||||
|
||||
g_string_append_c (str, ' ');
|
||||
g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id));
|
||||
g_string_append_printf (str, " %"G_GUINT32_FORMAT, val);
|
||||
}
|
||||
}
|
||||
|
||||
if (str) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
TYPE=Ethernet
|
||||
PROXY_METHOD=none
|
||||
BROWSER_ONLY=no
|
||||
ETHTOOL_OPTS="autoneg on ; -K net0 rxvlan off tx on ; -C net0"
|
||||
ETHTOOL_OPTS="autoneg on ; -K net0 rxvlan off tx on ; -C net0 ; -G net0"
|
||||
BOOTPROTO=dhcp
|
||||
DEFROUTE=yes
|
||||
IPV4_FAILURE_FATAL=no
|
||||
|
|
|
|||
|
|
@ -10364,35 +10364,48 @@ test_ethtool_names (void)
|
|||
{ NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse" },
|
||||
{ NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert" },
|
||||
};
|
||||
const struct {
|
||||
guint nm_ethtool_id_first;
|
||||
guint nm_ethtool_id_last;
|
||||
} s_idxs[] = {
|
||||
{ _NM_ETHTOOL_ID_FEATURE_FIRST, _NM_ETHTOOL_ID_FEATURE_LAST },
|
||||
{ _NM_ETHTOOL_ID_COALESCE_FIRST, _NM_ETHTOOL_ID_COALESCE_LAST },
|
||||
{ _NM_ETHTOOL_ID_RING_FIRST, _NM_ETHTOOL_ID_RING_LAST },
|
||||
};
|
||||
const NMEthtoolData *data;
|
||||
NMEthtoolID id;
|
||||
int i;
|
||||
guint i, k;
|
||||
|
||||
for (id = _NM_ETHTOOL_ID_FIRST; id <= _NM_ETHTOOL_ID_LAST; id++) {
|
||||
const char *ifcfg_rh_name;
|
||||
for (k = 0; k < sizeof(s_idxs) / sizeof(*s_idxs); ++k) {
|
||||
for (id = s_idxs[k].nm_ethtool_id_first; id <= s_idxs[k].nm_ethtool_id_last; id++) {
|
||||
const char *ifcfg_rh_name;
|
||||
|
||||
g_assert (id >= 0);
|
||||
g_assert (id < G_N_ELEMENTS (_nm_ethtool_ifcfg_names));
|
||||
ifcfg_rh_name = _nm_ethtool_ifcfg_names[id];
|
||||
g_assert (ifcfg_rh_name && ifcfg_rh_name[0]);
|
||||
g_assert (id >= 0);
|
||||
g_assert (id < G_N_ELEMENTS (_nm_ethtool_ifcfg_names));
|
||||
ifcfg_rh_name = _nm_ethtool_ifcfg_names[id];
|
||||
g_assert (ifcfg_rh_name && ifcfg_rh_name[0]);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (_nm_ethtool_ifcfg_names); i++) {
|
||||
if (i != id)
|
||||
g_assert_cmpstr (ifcfg_rh_name, !=, _nm_ethtool_ifcfg_names[i]);
|
||||
for (i = s_idxs[k].nm_ethtool_id_first; i < s_idxs[k].nm_ethtool_id_last; i++) {
|
||||
if (i != id)
|
||||
g_assert_cmpstr (ifcfg_rh_name, !=, _nm_ethtool_ifcfg_names[i]);
|
||||
}
|
||||
|
||||
g_assert_cmpstr (nms_ifcfg_rh_utils_get_ethtool_name (id), ==, ifcfg_rh_name);
|
||||
|
||||
data = nms_ifcfg_rh_utils_get_ethtool_by_name (ifcfg_rh_name, nm_ethtool_id_to_type (id));
|
||||
|
||||
g_assert (data);
|
||||
g_assert (data->id == id);
|
||||
}
|
||||
|
||||
g_assert_cmpstr (nms_ifcfg_rh_utils_get_ethtool_name (id), ==, ifcfg_rh_name);
|
||||
|
||||
data = nms_ifcfg_rh_utils_get_ethtool_by_name (ifcfg_rh_name);
|
||||
g_assert (data);
|
||||
g_assert (data->id == id);
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (kernel_names); i++) {
|
||||
const char *name = kernel_names[i].kernel_name;
|
||||
|
||||
id = kernel_names[i].ethtool_id;
|
||||
data = nms_ifcfg_rh_utils_get_ethtool_by_name (name);
|
||||
|
||||
data = nms_ifcfg_rh_utils_get_ethtool_by_name (name, nm_ethtool_id_to_type (id));
|
||||
|
||||
g_assert (data);
|
||||
g_assert (data->id == id);
|
||||
g_assert_cmpstr (nms_ifcfg_rh_utils_get_ethtool_name (id), !=, name);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue