STRUCT NLA_POLICY(9)
π struct nla_policy β attribute validation policy
okay bestie, welcome to the Kernel API Manual, section 9. This is the page for struct nla_policy, aka the glow-up your netlink attributes need before anyone's allowed to touch them β¨
πΈ NAME πΈ
struct nla_policy β attribute validation policy π
β¨ SYNOPSIS β¨
struct nla_policy {
u8 type;
u8 validation_type;
u16 len;
union {
u16 strict_start_type;
};
};
π¦ Members π¦
typeβ the type of the attribute, orNLA_UNSPEC. that's it, that's the field πvalidation_typeβ the type of attribute validation that gets done in addition to the type-specific validation (think range checks, function calls, all that extra credit work). peepenum nla_policy_validationfor the deets.lenβ the type specific length of the payload π{unnamed_union}β anonymous. it's giving mysterious, it's giving "no name needed" πstrict_start_typeβ the first attribute to validate strictly π₯
okay so this entry is special β it's used for the attribute at index0only, and it carries special data about the policy itself. namely, it specifies the "boundary type" where strict length validation starts for any attribute types>=this value. also, strict nesting validation starts right here too. periodt.
additionally (yes there's more, stay with me), it means thatNLA_UNSPECis actuallyNLA_REJECTfor any types>=this. so you need to useNLA_POLICY_MIN_LENto get the previous pure{ .len = xyz }behaviour back. the advantage? types that aren't specified in the policy get rejected. lowkey iconic π«Ά
for completely new families it should be set to 1 so the validation is enforced for all attributes. for existing ones, it should be set at least when new attributes get added to the enum used by the policy, and be set to the new value that was added, so strict validation is enforced from thereon π
π Description π
Policies are defined as arrays of this struct, and the array must be accessible by attribute type up to the highest identifier you expect to see. no cap, plan your indices.
π Meaning of len field
NLA_STRINGβ maximum length of stringNLA_NUL_STRINGβ maximum length of string (excludingNUL)NLA_FLAGβ unusedNLA_BINARYβ maximum length of attribute payload (but see also below, with the validation type)NLA_NESTED,NLA_NESTED_ARRAYβ length verification is done by checkinglenof the nested header (or empty); thelenfield is used ifnested_policyis also used, for the max attr number in the nested policyNLA_SINT,NLA_UINT,NLA_U8,NLA_U16,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"NLA_BITFIELD32β unusedNLA_REJECTβ unused- All other β minimum length of attribute payload
π Meaning of validation union
NLA_BITFIELD32β this is a 32-bit bitmap/bitselector attribute, andbitfield32_validis theu32value of valid flagsNLA_REJECTβ this attribute is always rejected, andreject_messagemay point to a string to report as the error instead of the generic one in extended ACK πNLA_NESTEDβnested_policypoints to a nested policy to validate, and you must also setlento the max attribute number. use the providedNLA_POLICY_NESTEDmacro. note thatnla_parsewill validate β but of course not parse β the nested sub-policies.NLA_NESTED_ARRAYβnested_policypoints to a nested policy to validate, and you must also setlento the max attribute number. use the providedNLA_POLICY_NESTED_ARRAYmacro. the difference fromNLA_NESTEDis the structure:NLA_NESTEDhas 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_UINT,NLA_U8,NLA_U16,NLA_U32,NLA_U64,NLA_BE16,NLA_BE32,NLA_SINT,NLA_S8,NLA_S16,NLA_S32,NLA_S64β theminandmaxfields get used depending on thevalidation_typefield. if that's 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 ares16, so you cannot enforce a range that doesn't fall within the range ofs16β do that using theNLA_POLICY_FULL_RANGEorNLA_POLICY_FULL_RANGE_SIGNEDmacros instead. use theNLA_POLICY_MIN,NLA_POLICY_MAXandNLA_POLICY_RANGEmacros.NLA_UINT,NLA_U8,NLA_U16,NLA_U32,NLA_U64β if thevalidation_typefield instead is set toNLA_VALIDATE_RANGE_PTR, thenrangemust be a pointer to astruct netlink_range_validationthat indicates the min/max values. useNLA_POLICY_FULL_RANGE.NLA_SINT,NLA_S8,NLA_S16,NLA_S32,NLA_S64β if thevalidation_typefield instead is set toNLA_VALIDATE_RANGE_PTR, thenrange_signedmust be a pointer to astruct netlink_range_validation_signedthat indicates the min/max values. useNLA_POLICY_FULL_RANGE_SIGNED.NLA_BINARYβ if the validation type is like the ones for integers above, then the min/max length (not value like for integers, bestie, length) of the attribute is enforced.- All other β unused. but note that it's a union π
π§ Meaning of validate field β use via NLA_POLICY_VALIDATE_FN
NLA_U8,NLA_U16,NLA_U32,NLA_U64,NLA_S8,NLA_S16,NLA_S32,NLA_S64,NLA_MSECS,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] = NLA_POLICY_EXACT_LEN(sizeof(struct mystruct)),
[ATTR_GOO] = NLA_POLICY_BITFIELD32(myvalidflags),
};
β SEE ALSO β
Kernel file ./include/net/netlink.h β plus, like, the entire extended netlink family reunion, no cap: struct nl_info(9), enum netlink_validation(9), nlmsg_msg_size(9), nlmsg_total_size(9), nlmsg_padlen(9), nlmsg_data(9), nlmsg_len(9), nlmsg_payload(9), nlmsg_attrdata(9), nlmsg_attrlen(9), nlmsg_ok(9), nlmsg_next(9), nla_parse(9), nla_parse_deprecated(9), nla_parse_deprecated_strict(9), __nlmsg_parse(9), nlmsg_parse(9), nlmsg_parse_deprecated(9), nlmsg_parse_deprecated_strict(9), nlmsg_find_attr(9), nla_validate_deprecated(9), nla_validate(9), nlmsg_validate_deprecated(9), nlmsg_report(9), nlmsg_seq(9), nlmsg_for_each_attr(9), nlmsg_for_each_attr_type(9), nlmsg_put(9), nlmsg_append(9), nlmsg_put_answer(9), nlmsg_new(9), nlmsg_new_large(9), nlmsg_end(9), nlmsg_get_pos(9), nlmsg_trim(9), nlmsg_cancel(9), nlmsg_free(9), nlmsg_consume(9), nlmsg_multicast_filtered(9), nlmsg_multicast(9), nlmsg_unicast(9), nlmsg_for_each_msg(9), nl_dump_check_consistent(9), nla_attr_size(9), nla_total_size(9), nla_padlen(9), nla_type(9), nla_data(9), nla_len(9), nla_ok(9), nla_next(9), nla_find_nested(9), nla_parse_nested(9), nla_parse_nested_deprecated(9), nla_put_u8(9), nla_put_u16(9), nla_put_be16(9), nla_put_net16(9), nla_put_le16(9), nla_put_u32(9), nla_put_uint(9), nla_put_be32(9), nla_put_net32(9), nla_put_le32(9), nla_put_u64_64bit(9), nla_put_be64(9), nla_put_net64(9), nla_put_le64(9), nla_put_s8(9), nla_put_s16(9), nla_put_s32(9), nla_put_s64(9), nla_put_sint(9), nla_put_string(9), nla_put_flag(9), nla_put_msecs(9), nla_put_in_addr(9), nla_put_in6_addr(9), nla_put_bitfield32(9), nla_get_u32(9), nla_get_u32_default(9), nla_get_be32(9), nla_get_be32_default(9), nla_get_le32(9), nla_get_le32_default(9), nla_get_u16(9), nla_get_u16_default(9), nla_get_be16(9), nla_get_be16_default(9), nla_get_le16(9), nla_get_le16_default(9), nla_get_u8(9), nla_get_u8_default(9), nla_get_u64(9), nla_get_u64_default(9), nla_get_uint(9), nla_get_uint_default(9), nla_get_be64(9), nla_get_be64_default(9), nla_get_le64(9), nla_get_le64_default(9), nla_get_s32(9), nla_get_s32_default(9), nla_get_s16(9), nla_get_s16_default(9), nla_get_s8(9), nla_get_s8_default(9), nla_get_s64(9), nla_get_s64_default(9), nla_get_sint(9), nla_get_sint_default(9), nla_get_flag(9), nla_get_msecs(9), nla_get_msecs_default(9), nla_get_in_addr(9), nla_get_in_addr_default(9), nla_get_in6_addr(9), nla_get_bitfield32(9), nla_memdup(9), nla_nest_start_noflag(9), nla_nest_start(9), nla_nest_end(9), nla_nest_end_safe(9), nla_nest_cancel(9), nla_put_empty_nest(9), __nla_validate_nested(9), nla_need_padding_for_64bit(9), nla_align_64bit(9), nla_total_size_64bit(9), nla_for_each_attr(9), nla_for_each_attr_type(9), nla_for_each_nested(9), nla_for_each_nested_type(9), nla_is_last(9)
and that's the whole page, bestie π«Ά this one shipped out from ./include/net β kernel source version dated October 2026, struct nla_policy(9) era. go forth and validate, you absolute icon π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms