diff options
author | Íñigo Huguet <inigohuguet@hotmail.com> | 2023-10-18 06:54:00 +0000 |
---|---|---|
committer | Íñigo Huguet <inigohuguet@hotmail.com> | 2023-10-18 06:54:00 +0000 |
commit | 2d956f4d51da2d524cd85164de5e9bf0e65de903 (patch) | |
tree | 9c415d1572cbb7578f009c955015d5f5c2d68d7f | |
parent | 123ca26770306b8fd3fbfd47c3c43a40f7a36cfb (diff) | |
parent | 6c41cb3a582d8281b4cf42fda5c27e763dddf85c (diff) |
merge: branch 'bg/ethtool-channels'
Add ethtool channels support
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1754
-rw-r--r-- | src/core/devices/nm-device.c | 120 | ||||
-rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 13 | ||||
-rw-r--r-- | src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 5 | ||||
-rw-r--r-- | src/libnm-base/nm-base.h | 20 | ||||
-rw-r--r-- | src/libnm-base/nm-ethtool-base.c | 26 | ||||
-rw-r--r-- | src/libnm-base/nm-ethtool-utils-base.h | 5 | ||||
-rw-r--r-- | src/libnm-client-impl/libnm.ver | 1 | ||||
-rw-r--r-- | src/libnm-client-public/nm-ethtool-utils.h | 5 | ||||
-rw-r--r-- | src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in | 16 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-setting-ethtool.c | 16 | ||||
-rw-r--r-- | src/libnm-core-public/nm-setting-ethtool.h | 3 | ||||
-rw-r--r-- | src/libnm-platform/nm-platform-utils.c | 63 | ||||
-rw-r--r-- | src/libnm-platform/nm-platform-utils.h | 4 | ||||
-rw-r--r-- | src/libnm-platform/nm-platform.c | 25 | ||||
-rw-r--r-- | src/libnm-platform/nm-platform.h | 8 | ||||
-rw-r--r-- | src/libnm-platform/nmp-base.h | 11 | ||||
-rw-r--r-- | src/libnmc-setting/nm-meta-setting-desc.c | 73 | ||||
-rw-r--r-- | src/nmcli/gen-metadata-nm-settings-nmcli.c | 25 | ||||
-rw-r--r-- | src/nmcli/gen-metadata-nm-settings-nmcli.xml.in | 12 |
19 files changed, 396 insertions, 55 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 2f7b4f81b8..0ab7d8c922 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -303,6 +303,7 @@ typedef struct { NMEthtoolCoalesceState *coalesce; NMEthtoolRingState *ring; NMEthtoolPauseState *pause; + NMEthtoolChannelsState *channels; } EthtoolState; typedef enum { @@ -2385,6 +2386,8 @@ _ethtool_features_reset(NMDevice *self, NMPlatform *platform, EthtoolState *etht gs_free NMEthtoolFeatureStates *features = NULL; features = g_steal_pointer(ðtool_state->features); + if (!features) + return; if (!nm_platform_ethtool_set_features(platform, ethtool_state->ifindex, @@ -2404,8 +2407,7 @@ _ethtool_features_set(NMDevice *self, { gs_free NMEthtoolFeatureStates *features = NULL; - if (ethtool_state->features) - _ethtool_features_reset(self, platform, ethtool_state); + _ethtool_features_reset(self, platform, ethtool_state); if (nm_setting_ethtool_init_features(s_ethtool, ethtool_state->requested) == 0) return; @@ -2603,6 +2605,104 @@ _ethtool_ring_set(NMDevice *self, } static void +_ethtool_channels_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) +{ + gs_free NMEthtoolChannelsState *channels = NULL; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(ethtool_state); + + channels = g_steal_pointer(ðtool_state->channels); + if (!channels) + return; + + if (!nm_platform_ethtool_set_channels(platform, ethtool_state->ifindex, channels)) + _LOGW(LOGD_DEVICE, "ethtool: failure resetting one or more channels settings"); + else + _LOGD(LOGD_DEVICE, "ethtool: channels settings successfully reset"); +} + +static void +_ethtool_channels_set(NMDevice *self, + NMPlatform *platform, + EthtoolState *ethtool_state, + NMSettingEthtool *s_ethtool) +{ + NMEthtoolChannelsState channels_old; + NMEthtoolChannelsState channels_new; + GHashTable *hash; + GHashTableIter iter; + const char *name; + GVariant *variant; + gboolean has_old = FALSE; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(NM_IS_SETTING_ETHTOOL(s_ethtool)); + nm_assert(ethtool_state); + nm_assert(!ethtool_state->channels); + + hash = _nm_setting_option_hash(NM_SETTING(s_ethtool), FALSE); + if (!hash) + return; + + 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); + guint32 u32; + + if (!nm_ethtool_id_is_channels(ethtool_id)) + continue; + + nm_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)); + + if (!has_old) { + if (!nm_platform_ethtool_get_link_channels(platform, + ethtool_state->ifindex, + &channels_old)) { + _LOGW(LOGD_DEVICE, + "ethtool: failure setting channels options (cannot read existing setting)"); + return; + } + has_old = TRUE; + channels_new = channels_old; + } + + u32 = g_variant_get_uint32(variant); + + switch (ethtool_id) { + case NM_ETHTOOL_ID_CHANNELS_RX: + channels_new.rx = u32; + break; + case NM_ETHTOOL_ID_CHANNELS_TX: + channels_new.tx = u32; + break; + case NM_ETHTOOL_ID_CHANNELS_OTHER: + channels_new.other = u32; + break; + case NM_ETHTOOL_ID_CHANNELS_COMBINED: + channels_new.combined = u32; + break; + default: + nm_assert_not_reached(); + } + } + + if (!has_old) + return; + + ethtool_state->channels = nm_memdup(&channels_old, sizeof(channels_old)); + + if (!nm_platform_ethtool_set_channels(platform, ethtool_state->ifindex, &channels_new)) { + _LOGW(LOGD_DEVICE, "ethtool: failure setting channels settings"); + return; + } + + _LOGD(LOGD_DEVICE, "ethtool: channels settings successfully set"); +} + +static void _ethtool_pause_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) { gs_free NMEthtoolPauseState *pause = NULL; @@ -2719,14 +2819,11 @@ _ethtool_state_reset(NMDevice *self) if (!ethtool_state) return; - if (ethtool_state->features) - _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); - if (ethtool_state->pause) - _ethtool_pause_reset(self, platform, ethtool_state); + _ethtool_features_reset(self, platform, ethtool_state); + _ethtool_coalesce_reset(self, platform, ethtool_state); + _ethtool_ring_reset(self, platform, ethtool_state); + _ethtool_pause_reset(self, platform, ethtool_state); + _ethtool_channels_reset(self, platform, ethtool_state); } static void @@ -2761,9 +2858,10 @@ _ethtool_state_set(NMDevice *self) _ethtool_coalesce_set(self, platform, ethtool_state, s_ethtool); _ethtool_ring_set(self, platform, ethtool_state, s_ethtool); _ethtool_pause_set(self, platform, ethtool_state, s_ethtool); + _ethtool_channels_set(self, platform, ethtool_state, s_ethtool); if (ethtool_state->features || ethtool_state->coalesce || ethtool_state->ring - || ethtool_state->pause) + || ethtool_state->pause || ethtool_state->channels) priv->ethtool_state = g_steal_pointer(ðtool_state); } diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 08deaf5abd..516f2fd890 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -1346,6 +1346,7 @@ write_ethtool_setting(NMConnection *connection, shvarFile *ifcfg, GError **error guint32 u32; gboolean b; gboolean any_option = FALSE; + char prop_name[300]; s_con = nm_connection_get_setting_connection(connection); if (s_con) { @@ -1426,6 +1427,18 @@ write_ethtool_setting(NMConnection *connection, shvarFile *ifcfg, GError **error any_option = TRUE; } + is_first = TRUE; + for (ethtool_id = _NM_ETHTOOL_ID_CHANNELS_FIRST; ethtool_id <= _NM_ETHTOOL_ID_CHANNELS_LAST; + ethtool_id++) { + if (nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + nm_ethtool_data[ethtool_id]->optname, + &u32)) { + nm_sprintf_buf(prop_name, "ethtool.%s", nm_ethtool_data[ethtool_id]->optname); + set_error_unsupported(error, connection, prop_name, FALSE); + return FALSE; + } + } + if (!any_option) { /* Write an empty dummy "-A" option without arguments. This is to * ensure that the reader will create an (all default) NMSettingEthtool. diff --git a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 8c1e9d9490..ccfc6ff394 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -3623,6 +3623,11 @@ test_roundtrip_ethtool(void) optname = nm_ethtool_data[ethtool_id]->optname; vtype = nm_ethtool_id_get_variant_type(ethtool_id); + if (nm_ethtool_optname_is_channels(optname)) { + /* Not supported */ + continue; + } + if (NM_IN_SET(ethtool_id, NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX, NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX)) { diff --git a/src/libnm-base/nm-base.h b/src/libnm-base/nm-base.h index 54d5e9e904..88acbcc5b2 100644 --- a/src/libnm-base/nm-base.h +++ b/src/libnm-base/nm-base.h @@ -124,14 +124,23 @@ typedef enum { 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_CHANNELS_FIRST = _NM_ETHTOOL_ID_RING_LAST + 1, + NM_ETHTOOL_ID_CHANNELS_RX = _NM_ETHTOOL_ID_CHANNELS_FIRST, + NM_ETHTOOL_ID_CHANNELS_TX, + NM_ETHTOOL_ID_CHANNELS_OTHER, + NM_ETHTOOL_ID_CHANNELS_COMBINED, + _NM_ETHTOOL_ID_CHANNELS_LAST = NM_ETHTOOL_ID_CHANNELS_COMBINED, + + _NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_CHANNELS_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_PAUSE_NUM = (_NM_ETHTOOL_ID_PAUSE_LAST - _NM_ETHTOOL_ID_PAUSE_FIRST + 1), - _NM_ETHTOOL_ID_NUM = (_NM_ETHTOOL_ID_LAST - _NM_ETHTOOL_ID_FIRST + 1), + _NM_ETHTOOL_ID_CHANNELS_NUM = + (_NM_ETHTOOL_ID_CHANNELS_LAST - _NM_ETHTOOL_ID_CHANNELS_FIRST + 1), + _NM_ETHTOOL_ID_NUM = (_NM_ETHTOOL_ID_LAST - _NM_ETHTOOL_ID_FIRST + 1), } NMEthtoolID; #define _NM_ETHTOOL_ID_FEATURE_AS_IDX(ethtool_id) ((ethtool_id) -_NM_ETHTOOL_ID_FEATURE_FIRST) @@ -143,6 +152,7 @@ typedef enum { NM_ETHTOOL_TYPE_FEATURE, NM_ETHTOOL_TYPE_RING, NM_ETHTOOL_TYPE_PAUSE, + NM_ETHTOOL_TYPE_CHANNELS, } NMEthtoolType; /****************************************************************************/ @@ -171,6 +181,12 @@ nm_ethtool_id_is_pause(NMEthtoolID id) return id >= _NM_ETHTOOL_ID_PAUSE_FIRST && id <= _NM_ETHTOOL_ID_PAUSE_LAST; } +static inline gboolean +nm_ethtool_id_is_channels(NMEthtoolID id) +{ + return id >= _NM_ETHTOOL_ID_CHANNELS_FIRST && id <= _NM_ETHTOOL_ID_CHANNELS_LAST; +} + /*****************************************************************************/ typedef enum { diff --git a/src/libnm-base/nm-ethtool-base.c b/src/libnm-base/nm-ethtool-base.c index c31cff6f53..25b12cda32 100644 --- a/src/libnm-base/nm-ethtool-base.c +++ b/src/libnm-base/nm-ethtool-base.c @@ -106,11 +106,19 @@ const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = { ETHT_DATA(RING_RX_JUMBO), ETHT_DATA(RING_RX_MINI), ETHT_DATA(RING_TX), + ETHT_DATA(CHANNELS_RX), + ETHT_DATA(CHANNELS_TX), + ETHT_DATA(CHANNELS_OTHER), + ETHT_DATA(CHANNELS_COMBINED), [_NM_ETHTOOL_ID_NUM] = NULL, }; static const guint8 _by_name[_NM_ETHTOOL_ID_NUM] = { /* sorted by optname. */ + NM_ETHTOOL_ID_CHANNELS_COMBINED, + NM_ETHTOOL_ID_CHANNELS_OTHER, + NM_ETHTOOL_ID_CHANNELS_RX, + NM_ETHTOOL_ID_CHANNELS_TX, NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX, NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX, NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH, @@ -291,6 +299,8 @@ nm_ethtool_id_to_type(NMEthtoolID id) return NM_ETHTOOL_TYPE_RING; if (nm_ethtool_id_is_pause(id)) return NM_ETHTOOL_TYPE_PAUSE; + if (nm_ethtool_id_is_channels(id)) + return NM_ETHTOOL_TYPE_CHANNELS; return NM_ETHTOOL_TYPE_UNKNOWN; } @@ -298,11 +308,17 @@ nm_ethtool_id_to_type(NMEthtoolID id) const GVariantType * nm_ethtool_id_get_variant_type(NMEthtoolID ethtool_id) { - if (nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id)) + switch (nm_ethtool_id_to_type(ethtool_id)) { + case NM_ETHTOOL_TYPE_FEATURE: + case NM_ETHTOOL_TYPE_PAUSE: return G_VARIANT_TYPE_BOOLEAN; - - if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) + case NM_ETHTOOL_TYPE_CHANNELS: + case NM_ETHTOOL_TYPE_COALESCE: + case NM_ETHTOOL_TYPE_RING: return G_VARIANT_TYPE_UINT32; - - return NULL; + case NM_ETHTOOL_TYPE_UNKNOWN: + nm_assert(ethtool_id == NM_ETHTOOL_ID_UNKNOWN); + return NULL; + } + return nm_assert_unreachable_val(NULL); } diff --git a/src/libnm-base/nm-ethtool-utils-base.h b/src/libnm-base/nm-ethtool-utils-base.h index fa9c30715d..80c640df39 100644 --- a/src/libnm-base/nm-ethtool-utils-base.h +++ b/src/libnm-base/nm-ethtool-utils-base.h @@ -104,6 +104,11 @@ G_BEGIN_DECLS #define NM_ETHTOOL_OPTNAME_PAUSE_RX "pause-rx" #define NM_ETHTOOL_OPTNAME_PAUSE_TX "pause-tx" +#define NM_ETHTOOL_OPTNAME_CHANNELS_RX "channels-rx" +#define NM_ETHTOOL_OPTNAME_CHANNELS_TX "channels-tx" +#define NM_ETHTOOL_OPTNAME_CHANNELS_OTHER "channels-other" +#define NM_ETHTOOL_OPTNAME_CHANNELS_COMBINED "channels-combined" + /*****************************************************************************/ G_END_DECLS diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index acbfb4a6e6..aeb51d3c26 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -1947,4 +1947,5 @@ global: libnm_1_46_0 { global: nm_access_point_get_bandwidth; + nm_ethtool_optname_is_channels; } libnm_1_44_0; diff --git a/src/libnm-client-public/nm-ethtool-utils.h b/src/libnm-client-public/nm-ethtool-utils.h index fa9c30715d..80c640df39 100644 --- a/src/libnm-client-public/nm-ethtool-utils.h +++ b/src/libnm-client-public/nm-ethtool-utils.h @@ -104,6 +104,11 @@ G_BEGIN_DECLS #define NM_ETHTOOL_OPTNAME_PAUSE_RX "pause-rx" #define NM_ETHTOOL_OPTNAME_PAUSE_TX "pause-tx" +#define NM_ETHTOOL_OPTNAME_CHANNELS_RX "channels-rx" +#define NM_ETHTOOL_OPTNAME_CHANNELS_TX "channels-tx" +#define NM_ETHTOOL_OPTNAME_CHANNELS_OTHER "channels-other" +#define NM_ETHTOOL_OPTNAME_CHANNELS_COMBINED "channels-combined" + /*****************************************************************************/ G_END_DECLS diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in index 4e17a45baa..d84c6c6e3d 100644 --- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in +++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in @@ -1292,6 +1292,22 @@ dbus-type="u" is-setting-option="1" /> + <property name="channels-rx" + dbus-type="u" + is-setting-option="1" + /> + <property name="channels-tx" + dbus-type="u" + is-setting-option="1" + /> + <property name="channels-other" + dbus-type="u" + is-setting-option="1" + /> + <property name="channels-combined" + dbus-type="u" + is-setting-option="1" + /> </setting> <setting name="generic" gtype="NMSettingGeneric" diff --git a/src/libnm-core-impl/nm-setting-ethtool.c b/src/libnm-core-impl/nm-setting-ethtool.c index ab1ed0e2b6..138e86c02e 100644 --- a/src/libnm-core-impl/nm-setting-ethtool.c +++ b/src/libnm-core-impl/nm-setting-ethtool.c @@ -76,6 +76,22 @@ nm_ethtool_optname_is_ring(const char *optname) } /** + * nm_ethtool_optname_is_channels: + * @optname: (nullable): the option name to check + * + * Checks whether @optname is a valid option name for a channels setting. + * + * Returns: %TRUE, if @optname is valid + * + * Since: 1.46 + */ +gboolean +nm_ethtool_optname_is_channels(const char *optname) +{ + return optname && nm_ethtool_id_is_channels(nm_ethtool_id_get_by_name(optname)); +} + +/** * nm_ethtool_optname_is_pause: * @optname: (nullable): the option name to check * diff --git a/src/libnm-core-public/nm-setting-ethtool.h b/src/libnm-core-public/nm-setting-ethtool.h index 698dcebe27..47db2573b7 100644 --- a/src/libnm-core-public/nm-setting-ethtool.h +++ b/src/libnm-core-public/nm-setting-ethtool.h @@ -26,6 +26,9 @@ gboolean nm_ethtool_optname_is_ring(const char *optname); NM_AVAILABLE_IN_1_32 gboolean nm_ethtool_optname_is_pause(const char *optname); +NM_AVAILABLE_IN_1_46 +gboolean nm_ethtool_optname_is_channels(const char *optname); + /*****************************************************************************/ #define NM_TYPE_SETTING_ETHTOOL (nm_setting_ethtool_get_type()) diff --git a/src/libnm-platform/nm-platform-utils.c b/src/libnm-platform/nm-platform-utils.c index 08d82fe87a..32c4732d3d 100644 --- a/src/libnm-platform/nm-platform-utils.c +++ b/src/libnm-platform/nm-platform-utils.c @@ -1068,6 +1068,69 @@ nmp_utils_ethtool_set_ring(int ifindex, const NMEthtoolRingState *ring) } gboolean +nmp_utils_ethtool_get_channels(int ifindex, NMEthtoolChannelsState *channels) +{ + struct ethtool_channels eth_data; + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(channels, FALSE); + + eth_data.cmd = ETHTOOL_GCHANNELS; + + if (_ethtool_call_once(ifindex, ð_data, sizeof(eth_data)) < 0) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: failure getting channels settings", + ifindex, + "get-channels"); + return FALSE; + } + + *channels = (NMEthtoolChannelsState){ + .rx = eth_data.rx_count, + .tx = eth_data.tx_count, + .other = eth_data.other_count, + .combined = eth_data.combined_count, + }; + + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: retrieved kernel channels settings", + ifindex, + "get-channels"); + return TRUE; +} + +gboolean +nmp_utils_ethtool_set_channels(int ifindex, const NMEthtoolChannelsState *channels) +{ + struct ethtool_channels eth_data; + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(channels, FALSE); + + eth_data = (struct ethtool_channels){ + .cmd = ETHTOOL_SCHANNELS, + .rx_count = channels->rx, + .tx_count = channels->tx, + .other_count = channels->other, + .combined_count = channels->combined, + }; + + if (_ethtool_call_once(ifindex, ð_data, sizeof(eth_data)) < 0) { + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: failure setting channels settings", + ifindex, + "set-channels"); + return FALSE; + } + + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %s: set kernel channels settings", + ifindex, + "set-channels"); + return TRUE; +} + +gboolean nmp_utils_ethtool_get_pause(int ifindex, NMEthtoolPauseState *pause) { struct ethtool_pauseparam eth_data; diff --git a/src/libnm-platform/nm-platform-utils.h b/src/libnm-platform/nm-platform-utils.h index 14b09a793e..815d165431 100644 --- a/src/libnm-platform/nm-platform-utils.h +++ b/src/libnm-platform/nm-platform-utils.h @@ -54,6 +54,10 @@ gboolean nmp_utils_ethtool_get_ring(int ifindex, NMEthtoolRingState *ring); gboolean nmp_utils_ethtool_set_ring(int ifindex, const NMEthtoolRingState *ring); +gboolean nmp_utils_ethtool_get_channels(int ifindex, NMEthtoolChannelsState *channels); + +gboolean nmp_utils_ethtool_set_channels(int ifindex, const NMEthtoolChannelsState *channels); + gboolean nmp_utils_ethtool_get_pause(int ifindex, NMEthtoolPauseState *pause); gboolean nmp_utils_ethtool_set_pause(int ifindex, const NMEthtoolPauseState *pause); diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 7bd9de4121..1b513d34be 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -3581,6 +3581,31 @@ nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingS } gboolean +nm_platform_ethtool_get_link_channels(NMPlatform *self, + int ifindex, + NMEthtoolChannelsState *channels) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(channels, FALSE); + + return nmp_utils_ethtool_get_channels(ifindex, channels); +} + +gboolean +nm_platform_ethtool_set_channels(NMPlatform *self, + int ifindex, + const NMEthtoolChannelsState *channels) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_set_channels(ifindex, channels); +} + +gboolean nm_platform_ethtool_get_link_pause(NMPlatform *self, int ifindex, NMEthtoolPauseState *pause) { _CHECK_SELF_NETNS(self, klass, netns, FALSE); diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 6ad0d15bd0..bc5bc5e8b4 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -2567,6 +2567,14 @@ gboolean nm_platform_ethtool_get_link_ring(NMPlatform *self, int ifindex, NMEtht gboolean nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingState *ring); +gboolean nm_platform_ethtool_get_link_channels(NMPlatform *self, + int ifindex, + NMEthtoolChannelsState *channels); + +gboolean nm_platform_ethtool_set_channels(NMPlatform *self, + int ifindex, + const NMEthtoolChannelsState *channels); + gboolean nm_platform_ethtool_get_link_pause(NMPlatform *self, int ifindex, NMEthtoolPauseState *pause); diff --git a/src/libnm-platform/nmp-base.h b/src/libnm-platform/nmp-base.h index ffe5936300..eeaad024a0 100644 --- a/src/libnm-platform/nmp-base.h +++ b/src/libnm-platform/nmp-base.h @@ -93,16 +93,12 @@ typedef struct { const NMEthtoolFeatureState states_list[]; } NMEthtoolFeatureStates; -/*****************************************************************************/ - typedef struct { guint32 s[_NM_ETHTOOL_ID_COALESCE_NUM /* indexed by (NMEthtoolID - _NM_ETHTOOL_ID_COALESCE_FIRST) */ ]; } NMEthtoolCoalesceState; -/*****************************************************************************/ - typedef struct { guint32 rx_pending; guint32 rx_mini_pending; @@ -116,6 +112,13 @@ typedef struct { bool tx : 1; } NMEthtoolPauseState; +typedef struct { + guint32 rx; + guint32 tx; + guint32 other; + guint32 combined; +} NMEthtoolChannelsState; + /*****************************************************************************/ typedef struct _NMPNetns NMPNetns; diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c index 4a6626d039..18bd407768 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.c +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -4421,26 +4421,32 @@ _get_fcn_ethtool(ARGS_GET_FCN) RETURN_UNSUPPORTED_GET_TYPE(); - if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) { + switch (nm_ethtool_id_to_type(ethtool_id)) { + case NM_ETHTOOL_TYPE_CHANNELS: + case NM_ETHTOOL_TYPE_COALESCE: + case NM_ETHTOOL_TYPE_RING: if (!nm_setting_option_get_uint32(setting, nm_ethtool_data[ethtool_id]->optname, &u32)) { NM_SET_OUT(out_is_default, TRUE); return NULL; } RETURN_STR_TO_FREE(nm_strdup_int(u32)); - } - - nm_assert(nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id)); + case NM_ETHTOOL_TYPE_FEATURE: + case NM_ETHTOOL_TYPE_PAUSE: + if (!nm_setting_option_get_boolean(setting, nm_ethtool_data[ethtool_id]->optname, &b)) { + NM_SET_OUT(out_is_default, TRUE); + return NULL; + } - if (!nm_setting_option_get_boolean(setting, nm_ethtool_data[ethtool_id]->optname, &b)) { - NM_SET_OUT(out_is_default, TRUE); - return NULL; + s = b ? N_("on") : N_("off"); + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + s = gettext(s); + return s; + case NM_ETHTOOL_TYPE_UNKNOWN: + nm_assert_not_reached(); } - s = b ? N_("on") : N_("off"); - if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) - s = gettext(s); - return s; + return NULL; } static gboolean @@ -4453,7 +4459,10 @@ _set_fcn_ethtool(ARGS_SET_FCN) if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) goto do_unset; - if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) { + switch (nm_ethtool_id_to_type(ethtool_id)) { + case NM_ETHTOOL_TYPE_CHANNELS: + case NM_ETHTOOL_TYPE_COALESCE: + case NM_ETHTOOL_TYPE_RING: i64 = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT32, -1); if (i64 == -1) { nm_utils_error_set( @@ -4468,25 +4477,27 @@ _set_fcn_ethtool(ARGS_SET_FCN) nm_setting_option_set_uint32(setting, nm_ethtool_data[ethtool_id]->optname, i64); return TRUE; - } - - nm_assert(nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id)); + case NM_ETHTOOL_TYPE_FEATURE: + case NM_ETHTOOL_TYPE_PAUSE: + if (!nmc_string_to_ternary_full(value, + NMC_STRING_TO_TERNARY_FLAGS_IGNORE_FOR_DEFAULT, + &t, + NULL)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is not valid; use 'on', 'off', or 'ignore'"), + value); + return FALSE; + } + if (t == NM_TERNARY_DEFAULT) + goto do_unset; - if (!nmc_string_to_ternary_full(value, - NMC_STRING_TO_TERNARY_FLAGS_IGNORE_FOR_DEFAULT, - &t, - NULL)) { - nm_utils_error_set(error, - NM_UTILS_ERROR_INVALID_ARGUMENT, - _("'%s' is not valid; use 'on', 'off', or 'ignore'"), - value); - return FALSE; + nm_setting_option_set_boolean(setting, nm_ethtool_data[ethtool_id]->optname, !!t); + return TRUE; + case NM_ETHTOOL_TYPE_UNKNOWN: + nm_assert_not_reached(); } - if (t == NM_TERNARY_DEFAULT) - goto do_unset; - - nm_setting_option_set_boolean(setting, nm_ethtool_data[ethtool_id]->optname, !!t); - return TRUE; + return FALSE; do_unset: nm_setting_option_set(setting, nm_ethtool_data[ethtool_id]->optname, NULL); @@ -5919,6 +5930,10 @@ static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = { PROPERTY_INFO_ETHTOOL (RING_RX_JUMBO), PROPERTY_INFO_ETHTOOL (RING_RX_MINI), PROPERTY_INFO_ETHTOOL (RING_TX), + PROPERTY_INFO_ETHTOOL (CHANNELS_RX), + PROPERTY_INFO_ETHTOOL (CHANNELS_TX), + PROPERTY_INFO_ETHTOOL (CHANNELS_OTHER), + PROPERTY_INFO_ETHTOOL (CHANNELS_COMBINED), NULL, }; diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.c b/src/nmcli/gen-metadata-nm-settings-nmcli.c index f29c91805c..f8dc303628 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.c +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.c @@ -111,10 +111,18 @@ get_ethtool_format(const NMMetaPropertyInfo *prop_info) ethtool_id = prop_info->property_typ_data->subtype.ethtool.ethtool_id; - if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) + switch (nm_ethtool_id_to_type(ethtool_id)) { + case NM_ETHTOOL_TYPE_CHANNELS: + case NM_ETHTOOL_TYPE_COALESCE: + case NM_ETHTOOL_TYPE_RING: return g_strdup("integer"); - else if (nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id)) + case NM_ETHTOOL_TYPE_FEATURE: + case NM_ETHTOOL_TYPE_PAUSE: return g_strdup("ternary"); + case NM_ETHTOOL_TYPE_UNKNOWN: + nm_assert_not_reached(); + }; + return NULL; } @@ -301,10 +309,19 @@ append_ethtool_valid_values(const NMMetaPropertyInfo *prop_info, GPtrArray *vali ethtool_id = prop_info->property_typ_data->subtype.ethtool.ethtool_id; - if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) + switch (nm_ethtool_id_to_type(ethtool_id)) { + case NM_ETHTOOL_TYPE_CHANNELS: + case NM_ETHTOOL_TYPE_COALESCE: + case NM_ETHTOOL_TYPE_RING: g_ptr_array_add(valid_values, g_strdup_printf("0 - %u", G_MAXUINT32)); - else if (nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id)) + break; + case NM_ETHTOOL_TYPE_FEATURE: + case NM_ETHTOOL_TYPE_PAUSE: append_vals(valid_values, "on", "off", "ignore"); + break; + case NM_ETHTOOL_TYPE_UNKNOWN: + nm_assert_not_reached(); + } } static void diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in index e61897e9d9..82304a409a 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in @@ -1040,6 +1040,18 @@ <property name="ring-tx" format="integer" values="0 - 4294967295" /> + <property name="channels-rx" + format="integer" + values="0 - 4294967295" /> + <property name="channels-tx" + format="integer" + values="0 - 4294967295" /> + <property name="channels-other" + format="integer" + values="0 - 4294967295" /> + <property name="channels-combined" + format="integer" + values="0 - 4294967295" /> </setting> <setting name="generic" > </setting> |