diff options
author | Antonio Cardace <acardace@redhat.com> | 2020-05-14 17:55:17 +0200 |
---|---|---|
committer | Antonio Cardace <acardace@redhat.com> | 2020-05-20 10:55:01 +0200 |
commit | e04e5a5c2a338b9946fbbfd09c957d84681eee35 (patch) | |
tree | bb4886378cd401ef6bc508737c182d6b95444298 | |
parent | 7109ac667ac4587eb94ee50173ea8768cd83a2fb (diff) | |
download | NetworkManager-e04e5a5c2a338b9946fbbfd09c957d84681eee35.tar.gz |
ifcfg-rh: add support for ethtool ring settings
Also update unit tests.
https://bugzilla.redhat.com/show_bug.cgi?id=1614700
8 files changed, 306 insertions, 122 deletions
diff --git a/shared/nm-libnm-core-intern/nm-ethtool-utils.c b/shared/nm-libnm-core-intern/nm-ethtool-utils.c index 340dd5bfa1..3e3c28d36a 100644 --- a/shared/nm-libnm-core-intern/nm-ethtool-utils.c +++ b/shared/nm-libnm-core-intern/nm-ethtool-utils.c @@ -261,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; +} diff --git a/shared/nm-libnm-core-intern/nm-ethtool-utils.h b/shared/nm-libnm-core-intern/nm-ethtool-utils.h index 6ee4eb6d86..0df3d3d00c 100644 --- a/shared/nm-libnm-core-intern/nm-ethtool-utils.h +++ b/shared/nm-libnm-core-intern/nm-ethtool-utils.h @@ -108,6 +108,13 @@ typedef enum { _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; @@ -117,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 @@ -145,6 +154,7 @@ 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__ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 11754e70fa..b0befd88da 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -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 (!*out_s_ethtool) - *out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); + if (words[0]) + ethtool_type = _get_ethtool_type_by_name (words[0]); - 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 (ethtool_type != NM_ETHTOOL_TYPE_UNKNOWN) { + if (!words[1]) { + /* first argument must be the interface name. This is invalid. */ + return; + } - if (nm_streq0 (opt_val, "on")) - onoff = NM_TERNARY_TRUE; - else if (nm_streq0 (opt_val, "off")) - onoff = NM_TERNARY_FALSE; + if (!*out_s_ethtool) + *out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); - d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt); + /* skip ethtool type && interface name */ + w_iter = &words[2]; - 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++; - } + if (ethtool_type == NM_ETHTOOL_TYPE_FEATURE) { + while (w_iter && *w_iter) { + w_iter = _next_ethtool_options_nmternary (w_iter, + ethtool_type, + &ifcfg_option); - /* 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 (ifcfg_option.has_value) + nm_setting_ethtool_set_feature (*out_s_ethtool, + ifcfg_option.optname, + ifcfg_option.v.nmternary); } - - 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; + 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); } - - nm_setting_ethtool_set_coalesce (*out_s_ethtool, - d->optname, - (guint32) i64); } + return; } - return; + /* unsupported ethtool type */ + nm_assert_not_reached(); } /* /sbin/ethtool -s ${REALDEVICE} $opts */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index 08700a8a2f..ccaec401ea 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -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; diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index ed41a3eab0..b6d19e8403 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -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_ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 64fdd8b182..aaa330685d 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -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) { diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected index 39fdce8683..644fa06754 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected @@ -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 diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 34d4061b1a..a028d5281f 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -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); + 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); + 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); + } } 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); |