diff options
author | Michal Kubecek <mkubecek@suse.cz> | 2020-02-15 01:55:53 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-02-17 04:28:51 +0100 |
commit | 6699170376ab941c1cc5c3bcefa766efc3575c73 (patch) | |
tree | cc0121d1083e0192a0e0b32b49f6ae6a68756af9 | |
parent | net: dsa: b53: Ensure the default VID is untagged (diff) | |
download | linux-6699170376ab941c1cc5c3bcefa766efc3575c73.tar.xz linux-6699170376ab941c1cc5c3bcefa766efc3575c73.zip |
ethtool: fix application of verbose no_mask bitset
A bitset without mask in a _SET request means we want exactly the bits in
the bitset to be set. This works correctly for compact format but when
verbose format is parsed, ethnl_update_bitset32_verbose() only sets the
bits present in the request bitset but does not clear the rest. This can
cause incorrect results like
lion:~ # ethtool eth0 | grep Wake
Supports Wake-on: pumbg
Wake-on: g
lion:~ # ethtool -s eth0 wol u
lion:~ # ethtool eth0 | grep Wake
Supports Wake-on: pumbg
Wake-on: ug
when the second ethtool command issues request
ETHTOOL_MSG_WOL_SET
ETHTOOL_A_WOL_HEADER
ETHTOOL_A_HEADER_DEV_NAME = "eth0"
ETHTOOL_A_WOL_MODES
ETHTOOL_A_BITSET_NOMASK
ETHTOOL_A_BITSET_BITS
ETHTOOL_A_BITSET_BITS_BIT
ETHTOOL_BITSET_BIT_INDEX = 1
Fix the logic by clearing the whole target bitmap before we start iterating
through the request bits.
Fixes: 10b518d4e6dd ("ethtool: netlink bitset handling")
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ethtool/bitset.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/net/ethtool/bitset.c b/net/ethtool/bitset.c index fce45dac4205..8977fe1f3946 100644 --- a/net/ethtool/bitset.c +++ b/net/ethtool/bitset.c @@ -447,7 +447,10 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, "mask only allowed in compact bitset"); return -EINVAL; } + no_mask = tb[ETHTOOL_A_BITSET_NOMASK]; + if (no_mask) + ethnl_bitmap32_clear(bitmap, 0, nbits, mod); nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) { bool old_val, new_val; |