netlink: introduce bigendian integer types
Jakub reported that the addition of the "network_byte_order"
member in struct nla_policy increases size of 32bit platforms.
Instead of scraping the bit from elsewhere Johannes suggested
to add explicit NLA_BE types instead, so do this here.
NLA_POLICY_MAX_BE() macro is removed again, there is no need
for it: NLA_POLICY_MAX(NLA_BE.., ..) will do the right thing.
NLA_BE64 can be added later.
Fixes: 08724ef699
("netlink: introduce NLA_POLICY_MAX_BE")
Reported-by: Jakub Kicinski <kuba@kernel.org>
Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
Link: https://lore.kernel.org/r/20221031123407.9158-1-fw@strlen.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
fc57062f98
commit
ecaf75ffd5
|
@ -181,6 +181,8 @@ enum {
|
|||
NLA_S64,
|
||||
NLA_BITFIELD32,
|
||||
NLA_REJECT,
|
||||
NLA_BE16,
|
||||
NLA_BE32,
|
||||
__NLA_TYPE_MAX,
|
||||
};
|
||||
|
||||
|
@ -231,6 +233,7 @@ enum nla_policy_validation {
|
|||
* NLA_U32, NLA_U64,
|
||||
* NLA_S8, NLA_S16,
|
||||
* NLA_S32, NLA_S64,
|
||||
* NLA_BE16, NLA_BE32,
|
||||
* NLA_MSECS Leaving the length field zero will verify the
|
||||
* given type fits, using it verifies minimum length
|
||||
* just like "All other"
|
||||
|
@ -261,6 +264,8 @@ enum nla_policy_validation {
|
|||
* NLA_U16,
|
||||
* NLA_U32,
|
||||
* NLA_U64,
|
||||
* NLA_BE16,
|
||||
* NLA_BE32,
|
||||
* NLA_S8,
|
||||
* NLA_S16,
|
||||
* NLA_S32,
|
||||
|
@ -349,7 +354,6 @@ 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);
|
||||
|
@ -374,6 +378,8 @@ struct nla_policy {
|
|||
(tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 || tp == NLA_U64)
|
||||
#define __NLA_IS_SINT_TYPE(tp) \
|
||||
(tp == NLA_S8 || tp == NLA_S16 || tp == NLA_S32 || tp == NLA_S64)
|
||||
#define __NLA_IS_BEINT_TYPE(tp) \
|
||||
(tp == NLA_BE16 || tp == NLA_BE32)
|
||||
|
||||
#define __NLA_ENSURE(condition) BUILD_BUG_ON_ZERO(!(condition))
|
||||
#define NLA_ENSURE_UINT_TYPE(tp) \
|
||||
|
@ -387,6 +393,7 @@ struct nla_policy {
|
|||
#define NLA_ENSURE_INT_OR_BINARY_TYPE(tp) \
|
||||
(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) || \
|
||||
__NLA_IS_SINT_TYPE(tp) || \
|
||||
__NLA_IS_BEINT_TYPE(tp) || \
|
||||
tp == NLA_MSECS || \
|
||||
tp == NLA_BINARY) + tp)
|
||||
#define NLA_ENSURE_NO_VALIDATION_PTR(tp) \
|
||||
|
@ -394,6 +401,8 @@ struct nla_policy {
|
|||
tp != NLA_REJECT && \
|
||||
tp != NLA_NESTED && \
|
||||
tp != NLA_NESTED_ARRAY) + tp)
|
||||
#define NLA_ENSURE_BEINT_TYPE(tp) \
|
||||
(__NLA_ENSURE(__NLA_IS_BEINT_TYPE(tp)) + tp)
|
||||
|
||||
#define NLA_POLICY_RANGE(tp, _min, _max) { \
|
||||
.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \
|
||||
|
@ -424,14 +433,6 @@ 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) { \
|
||||
|
|
41
lib/nlattr.c
41
lib/nlattr.c
|
@ -124,10 +124,12 @@ void nla_get_range_unsigned(const struct nla_policy *pt,
|
|||
range->max = U8_MAX;
|
||||
break;
|
||||
case NLA_U16:
|
||||
case NLA_BE16:
|
||||
case NLA_BINARY:
|
||||
range->max = U16_MAX;
|
||||
break;
|
||||
case NLA_U32:
|
||||
case NLA_BE32:
|
||||
range->max = U32_MAX;
|
||||
break;
|
||||
case NLA_U64:
|
||||
|
@ -159,31 +161,6 @@ 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,
|
||||
|
@ -197,9 +174,13 @@ 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);
|
||||
value = nla_get_u64(nla);
|
||||
break;
|
||||
case NLA_MSECS:
|
||||
value = nla_get_u64(nla);
|
||||
|
@ -207,6 +188,12 @@ static int nla_validate_range_unsigned(const struct nla_policy *pt,
|
|||
case NLA_BINARY:
|
||||
value = nla_len(nla);
|
||||
break;
|
||||
case NLA_BE16:
|
||||
value = ntohs(nla_get_be16(nla));
|
||||
break;
|
||||
case NLA_BE32:
|
||||
value = ntohl(nla_get_be32(nla));
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -334,6 +321,8 @@ static int nla_validate_int_range(const struct nla_policy *pt,
|
|||
case NLA_U64:
|
||||
case NLA_MSECS:
|
||||
case NLA_BINARY:
|
||||
case NLA_BE16:
|
||||
case NLA_BE32:
|
||||
return nla_validate_range_unsigned(pt, nla, extack, validate);
|
||||
case NLA_S8:
|
||||
case NLA_S16:
|
||||
|
|
|
@ -173,10 +173,10 @@ static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = {
|
|||
[NFTA_PAYLOAD_SREG] = { .type = NLA_U32 },
|
||||
[NFTA_PAYLOAD_DREG] = { .type = NLA_U32 },
|
||||
[NFTA_PAYLOAD_BASE] = { .type = NLA_U32 },
|
||||
[NFTA_PAYLOAD_OFFSET] = NLA_POLICY_MAX_BE(NLA_U32, 255),
|
||||
[NFTA_PAYLOAD_LEN] = NLA_POLICY_MAX_BE(NLA_U32, 255),
|
||||
[NFTA_PAYLOAD_OFFSET] = NLA_POLICY_MAX(NLA_BE32, 255),
|
||||
[NFTA_PAYLOAD_LEN] = NLA_POLICY_MAX(NLA_BE32, 255),
|
||||
[NFTA_PAYLOAD_CSUM_TYPE] = { .type = NLA_U32 },
|
||||
[NFTA_PAYLOAD_CSUM_OFFSET] = NLA_POLICY_MAX_BE(NLA_U32, 255),
|
||||
[NFTA_PAYLOAD_CSUM_OFFSET] = NLA_POLICY_MAX(NLA_BE32, 255),
|
||||
[NFTA_PAYLOAD_CSUM_FLAGS] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue