From: Michal Kubecek <mkubecek@suse.cz>
To: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Jiri Pirko <jiri@resnulli.us>,
David Miller <davem@davemloft.net>,
Florian Fainelli <f.fainelli@gmail.com>,
Roopa Prabhu <roopa@cumulusnetworks.com>,
Jakub Kicinski <kubakici@wp.pl>,
"John W. Linville" <linville@tuxdriver.com>
Subject: [RFC PATCH net-next v2 14/17] ethtool: implement SET_SETTINGS request for features
Date: Mon, 30 Jul 2018 14:53:52 +0200 (CEST) [thread overview]
Message-ID: <1127951c1ac8d2fb6fcb3d6caba6f45bcd74a37d.1532953989.git.mkubecek@suse.cz> (raw)
In-Reply-To: <cover.1532953989.git.mkubecek@suse.cz>
Using ETHNL_SETTINGS_FEATURES attribute, userspace can modify device
features. Actual change is subject to netdev_change_features() sanity
checks so that it can differ from what was requested. Unlike with most
other requests, kernel can reply (if ETHA_FEATURES_WANT_DIFF flag is used)
with a message in the same format but with different semantics: information
about difference between user request and actual result and difference
between old and new state of dev->features.
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
---
Documentation/networking/ethtool-netlink.txt | 30 +++--
include/uapi/linux/ethtool_netlink.h | 1 +
net/ethtool/settings.c | 127 +++++++++++++++++++
3 files changed, 150 insertions(+), 8 deletions(-)
diff --git a/Documentation/networking/ethtool-netlink.txt b/Documentation/networking/ethtool-netlink.txt
index c7fe4f518972..307d8c6c6c85 100644
--- a/Documentation/networking/ethtool-netlink.txt
+++ b/Documentation/networking/ethtool-netlink.txt
@@ -285,6 +285,9 @@ to be passed with SET_SETTINGS request:
ETHA_SETTINGS_SOPASS (binary) SecureOn(tm) password
ETHA_SETTINGS_MSGLVL (bitfield32) debug level
ETHA_SETTINGS_LINK_MODES (bitset) device link modes
+ ETHA_SETTINGS_FEATURES (nested) device features
+ ETHA_FEATURES_WANTED (bitset) wanted features
+ ETHA_FEATURES_WANT_DIFF (flag) actual diff
For both bitfield32 types, value and selector work the usual way, i.e. bits
set in selector are set to corresponding bits from value and the rest is
@@ -299,6 +302,17 @@ autoselection is done on ethtool side with ioctl interface, netlink interface
is supposed to allow requesting changes without knowing what exactly kernel
supports.
+When changing device features, only ETHA_FEATURES_WANTED is passed. As usual,
+mask defines which bits are to be set and value their values. If the request
+has ETHA_FEATURES_WANT_DIFF flag set, reply will contain a message in the same
+format as response to GET request, except only two bitsets are provided.
+ETHA_FEATURES_WANTED shows difference between requested features and actual
+result (dev->features after the operation); mask shows bits which differ and
+value their values from the original request (new values are negated). Value
+shows changes between old dev->features (before the operation) and new (after
+the operation); mask shows bits which have been changed and value their new
+values.
+
Request translation
-------------------
@@ -328,30 +342,30 @@ ETHTOOL_SRINGPARAM n/a
ETHTOOL_GPAUSEPARAM n/a
ETHTOOL_SPAUSEPARAM n/a
ETHTOOL_GRXCSUM ETHNL_CMD_GET_SETTINGS
-ETHTOOL_SRXCSUM n/a
+ETHTOOL_SRXCSUM ETHNL_CMD_SET_SETTINGS
ETHTOOL_GTXCSUM ETHNL_CMD_GET_SETTINGS
-ETHTOOL_STXCSUM n/a
+ETHTOOL_STXCSUM ETHNL_CMD_SET_SETTINGS
ETHTOOL_GSG ETHNL_CMD_GET_SETTINGS
-ETHTOOL_SSG n/a
+ETHTOOL_SSG ETHNL_CMD_SET_SETTINGS
ETHTOOL_TEST n/a
ETHTOOL_GSTRINGS ETHNL_CMD_GET_STRSET
ETHTOOL_PHYS_ID n/a
ETHTOOL_GSTATS n/a
ETHTOOL_GTSO ETHNL_CMD_GET_SETTINGS
-ETHTOOL_STSO n/a
+ETHTOOL_STSO ETHNL_CMD_SET_SETTINGS
ETHTOOL_GPERMADDR n/a
ETHTOOL_GUFO ETHNL_CMD_GET_SETTINGS
-ETHTOOL_SUFO n/a
+ETHTOOL_SUFO ETHNL_CMD_SET_SETTINGS
ETHTOOL_GGSO ETHNL_CMD_GET_SETTINGS
-ETHTOOL_SGSO n/a
+ETHTOOL_SGSO ETHNL_CMD_SET_SETTINGS
ETHTOOL_GFLAGS ETHNL_CMD_GET_SETTINGS
-ETHTOOL_SFLAGS n/a
+ETHTOOL_SFLAGS ETHNL_CMD_SET_SETTINGS
ETHTOOL_GPFLAGS n/a
ETHTOOL_SPFLAGS n/a
ETHTOOL_GRXFH n/a
ETHTOOL_SRXFH n/a
ETHTOOL_GGRO ETHNL_CMD_GET_SETTINGS
-ETHTOOL_SGRO n/a
+ETHTOOL_SGRO ETHNL_CMD_SET_SETTINGS
ETHTOOL_GRXRINGS n/a
ETHTOOL_GRXCLSRLCNT n/a
ETHTOOL_GRXCLSRULE n/a
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 06c78b281275..8dfcb9ef4009 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -191,6 +191,7 @@ enum {
ETHA_FEATURES_WANTED, /* bitset */
ETHA_FEATURES_ACTIVE, /* bitset */
ETHA_FEATURES_NOCHANGE, /* bitset */
+ ETHA_FEATURES_WANT_DIFF, /* flag */
__ETHA_FEATURES_MAX,
ETHA_FEATURES_MAX = (__ETHA_FEATURES_MAX - 1)
diff --git a/net/ethtool/settings.c b/net/ethtool/settings.c
index 678199e621a2..475582b7950c 100644
--- a/net/ethtool/settings.c
+++ b/net/ethtool/settings.c
@@ -1016,6 +1016,122 @@ static int ethnl_update_lsettings(struct genl_info *info, struct nlattr **tb,
return 0;
}
+static const struct nla_policy features_policy[ETHA_FEATURES_MAX + 1] = {
+ [ETHA_FEATURES_UNSPEC] = { .type = NLA_UNSPEC },
+ [ETHA_FEATURES_HW] = { .type = NLA_NESTED },
+ [ETHA_FEATURES_WANTED] = { .type = NLA_NESTED },
+ [ETHA_FEATURES_ACTIVE] = { .type = NLA_NESTED },
+ [ETHA_FEATURES_NOCHANGE] = { .type = NLA_NESTED },
+ [ETHA_FEATURES_WANT_DIFF] = { .type = NLA_FLAG },
+};
+
+static void bitmap_from_features(unsigned long *bitmap, netdev_features_t val)
+{
+ const unsigned int words = BITS_TO_LONGS(NETDEV_FEATURE_COUNT);
+ unsigned int i;
+
+ bitmap_zero(bitmap, NETDEV_FEATURE_COUNT);
+ for (i = 0; i < words; i++)
+ bitmap[i] = (unsigned long)(val >> (i * BITS_PER_LONG));
+}
+
+static netdev_features_t features_from_bitmap(unsigned long *bitmap)
+{
+ const unsigned int words = BITS_TO_LONGS(NETDEV_FEATURE_COUNT);
+ netdev_features_t ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < words; i++)
+ ret |= (netdev_features_t)(bitmap[i]) << (i * BITS_PER_LONG);
+ return ret;
+}
+
+int update_features(struct genl_info *info, struct net_device *dev,
+ const struct nlattr *nest, bool compact)
+{
+ struct nlattr *tb[ETHA_FEATURES_MAX + 1];
+ DECLARE_BITMAP(old_active, NETDEV_FEATURE_COUNT);
+ DECLARE_BITMAP(req_wanted, NETDEV_FEATURE_COUNT);
+ DECLARE_BITMAP(req_mask, NETDEV_FEATURE_COUNT);
+ DECLARE_BITMAP(new_active, NETDEV_FEATURE_COUNT);
+ DECLARE_BITMAP(wanted_diff_mask, NETDEV_FEATURE_COUNT);
+ DECLARE_BITMAP(active_diff_mask, NETDEV_FEATURE_COUNT);
+ struct nlattr *feat_attr;
+ unsigned int reply_len;
+ struct sk_buff *rskb;
+ bool mod = false;
+ void *ehdr;
+ int ret;
+
+ ret = nla_parse_nested(tb, ETHA_FEATURES_MAX, nest, features_policy,
+ info->extack);
+ if (ret < 0)
+ return ret;
+ if (tb[ETHA_FEATURES_HW] || !tb[ETHA_FEATURES_WANTED] ||
+ tb[ETHA_FEATURES_ACTIVE] || tb[ETHA_FEATURES_NOCHANGE])
+ return -EINVAL;
+
+ bitmap_from_features(old_active, dev->features);
+ bitmap_copy(req_wanted, old_active, NETDEV_FEATURE_COUNT);
+ bitmap_zero(req_mask, NETDEV_FEATURE_COUNT);
+ mod = ethnl_update_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
+ tb[ETHA_FEATURES_WANTED], &ret, feature_names,
+ info);
+ if (ret < 0 || !mod)
+ return ret;
+
+ dev->wanted_features = features_from_bitmap(req_wanted);
+ netdev_update_features(dev);
+ if (!tb[ETHA_FEATURES_WANT_DIFF])
+ return 0;
+ bitmap_from_features(new_active, dev->features);
+ bitmap_xor(wanted_diff_mask, req_wanted, new_active,
+ NETDEV_FEATURE_COUNT);
+ bitmap_xor(active_diff_mask, old_active, new_active,
+ NETDEV_FEATURE_COUNT);
+ bitmap_and(wanted_diff_mask, wanted_diff_mask, req_mask,
+ NETDEV_FEATURE_COUNT);
+ bitmap_and(req_wanted, req_wanted, wanted_diff_mask,
+ NETDEV_FEATURE_COUNT);
+ bitmap_and(new_active, new_active, active_diff_mask,
+ NETDEV_FEATURE_COUNT);
+
+ reply_len = ethnl_bitset_size(compact, NETDEV_FEATURE_COUNT, req_wanted,
+ wanted_diff_mask, feature_names) +
+ ethnl_bitset_size(compact, NETDEV_FEATURE_COUNT, new_active,
+ active_diff_mask, feature_names);
+ reply_len = nla_total_size(reply_len);
+ rskb = ethnl_reply_init(reply_len, dev, ETHNL_CMD_SET_SETTINGS,
+ ETHA_SETTINGS_DEV, info, &ehdr);
+ if (!rskb)
+ goto err;
+ ret = -EMSGSIZE;
+
+ feat_attr = ethnl_nest_start(rskb, ETHA_SETTINGS_FEATURES);
+ if (!feat_attr)
+ goto err;
+ ret = ethnl_put_bitset(rskb, ETHA_FEATURES_WANTED, compact,
+ NETDEV_FEATURE_COUNT, req_wanted,
+ wanted_diff_mask, feature_names);
+ if (ret < 0)
+ goto err;
+ ret = ethnl_put_bitset(rskb, ETHA_FEATURES_ACTIVE, compact,
+ NETDEV_FEATURE_COUNT, new_active,
+ active_diff_mask, feature_names);
+ if (ret < 0)
+ goto err;
+ nla_nest_end(rskb, feat_attr);
+
+ genlmsg_end(rskb, ehdr);
+ return genlmsg_reply(rskb, info);
+err:
+ WARN_ONCE(ret == -EMSGSIZE,
+ "calculated message payload length (%d) not sufficient\n",
+ reply_len);
+ nlmsg_free(rskb);
+ return ret;
+}
+
int ethnl_set_settings(struct sk_buff *skb, struct genl_info *info)
{
struct nlattr *tb[ETHA_SETTINGS_MAX + 1];
@@ -1092,6 +1208,17 @@ int ethnl_set_settings(struct sk_buff *skb, struct genl_info *info)
req_mask |= ETH_SETTINGS_IM_MSGLEVEL;
}
}
+ if (tb[ETHA_SETTINGS_FEATURES]) {
+ bool compact = tb[ETHA_SETTINGS_COMPACT];
+
+ ret = update_features(info, dev, tb[ETHA_SETTINGS_FEATURES],
+ compact);
+ if (ret > 0) {
+ req_mask |= ETH_SETTINGS_IM_FEATURES;
+ ret = 0;
+ }
+
+ }
ret = 0;
out_unlock:
--
2.18.0
next prev parent reply other threads:[~2018-07-30 12:54 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-30 12:52 [RFC PATCH net-next v2 00/17] ethtool netlink interface (WiP) Michal Kubecek
2018-07-30 12:52 ` [RFC PATCH net-next v2 01/17] netlink: introduce nla_put_bitfield32() Michal Kubecek
2018-07-30 12:52 ` [RFC PATCH net-next v2 02/17] ethtool: move to its own directory Michal Kubecek
2018-07-30 12:52 ` [RFC PATCH net-next v2 03/17] ethtool: introduce ethtool netlink interface Michal Kubecek
2018-07-30 12:53 ` [RFC PATCH net-next v2 04/17] ethtool: helper functions for " Michal Kubecek
2018-07-30 12:53 ` [RFC PATCH net-next v2 05/17] ethtool: netlink bitset handling Michal Kubecek
2018-07-30 12:53 ` [RFC PATCH net-next v2 06/17] ethtool: support for netlink notifications Michal Kubecek
2018-07-30 13:16 ` Jiri Pirko
2018-07-30 17:01 ` Michal Kubecek
2018-07-31 6:46 ` Jiri Pirko
2018-07-30 12:53 ` [RFC PATCH net-next v2 07/17] ethtool: implement EVENT notifications Michal Kubecek
2018-07-30 12:53 ` [RFC PATCH net-next v2 08/17] ethtool: implement GET_STRSET message Michal Kubecek
2018-07-30 12:53 ` [RFC PATCH net-next v2 09/17] ethtool: implement GET_DRVINFO message Michal Kubecek
2018-07-30 13:21 ` Jiri Pirko
2018-07-30 14:37 ` Michal Kubecek
2018-07-30 14:28 ` Andrew Lunn
2018-07-30 14:46 ` Michal Kubecek
2018-07-30 15:48 ` Andrew Lunn
2018-07-30 16:47 ` Michal Kubecek
2018-07-31 0:56 ` Jakub Kicinski
2018-07-30 12:53 ` [RFC PATCH net-next v2 10/17] ethtool: implement GET_SETTINGS message Michal Kubecek
2018-07-30 18:54 ` Andrew Lunn
2018-08-21 9:32 ` Michal Kubecek
2018-08-21 14:10 ` Andrew Lunn
2018-08-21 14:52 ` Michal Kubecek
2018-07-30 19:06 ` Andrew Lunn
2018-07-30 19:09 ` Andrew Lunn
2018-07-30 19:42 ` Michal Kubecek
2018-07-30 12:53 ` [RFC PATCH net-next v2 11/17] ethtool: implement GET_SETTINGS request for features Michal Kubecek
2018-07-30 12:53 ` [RFC PATCH net-next v2 12/17] ethtool: implement SET_SETTINGS notification Michal Kubecek
2018-07-30 12:53 ` [RFC PATCH net-next v2 13/17] ethtool: implement SET_SETTINGS message Michal Kubecek
2018-07-30 12:53 ` Michal Kubecek [this message]
2018-07-30 12:53 ` [RFC PATCH net-next v2 15/17] ethtool: implement GET_PARAMS message Michal Kubecek
2018-07-30 12:54 ` [RFC PATCH net-next v2 16/17] ethtool: implement SET_PARAMS notification Michal Kubecek
2018-07-30 12:54 ` [RFC PATCH net-next v2 17/17] ethtool: implement SET_PARAMS message Michal Kubecek
2018-07-30 13:07 ` [RFC PATCH net-next v2 00/17] ethtool netlink interface (WiP) Jiri Pirko
2018-07-31 0:38 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1127951c1ac8d2fb6fcb3d6caba6f45bcd74a37d.1532953989.git.mkubecek@suse.cz \
--to=mkubecek@suse.cz \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=jiri@resnulli.us \
--cc=kubakici@wp.pl \
--cc=linux-kernel@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=netdev@vger.kernel.org \
--cc=roopa@cumulusnetworks.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.