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".
This commit is contained in:
Thomas Haller
2021-05-14 13:07:56 +02:00
parent dfc5667603
commit 98a89a05ec

View File

@@ -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)) {