diff options
author | David S. Miller <davem@davemloft.net> | 2020-10-06 06:25:56 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-10-06 06:25:56 -0700 |
commit | 9faebeb2d80065926dfbc09cb73b1bb7779a89cd (patch) | |
tree | 09c011ae2e2e53713b8d3ee0e531fdfa4dbf29bd /lib | |
parent | 02da0b615b4bd7db747ed77199d5f1a161a0411a (diff) | |
parent | a0de1cd3568749d3410c89b1c8bb70e90d61659f (diff) | |
download | lwn-9faebeb2d80065926dfbc09cb73b1bb7779a89cd.tar.gz lwn-9faebeb2d80065926dfbc09cb73b1bb7779a89cd.zip |
Merge branch 'ethtool-allow-dumping-policies-to-user-space'
Jakub Kicinski says:
====================
ethtool: allow dumping policies to user space
This series wires up ethtool policies to ops, so they can be
dumped to user space for feature discovery.
First patch wires up GET commands, and second patch wires up SETs.
The policy tables are trimmed to save space and LoC.
Next - take care of linking up nested policies for the header
(which is the policy what we actually care about). And once header
policy is linked make sure that attribute range validation for flags
is done by policy, not a conditions in the code. New type of policy
is needed to validate masks (patch 6).
Netlink as always staying a step ahead of all the other kernel
API interfaces :)
v2:
- merge patches 1 & 2 -> 1
- add patch 3 & 5
- remove .max_attr from struct ethnl_request_ops
====================
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/nlattr.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/nlattr.c b/lib/nlattr.c index 80ff9fe83696..9c99f5daa4d2 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -323,6 +323,37 @@ static int nla_validate_int_range(const struct nla_policy *pt, } } +static int nla_validate_mask(const struct nla_policy *pt, + const struct nlattr *nla, + struct netlink_ext_ack *extack) +{ + u64 value; + + switch (pt->type) { + case NLA_U8: + value = nla_get_u8(nla); + break; + case NLA_U16: + value = nla_get_u16(nla); + break; + case NLA_U32: + value = nla_get_u32(nla); + break; + case NLA_U64: + value = nla_get_u64(nla); + break; + default: + return -EINVAL; + } + + if (value & ~(u64)pt->mask) { + NL_SET_ERR_MSG_ATTR(extack, nla, "reserved bit set"); + return -EINVAL; + } + + return 0; +} + static int validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *policy, unsigned int validate, struct netlink_ext_ack *extack, unsigned int depth) @@ -503,6 +534,11 @@ static int validate_nla(const struct nlattr *nla, int maxtype, if (err) return err; break; + case NLA_VALIDATE_MASK: + err = nla_validate_mask(pt, nla, extack); + if (err) + return err; + break; case NLA_VALIDATE_FUNCTION: if (pt->validate) { err = pt->validate(nla, extack); |