summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Cardace <acardace@redhat.com>2020-05-14 17:55:17 +0200
committerAntonio Cardace <acardace@redhat.com>2020-05-20 10:55:01 +0200
commite04e5a5c2a338b9946fbbfd09c957d84681eee35 (patch)
treebb4886378cd401ef6bc508737c182d6b95444298
parent7109ac667ac4587eb94ee50173ea8768cd83a2fb (diff)
downloadNetworkManager-e04e5a5c2a338b9946fbbfd09c957d84681eee35.tar.gz
ifcfg-rh: add support for ethtool ring settings
Also update unit tests. https://bugzilla.redhat.com/show_bug.cgi?id=1614700
-rw-r--r--shared/nm-libnm-core-intern/nm-ethtool-utils.c13
-rw-r--r--shared/nm-libnm-core-intern/nm-ethtool-utils.h10
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c249
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c89
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h3
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c17
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c45
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);