forked from Minki/linux
netlink: introduce NLA_POLICY_MAX_BE
netlink allows to specify allowed ranges for integer types. Unfortunately, nfnetlink passes integers in big endian, so the existing NLA_POLICY_MAX() cannot be used. At the moment, nfnetlink users, such as nf_tables, need to resort to programmatic checking via helpers such as nft_parse_u32_check(). This is both cumbersome and error prone. This adds NLA_POLICY_MAX_BE which adds range check support for BE16, BE32 and BE64 integers. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
98ba81081b
commit
08724ef699
@ -325,6 +325,7 @@ struct nla_policy {
|
||||
struct netlink_range_validation_signed *range_signed;
|
||||
struct {
|
||||
s16 min, max;
|
||||
u8 network_byte_order:1;
|
||||
};
|
||||
int (*validate)(const struct nlattr *attr,
|
||||
struct netlink_ext_ack *extack);
|
||||
@ -418,6 +419,14 @@ struct nla_policy {
|
||||
.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \
|
||||
.validation_type = NLA_VALIDATE_MAX, \
|
||||
.max = _max, \
|
||||
.network_byte_order = 0, \
|
||||
}
|
||||
|
||||
#define NLA_POLICY_MAX_BE(tp, _max) { \
|
||||
.type = NLA_ENSURE_UINT_TYPE(tp), \
|
||||
.validation_type = NLA_VALIDATE_MAX, \
|
||||
.max = _max, \
|
||||
.network_byte_order = 1, \
|
||||
}
|
||||
|
||||
#define NLA_POLICY_MASK(tp, _mask) { \
|
||||
|
31
lib/nlattr.c
31
lib/nlattr.c
@ -159,6 +159,31 @@ void nla_get_range_unsigned(const struct nla_policy *pt,
|
||||
}
|
||||
}
|
||||
|
||||
static u64 nla_get_attr_bo(const struct nla_policy *pt,
|
||||
const struct nlattr *nla)
|
||||
{
|
||||
switch (pt->type) {
|
||||
case NLA_U16:
|
||||
if (pt->network_byte_order)
|
||||
return ntohs(nla_get_be16(nla));
|
||||
|
||||
return nla_get_u16(nla);
|
||||
case NLA_U32:
|
||||
if (pt->network_byte_order)
|
||||
return ntohl(nla_get_be32(nla));
|
||||
|
||||
return nla_get_u32(nla);
|
||||
case NLA_U64:
|
||||
if (pt->network_byte_order)
|
||||
return be64_to_cpu(nla_get_be64(nla));
|
||||
|
||||
return nla_get_u64(nla);
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nla_validate_range_unsigned(const struct nla_policy *pt,
|
||||
const struct nlattr *nla,
|
||||
struct netlink_ext_ack *extack,
|
||||
@ -172,12 +197,10 @@ static int nla_validate_range_unsigned(const struct nla_policy *pt,
|
||||
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_attr_bo(pt, nla);
|
||||
break;
|
||||
case NLA_MSECS:
|
||||
value = nla_get_u64(nla);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user