Commit 0df55a03 authored by David S. Miller's avatar David S. Miller

Merge branch 'ethtool-netlink-bug-fixes'

Maxim Mikityanskiy says:

====================
ethtool-netlink bug fixes

This series contains a few bug fixes for ethtool-netlink. These bugs are
specific for the netlink interface, and the legacy ioctl interface is
not affected. These patches aim to have the same behavior in
ethtool-netlink as in the legacy ethtool.

Please also see the sibling series for the userspace tool.

v2 changes: Added Fixes tags.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4ef1a7cb f01204ec
...@@ -224,7 +224,9 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info) ...@@ -224,7 +224,9 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
DECLARE_BITMAP(wanted_diff_mask, NETDEV_FEATURE_COUNT); DECLARE_BITMAP(wanted_diff_mask, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(active_diff_mask, NETDEV_FEATURE_COUNT); DECLARE_BITMAP(active_diff_mask, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(old_active, NETDEV_FEATURE_COUNT); DECLARE_BITMAP(old_active, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(old_wanted, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(new_active, NETDEV_FEATURE_COUNT); DECLARE_BITMAP(new_active, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(new_wanted, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(req_wanted, NETDEV_FEATURE_COUNT); DECLARE_BITMAP(req_wanted, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(req_mask, NETDEV_FEATURE_COUNT); DECLARE_BITMAP(req_mask, NETDEV_FEATURE_COUNT);
struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1]; struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1];
...@@ -250,6 +252,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info) ...@@ -250,6 +252,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
rtnl_lock(); rtnl_lock();
ethnl_features_to_bitmap(old_active, dev->features); ethnl_features_to_bitmap(old_active, dev->features);
ethnl_features_to_bitmap(old_wanted, dev->wanted_features);
ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT, ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
tb[ETHTOOL_A_FEATURES_WANTED], tb[ETHTOOL_A_FEATURES_WANTED],
netdev_features_strings, info->extack); netdev_features_strings, info->extack);
...@@ -261,17 +264,15 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info) ...@@ -261,17 +264,15 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
goto out_rtnl; goto out_rtnl;
} }
/* set req_wanted bits not in req_mask from old_active */ /* set req_wanted bits not in req_mask from old_wanted */
bitmap_and(req_wanted, req_wanted, req_mask, NETDEV_FEATURE_COUNT); bitmap_and(req_wanted, req_wanted, req_mask, NETDEV_FEATURE_COUNT);
bitmap_andnot(new_active, old_active, req_mask, NETDEV_FEATURE_COUNT); bitmap_andnot(new_wanted, old_wanted, req_mask, NETDEV_FEATURE_COUNT);
bitmap_or(req_wanted, new_active, req_wanted, NETDEV_FEATURE_COUNT); bitmap_or(req_wanted, new_wanted, req_wanted, NETDEV_FEATURE_COUNT);
if (bitmap_equal(req_wanted, old_active, NETDEV_FEATURE_COUNT)) { if (!bitmap_equal(req_wanted, old_wanted, NETDEV_FEATURE_COUNT)) {
ret = 0; dev->wanted_features &= ~dev->hw_features;
goto out_rtnl; dev->wanted_features |= ethnl_bitmap_to_features(req_wanted) & dev->hw_features;
__netdev_update_features(dev);
} }
dev->wanted_features = ethnl_bitmap_to_features(req_wanted);
__netdev_update_features(dev);
ethnl_features_to_bitmap(new_active, dev->features); ethnl_features_to_bitmap(new_active, dev->features);
mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT); mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment