From 98a89a05ecf2a005073fda97cf933ad69bec11e0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 14 May 2021 13:07:56 +0200 Subject: [PATCH] core: explicitly disable ethtool.pause-autoneg when setting pause-rx/pause-tx Kernel will coerce values like ethtool -A eth0 autoneg on rx off to have autonet still on. Also, if autoneg on the interface is enabled, then `ethtool -A eth0 tx off` has no effect. In NetworkManager, the user cannot configure "autoneg on" together with any rx/tx settings. That would render the profile invalid. However, we also need to take care that a profile nmcli connection add ... ethtool.pause-autoneg ignore ethtool.pause-tx off really means off. That means, we must coerce an unspecified autoneg setting to "off". --- src/core/devices/nm-device.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 92f37f2f52..ca1b56b2ad 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -2174,7 +2174,10 @@ _ethtool_pause_set(NMDevice * self, GHashTableIter iter; const char * name; GVariant * variant; - gboolean has_old = FALSE; + gboolean has_old = FALSE; + NMTernary pause_autoneg = NM_TERNARY_DEFAULT; + NMTernary pause_rx = NM_TERNARY_DEFAULT; + NMTernary pause_tx = NM_TERNARY_DEFAULT; nm_assert(NM_IS_DEVICE(self)); nm_assert(NM_IS_PLATFORM(platform)); @@ -2202,19 +2205,18 @@ _ethtool_pause_set(NMDevice * self, "existing setting)"); return; } - has_old = TRUE; - pause_new = pause_old; + has_old = TRUE; } switch (ethtool_id) { case NM_ETHTOOL_ID_PAUSE_AUTONEG: - pause_new.autoneg = g_variant_get_boolean(variant); + pause_autoneg = g_variant_get_boolean(variant); break; case NM_ETHTOOL_ID_PAUSE_RX: - pause_new.rx = g_variant_get_boolean(variant); + pause_rx = g_variant_get_boolean(variant); break; case NM_ETHTOOL_ID_PAUSE_TX: - pause_new.tx = g_variant_get_boolean(variant); + pause_tx = g_variant_get_boolean(variant); break; default: nm_assert_not_reached(); @@ -2224,6 +2226,20 @@ _ethtool_pause_set(NMDevice * self, if (!has_old) return; + if (pause_rx != NM_TERNARY_DEFAULT || pause_tx != NM_TERNARY_DEFAULT) { + /* this implies to explicitly disable autoneg. */ + nm_assert(pause_autoneg != NM_TERNARY_TRUE); + pause_autoneg = NM_TERNARY_FALSE; + } + + pause_new = pause_old; + if (pause_autoneg != NM_TERNARY_DEFAULT) + pause_new.autoneg = !!pause_autoneg; + if (pause_rx != NM_TERNARY_DEFAULT) + pause_new.rx = !!pause_rx; + if (pause_tx != NM_TERNARY_DEFAULT) + pause_new.tx = !!pause_tx; + ethtool_state->pause = nm_memdup(&pause_old, sizeof(pause_old)); if (!nm_platform_ethtool_set_pause(platform, ethtool_state->ifindex, &pause_new)) {