summaryrefslogtreecommitdiff
path: root/include/net/netlink.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/netlink.h')
-rw-r--r--include/net/netlink.h135
1 files changed, 99 insertions, 36 deletions
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 67c57d6942e3..c0411f14fb53 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -182,19 +182,28 @@ enum {
NLA_BITFIELD32,
NLA_REJECT,
NLA_EXACT_LEN,
- NLA_EXACT_LEN_WARN,
NLA_MIN_LEN,
__NLA_TYPE_MAX,
};
#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
+struct netlink_range_validation {
+ u64 min, max;
+};
+
+struct netlink_range_validation_signed {
+ s64 min, max;
+};
+
enum nla_policy_validation {
NLA_VALIDATE_NONE,
NLA_VALIDATE_RANGE,
NLA_VALIDATE_MIN,
NLA_VALIDATE_MAX,
+ NLA_VALIDATE_RANGE_PTR,
NLA_VALIDATE_FUNCTION,
+ NLA_VALIDATE_WARN_TOO_LONG,
};
/**
@@ -217,7 +226,7 @@ enum nla_policy_validation {
* NLA_NESTED,
* NLA_NESTED_ARRAY Length verification is done by checking len of
* nested header (or empty); len field is used if
- * validation_data is also used, for the max attr
+ * nested_policy is also used, for the max attr
* number in the nested policy.
* NLA_U8, NLA_U16,
* NLA_U32, NLA_U64,
@@ -228,34 +237,32 @@ enum nla_policy_validation {
* just like "All other"
* NLA_BITFIELD32 Unused
* NLA_REJECT Unused
- * NLA_EXACT_LEN Attribute must have exactly this length, otherwise
- * it is rejected.
- * NLA_EXACT_LEN_WARN Attribute should have exactly this length, a warning
- * is logged if it is longer, shorter is rejected.
+ * NLA_EXACT_LEN Attribute should have exactly this length, otherwise
+ * it is rejected or warned about, the latter happening
+ * if and only if the `validation_type' is set to
+ * NLA_VALIDATE_WARN_TOO_LONG.
* NLA_MIN_LEN Minimum length of attribute payload
* All other Minimum length of attribute payload
*
- * Meaning of `validation_data' field:
+ * Meaning of validation union:
* NLA_BITFIELD32 This is a 32-bit bitmap/bitselector attribute and
- * validation data must point to a u32 value of valid
- * flags
- * NLA_REJECT This attribute is always rejected and validation data
+ * `bitfield32_valid' is the u32 value of valid flags
+ * NLA_REJECT This attribute is always rejected and `reject_message'
* may point to a string to report as the error instead
* of the generic one in extended ACK.
- * NLA_NESTED Points to a nested policy to validate, must also set
- * `len' to the max attribute number.
+ * NLA_NESTED `nested_policy' to a nested policy to validate, must
+ * also set `len' to the max attribute number. Use the
+ * provided NLA_POLICY_NESTED() macro.
* Note that nla_parse() will validate, but of course not
* parse, the nested sub-policies.
- * NLA_NESTED_ARRAY Points to a nested policy to validate, must also set
- * `len' to the max attribute number. The difference to
- * NLA_NESTED is the structure - NLA_NESTED has the
- * nested attributes directly inside, while an array has
- * the nested attributes at another level down and the
- * attributes directly in the nesting don't matter.
- * All other Unused - but note that it's a union
- *
- * Meaning of `min' and `max' fields, use via NLA_POLICY_MIN, NLA_POLICY_MAX
- * and NLA_POLICY_RANGE:
+ * NLA_NESTED_ARRAY `nested_policy' points to a nested policy to validate,
+ * must also set `len' to the max attribute number. Use
+ * the provided NLA_POLICY_NESTED_ARRAY() macro.
+ * The difference to NLA_NESTED is the structure:
+ * NLA_NESTED has the nested attributes directly inside
+ * while an array has the nested attributes at another
+ * level down and the attribute types directly in the
+ * nesting don't matter.
* NLA_U8,
* NLA_U16,
* NLA_U32,
@@ -263,29 +270,47 @@ enum nla_policy_validation {
* NLA_S8,
* NLA_S16,
* NLA_S32,
- * NLA_S64 These are used depending on the validation_type
- * field, if that is min/max/range then the minimum,
- * maximum and both are used (respectively) to check
+ * NLA_S64 The `min' and `max' fields are used depending on the
+ * validation_type field, if that is min/max/range then
+ * the min, max or both are used (respectively) to check
* the value of the integer attribute.
* Note that in the interest of code simplicity and
* struct size both limits are s16, so you cannot
* enforce a range that doesn't fall within the range
* of s16 - do that as usual in the code instead.
+ * Use the NLA_POLICY_MIN(), NLA_POLICY_MAX() and
+ * NLA_POLICY_RANGE() macros.
+ * NLA_U8,
+ * NLA_U16,
+ * NLA_U32,
+ * NLA_U64 If the validation_type field instead is set to
+ * NLA_VALIDATE_RANGE_PTR, `range' must be a pointer
+ * to a struct netlink_range_validation that indicates
+ * the min/max values.
+ * Use NLA_POLICY_FULL_RANGE().
+ * NLA_S8,
+ * NLA_S16,
+ * NLA_S32,
+ * NLA_S64 If the validation_type field instead is set to
+ * NLA_VALIDATE_RANGE_PTR, `range_signed' must be a
+ * pointer to a struct netlink_range_validation_signed
+ * that indicates the min/max values.
+ * Use NLA_POLICY_FULL_RANGE_SIGNED().
* All other Unused - but note that it's a union
*
* Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN:
- * NLA_BINARY Validation function called for the attribute,
- * not compatible with use of the validation_data
- * as in NLA_BITFIELD32, NLA_REJECT, NLA_NESTED and
- * NLA_NESTED_ARRAY.
+ * NLA_BINARY Validation function called for the attribute.
* All other Unused - but note that it's a union
*
* Example:
+ *
+ * static const u32 myvalidflags = 0xff231023;
+ *
* static const struct nla_policy my_policy[ATTR_MAX+1] = {
* [ATTR_FOO] = { .type = NLA_U16 },
* [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ },
* [ATTR_BAZ] = { .type = NLA_EXACT_LEN, .len = sizeof(struct mystruct) },
- * [ATTR_GOO] = { .type = NLA_BITFIELD32, .validation_data = &myvalidflags },
+ * [ATTR_GOO] = NLA_POLICY_BITFIELD32(myvalidflags),
* };
*/
struct nla_policy {
@@ -293,7 +318,11 @@ struct nla_policy {
u8 validation_type;
u16 len;
union {
- const void *validation_data;
+ const u32 bitfield32_valid;
+ const char *reject_message;
+ const struct nla_policy *nested_policy;
+ struct netlink_range_validation *range;
+ struct netlink_range_validation_signed *range_signed;
struct {
s16 min, max;
};
@@ -321,28 +350,39 @@ struct nla_policy {
};
#define NLA_POLICY_EXACT_LEN(_len) { .type = NLA_EXACT_LEN, .len = _len }
-#define NLA_POLICY_EXACT_LEN_WARN(_len) { .type = NLA_EXACT_LEN_WARN, \
- .len = _len }
+#define NLA_POLICY_EXACT_LEN_WARN(_len) \
+ { .type = NLA_EXACT_LEN, .len = _len, \
+ .validation_type = NLA_VALIDATE_WARN_TOO_LONG, }
#define NLA_POLICY_MIN_LEN(_len) { .type = NLA_MIN_LEN, .len = _len }
#define NLA_POLICY_ETH_ADDR NLA_POLICY_EXACT_LEN(ETH_ALEN)
#define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)
#define _NLA_POLICY_NESTED(maxattr, policy) \
- { .type = NLA_NESTED, .validation_data = policy, .len = maxattr }
+ { .type = NLA_NESTED, .nested_policy = policy, .len = maxattr }
#define _NLA_POLICY_NESTED_ARRAY(maxattr, policy) \
- { .type = NLA_NESTED_ARRAY, .validation_data = policy, .len = maxattr }
+ { .type = NLA_NESTED_ARRAY, .nested_policy = policy, .len = maxattr }
#define NLA_POLICY_NESTED(policy) \
_NLA_POLICY_NESTED(ARRAY_SIZE(policy) - 1, policy)
#define NLA_POLICY_NESTED_ARRAY(policy) \
_NLA_POLICY_NESTED_ARRAY(ARRAY_SIZE(policy) - 1, policy)
+#define NLA_POLICY_BITFIELD32(valid) \
+ { .type = NLA_BITFIELD32, .bitfield32_valid = valid }
#define __NLA_ENSURE(condition) BUILD_BUG_ON_ZERO(!(condition))
+#define NLA_ENSURE_UINT_TYPE(tp) \
+ (__NLA_ENSURE(tp == NLA_U8 || tp == NLA_U16 || \
+ tp == NLA_U32 || tp == NLA_U64 || \
+ tp == NLA_MSECS) + tp)
+#define NLA_ENSURE_SINT_TYPE(tp) \
+ (__NLA_ENSURE(tp == NLA_S8 || tp == NLA_S16 || \
+ tp == NLA_S32 || tp == NLA_S64) + tp)
#define NLA_ENSURE_INT_TYPE(tp) \
(__NLA_ENSURE(tp == NLA_S8 || tp == NLA_U8 || \
tp == NLA_S16 || tp == NLA_U16 || \
tp == NLA_S32 || tp == NLA_U32 || \
- tp == NLA_S64 || tp == NLA_U64) + tp)
+ tp == NLA_S64 || tp == NLA_U64 || \
+ tp == NLA_MSECS) + tp)
#define NLA_ENSURE_NO_VALIDATION_PTR(tp) \
(__NLA_ENSURE(tp != NLA_BITFIELD32 && \
tp != NLA_REJECT && \
@@ -356,6 +396,18 @@ struct nla_policy {
.max = _max \
}
+#define NLA_POLICY_FULL_RANGE(tp, _range) { \
+ .type = NLA_ENSURE_UINT_TYPE(tp), \
+ .validation_type = NLA_VALIDATE_RANGE_PTR, \
+ .range = _range, \
+}
+
+#define NLA_POLICY_FULL_RANGE_SIGNED(tp, _range) { \
+ .type = NLA_ENSURE_SINT_TYPE(tp), \
+ .validation_type = NLA_VALIDATE_RANGE_PTR, \
+ .range_signed = _range, \
+}
+
#define NLA_POLICY_MIN(tp, _min) { \
.type = NLA_ENSURE_INT_TYPE(tp), \
.validation_type = NLA_VALIDATE_MIN, \
@@ -1876,4 +1928,15 @@ static inline bool nla_is_last(const struct nlattr *nla, int rem)
return nla->nla_len == rem;
}
+void nla_get_range_unsigned(const struct nla_policy *pt,
+ struct netlink_range_validation *range);
+void nla_get_range_signed(const struct nla_policy *pt,
+ struct netlink_range_validation_signed *range);
+
+int netlink_policy_dump_start(const struct nla_policy *policy,
+ unsigned int maxtype,
+ unsigned long *state);
+bool netlink_policy_dump_loop(unsigned long *state);
+int netlink_policy_dump_write(struct sk_buff *skb, unsigned long state);
+
#endif