162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __NET_NETLINK_H 362306a36Sopenharmony_ci#define __NET_NETLINK_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/types.h> 662306a36Sopenharmony_ci#include <linux/netlink.h> 762306a36Sopenharmony_ci#include <linux/jiffies.h> 862306a36Sopenharmony_ci#include <linux/in6.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/* ======================================================================== 1162306a36Sopenharmony_ci * Netlink Messages and Attributes Interface (As Seen On TV) 1262306a36Sopenharmony_ci * ------------------------------------------------------------------------ 1362306a36Sopenharmony_ci * Messages Interface 1462306a36Sopenharmony_ci * ------------------------------------------------------------------------ 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * Message Format: 1762306a36Sopenharmony_ci * <--- nlmsg_total_size(payload) ---> 1862306a36Sopenharmony_ci * <-- nlmsg_msg_size(payload) -> 1962306a36Sopenharmony_ci * +----------+- - -+-------------+- - -+-------- - - 2062306a36Sopenharmony_ci * | nlmsghdr | Pad | Payload | Pad | nlmsghdr 2162306a36Sopenharmony_ci * +----------+- - -+-------------+- - -+-------- - - 2262306a36Sopenharmony_ci * nlmsg_data(nlh)---^ ^ 2362306a36Sopenharmony_ci * nlmsg_next(nlh)-----------------------+ 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * Payload Format: 2662306a36Sopenharmony_ci * <---------------------- nlmsg_len(nlh) ---------------------> 2762306a36Sopenharmony_ci * <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) -> 2862306a36Sopenharmony_ci * +----------------------+- - -+--------------------------------+ 2962306a36Sopenharmony_ci * | Family Header | Pad | Attributes | 3062306a36Sopenharmony_ci * +----------------------+- - -+--------------------------------+ 3162306a36Sopenharmony_ci * nlmsg_attrdata(nlh, hdrlen)---^ 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * Data Structures: 3462306a36Sopenharmony_ci * struct nlmsghdr netlink message header 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * Message Construction: 3762306a36Sopenharmony_ci * nlmsg_new() create a new netlink message 3862306a36Sopenharmony_ci * nlmsg_put() add a netlink message to an skb 3962306a36Sopenharmony_ci * nlmsg_put_answer() callback based nlmsg_put() 4062306a36Sopenharmony_ci * nlmsg_end() finalize netlink message 4162306a36Sopenharmony_ci * nlmsg_get_pos() return current position in message 4262306a36Sopenharmony_ci * nlmsg_trim() trim part of message 4362306a36Sopenharmony_ci * nlmsg_cancel() cancel message construction 4462306a36Sopenharmony_ci * nlmsg_free() free a netlink message 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * Message Sending: 4762306a36Sopenharmony_ci * nlmsg_multicast() multicast message to several groups 4862306a36Sopenharmony_ci * nlmsg_unicast() unicast a message to a single socket 4962306a36Sopenharmony_ci * nlmsg_notify() send notification message 5062306a36Sopenharmony_ci * 5162306a36Sopenharmony_ci * Message Length Calculations: 5262306a36Sopenharmony_ci * nlmsg_msg_size(payload) length of message w/o padding 5362306a36Sopenharmony_ci * nlmsg_total_size(payload) length of message w/ padding 5462306a36Sopenharmony_ci * nlmsg_padlen(payload) length of padding at tail 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * Message Payload Access: 5762306a36Sopenharmony_ci * nlmsg_data(nlh) head of message payload 5862306a36Sopenharmony_ci * nlmsg_len(nlh) length of message payload 5962306a36Sopenharmony_ci * nlmsg_attrdata(nlh, hdrlen) head of attributes data 6062306a36Sopenharmony_ci * nlmsg_attrlen(nlh, hdrlen) length of attributes data 6162306a36Sopenharmony_ci * 6262306a36Sopenharmony_ci * Message Parsing: 6362306a36Sopenharmony_ci * nlmsg_ok(nlh, remaining) does nlh fit into remaining bytes? 6462306a36Sopenharmony_ci * nlmsg_next(nlh, remaining) get next netlink message 6562306a36Sopenharmony_ci * nlmsg_parse() parse attributes of a message 6662306a36Sopenharmony_ci * nlmsg_find_attr() find an attribute in a message 6762306a36Sopenharmony_ci * nlmsg_for_each_msg() loop over all messages 6862306a36Sopenharmony_ci * nlmsg_validate() validate netlink message incl. attrs 6962306a36Sopenharmony_ci * nlmsg_for_each_attr() loop over all attributes 7062306a36Sopenharmony_ci * 7162306a36Sopenharmony_ci * Misc: 7262306a36Sopenharmony_ci * nlmsg_report() report back to application? 7362306a36Sopenharmony_ci * 7462306a36Sopenharmony_ci * ------------------------------------------------------------------------ 7562306a36Sopenharmony_ci * Attributes Interface 7662306a36Sopenharmony_ci * ------------------------------------------------------------------------ 7762306a36Sopenharmony_ci * 7862306a36Sopenharmony_ci * Attribute Format: 7962306a36Sopenharmony_ci * <------- nla_total_size(payload) -------> 8062306a36Sopenharmony_ci * <---- nla_attr_size(payload) -----> 8162306a36Sopenharmony_ci * +----------+- - -+- - - - - - - - - +- - -+-------- - - 8262306a36Sopenharmony_ci * | Header | Pad | Payload | Pad | Header 8362306a36Sopenharmony_ci * +----------+- - -+- - - - - - - - - +- - -+-------- - - 8462306a36Sopenharmony_ci * <- nla_len(nla) -> ^ 8562306a36Sopenharmony_ci * nla_data(nla)----^ | 8662306a36Sopenharmony_ci * nla_next(nla)-----------------------------' 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * Data Structures: 8962306a36Sopenharmony_ci * struct nlattr netlink attribute header 9062306a36Sopenharmony_ci * 9162306a36Sopenharmony_ci * Attribute Construction: 9262306a36Sopenharmony_ci * nla_reserve(skb, type, len) reserve room for an attribute 9362306a36Sopenharmony_ci * nla_reserve_nohdr(skb, len) reserve room for an attribute w/o hdr 9462306a36Sopenharmony_ci * nla_put(skb, type, len, data) add attribute to skb 9562306a36Sopenharmony_ci * nla_put_nohdr(skb, len, data) add attribute w/o hdr 9662306a36Sopenharmony_ci * nla_append(skb, len, data) append data to skb 9762306a36Sopenharmony_ci * 9862306a36Sopenharmony_ci * Attribute Construction for Basic Types: 9962306a36Sopenharmony_ci * nla_put_u8(skb, type, value) add u8 attribute to skb 10062306a36Sopenharmony_ci * nla_put_u16(skb, type, value) add u16 attribute to skb 10162306a36Sopenharmony_ci * nla_put_u32(skb, type, value) add u32 attribute to skb 10262306a36Sopenharmony_ci * nla_put_u64_64bit(skb, type, 10362306a36Sopenharmony_ci * value, padattr) add u64 attribute to skb 10462306a36Sopenharmony_ci * nla_put_s8(skb, type, value) add s8 attribute to skb 10562306a36Sopenharmony_ci * nla_put_s16(skb, type, value) add s16 attribute to skb 10662306a36Sopenharmony_ci * nla_put_s32(skb, type, value) add s32 attribute to skb 10762306a36Sopenharmony_ci * nla_put_s64(skb, type, value, 10862306a36Sopenharmony_ci * padattr) add s64 attribute to skb 10962306a36Sopenharmony_ci * nla_put_string(skb, type, str) add string attribute to skb 11062306a36Sopenharmony_ci * nla_put_flag(skb, type) add flag attribute to skb 11162306a36Sopenharmony_ci * nla_put_msecs(skb, type, jiffies, 11262306a36Sopenharmony_ci * padattr) add msecs attribute to skb 11362306a36Sopenharmony_ci * nla_put_in_addr(skb, type, addr) add IPv4 address attribute to skb 11462306a36Sopenharmony_ci * nla_put_in6_addr(skb, type, addr) add IPv6 address attribute to skb 11562306a36Sopenharmony_ci * 11662306a36Sopenharmony_ci * Nested Attributes Construction: 11762306a36Sopenharmony_ci * nla_nest_start(skb, type) start a nested attribute 11862306a36Sopenharmony_ci * nla_nest_end(skb, nla) finalize a nested attribute 11962306a36Sopenharmony_ci * nla_nest_cancel(skb, nla) cancel nested attribute construction 12062306a36Sopenharmony_ci * 12162306a36Sopenharmony_ci * Attribute Length Calculations: 12262306a36Sopenharmony_ci * nla_attr_size(payload) length of attribute w/o padding 12362306a36Sopenharmony_ci * nla_total_size(payload) length of attribute w/ padding 12462306a36Sopenharmony_ci * nla_padlen(payload) length of padding 12562306a36Sopenharmony_ci * 12662306a36Sopenharmony_ci * Attribute Payload Access: 12762306a36Sopenharmony_ci * nla_data(nla) head of attribute payload 12862306a36Sopenharmony_ci * nla_len(nla) length of attribute payload 12962306a36Sopenharmony_ci * 13062306a36Sopenharmony_ci * Attribute Payload Access for Basic Types: 13162306a36Sopenharmony_ci * nla_get_u8(nla) get payload for a u8 attribute 13262306a36Sopenharmony_ci * nla_get_u16(nla) get payload for a u16 attribute 13362306a36Sopenharmony_ci * nla_get_u32(nla) get payload for a u32 attribute 13462306a36Sopenharmony_ci * nla_get_u64(nla) get payload for a u64 attribute 13562306a36Sopenharmony_ci * nla_get_s8(nla) get payload for a s8 attribute 13662306a36Sopenharmony_ci * nla_get_s16(nla) get payload for a s16 attribute 13762306a36Sopenharmony_ci * nla_get_s32(nla) get payload for a s32 attribute 13862306a36Sopenharmony_ci * nla_get_s64(nla) get payload for a s64 attribute 13962306a36Sopenharmony_ci * nla_get_flag(nla) return 1 if flag is true 14062306a36Sopenharmony_ci * nla_get_msecs(nla) get payload for a msecs attribute 14162306a36Sopenharmony_ci * 14262306a36Sopenharmony_ci * Attribute Misc: 14362306a36Sopenharmony_ci * nla_memcpy(dest, nla, count) copy attribute into memory 14462306a36Sopenharmony_ci * nla_memcmp(nla, data, size) compare attribute with memory area 14562306a36Sopenharmony_ci * nla_strscpy(dst, nla, size) copy attribute to a sized string 14662306a36Sopenharmony_ci * nla_strcmp(nla, str) compare attribute with string 14762306a36Sopenharmony_ci * 14862306a36Sopenharmony_ci * Attribute Parsing: 14962306a36Sopenharmony_ci * nla_ok(nla, remaining) does nla fit into remaining bytes? 15062306a36Sopenharmony_ci * nla_next(nla, remaining) get next netlink attribute 15162306a36Sopenharmony_ci * nla_validate() validate a stream of attributes 15262306a36Sopenharmony_ci * nla_validate_nested() validate a stream of nested attributes 15362306a36Sopenharmony_ci * nla_find() find attribute in stream of attributes 15462306a36Sopenharmony_ci * nla_find_nested() find attribute in nested attributes 15562306a36Sopenharmony_ci * nla_parse() parse and validate stream of attrs 15662306a36Sopenharmony_ci * nla_parse_nested() parse nested attributes 15762306a36Sopenharmony_ci * nla_for_each_attr() loop over all attributes 15862306a36Sopenharmony_ci * nla_for_each_nested() loop over the nested attributes 15962306a36Sopenharmony_ci *========================================================================= 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci /** 16362306a36Sopenharmony_ci * Standard attribute types to specify validation policy 16462306a36Sopenharmony_ci */ 16562306a36Sopenharmony_cienum { 16662306a36Sopenharmony_ci NLA_UNSPEC, 16762306a36Sopenharmony_ci NLA_U8, 16862306a36Sopenharmony_ci NLA_U16, 16962306a36Sopenharmony_ci NLA_U32, 17062306a36Sopenharmony_ci NLA_U64, 17162306a36Sopenharmony_ci NLA_STRING, 17262306a36Sopenharmony_ci NLA_FLAG, 17362306a36Sopenharmony_ci NLA_MSECS, 17462306a36Sopenharmony_ci NLA_NESTED, 17562306a36Sopenharmony_ci NLA_NESTED_ARRAY, 17662306a36Sopenharmony_ci NLA_NUL_STRING, 17762306a36Sopenharmony_ci NLA_BINARY, 17862306a36Sopenharmony_ci NLA_S8, 17962306a36Sopenharmony_ci NLA_S16, 18062306a36Sopenharmony_ci NLA_S32, 18162306a36Sopenharmony_ci NLA_S64, 18262306a36Sopenharmony_ci NLA_BITFIELD32, 18362306a36Sopenharmony_ci NLA_REJECT, 18462306a36Sopenharmony_ci NLA_BE16, 18562306a36Sopenharmony_ci NLA_BE32, 18662306a36Sopenharmony_ci __NLA_TYPE_MAX, 18762306a36Sopenharmony_ci}; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistruct netlink_range_validation { 19262306a36Sopenharmony_ci u64 min, max; 19362306a36Sopenharmony_ci}; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistruct netlink_range_validation_signed { 19662306a36Sopenharmony_ci s64 min, max; 19762306a36Sopenharmony_ci}; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_cienum nla_policy_validation { 20062306a36Sopenharmony_ci NLA_VALIDATE_NONE, 20162306a36Sopenharmony_ci NLA_VALIDATE_RANGE, 20262306a36Sopenharmony_ci NLA_VALIDATE_RANGE_WARN_TOO_LONG, 20362306a36Sopenharmony_ci NLA_VALIDATE_MIN, 20462306a36Sopenharmony_ci NLA_VALIDATE_MAX, 20562306a36Sopenharmony_ci NLA_VALIDATE_MASK, 20662306a36Sopenharmony_ci NLA_VALIDATE_RANGE_PTR, 20762306a36Sopenharmony_ci NLA_VALIDATE_FUNCTION, 20862306a36Sopenharmony_ci}; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci/** 21162306a36Sopenharmony_ci * struct nla_policy - attribute validation policy 21262306a36Sopenharmony_ci * @type: Type of attribute or NLA_UNSPEC 21362306a36Sopenharmony_ci * @validation_type: type of attribute validation done in addition to 21462306a36Sopenharmony_ci * type-specific validation (e.g. range, function call), see 21562306a36Sopenharmony_ci * &enum nla_policy_validation 21662306a36Sopenharmony_ci * @len: Type specific length of payload 21762306a36Sopenharmony_ci * 21862306a36Sopenharmony_ci * Policies are defined as arrays of this struct, the array must be 21962306a36Sopenharmony_ci * accessible by attribute type up to the highest identifier to be expected. 22062306a36Sopenharmony_ci * 22162306a36Sopenharmony_ci * Meaning of `len' field: 22262306a36Sopenharmony_ci * NLA_STRING Maximum length of string 22362306a36Sopenharmony_ci * NLA_NUL_STRING Maximum length of string (excluding NUL) 22462306a36Sopenharmony_ci * NLA_FLAG Unused 22562306a36Sopenharmony_ci * NLA_BINARY Maximum length of attribute payload 22662306a36Sopenharmony_ci * (but see also below with the validation type) 22762306a36Sopenharmony_ci * NLA_NESTED, 22862306a36Sopenharmony_ci * NLA_NESTED_ARRAY Length verification is done by checking len of 22962306a36Sopenharmony_ci * nested header (or empty); len field is used if 23062306a36Sopenharmony_ci * nested_policy is also used, for the max attr 23162306a36Sopenharmony_ci * number in the nested policy. 23262306a36Sopenharmony_ci * NLA_U8, NLA_U16, 23362306a36Sopenharmony_ci * NLA_U32, NLA_U64, 23462306a36Sopenharmony_ci * NLA_S8, NLA_S16, 23562306a36Sopenharmony_ci * NLA_S32, NLA_S64, 23662306a36Sopenharmony_ci * NLA_BE16, NLA_BE32, 23762306a36Sopenharmony_ci * NLA_MSECS Leaving the length field zero will verify the 23862306a36Sopenharmony_ci * given type fits, using it verifies minimum length 23962306a36Sopenharmony_ci * just like "All other" 24062306a36Sopenharmony_ci * NLA_BITFIELD32 Unused 24162306a36Sopenharmony_ci * NLA_REJECT Unused 24262306a36Sopenharmony_ci * All other Minimum length of attribute payload 24362306a36Sopenharmony_ci * 24462306a36Sopenharmony_ci * Meaning of validation union: 24562306a36Sopenharmony_ci * NLA_BITFIELD32 This is a 32-bit bitmap/bitselector attribute and 24662306a36Sopenharmony_ci * `bitfield32_valid' is the u32 value of valid flags 24762306a36Sopenharmony_ci * NLA_REJECT This attribute is always rejected and `reject_message' 24862306a36Sopenharmony_ci * may point to a string to report as the error instead 24962306a36Sopenharmony_ci * of the generic one in extended ACK. 25062306a36Sopenharmony_ci * NLA_NESTED `nested_policy' to a nested policy to validate, must 25162306a36Sopenharmony_ci * also set `len' to the max attribute number. Use the 25262306a36Sopenharmony_ci * provided NLA_POLICY_NESTED() macro. 25362306a36Sopenharmony_ci * Note that nla_parse() will validate, but of course not 25462306a36Sopenharmony_ci * parse, the nested sub-policies. 25562306a36Sopenharmony_ci * NLA_NESTED_ARRAY `nested_policy' points to a nested policy to validate, 25662306a36Sopenharmony_ci * must also set `len' to the max attribute number. Use 25762306a36Sopenharmony_ci * the provided NLA_POLICY_NESTED_ARRAY() macro. 25862306a36Sopenharmony_ci * The difference to NLA_NESTED is the structure: 25962306a36Sopenharmony_ci * NLA_NESTED has the nested attributes directly inside 26062306a36Sopenharmony_ci * while an array has the nested attributes at another 26162306a36Sopenharmony_ci * level down and the attribute types directly in the 26262306a36Sopenharmony_ci * nesting don't matter. 26362306a36Sopenharmony_ci * NLA_U8, 26462306a36Sopenharmony_ci * NLA_U16, 26562306a36Sopenharmony_ci * NLA_U32, 26662306a36Sopenharmony_ci * NLA_U64, 26762306a36Sopenharmony_ci * NLA_BE16, 26862306a36Sopenharmony_ci * NLA_BE32, 26962306a36Sopenharmony_ci * NLA_S8, 27062306a36Sopenharmony_ci * NLA_S16, 27162306a36Sopenharmony_ci * NLA_S32, 27262306a36Sopenharmony_ci * NLA_S64 The `min' and `max' fields are used depending on the 27362306a36Sopenharmony_ci * validation_type field, if that is min/max/range then 27462306a36Sopenharmony_ci * the min, max or both are used (respectively) to check 27562306a36Sopenharmony_ci * the value of the integer attribute. 27662306a36Sopenharmony_ci * Note that in the interest of code simplicity and 27762306a36Sopenharmony_ci * struct size both limits are s16, so you cannot 27862306a36Sopenharmony_ci * enforce a range that doesn't fall within the range 27962306a36Sopenharmony_ci * of s16 - do that using the NLA_POLICY_FULL_RANGE() 28062306a36Sopenharmony_ci * or NLA_POLICY_FULL_RANGE_SIGNED() macros instead. 28162306a36Sopenharmony_ci * Use the NLA_POLICY_MIN(), NLA_POLICY_MAX() and 28262306a36Sopenharmony_ci * NLA_POLICY_RANGE() macros. 28362306a36Sopenharmony_ci * NLA_U8, 28462306a36Sopenharmony_ci * NLA_U16, 28562306a36Sopenharmony_ci * NLA_U32, 28662306a36Sopenharmony_ci * NLA_U64 If the validation_type field instead is set to 28762306a36Sopenharmony_ci * NLA_VALIDATE_RANGE_PTR, `range' must be a pointer 28862306a36Sopenharmony_ci * to a struct netlink_range_validation that indicates 28962306a36Sopenharmony_ci * the min/max values. 29062306a36Sopenharmony_ci * Use NLA_POLICY_FULL_RANGE(). 29162306a36Sopenharmony_ci * NLA_S8, 29262306a36Sopenharmony_ci * NLA_S16, 29362306a36Sopenharmony_ci * NLA_S32, 29462306a36Sopenharmony_ci * NLA_S64 If the validation_type field instead is set to 29562306a36Sopenharmony_ci * NLA_VALIDATE_RANGE_PTR, `range_signed' must be a 29662306a36Sopenharmony_ci * pointer to a struct netlink_range_validation_signed 29762306a36Sopenharmony_ci * that indicates the min/max values. 29862306a36Sopenharmony_ci * Use NLA_POLICY_FULL_RANGE_SIGNED(). 29962306a36Sopenharmony_ci * 30062306a36Sopenharmony_ci * NLA_BINARY If the validation type is like the ones for integers 30162306a36Sopenharmony_ci * above, then the min/max length (not value like for 30262306a36Sopenharmony_ci * integers) of the attribute is enforced. 30362306a36Sopenharmony_ci * 30462306a36Sopenharmony_ci * All other Unused - but note that it's a union 30562306a36Sopenharmony_ci * 30662306a36Sopenharmony_ci * Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN: 30762306a36Sopenharmony_ci * NLA_BINARY Validation function called for the attribute. 30862306a36Sopenharmony_ci * All other Unused - but note that it's a union 30962306a36Sopenharmony_ci * 31062306a36Sopenharmony_ci * Example: 31162306a36Sopenharmony_ci * 31262306a36Sopenharmony_ci * static const u32 myvalidflags = 0xff231023; 31362306a36Sopenharmony_ci * 31462306a36Sopenharmony_ci * static const struct nla_policy my_policy[ATTR_MAX+1] = { 31562306a36Sopenharmony_ci * [ATTR_FOO] = { .type = NLA_U16 }, 31662306a36Sopenharmony_ci * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, 31762306a36Sopenharmony_ci * [ATTR_BAZ] = NLA_POLICY_EXACT_LEN(sizeof(struct mystruct)), 31862306a36Sopenharmony_ci * [ATTR_GOO] = NLA_POLICY_BITFIELD32(myvalidflags), 31962306a36Sopenharmony_ci * }; 32062306a36Sopenharmony_ci */ 32162306a36Sopenharmony_cistruct nla_policy { 32262306a36Sopenharmony_ci u8 type; 32362306a36Sopenharmony_ci u8 validation_type; 32462306a36Sopenharmony_ci u16 len; 32562306a36Sopenharmony_ci union { 32662306a36Sopenharmony_ci /** 32762306a36Sopenharmony_ci * @strict_start_type: first attribute to validate strictly 32862306a36Sopenharmony_ci * 32962306a36Sopenharmony_ci * This entry is special, and used for the attribute at index 0 33062306a36Sopenharmony_ci * only, and specifies special data about the policy, namely it 33162306a36Sopenharmony_ci * specifies the "boundary type" where strict length validation 33262306a36Sopenharmony_ci * starts for any attribute types >= this value, also, strict 33362306a36Sopenharmony_ci * nesting validation starts here. 33462306a36Sopenharmony_ci * 33562306a36Sopenharmony_ci * Additionally, it means that NLA_UNSPEC is actually NLA_REJECT 33662306a36Sopenharmony_ci * for any types >= this, so need to use NLA_POLICY_MIN_LEN() to 33762306a36Sopenharmony_ci * get the previous pure { .len = xyz } behaviour. The advantage 33862306a36Sopenharmony_ci * of this is that types not specified in the policy will be 33962306a36Sopenharmony_ci * rejected. 34062306a36Sopenharmony_ci * 34162306a36Sopenharmony_ci * For completely new families it should be set to 1 so that the 34262306a36Sopenharmony_ci * validation is enforced for all attributes. For existing ones 34362306a36Sopenharmony_ci * it should be set at least when new attributes are added to 34462306a36Sopenharmony_ci * the enum used by the policy, and be set to the new value that 34562306a36Sopenharmony_ci * was added to enforce strict validation from thereon. 34662306a36Sopenharmony_ci */ 34762306a36Sopenharmony_ci u16 strict_start_type; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci /* private: use NLA_POLICY_*() to set */ 35062306a36Sopenharmony_ci const u32 bitfield32_valid; 35162306a36Sopenharmony_ci const u32 mask; 35262306a36Sopenharmony_ci const char *reject_message; 35362306a36Sopenharmony_ci const struct nla_policy *nested_policy; 35462306a36Sopenharmony_ci struct netlink_range_validation *range; 35562306a36Sopenharmony_ci struct netlink_range_validation_signed *range_signed; 35662306a36Sopenharmony_ci struct { 35762306a36Sopenharmony_ci s16 min, max; 35862306a36Sopenharmony_ci }; 35962306a36Sopenharmony_ci int (*validate)(const struct nlattr *attr, 36062306a36Sopenharmony_ci struct netlink_ext_ack *extack); 36162306a36Sopenharmony_ci }; 36262306a36Sopenharmony_ci}; 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci#define NLA_POLICY_ETH_ADDR NLA_POLICY_EXACT_LEN(ETH_ALEN) 36562306a36Sopenharmony_ci#define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN) 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci#define _NLA_POLICY_NESTED(maxattr, policy) \ 36862306a36Sopenharmony_ci { .type = NLA_NESTED, .nested_policy = policy, .len = maxattr } 36962306a36Sopenharmony_ci#define _NLA_POLICY_NESTED_ARRAY(maxattr, policy) \ 37062306a36Sopenharmony_ci { .type = NLA_NESTED_ARRAY, .nested_policy = policy, .len = maxattr } 37162306a36Sopenharmony_ci#define NLA_POLICY_NESTED(policy) \ 37262306a36Sopenharmony_ci _NLA_POLICY_NESTED(ARRAY_SIZE(policy) - 1, policy) 37362306a36Sopenharmony_ci#define NLA_POLICY_NESTED_ARRAY(policy) \ 37462306a36Sopenharmony_ci _NLA_POLICY_NESTED_ARRAY(ARRAY_SIZE(policy) - 1, policy) 37562306a36Sopenharmony_ci#define NLA_POLICY_BITFIELD32(valid) \ 37662306a36Sopenharmony_ci { .type = NLA_BITFIELD32, .bitfield32_valid = valid } 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci#define __NLA_IS_UINT_TYPE(tp) \ 37962306a36Sopenharmony_ci (tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 || \ 38062306a36Sopenharmony_ci tp == NLA_U64 || tp == NLA_BE16 || tp == NLA_BE32) 38162306a36Sopenharmony_ci#define __NLA_IS_SINT_TYPE(tp) \ 38262306a36Sopenharmony_ci (tp == NLA_S8 || tp == NLA_S16 || tp == NLA_S32 || tp == NLA_S64) 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci#define __NLA_ENSURE(condition) BUILD_BUG_ON_ZERO(!(condition)) 38562306a36Sopenharmony_ci#define NLA_ENSURE_UINT_TYPE(tp) \ 38662306a36Sopenharmony_ci (__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp)) + tp) 38762306a36Sopenharmony_ci#define NLA_ENSURE_UINT_OR_BINARY_TYPE(tp) \ 38862306a36Sopenharmony_ci (__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) || \ 38962306a36Sopenharmony_ci tp == NLA_MSECS || \ 39062306a36Sopenharmony_ci tp == NLA_BINARY) + tp) 39162306a36Sopenharmony_ci#define NLA_ENSURE_SINT_TYPE(tp) \ 39262306a36Sopenharmony_ci (__NLA_ENSURE(__NLA_IS_SINT_TYPE(tp)) + tp) 39362306a36Sopenharmony_ci#define NLA_ENSURE_INT_OR_BINARY_TYPE(tp) \ 39462306a36Sopenharmony_ci (__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) || \ 39562306a36Sopenharmony_ci __NLA_IS_SINT_TYPE(tp) || \ 39662306a36Sopenharmony_ci tp == NLA_MSECS || \ 39762306a36Sopenharmony_ci tp == NLA_BINARY) + tp) 39862306a36Sopenharmony_ci#define NLA_ENSURE_NO_VALIDATION_PTR(tp) \ 39962306a36Sopenharmony_ci (__NLA_ENSURE(tp != NLA_BITFIELD32 && \ 40062306a36Sopenharmony_ci tp != NLA_REJECT && \ 40162306a36Sopenharmony_ci tp != NLA_NESTED && \ 40262306a36Sopenharmony_ci tp != NLA_NESTED_ARRAY) + tp) 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci#define NLA_POLICY_RANGE(tp, _min, _max) { \ 40562306a36Sopenharmony_ci .type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \ 40662306a36Sopenharmony_ci .validation_type = NLA_VALIDATE_RANGE, \ 40762306a36Sopenharmony_ci .min = _min, \ 40862306a36Sopenharmony_ci .max = _max \ 40962306a36Sopenharmony_ci} 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci#define NLA_POLICY_FULL_RANGE(tp, _range) { \ 41262306a36Sopenharmony_ci .type = NLA_ENSURE_UINT_OR_BINARY_TYPE(tp), \ 41362306a36Sopenharmony_ci .validation_type = NLA_VALIDATE_RANGE_PTR, \ 41462306a36Sopenharmony_ci .range = _range, \ 41562306a36Sopenharmony_ci} 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci#define NLA_POLICY_FULL_RANGE_SIGNED(tp, _range) { \ 41862306a36Sopenharmony_ci .type = NLA_ENSURE_SINT_TYPE(tp), \ 41962306a36Sopenharmony_ci .validation_type = NLA_VALIDATE_RANGE_PTR, \ 42062306a36Sopenharmony_ci .range_signed = _range, \ 42162306a36Sopenharmony_ci} 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci#define NLA_POLICY_MIN(tp, _min) { \ 42462306a36Sopenharmony_ci .type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \ 42562306a36Sopenharmony_ci .validation_type = NLA_VALIDATE_MIN, \ 42662306a36Sopenharmony_ci .min = _min, \ 42762306a36Sopenharmony_ci} 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci#define NLA_POLICY_MAX(tp, _max) { \ 43062306a36Sopenharmony_ci .type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \ 43162306a36Sopenharmony_ci .validation_type = NLA_VALIDATE_MAX, \ 43262306a36Sopenharmony_ci .max = _max, \ 43362306a36Sopenharmony_ci} 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci#define NLA_POLICY_MASK(tp, _mask) { \ 43662306a36Sopenharmony_ci .type = NLA_ENSURE_UINT_TYPE(tp), \ 43762306a36Sopenharmony_ci .validation_type = NLA_VALIDATE_MASK, \ 43862306a36Sopenharmony_ci .mask = _mask, \ 43962306a36Sopenharmony_ci} 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci#define NLA_POLICY_VALIDATE_FN(tp, fn, ...) { \ 44262306a36Sopenharmony_ci .type = NLA_ENSURE_NO_VALIDATION_PTR(tp), \ 44362306a36Sopenharmony_ci .validation_type = NLA_VALIDATE_FUNCTION, \ 44462306a36Sopenharmony_ci .validate = fn, \ 44562306a36Sopenharmony_ci .len = __VA_ARGS__ + 0, \ 44662306a36Sopenharmony_ci} 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci#define NLA_POLICY_EXACT_LEN(_len) NLA_POLICY_RANGE(NLA_BINARY, _len, _len) 44962306a36Sopenharmony_ci#define NLA_POLICY_EXACT_LEN_WARN(_len) { \ 45062306a36Sopenharmony_ci .type = NLA_BINARY, \ 45162306a36Sopenharmony_ci .validation_type = NLA_VALIDATE_RANGE_WARN_TOO_LONG, \ 45262306a36Sopenharmony_ci .min = _len, \ 45362306a36Sopenharmony_ci .max = _len \ 45462306a36Sopenharmony_ci} 45562306a36Sopenharmony_ci#define NLA_POLICY_MIN_LEN(_len) NLA_POLICY_MIN(NLA_BINARY, _len) 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci/** 45862306a36Sopenharmony_ci * struct nl_info - netlink source information 45962306a36Sopenharmony_ci * @nlh: Netlink message header of original request 46062306a36Sopenharmony_ci * @nl_net: Network namespace 46162306a36Sopenharmony_ci * @portid: Netlink PORTID of requesting application 46262306a36Sopenharmony_ci * @skip_notify: Skip netlink notifications to user space 46362306a36Sopenharmony_ci * @skip_notify_kernel: Skip selected in-kernel notifications 46462306a36Sopenharmony_ci */ 46562306a36Sopenharmony_cistruct nl_info { 46662306a36Sopenharmony_ci struct nlmsghdr *nlh; 46762306a36Sopenharmony_ci struct net *nl_net; 46862306a36Sopenharmony_ci u32 portid; 46962306a36Sopenharmony_ci u8 skip_notify:1, 47062306a36Sopenharmony_ci skip_notify_kernel:1; 47162306a36Sopenharmony_ci}; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci/** 47462306a36Sopenharmony_ci * enum netlink_validation - netlink message/attribute validation levels 47562306a36Sopenharmony_ci * @NL_VALIDATE_LIBERAL: Old-style "be liberal" validation, not caring about 47662306a36Sopenharmony_ci * extra data at the end of the message, attributes being longer than 47762306a36Sopenharmony_ci * they should be, or unknown attributes being present. 47862306a36Sopenharmony_ci * @NL_VALIDATE_TRAILING: Reject junk data encountered after attribute parsing. 47962306a36Sopenharmony_ci * @NL_VALIDATE_MAXTYPE: Reject attributes > max type; Together with _TRAILING 48062306a36Sopenharmony_ci * this is equivalent to the old nla_parse_strict()/nlmsg_parse_strict(). 48162306a36Sopenharmony_ci * @NL_VALIDATE_UNSPEC: Reject attributes with NLA_UNSPEC in the policy. 48262306a36Sopenharmony_ci * This can safely be set by the kernel when the given policy has no 48362306a36Sopenharmony_ci * NLA_UNSPEC anymore, and can thus be used to ensure policy entries 48462306a36Sopenharmony_ci * are enforced going forward. 48562306a36Sopenharmony_ci * @NL_VALIDATE_STRICT_ATTRS: strict attribute policy parsing (e.g. 48662306a36Sopenharmony_ci * U8, U16, U32 must have exact size, etc.) 48762306a36Sopenharmony_ci * @NL_VALIDATE_NESTED: Check that NLA_F_NESTED is set for NLA_NESTED(_ARRAY) 48862306a36Sopenharmony_ci * and unset for other policies. 48962306a36Sopenharmony_ci */ 49062306a36Sopenharmony_cienum netlink_validation { 49162306a36Sopenharmony_ci NL_VALIDATE_LIBERAL = 0, 49262306a36Sopenharmony_ci NL_VALIDATE_TRAILING = BIT(0), 49362306a36Sopenharmony_ci NL_VALIDATE_MAXTYPE = BIT(1), 49462306a36Sopenharmony_ci NL_VALIDATE_UNSPEC = BIT(2), 49562306a36Sopenharmony_ci NL_VALIDATE_STRICT_ATTRS = BIT(3), 49662306a36Sopenharmony_ci NL_VALIDATE_NESTED = BIT(4), 49762306a36Sopenharmony_ci}; 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci#define NL_VALIDATE_DEPRECATED_STRICT (NL_VALIDATE_TRAILING |\ 50062306a36Sopenharmony_ci NL_VALIDATE_MAXTYPE) 50162306a36Sopenharmony_ci#define NL_VALIDATE_STRICT (NL_VALIDATE_TRAILING |\ 50262306a36Sopenharmony_ci NL_VALIDATE_MAXTYPE |\ 50362306a36Sopenharmony_ci NL_VALIDATE_UNSPEC |\ 50462306a36Sopenharmony_ci NL_VALIDATE_STRICT_ATTRS |\ 50562306a36Sopenharmony_ci NL_VALIDATE_NESTED) 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ciint netlink_rcv_skb(struct sk_buff *skb, 50862306a36Sopenharmony_ci int (*cb)(struct sk_buff *, struct nlmsghdr *, 50962306a36Sopenharmony_ci struct netlink_ext_ack *)); 51062306a36Sopenharmony_ciint nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid, 51162306a36Sopenharmony_ci unsigned int group, int report, gfp_t flags); 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ciint __nla_validate(const struct nlattr *head, int len, int maxtype, 51462306a36Sopenharmony_ci const struct nla_policy *policy, unsigned int validate, 51562306a36Sopenharmony_ci struct netlink_ext_ack *extack); 51662306a36Sopenharmony_ciint __nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, 51762306a36Sopenharmony_ci int len, const struct nla_policy *policy, unsigned int validate, 51862306a36Sopenharmony_ci struct netlink_ext_ack *extack); 51962306a36Sopenharmony_ciint nla_policy_len(const struct nla_policy *, int); 52062306a36Sopenharmony_cistruct nlattr *nla_find(const struct nlattr *head, int len, int attrtype); 52162306a36Sopenharmony_cissize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize); 52262306a36Sopenharmony_cichar *nla_strdup(const struct nlattr *nla, gfp_t flags); 52362306a36Sopenharmony_ciint nla_memcpy(void *dest, const struct nlattr *src, int count); 52462306a36Sopenharmony_ciint nla_memcmp(const struct nlattr *nla, const void *data, size_t size); 52562306a36Sopenharmony_ciint nla_strcmp(const struct nlattr *nla, const char *str); 52662306a36Sopenharmony_cistruct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen); 52762306a36Sopenharmony_cistruct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype, 52862306a36Sopenharmony_ci int attrlen, int padattr); 52962306a36Sopenharmony_civoid *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen); 53062306a36Sopenharmony_cistruct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen); 53162306a36Sopenharmony_cistruct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype, 53262306a36Sopenharmony_ci int attrlen, int padattr); 53362306a36Sopenharmony_civoid *nla_reserve_nohdr(struct sk_buff *skb, int attrlen); 53462306a36Sopenharmony_civoid __nla_put(struct sk_buff *skb, int attrtype, int attrlen, 53562306a36Sopenharmony_ci const void *data); 53662306a36Sopenharmony_civoid __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen, 53762306a36Sopenharmony_ci const void *data, int padattr); 53862306a36Sopenharmony_civoid __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data); 53962306a36Sopenharmony_ciint nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data); 54062306a36Sopenharmony_ciint nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen, 54162306a36Sopenharmony_ci const void *data, int padattr); 54262306a36Sopenharmony_ciint nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data); 54362306a36Sopenharmony_ciint nla_append(struct sk_buff *skb, int attrlen, const void *data); 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci/************************************************************************** 54662306a36Sopenharmony_ci * Netlink Messages 54762306a36Sopenharmony_ci **************************************************************************/ 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci/** 55062306a36Sopenharmony_ci * nlmsg_msg_size - length of netlink message not including padding 55162306a36Sopenharmony_ci * @payload: length of message payload 55262306a36Sopenharmony_ci */ 55362306a36Sopenharmony_cistatic inline int nlmsg_msg_size(int payload) 55462306a36Sopenharmony_ci{ 55562306a36Sopenharmony_ci return NLMSG_HDRLEN + payload; 55662306a36Sopenharmony_ci} 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci/** 55962306a36Sopenharmony_ci * nlmsg_total_size - length of netlink message including padding 56062306a36Sopenharmony_ci * @payload: length of message payload 56162306a36Sopenharmony_ci */ 56262306a36Sopenharmony_cistatic inline int nlmsg_total_size(int payload) 56362306a36Sopenharmony_ci{ 56462306a36Sopenharmony_ci return NLMSG_ALIGN(nlmsg_msg_size(payload)); 56562306a36Sopenharmony_ci} 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci/** 56862306a36Sopenharmony_ci * nlmsg_padlen - length of padding at the message's tail 56962306a36Sopenharmony_ci * @payload: length of message payload 57062306a36Sopenharmony_ci */ 57162306a36Sopenharmony_cistatic inline int nlmsg_padlen(int payload) 57262306a36Sopenharmony_ci{ 57362306a36Sopenharmony_ci return nlmsg_total_size(payload) - nlmsg_msg_size(payload); 57462306a36Sopenharmony_ci} 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci/** 57762306a36Sopenharmony_ci * nlmsg_data - head of message payload 57862306a36Sopenharmony_ci * @nlh: netlink message header 57962306a36Sopenharmony_ci */ 58062306a36Sopenharmony_cistatic inline void *nlmsg_data(const struct nlmsghdr *nlh) 58162306a36Sopenharmony_ci{ 58262306a36Sopenharmony_ci return (unsigned char *) nlh + NLMSG_HDRLEN; 58362306a36Sopenharmony_ci} 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci/** 58662306a36Sopenharmony_ci * nlmsg_len - length of message payload 58762306a36Sopenharmony_ci * @nlh: netlink message header 58862306a36Sopenharmony_ci */ 58962306a36Sopenharmony_cistatic inline int nlmsg_len(const struct nlmsghdr *nlh) 59062306a36Sopenharmony_ci{ 59162306a36Sopenharmony_ci return nlh->nlmsg_len - NLMSG_HDRLEN; 59262306a36Sopenharmony_ci} 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci/** 59562306a36Sopenharmony_ci * nlmsg_attrdata - head of attributes data 59662306a36Sopenharmony_ci * @nlh: netlink message header 59762306a36Sopenharmony_ci * @hdrlen: length of family specific header 59862306a36Sopenharmony_ci */ 59962306a36Sopenharmony_cistatic inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, 60062306a36Sopenharmony_ci int hdrlen) 60162306a36Sopenharmony_ci{ 60262306a36Sopenharmony_ci unsigned char *data = nlmsg_data(nlh); 60362306a36Sopenharmony_ci return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen)); 60462306a36Sopenharmony_ci} 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ci/** 60762306a36Sopenharmony_ci * nlmsg_attrlen - length of attributes data 60862306a36Sopenharmony_ci * @nlh: netlink message header 60962306a36Sopenharmony_ci * @hdrlen: length of family specific header 61062306a36Sopenharmony_ci */ 61162306a36Sopenharmony_cistatic inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen) 61262306a36Sopenharmony_ci{ 61362306a36Sopenharmony_ci return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen); 61462306a36Sopenharmony_ci} 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci/** 61762306a36Sopenharmony_ci * nlmsg_ok - check if the netlink message fits into the remaining bytes 61862306a36Sopenharmony_ci * @nlh: netlink message header 61962306a36Sopenharmony_ci * @remaining: number of bytes remaining in message stream 62062306a36Sopenharmony_ci */ 62162306a36Sopenharmony_cistatic inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining) 62262306a36Sopenharmony_ci{ 62362306a36Sopenharmony_ci return (remaining >= (int) sizeof(struct nlmsghdr) && 62462306a36Sopenharmony_ci nlh->nlmsg_len >= sizeof(struct nlmsghdr) && 62562306a36Sopenharmony_ci nlh->nlmsg_len <= remaining); 62662306a36Sopenharmony_ci} 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci/** 62962306a36Sopenharmony_ci * nlmsg_next - next netlink message in message stream 63062306a36Sopenharmony_ci * @nlh: netlink message header 63162306a36Sopenharmony_ci * @remaining: number of bytes remaining in message stream 63262306a36Sopenharmony_ci * 63362306a36Sopenharmony_ci * Returns the next netlink message in the message stream and 63462306a36Sopenharmony_ci * decrements remaining by the size of the current message. 63562306a36Sopenharmony_ci */ 63662306a36Sopenharmony_cistatic inline struct nlmsghdr * 63762306a36Sopenharmony_cinlmsg_next(const struct nlmsghdr *nlh, int *remaining) 63862306a36Sopenharmony_ci{ 63962306a36Sopenharmony_ci int totlen = NLMSG_ALIGN(nlh->nlmsg_len); 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci *remaining -= totlen; 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci return (struct nlmsghdr *) ((unsigned char *) nlh + totlen); 64462306a36Sopenharmony_ci} 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci/** 64762306a36Sopenharmony_ci * nla_parse - Parse a stream of attributes into a tb buffer 64862306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 64962306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 65062306a36Sopenharmony_ci * @head: head of attribute stream 65162306a36Sopenharmony_ci * @len: length of attribute stream 65262306a36Sopenharmony_ci * @policy: validation policy 65362306a36Sopenharmony_ci * @extack: extended ACK pointer 65462306a36Sopenharmony_ci * 65562306a36Sopenharmony_ci * Parses a stream of attributes and stores a pointer to each attribute in 65662306a36Sopenharmony_ci * the tb array accessible via the attribute type. Attributes with a type 65762306a36Sopenharmony_ci * exceeding maxtype will be rejected, policy must be specified, attributes 65862306a36Sopenharmony_ci * will be validated in the strictest way possible. 65962306a36Sopenharmony_ci * 66062306a36Sopenharmony_ci * Returns 0 on success or a negative error code. 66162306a36Sopenharmony_ci */ 66262306a36Sopenharmony_cistatic inline int nla_parse(struct nlattr **tb, int maxtype, 66362306a36Sopenharmony_ci const struct nlattr *head, int len, 66462306a36Sopenharmony_ci const struct nla_policy *policy, 66562306a36Sopenharmony_ci struct netlink_ext_ack *extack) 66662306a36Sopenharmony_ci{ 66762306a36Sopenharmony_ci return __nla_parse(tb, maxtype, head, len, policy, 66862306a36Sopenharmony_ci NL_VALIDATE_STRICT, extack); 66962306a36Sopenharmony_ci} 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci/** 67262306a36Sopenharmony_ci * nla_parse_deprecated - Parse a stream of attributes into a tb buffer 67362306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 67462306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 67562306a36Sopenharmony_ci * @head: head of attribute stream 67662306a36Sopenharmony_ci * @len: length of attribute stream 67762306a36Sopenharmony_ci * @policy: validation policy 67862306a36Sopenharmony_ci * @extack: extended ACK pointer 67962306a36Sopenharmony_ci * 68062306a36Sopenharmony_ci * Parses a stream of attributes and stores a pointer to each attribute in 68162306a36Sopenharmony_ci * the tb array accessible via the attribute type. Attributes with a type 68262306a36Sopenharmony_ci * exceeding maxtype will be ignored and attributes from the policy are not 68362306a36Sopenharmony_ci * always strictly validated (only for new attributes). 68462306a36Sopenharmony_ci * 68562306a36Sopenharmony_ci * Returns 0 on success or a negative error code. 68662306a36Sopenharmony_ci */ 68762306a36Sopenharmony_cistatic inline int nla_parse_deprecated(struct nlattr **tb, int maxtype, 68862306a36Sopenharmony_ci const struct nlattr *head, int len, 68962306a36Sopenharmony_ci const struct nla_policy *policy, 69062306a36Sopenharmony_ci struct netlink_ext_ack *extack) 69162306a36Sopenharmony_ci{ 69262306a36Sopenharmony_ci return __nla_parse(tb, maxtype, head, len, policy, 69362306a36Sopenharmony_ci NL_VALIDATE_LIBERAL, extack); 69462306a36Sopenharmony_ci} 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci/** 69762306a36Sopenharmony_ci * nla_parse_deprecated_strict - Parse a stream of attributes into a tb buffer 69862306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 69962306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 70062306a36Sopenharmony_ci * @head: head of attribute stream 70162306a36Sopenharmony_ci * @len: length of attribute stream 70262306a36Sopenharmony_ci * @policy: validation policy 70362306a36Sopenharmony_ci * @extack: extended ACK pointer 70462306a36Sopenharmony_ci * 70562306a36Sopenharmony_ci * Parses a stream of attributes and stores a pointer to each attribute in 70662306a36Sopenharmony_ci * the tb array accessible via the attribute type. Attributes with a type 70762306a36Sopenharmony_ci * exceeding maxtype will be rejected as well as trailing data, but the 70862306a36Sopenharmony_ci * policy is not completely strictly validated (only for new attributes). 70962306a36Sopenharmony_ci * 71062306a36Sopenharmony_ci * Returns 0 on success or a negative error code. 71162306a36Sopenharmony_ci */ 71262306a36Sopenharmony_cistatic inline int nla_parse_deprecated_strict(struct nlattr **tb, int maxtype, 71362306a36Sopenharmony_ci const struct nlattr *head, 71462306a36Sopenharmony_ci int len, 71562306a36Sopenharmony_ci const struct nla_policy *policy, 71662306a36Sopenharmony_ci struct netlink_ext_ack *extack) 71762306a36Sopenharmony_ci{ 71862306a36Sopenharmony_ci return __nla_parse(tb, maxtype, head, len, policy, 71962306a36Sopenharmony_ci NL_VALIDATE_DEPRECATED_STRICT, extack); 72062306a36Sopenharmony_ci} 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci/** 72362306a36Sopenharmony_ci * __nlmsg_parse - parse attributes of a netlink message 72462306a36Sopenharmony_ci * @nlh: netlink message header 72562306a36Sopenharmony_ci * @hdrlen: length of family specific header 72662306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 72762306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 72862306a36Sopenharmony_ci * @policy: validation policy 72962306a36Sopenharmony_ci * @validate: validation strictness 73062306a36Sopenharmony_ci * @extack: extended ACK report struct 73162306a36Sopenharmony_ci * 73262306a36Sopenharmony_ci * See nla_parse() 73362306a36Sopenharmony_ci */ 73462306a36Sopenharmony_cistatic inline int __nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, 73562306a36Sopenharmony_ci struct nlattr *tb[], int maxtype, 73662306a36Sopenharmony_ci const struct nla_policy *policy, 73762306a36Sopenharmony_ci unsigned int validate, 73862306a36Sopenharmony_ci struct netlink_ext_ack *extack) 73962306a36Sopenharmony_ci{ 74062306a36Sopenharmony_ci if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) { 74162306a36Sopenharmony_ci NL_SET_ERR_MSG(extack, "Invalid header length"); 74262306a36Sopenharmony_ci return -EINVAL; 74362306a36Sopenharmony_ci } 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci return __nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen), 74662306a36Sopenharmony_ci nlmsg_attrlen(nlh, hdrlen), policy, validate, 74762306a36Sopenharmony_ci extack); 74862306a36Sopenharmony_ci} 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci/** 75162306a36Sopenharmony_ci * nlmsg_parse - parse attributes of a netlink message 75262306a36Sopenharmony_ci * @nlh: netlink message header 75362306a36Sopenharmony_ci * @hdrlen: length of family specific header 75462306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 75562306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 75662306a36Sopenharmony_ci * @policy: validation policy 75762306a36Sopenharmony_ci * @extack: extended ACK report struct 75862306a36Sopenharmony_ci * 75962306a36Sopenharmony_ci * See nla_parse() 76062306a36Sopenharmony_ci */ 76162306a36Sopenharmony_cistatic inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, 76262306a36Sopenharmony_ci struct nlattr *tb[], int maxtype, 76362306a36Sopenharmony_ci const struct nla_policy *policy, 76462306a36Sopenharmony_ci struct netlink_ext_ack *extack) 76562306a36Sopenharmony_ci{ 76662306a36Sopenharmony_ci return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy, 76762306a36Sopenharmony_ci NL_VALIDATE_STRICT, extack); 76862306a36Sopenharmony_ci} 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ci/** 77162306a36Sopenharmony_ci * nlmsg_parse_deprecated - parse attributes of a netlink message 77262306a36Sopenharmony_ci * @nlh: netlink message header 77362306a36Sopenharmony_ci * @hdrlen: length of family specific header 77462306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 77562306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 77662306a36Sopenharmony_ci * @policy: validation policy 77762306a36Sopenharmony_ci * @extack: extended ACK report struct 77862306a36Sopenharmony_ci * 77962306a36Sopenharmony_ci * See nla_parse_deprecated() 78062306a36Sopenharmony_ci */ 78162306a36Sopenharmony_cistatic inline int nlmsg_parse_deprecated(const struct nlmsghdr *nlh, int hdrlen, 78262306a36Sopenharmony_ci struct nlattr *tb[], int maxtype, 78362306a36Sopenharmony_ci const struct nla_policy *policy, 78462306a36Sopenharmony_ci struct netlink_ext_ack *extack) 78562306a36Sopenharmony_ci{ 78662306a36Sopenharmony_ci return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy, 78762306a36Sopenharmony_ci NL_VALIDATE_LIBERAL, extack); 78862306a36Sopenharmony_ci} 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci/** 79162306a36Sopenharmony_ci * nlmsg_parse_deprecated_strict - parse attributes of a netlink message 79262306a36Sopenharmony_ci * @nlh: netlink message header 79362306a36Sopenharmony_ci * @hdrlen: length of family specific header 79462306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 79562306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 79662306a36Sopenharmony_ci * @policy: validation policy 79762306a36Sopenharmony_ci * @extack: extended ACK report struct 79862306a36Sopenharmony_ci * 79962306a36Sopenharmony_ci * See nla_parse_deprecated_strict() 80062306a36Sopenharmony_ci */ 80162306a36Sopenharmony_cistatic inline int 80262306a36Sopenharmony_cinlmsg_parse_deprecated_strict(const struct nlmsghdr *nlh, int hdrlen, 80362306a36Sopenharmony_ci struct nlattr *tb[], int maxtype, 80462306a36Sopenharmony_ci const struct nla_policy *policy, 80562306a36Sopenharmony_ci struct netlink_ext_ack *extack) 80662306a36Sopenharmony_ci{ 80762306a36Sopenharmony_ci return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy, 80862306a36Sopenharmony_ci NL_VALIDATE_DEPRECATED_STRICT, extack); 80962306a36Sopenharmony_ci} 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci/** 81262306a36Sopenharmony_ci * nlmsg_find_attr - find a specific attribute in a netlink message 81362306a36Sopenharmony_ci * @nlh: netlink message header 81462306a36Sopenharmony_ci * @hdrlen: length of familiy specific header 81562306a36Sopenharmony_ci * @attrtype: type of attribute to look for 81662306a36Sopenharmony_ci * 81762306a36Sopenharmony_ci * Returns the first attribute which matches the specified type. 81862306a36Sopenharmony_ci */ 81962306a36Sopenharmony_cistatic inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, 82062306a36Sopenharmony_ci int hdrlen, int attrtype) 82162306a36Sopenharmony_ci{ 82262306a36Sopenharmony_ci return nla_find(nlmsg_attrdata(nlh, hdrlen), 82362306a36Sopenharmony_ci nlmsg_attrlen(nlh, hdrlen), attrtype); 82462306a36Sopenharmony_ci} 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci/** 82762306a36Sopenharmony_ci * nla_validate_deprecated - Validate a stream of attributes 82862306a36Sopenharmony_ci * @head: head of attribute stream 82962306a36Sopenharmony_ci * @len: length of attribute stream 83062306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 83162306a36Sopenharmony_ci * @policy: validation policy 83262306a36Sopenharmony_ci * @extack: extended ACK report struct 83362306a36Sopenharmony_ci * 83462306a36Sopenharmony_ci * Validates all attributes in the specified attribute stream against the 83562306a36Sopenharmony_ci * specified policy. Validation is done in liberal mode. 83662306a36Sopenharmony_ci * See documenation of struct nla_policy for more details. 83762306a36Sopenharmony_ci * 83862306a36Sopenharmony_ci * Returns 0 on success or a negative error code. 83962306a36Sopenharmony_ci */ 84062306a36Sopenharmony_cistatic inline int nla_validate_deprecated(const struct nlattr *head, int len, 84162306a36Sopenharmony_ci int maxtype, 84262306a36Sopenharmony_ci const struct nla_policy *policy, 84362306a36Sopenharmony_ci struct netlink_ext_ack *extack) 84462306a36Sopenharmony_ci{ 84562306a36Sopenharmony_ci return __nla_validate(head, len, maxtype, policy, NL_VALIDATE_LIBERAL, 84662306a36Sopenharmony_ci extack); 84762306a36Sopenharmony_ci} 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci/** 85062306a36Sopenharmony_ci * nla_validate - Validate a stream of attributes 85162306a36Sopenharmony_ci * @head: head of attribute stream 85262306a36Sopenharmony_ci * @len: length of attribute stream 85362306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 85462306a36Sopenharmony_ci * @policy: validation policy 85562306a36Sopenharmony_ci * @extack: extended ACK report struct 85662306a36Sopenharmony_ci * 85762306a36Sopenharmony_ci * Validates all attributes in the specified attribute stream against the 85862306a36Sopenharmony_ci * specified policy. Validation is done in strict mode. 85962306a36Sopenharmony_ci * See documenation of struct nla_policy for more details. 86062306a36Sopenharmony_ci * 86162306a36Sopenharmony_ci * Returns 0 on success or a negative error code. 86262306a36Sopenharmony_ci */ 86362306a36Sopenharmony_cistatic inline int nla_validate(const struct nlattr *head, int len, int maxtype, 86462306a36Sopenharmony_ci const struct nla_policy *policy, 86562306a36Sopenharmony_ci struct netlink_ext_ack *extack) 86662306a36Sopenharmony_ci{ 86762306a36Sopenharmony_ci return __nla_validate(head, len, maxtype, policy, NL_VALIDATE_STRICT, 86862306a36Sopenharmony_ci extack); 86962306a36Sopenharmony_ci} 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci/** 87262306a36Sopenharmony_ci * nlmsg_validate_deprecated - validate a netlink message including attributes 87362306a36Sopenharmony_ci * @nlh: netlinket message header 87462306a36Sopenharmony_ci * @hdrlen: length of familiy specific header 87562306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 87662306a36Sopenharmony_ci * @policy: validation policy 87762306a36Sopenharmony_ci * @extack: extended ACK report struct 87862306a36Sopenharmony_ci */ 87962306a36Sopenharmony_cistatic inline int nlmsg_validate_deprecated(const struct nlmsghdr *nlh, 88062306a36Sopenharmony_ci int hdrlen, int maxtype, 88162306a36Sopenharmony_ci const struct nla_policy *policy, 88262306a36Sopenharmony_ci struct netlink_ext_ack *extack) 88362306a36Sopenharmony_ci{ 88462306a36Sopenharmony_ci if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 88562306a36Sopenharmony_ci return -EINVAL; 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci return __nla_validate(nlmsg_attrdata(nlh, hdrlen), 88862306a36Sopenharmony_ci nlmsg_attrlen(nlh, hdrlen), maxtype, 88962306a36Sopenharmony_ci policy, NL_VALIDATE_LIBERAL, extack); 89062306a36Sopenharmony_ci} 89162306a36Sopenharmony_ci 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci/** 89562306a36Sopenharmony_ci * nlmsg_report - need to report back to application? 89662306a36Sopenharmony_ci * @nlh: netlink message header 89762306a36Sopenharmony_ci * 89862306a36Sopenharmony_ci * Returns 1 if a report back to the application is requested. 89962306a36Sopenharmony_ci */ 90062306a36Sopenharmony_cistatic inline int nlmsg_report(const struct nlmsghdr *nlh) 90162306a36Sopenharmony_ci{ 90262306a36Sopenharmony_ci return nlh ? !!(nlh->nlmsg_flags & NLM_F_ECHO) : 0; 90362306a36Sopenharmony_ci} 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci/** 90662306a36Sopenharmony_ci * nlmsg_seq - return the seq number of netlink message 90762306a36Sopenharmony_ci * @nlh: netlink message header 90862306a36Sopenharmony_ci * 90962306a36Sopenharmony_ci * Returns 0 if netlink message is NULL 91062306a36Sopenharmony_ci */ 91162306a36Sopenharmony_cistatic inline u32 nlmsg_seq(const struct nlmsghdr *nlh) 91262306a36Sopenharmony_ci{ 91362306a36Sopenharmony_ci return nlh ? nlh->nlmsg_seq : 0; 91462306a36Sopenharmony_ci} 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci/** 91762306a36Sopenharmony_ci * nlmsg_for_each_attr - iterate over a stream of attributes 91862306a36Sopenharmony_ci * @pos: loop counter, set to current attribute 91962306a36Sopenharmony_ci * @nlh: netlink message header 92062306a36Sopenharmony_ci * @hdrlen: length of familiy specific header 92162306a36Sopenharmony_ci * @rem: initialized to len, holds bytes currently remaining in stream 92262306a36Sopenharmony_ci */ 92362306a36Sopenharmony_ci#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ 92462306a36Sopenharmony_ci nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \ 92562306a36Sopenharmony_ci nlmsg_attrlen(nlh, hdrlen), rem) 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci/** 92862306a36Sopenharmony_ci * nlmsg_put - Add a new netlink message to an skb 92962306a36Sopenharmony_ci * @skb: socket buffer to store message in 93062306a36Sopenharmony_ci * @portid: netlink PORTID of requesting application 93162306a36Sopenharmony_ci * @seq: sequence number of message 93262306a36Sopenharmony_ci * @type: message type 93362306a36Sopenharmony_ci * @payload: length of message payload 93462306a36Sopenharmony_ci * @flags: message flags 93562306a36Sopenharmony_ci * 93662306a36Sopenharmony_ci * Returns NULL if the tailroom of the skb is insufficient to store 93762306a36Sopenharmony_ci * the message header and payload. 93862306a36Sopenharmony_ci */ 93962306a36Sopenharmony_cistatic inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, 94062306a36Sopenharmony_ci int type, int payload, int flags) 94162306a36Sopenharmony_ci{ 94262306a36Sopenharmony_ci if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload))) 94362306a36Sopenharmony_ci return NULL; 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci return __nlmsg_put(skb, portid, seq, type, payload, flags); 94662306a36Sopenharmony_ci} 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_ci/** 94962306a36Sopenharmony_ci * nlmsg_append - Add more data to a nlmsg in a skb 95062306a36Sopenharmony_ci * @skb: socket buffer to store message in 95162306a36Sopenharmony_ci * @size: length of message payload 95262306a36Sopenharmony_ci * 95362306a36Sopenharmony_ci * Append data to an existing nlmsg, used when constructing a message 95462306a36Sopenharmony_ci * with multiple fixed-format headers (which is rare). 95562306a36Sopenharmony_ci * Returns NULL if the tailroom of the skb is insufficient to store 95662306a36Sopenharmony_ci * the extra payload. 95762306a36Sopenharmony_ci */ 95862306a36Sopenharmony_cistatic inline void *nlmsg_append(struct sk_buff *skb, u32 size) 95962306a36Sopenharmony_ci{ 96062306a36Sopenharmony_ci if (unlikely(skb_tailroom(skb) < NLMSG_ALIGN(size))) 96162306a36Sopenharmony_ci return NULL; 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci if (NLMSG_ALIGN(size) - size) 96462306a36Sopenharmony_ci memset(skb_tail_pointer(skb) + size, 0, 96562306a36Sopenharmony_ci NLMSG_ALIGN(size) - size); 96662306a36Sopenharmony_ci return __skb_put(skb, NLMSG_ALIGN(size)); 96762306a36Sopenharmony_ci} 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci/** 97062306a36Sopenharmony_ci * nlmsg_put_answer - Add a new callback based netlink message to an skb 97162306a36Sopenharmony_ci * @skb: socket buffer to store message in 97262306a36Sopenharmony_ci * @cb: netlink callback 97362306a36Sopenharmony_ci * @type: message type 97462306a36Sopenharmony_ci * @payload: length of message payload 97562306a36Sopenharmony_ci * @flags: message flags 97662306a36Sopenharmony_ci * 97762306a36Sopenharmony_ci * Returns NULL if the tailroom of the skb is insufficient to store 97862306a36Sopenharmony_ci * the message header and payload. 97962306a36Sopenharmony_ci */ 98062306a36Sopenharmony_cistatic inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, 98162306a36Sopenharmony_ci struct netlink_callback *cb, 98262306a36Sopenharmony_ci int type, int payload, 98362306a36Sopenharmony_ci int flags) 98462306a36Sopenharmony_ci{ 98562306a36Sopenharmony_ci return nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 98662306a36Sopenharmony_ci type, payload, flags); 98762306a36Sopenharmony_ci} 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci/** 99062306a36Sopenharmony_ci * nlmsg_new - Allocate a new netlink message 99162306a36Sopenharmony_ci * @payload: size of the message payload 99262306a36Sopenharmony_ci * @flags: the type of memory to allocate. 99362306a36Sopenharmony_ci * 99462306a36Sopenharmony_ci * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known 99562306a36Sopenharmony_ci * and a good default is needed. 99662306a36Sopenharmony_ci */ 99762306a36Sopenharmony_cistatic inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags) 99862306a36Sopenharmony_ci{ 99962306a36Sopenharmony_ci return alloc_skb(nlmsg_total_size(payload), flags); 100062306a36Sopenharmony_ci} 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci/** 100362306a36Sopenharmony_ci * nlmsg_end - Finalize a netlink message 100462306a36Sopenharmony_ci * @skb: socket buffer the message is stored in 100562306a36Sopenharmony_ci * @nlh: netlink message header 100662306a36Sopenharmony_ci * 100762306a36Sopenharmony_ci * Corrects the netlink message header to include the appeneded 100862306a36Sopenharmony_ci * attributes. Only necessary if attributes have been added to 100962306a36Sopenharmony_ci * the message. 101062306a36Sopenharmony_ci */ 101162306a36Sopenharmony_cistatic inline void nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh) 101262306a36Sopenharmony_ci{ 101362306a36Sopenharmony_ci nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh; 101462306a36Sopenharmony_ci} 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci/** 101762306a36Sopenharmony_ci * nlmsg_get_pos - return current position in netlink message 101862306a36Sopenharmony_ci * @skb: socket buffer the message is stored in 101962306a36Sopenharmony_ci * 102062306a36Sopenharmony_ci * Returns a pointer to the current tail of the message. 102162306a36Sopenharmony_ci */ 102262306a36Sopenharmony_cistatic inline void *nlmsg_get_pos(struct sk_buff *skb) 102362306a36Sopenharmony_ci{ 102462306a36Sopenharmony_ci return skb_tail_pointer(skb); 102562306a36Sopenharmony_ci} 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci/** 102862306a36Sopenharmony_ci * nlmsg_trim - Trim message to a mark 102962306a36Sopenharmony_ci * @skb: socket buffer the message is stored in 103062306a36Sopenharmony_ci * @mark: mark to trim to 103162306a36Sopenharmony_ci * 103262306a36Sopenharmony_ci * Trims the message to the provided mark. 103362306a36Sopenharmony_ci */ 103462306a36Sopenharmony_cistatic inline void nlmsg_trim(struct sk_buff *skb, const void *mark) 103562306a36Sopenharmony_ci{ 103662306a36Sopenharmony_ci if (mark) { 103762306a36Sopenharmony_ci WARN_ON((unsigned char *) mark < skb->data); 103862306a36Sopenharmony_ci skb_trim(skb, (unsigned char *) mark - skb->data); 103962306a36Sopenharmony_ci } 104062306a36Sopenharmony_ci} 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ci/** 104362306a36Sopenharmony_ci * nlmsg_cancel - Cancel construction of a netlink message 104462306a36Sopenharmony_ci * @skb: socket buffer the message is stored in 104562306a36Sopenharmony_ci * @nlh: netlink message header 104662306a36Sopenharmony_ci * 104762306a36Sopenharmony_ci * Removes the complete netlink message including all 104862306a36Sopenharmony_ci * attributes from the socket buffer again. 104962306a36Sopenharmony_ci */ 105062306a36Sopenharmony_cistatic inline void nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh) 105162306a36Sopenharmony_ci{ 105262306a36Sopenharmony_ci nlmsg_trim(skb, nlh); 105362306a36Sopenharmony_ci} 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_ci/** 105662306a36Sopenharmony_ci * nlmsg_free - free a netlink message 105762306a36Sopenharmony_ci * @skb: socket buffer of netlink message 105862306a36Sopenharmony_ci */ 105962306a36Sopenharmony_cistatic inline void nlmsg_free(struct sk_buff *skb) 106062306a36Sopenharmony_ci{ 106162306a36Sopenharmony_ci kfree_skb(skb); 106262306a36Sopenharmony_ci} 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci/** 106562306a36Sopenharmony_ci * nlmsg_multicast - multicast a netlink message 106662306a36Sopenharmony_ci * @sk: netlink socket to spread messages to 106762306a36Sopenharmony_ci * @skb: netlink message as socket buffer 106862306a36Sopenharmony_ci * @portid: own netlink portid to avoid sending to yourself 106962306a36Sopenharmony_ci * @group: multicast group id 107062306a36Sopenharmony_ci * @flags: allocation flags 107162306a36Sopenharmony_ci */ 107262306a36Sopenharmony_cistatic inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb, 107362306a36Sopenharmony_ci u32 portid, unsigned int group, gfp_t flags) 107462306a36Sopenharmony_ci{ 107562306a36Sopenharmony_ci int err; 107662306a36Sopenharmony_ci 107762306a36Sopenharmony_ci NETLINK_CB(skb).dst_group = group; 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci err = netlink_broadcast(sk, skb, portid, group, flags); 108062306a36Sopenharmony_ci if (err > 0) 108162306a36Sopenharmony_ci err = 0; 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci return err; 108462306a36Sopenharmony_ci} 108562306a36Sopenharmony_ci 108662306a36Sopenharmony_ci/** 108762306a36Sopenharmony_ci * nlmsg_unicast - unicast a netlink message 108862306a36Sopenharmony_ci * @sk: netlink socket to spread message to 108962306a36Sopenharmony_ci * @skb: netlink message as socket buffer 109062306a36Sopenharmony_ci * @portid: netlink portid of the destination socket 109162306a36Sopenharmony_ci */ 109262306a36Sopenharmony_cistatic inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 portid) 109362306a36Sopenharmony_ci{ 109462306a36Sopenharmony_ci int err; 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci err = netlink_unicast(sk, skb, portid, MSG_DONTWAIT); 109762306a36Sopenharmony_ci if (err > 0) 109862306a36Sopenharmony_ci err = 0; 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci return err; 110162306a36Sopenharmony_ci} 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci/** 110462306a36Sopenharmony_ci * nlmsg_for_each_msg - iterate over a stream of messages 110562306a36Sopenharmony_ci * @pos: loop counter, set to current message 110662306a36Sopenharmony_ci * @head: head of message stream 110762306a36Sopenharmony_ci * @len: length of message stream 110862306a36Sopenharmony_ci * @rem: initialized to len, holds bytes currently remaining in stream 110962306a36Sopenharmony_ci */ 111062306a36Sopenharmony_ci#define nlmsg_for_each_msg(pos, head, len, rem) \ 111162306a36Sopenharmony_ci for (pos = head, rem = len; \ 111262306a36Sopenharmony_ci nlmsg_ok(pos, rem); \ 111362306a36Sopenharmony_ci pos = nlmsg_next(pos, &(rem))) 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci/** 111662306a36Sopenharmony_ci * nl_dump_check_consistent - check if sequence is consistent and advertise if not 111762306a36Sopenharmony_ci * @cb: netlink callback structure that stores the sequence number 111862306a36Sopenharmony_ci * @nlh: netlink message header to write the flag to 111962306a36Sopenharmony_ci * 112062306a36Sopenharmony_ci * This function checks if the sequence (generation) number changed during dump 112162306a36Sopenharmony_ci * and if it did, advertises it in the netlink message header. 112262306a36Sopenharmony_ci * 112362306a36Sopenharmony_ci * The correct way to use it is to set cb->seq to the generation counter when 112462306a36Sopenharmony_ci * all locks for dumping have been acquired, and then call this function for 112562306a36Sopenharmony_ci * each message that is generated. 112662306a36Sopenharmony_ci * 112762306a36Sopenharmony_ci * Note that due to initialisation concerns, 0 is an invalid sequence number 112862306a36Sopenharmony_ci * and must not be used by code that uses this functionality. 112962306a36Sopenharmony_ci */ 113062306a36Sopenharmony_cistatic inline void 113162306a36Sopenharmony_cinl_dump_check_consistent(struct netlink_callback *cb, 113262306a36Sopenharmony_ci struct nlmsghdr *nlh) 113362306a36Sopenharmony_ci{ 113462306a36Sopenharmony_ci if (cb->prev_seq && cb->seq != cb->prev_seq) 113562306a36Sopenharmony_ci nlh->nlmsg_flags |= NLM_F_DUMP_INTR; 113662306a36Sopenharmony_ci cb->prev_seq = cb->seq; 113762306a36Sopenharmony_ci} 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci/************************************************************************** 114062306a36Sopenharmony_ci * Netlink Attributes 114162306a36Sopenharmony_ci **************************************************************************/ 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci/** 114462306a36Sopenharmony_ci * nla_attr_size - length of attribute not including padding 114562306a36Sopenharmony_ci * @payload: length of payload 114662306a36Sopenharmony_ci */ 114762306a36Sopenharmony_cistatic inline int nla_attr_size(int payload) 114862306a36Sopenharmony_ci{ 114962306a36Sopenharmony_ci return NLA_HDRLEN + payload; 115062306a36Sopenharmony_ci} 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci/** 115362306a36Sopenharmony_ci * nla_total_size - total length of attribute including padding 115462306a36Sopenharmony_ci * @payload: length of payload 115562306a36Sopenharmony_ci */ 115662306a36Sopenharmony_cistatic inline int nla_total_size(int payload) 115762306a36Sopenharmony_ci{ 115862306a36Sopenharmony_ci return NLA_ALIGN(nla_attr_size(payload)); 115962306a36Sopenharmony_ci} 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_ci/** 116262306a36Sopenharmony_ci * nla_padlen - length of padding at the tail of attribute 116362306a36Sopenharmony_ci * @payload: length of payload 116462306a36Sopenharmony_ci */ 116562306a36Sopenharmony_cistatic inline int nla_padlen(int payload) 116662306a36Sopenharmony_ci{ 116762306a36Sopenharmony_ci return nla_total_size(payload) - nla_attr_size(payload); 116862306a36Sopenharmony_ci} 116962306a36Sopenharmony_ci 117062306a36Sopenharmony_ci/** 117162306a36Sopenharmony_ci * nla_type - attribute type 117262306a36Sopenharmony_ci * @nla: netlink attribute 117362306a36Sopenharmony_ci */ 117462306a36Sopenharmony_cistatic inline int nla_type(const struct nlattr *nla) 117562306a36Sopenharmony_ci{ 117662306a36Sopenharmony_ci return nla->nla_type & NLA_TYPE_MASK; 117762306a36Sopenharmony_ci} 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_ci/** 118062306a36Sopenharmony_ci * nla_data - head of payload 118162306a36Sopenharmony_ci * @nla: netlink attribute 118262306a36Sopenharmony_ci */ 118362306a36Sopenharmony_cistatic inline void *nla_data(const struct nlattr *nla) 118462306a36Sopenharmony_ci{ 118562306a36Sopenharmony_ci return (char *) nla + NLA_HDRLEN; 118662306a36Sopenharmony_ci} 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ci/** 118962306a36Sopenharmony_ci * nla_len - length of payload 119062306a36Sopenharmony_ci * @nla: netlink attribute 119162306a36Sopenharmony_ci */ 119262306a36Sopenharmony_cistatic inline int nla_len(const struct nlattr *nla) 119362306a36Sopenharmony_ci{ 119462306a36Sopenharmony_ci return nla->nla_len - NLA_HDRLEN; 119562306a36Sopenharmony_ci} 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci/** 119862306a36Sopenharmony_ci * nla_ok - check if the netlink attribute fits into the remaining bytes 119962306a36Sopenharmony_ci * @nla: netlink attribute 120062306a36Sopenharmony_ci * @remaining: number of bytes remaining in attribute stream 120162306a36Sopenharmony_ci */ 120262306a36Sopenharmony_cistatic inline int nla_ok(const struct nlattr *nla, int remaining) 120362306a36Sopenharmony_ci{ 120462306a36Sopenharmony_ci return remaining >= (int) sizeof(*nla) && 120562306a36Sopenharmony_ci nla->nla_len >= sizeof(*nla) && 120662306a36Sopenharmony_ci nla->nla_len <= remaining; 120762306a36Sopenharmony_ci} 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_ci/** 121062306a36Sopenharmony_ci * nla_next - next netlink attribute in attribute stream 121162306a36Sopenharmony_ci * @nla: netlink attribute 121262306a36Sopenharmony_ci * @remaining: number of bytes remaining in attribute stream 121362306a36Sopenharmony_ci * 121462306a36Sopenharmony_ci * Returns the next netlink attribute in the attribute stream and 121562306a36Sopenharmony_ci * decrements remaining by the size of the current attribute. 121662306a36Sopenharmony_ci */ 121762306a36Sopenharmony_cistatic inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining) 121862306a36Sopenharmony_ci{ 121962306a36Sopenharmony_ci unsigned int totlen = NLA_ALIGN(nla->nla_len); 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci *remaining -= totlen; 122262306a36Sopenharmony_ci return (struct nlattr *) ((char *) nla + totlen); 122362306a36Sopenharmony_ci} 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci/** 122662306a36Sopenharmony_ci * nla_find_nested - find attribute in a set of nested attributes 122762306a36Sopenharmony_ci * @nla: attribute containing the nested attributes 122862306a36Sopenharmony_ci * @attrtype: type of attribute to look for 122962306a36Sopenharmony_ci * 123062306a36Sopenharmony_ci * Returns the first attribute which matches the specified type. 123162306a36Sopenharmony_ci */ 123262306a36Sopenharmony_cistatic inline struct nlattr * 123362306a36Sopenharmony_cinla_find_nested(const struct nlattr *nla, int attrtype) 123462306a36Sopenharmony_ci{ 123562306a36Sopenharmony_ci return nla_find(nla_data(nla), nla_len(nla), attrtype); 123662306a36Sopenharmony_ci} 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci/** 123962306a36Sopenharmony_ci * nla_parse_nested - parse nested attributes 124062306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 124162306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 124262306a36Sopenharmony_ci * @nla: attribute containing the nested attributes 124362306a36Sopenharmony_ci * @policy: validation policy 124462306a36Sopenharmony_ci * @extack: extended ACK report struct 124562306a36Sopenharmony_ci * 124662306a36Sopenharmony_ci * See nla_parse() 124762306a36Sopenharmony_ci */ 124862306a36Sopenharmony_cistatic inline int nla_parse_nested(struct nlattr *tb[], int maxtype, 124962306a36Sopenharmony_ci const struct nlattr *nla, 125062306a36Sopenharmony_ci const struct nla_policy *policy, 125162306a36Sopenharmony_ci struct netlink_ext_ack *extack) 125262306a36Sopenharmony_ci{ 125362306a36Sopenharmony_ci if (!(nla->nla_type & NLA_F_NESTED)) { 125462306a36Sopenharmony_ci NL_SET_ERR_MSG_ATTR(extack, nla, "NLA_F_NESTED is missing"); 125562306a36Sopenharmony_ci return -EINVAL; 125662306a36Sopenharmony_ci } 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ci return __nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy, 125962306a36Sopenharmony_ci NL_VALIDATE_STRICT, extack); 126062306a36Sopenharmony_ci} 126162306a36Sopenharmony_ci 126262306a36Sopenharmony_ci/** 126362306a36Sopenharmony_ci * nla_parse_nested_deprecated - parse nested attributes 126462306a36Sopenharmony_ci * @tb: destination array with maxtype+1 elements 126562306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 126662306a36Sopenharmony_ci * @nla: attribute containing the nested attributes 126762306a36Sopenharmony_ci * @policy: validation policy 126862306a36Sopenharmony_ci * @extack: extended ACK report struct 126962306a36Sopenharmony_ci * 127062306a36Sopenharmony_ci * See nla_parse_deprecated() 127162306a36Sopenharmony_ci */ 127262306a36Sopenharmony_cistatic inline int nla_parse_nested_deprecated(struct nlattr *tb[], int maxtype, 127362306a36Sopenharmony_ci const struct nlattr *nla, 127462306a36Sopenharmony_ci const struct nla_policy *policy, 127562306a36Sopenharmony_ci struct netlink_ext_ack *extack) 127662306a36Sopenharmony_ci{ 127762306a36Sopenharmony_ci return __nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy, 127862306a36Sopenharmony_ci NL_VALIDATE_LIBERAL, extack); 127962306a36Sopenharmony_ci} 128062306a36Sopenharmony_ci 128162306a36Sopenharmony_ci/** 128262306a36Sopenharmony_ci * nla_put_u8 - Add a u8 netlink attribute to a socket buffer 128362306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 128462306a36Sopenharmony_ci * @attrtype: attribute type 128562306a36Sopenharmony_ci * @value: numeric value 128662306a36Sopenharmony_ci */ 128762306a36Sopenharmony_cistatic inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value) 128862306a36Sopenharmony_ci{ 128962306a36Sopenharmony_ci /* temporary variables to work around GCC PR81715 with asan-stack=1 */ 129062306a36Sopenharmony_ci u8 tmp = value; 129162306a36Sopenharmony_ci 129262306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(u8), &tmp); 129362306a36Sopenharmony_ci} 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci/** 129662306a36Sopenharmony_ci * nla_put_u16 - Add a u16 netlink attribute to a socket buffer 129762306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 129862306a36Sopenharmony_ci * @attrtype: attribute type 129962306a36Sopenharmony_ci * @value: numeric value 130062306a36Sopenharmony_ci */ 130162306a36Sopenharmony_cistatic inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value) 130262306a36Sopenharmony_ci{ 130362306a36Sopenharmony_ci u16 tmp = value; 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(u16), &tmp); 130662306a36Sopenharmony_ci} 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci/** 130962306a36Sopenharmony_ci * nla_put_be16 - Add a __be16 netlink attribute to a socket buffer 131062306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 131162306a36Sopenharmony_ci * @attrtype: attribute type 131262306a36Sopenharmony_ci * @value: numeric value 131362306a36Sopenharmony_ci */ 131462306a36Sopenharmony_cistatic inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value) 131562306a36Sopenharmony_ci{ 131662306a36Sopenharmony_ci __be16 tmp = value; 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(__be16), &tmp); 131962306a36Sopenharmony_ci} 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_ci/** 132262306a36Sopenharmony_ci * nla_put_net16 - Add 16-bit network byte order netlink attribute to a socket buffer 132362306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 132462306a36Sopenharmony_ci * @attrtype: attribute type 132562306a36Sopenharmony_ci * @value: numeric value 132662306a36Sopenharmony_ci */ 132762306a36Sopenharmony_cistatic inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value) 132862306a36Sopenharmony_ci{ 132962306a36Sopenharmony_ci __be16 tmp = value; 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, tmp); 133262306a36Sopenharmony_ci} 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_ci/** 133562306a36Sopenharmony_ci * nla_put_le16 - Add a __le16 netlink attribute to a socket buffer 133662306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 133762306a36Sopenharmony_ci * @attrtype: attribute type 133862306a36Sopenharmony_ci * @value: numeric value 133962306a36Sopenharmony_ci */ 134062306a36Sopenharmony_cistatic inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value) 134162306a36Sopenharmony_ci{ 134262306a36Sopenharmony_ci __le16 tmp = value; 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(__le16), &tmp); 134562306a36Sopenharmony_ci} 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci/** 134862306a36Sopenharmony_ci * nla_put_u32 - Add a u32 netlink attribute to a socket buffer 134962306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 135062306a36Sopenharmony_ci * @attrtype: attribute type 135162306a36Sopenharmony_ci * @value: numeric value 135262306a36Sopenharmony_ci */ 135362306a36Sopenharmony_cistatic inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value) 135462306a36Sopenharmony_ci{ 135562306a36Sopenharmony_ci u32 tmp = value; 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(u32), &tmp); 135862306a36Sopenharmony_ci} 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci/** 136162306a36Sopenharmony_ci * nla_put_be32 - Add a __be32 netlink attribute to a socket buffer 136262306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 136362306a36Sopenharmony_ci * @attrtype: attribute type 136462306a36Sopenharmony_ci * @value: numeric value 136562306a36Sopenharmony_ci */ 136662306a36Sopenharmony_cistatic inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value) 136762306a36Sopenharmony_ci{ 136862306a36Sopenharmony_ci __be32 tmp = value; 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(__be32), &tmp); 137162306a36Sopenharmony_ci} 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci/** 137462306a36Sopenharmony_ci * nla_put_net32 - Add 32-bit network byte order netlink attribute to a socket buffer 137562306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 137662306a36Sopenharmony_ci * @attrtype: attribute type 137762306a36Sopenharmony_ci * @value: numeric value 137862306a36Sopenharmony_ci */ 137962306a36Sopenharmony_cistatic inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value) 138062306a36Sopenharmony_ci{ 138162306a36Sopenharmony_ci __be32 tmp = value; 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, tmp); 138462306a36Sopenharmony_ci} 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ci/** 138762306a36Sopenharmony_ci * nla_put_le32 - Add a __le32 netlink attribute to a socket buffer 138862306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 138962306a36Sopenharmony_ci * @attrtype: attribute type 139062306a36Sopenharmony_ci * @value: numeric value 139162306a36Sopenharmony_ci */ 139262306a36Sopenharmony_cistatic inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value) 139362306a36Sopenharmony_ci{ 139462306a36Sopenharmony_ci __le32 tmp = value; 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(__le32), &tmp); 139762306a36Sopenharmony_ci} 139862306a36Sopenharmony_ci 139962306a36Sopenharmony_ci/** 140062306a36Sopenharmony_ci * nla_put_u64_64bit - Add a u64 netlink attribute to a skb and align it 140162306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 140262306a36Sopenharmony_ci * @attrtype: attribute type 140362306a36Sopenharmony_ci * @value: numeric value 140462306a36Sopenharmony_ci * @padattr: attribute type for the padding 140562306a36Sopenharmony_ci */ 140662306a36Sopenharmony_cistatic inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype, 140762306a36Sopenharmony_ci u64 value, int padattr) 140862306a36Sopenharmony_ci{ 140962306a36Sopenharmony_ci u64 tmp = value; 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci return nla_put_64bit(skb, attrtype, sizeof(u64), &tmp, padattr); 141262306a36Sopenharmony_ci} 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_ci/** 141562306a36Sopenharmony_ci * nla_put_be64 - Add a __be64 netlink attribute to a socket buffer and align it 141662306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 141762306a36Sopenharmony_ci * @attrtype: attribute type 141862306a36Sopenharmony_ci * @value: numeric value 141962306a36Sopenharmony_ci * @padattr: attribute type for the padding 142062306a36Sopenharmony_ci */ 142162306a36Sopenharmony_cistatic inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value, 142262306a36Sopenharmony_ci int padattr) 142362306a36Sopenharmony_ci{ 142462306a36Sopenharmony_ci __be64 tmp = value; 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci return nla_put_64bit(skb, attrtype, sizeof(__be64), &tmp, padattr); 142762306a36Sopenharmony_ci} 142862306a36Sopenharmony_ci 142962306a36Sopenharmony_ci/** 143062306a36Sopenharmony_ci * nla_put_net64 - Add 64-bit network byte order nlattr to a skb and align it 143162306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 143262306a36Sopenharmony_ci * @attrtype: attribute type 143362306a36Sopenharmony_ci * @value: numeric value 143462306a36Sopenharmony_ci * @padattr: attribute type for the padding 143562306a36Sopenharmony_ci */ 143662306a36Sopenharmony_cistatic inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value, 143762306a36Sopenharmony_ci int padattr) 143862306a36Sopenharmony_ci{ 143962306a36Sopenharmony_ci __be64 tmp = value; 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci return nla_put_be64(skb, attrtype | NLA_F_NET_BYTEORDER, tmp, 144262306a36Sopenharmony_ci padattr); 144362306a36Sopenharmony_ci} 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ci/** 144662306a36Sopenharmony_ci * nla_put_le64 - Add a __le64 netlink attribute to a socket buffer and align it 144762306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 144862306a36Sopenharmony_ci * @attrtype: attribute type 144962306a36Sopenharmony_ci * @value: numeric value 145062306a36Sopenharmony_ci * @padattr: attribute type for the padding 145162306a36Sopenharmony_ci */ 145262306a36Sopenharmony_cistatic inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value, 145362306a36Sopenharmony_ci int padattr) 145462306a36Sopenharmony_ci{ 145562306a36Sopenharmony_ci __le64 tmp = value; 145662306a36Sopenharmony_ci 145762306a36Sopenharmony_ci return nla_put_64bit(skb, attrtype, sizeof(__le64), &tmp, padattr); 145862306a36Sopenharmony_ci} 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci/** 146162306a36Sopenharmony_ci * nla_put_s8 - Add a s8 netlink attribute to a socket buffer 146262306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 146362306a36Sopenharmony_ci * @attrtype: attribute type 146462306a36Sopenharmony_ci * @value: numeric value 146562306a36Sopenharmony_ci */ 146662306a36Sopenharmony_cistatic inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value) 146762306a36Sopenharmony_ci{ 146862306a36Sopenharmony_ci s8 tmp = value; 146962306a36Sopenharmony_ci 147062306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(s8), &tmp); 147162306a36Sopenharmony_ci} 147262306a36Sopenharmony_ci 147362306a36Sopenharmony_ci/** 147462306a36Sopenharmony_ci * nla_put_s16 - Add a s16 netlink attribute to a socket buffer 147562306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 147662306a36Sopenharmony_ci * @attrtype: attribute type 147762306a36Sopenharmony_ci * @value: numeric value 147862306a36Sopenharmony_ci */ 147962306a36Sopenharmony_cistatic inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value) 148062306a36Sopenharmony_ci{ 148162306a36Sopenharmony_ci s16 tmp = value; 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(s16), &tmp); 148462306a36Sopenharmony_ci} 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_ci/** 148762306a36Sopenharmony_ci * nla_put_s32 - Add a s32 netlink attribute to a socket buffer 148862306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 148962306a36Sopenharmony_ci * @attrtype: attribute type 149062306a36Sopenharmony_ci * @value: numeric value 149162306a36Sopenharmony_ci */ 149262306a36Sopenharmony_cistatic inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value) 149362306a36Sopenharmony_ci{ 149462306a36Sopenharmony_ci s32 tmp = value; 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(s32), &tmp); 149762306a36Sopenharmony_ci} 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_ci/** 150062306a36Sopenharmony_ci * nla_put_s64 - Add a s64 netlink attribute to a socket buffer and align it 150162306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 150262306a36Sopenharmony_ci * @attrtype: attribute type 150362306a36Sopenharmony_ci * @value: numeric value 150462306a36Sopenharmony_ci * @padattr: attribute type for the padding 150562306a36Sopenharmony_ci */ 150662306a36Sopenharmony_cistatic inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value, 150762306a36Sopenharmony_ci int padattr) 150862306a36Sopenharmony_ci{ 150962306a36Sopenharmony_ci s64 tmp = value; 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci return nla_put_64bit(skb, attrtype, sizeof(s64), &tmp, padattr); 151262306a36Sopenharmony_ci} 151362306a36Sopenharmony_ci 151462306a36Sopenharmony_ci/** 151562306a36Sopenharmony_ci * nla_put_string - Add a string netlink attribute to a socket buffer 151662306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 151762306a36Sopenharmony_ci * @attrtype: attribute type 151862306a36Sopenharmony_ci * @str: NUL terminated string 151962306a36Sopenharmony_ci */ 152062306a36Sopenharmony_cistatic inline int nla_put_string(struct sk_buff *skb, int attrtype, 152162306a36Sopenharmony_ci const char *str) 152262306a36Sopenharmony_ci{ 152362306a36Sopenharmony_ci return nla_put(skb, attrtype, strlen(str) + 1, str); 152462306a36Sopenharmony_ci} 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci/** 152762306a36Sopenharmony_ci * nla_put_flag - Add a flag netlink attribute to a socket buffer 152862306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 152962306a36Sopenharmony_ci * @attrtype: attribute type 153062306a36Sopenharmony_ci */ 153162306a36Sopenharmony_cistatic inline int nla_put_flag(struct sk_buff *skb, int attrtype) 153262306a36Sopenharmony_ci{ 153362306a36Sopenharmony_ci return nla_put(skb, attrtype, 0, NULL); 153462306a36Sopenharmony_ci} 153562306a36Sopenharmony_ci 153662306a36Sopenharmony_ci/** 153762306a36Sopenharmony_ci * nla_put_msecs - Add a msecs netlink attribute to a skb and align it 153862306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 153962306a36Sopenharmony_ci * @attrtype: attribute type 154062306a36Sopenharmony_ci * @njiffies: number of jiffies to convert to msecs 154162306a36Sopenharmony_ci * @padattr: attribute type for the padding 154262306a36Sopenharmony_ci */ 154362306a36Sopenharmony_cistatic inline int nla_put_msecs(struct sk_buff *skb, int attrtype, 154462306a36Sopenharmony_ci unsigned long njiffies, int padattr) 154562306a36Sopenharmony_ci{ 154662306a36Sopenharmony_ci u64 tmp = jiffies_to_msecs(njiffies); 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci return nla_put_64bit(skb, attrtype, sizeof(u64), &tmp, padattr); 154962306a36Sopenharmony_ci} 155062306a36Sopenharmony_ci 155162306a36Sopenharmony_ci/** 155262306a36Sopenharmony_ci * nla_put_in_addr - Add an IPv4 address netlink attribute to a socket 155362306a36Sopenharmony_ci * buffer 155462306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 155562306a36Sopenharmony_ci * @attrtype: attribute type 155662306a36Sopenharmony_ci * @addr: IPv4 address 155762306a36Sopenharmony_ci */ 155862306a36Sopenharmony_cistatic inline int nla_put_in_addr(struct sk_buff *skb, int attrtype, 155962306a36Sopenharmony_ci __be32 addr) 156062306a36Sopenharmony_ci{ 156162306a36Sopenharmony_ci __be32 tmp = addr; 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_ci return nla_put_be32(skb, attrtype, tmp); 156462306a36Sopenharmony_ci} 156562306a36Sopenharmony_ci 156662306a36Sopenharmony_ci/** 156762306a36Sopenharmony_ci * nla_put_in6_addr - Add an IPv6 address netlink attribute to a socket 156862306a36Sopenharmony_ci * buffer 156962306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 157062306a36Sopenharmony_ci * @attrtype: attribute type 157162306a36Sopenharmony_ci * @addr: IPv6 address 157262306a36Sopenharmony_ci */ 157362306a36Sopenharmony_cistatic inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype, 157462306a36Sopenharmony_ci const struct in6_addr *addr) 157562306a36Sopenharmony_ci{ 157662306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(*addr), addr); 157762306a36Sopenharmony_ci} 157862306a36Sopenharmony_ci 157962306a36Sopenharmony_ci/** 158062306a36Sopenharmony_ci * nla_put_bitfield32 - Add a bitfield32 netlink attribute to a socket buffer 158162306a36Sopenharmony_ci * @skb: socket buffer to add attribute to 158262306a36Sopenharmony_ci * @attrtype: attribute type 158362306a36Sopenharmony_ci * @value: value carrying bits 158462306a36Sopenharmony_ci * @selector: selector of valid bits 158562306a36Sopenharmony_ci */ 158662306a36Sopenharmony_cistatic inline int nla_put_bitfield32(struct sk_buff *skb, int attrtype, 158762306a36Sopenharmony_ci __u32 value, __u32 selector) 158862306a36Sopenharmony_ci{ 158962306a36Sopenharmony_ci struct nla_bitfield32 tmp = { value, selector, }; 159062306a36Sopenharmony_ci 159162306a36Sopenharmony_ci return nla_put(skb, attrtype, sizeof(tmp), &tmp); 159262306a36Sopenharmony_ci} 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci/** 159562306a36Sopenharmony_ci * nla_get_u32 - return payload of u32 attribute 159662306a36Sopenharmony_ci * @nla: u32 netlink attribute 159762306a36Sopenharmony_ci */ 159862306a36Sopenharmony_cistatic inline u32 nla_get_u32(const struct nlattr *nla) 159962306a36Sopenharmony_ci{ 160062306a36Sopenharmony_ci return *(u32 *) nla_data(nla); 160162306a36Sopenharmony_ci} 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_ci/** 160462306a36Sopenharmony_ci * nla_get_be32 - return payload of __be32 attribute 160562306a36Sopenharmony_ci * @nla: __be32 netlink attribute 160662306a36Sopenharmony_ci */ 160762306a36Sopenharmony_cistatic inline __be32 nla_get_be32(const struct nlattr *nla) 160862306a36Sopenharmony_ci{ 160962306a36Sopenharmony_ci return *(__be32 *) nla_data(nla); 161062306a36Sopenharmony_ci} 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci/** 161362306a36Sopenharmony_ci * nla_get_le32 - return payload of __le32 attribute 161462306a36Sopenharmony_ci * @nla: __le32 netlink attribute 161562306a36Sopenharmony_ci */ 161662306a36Sopenharmony_cistatic inline __le32 nla_get_le32(const struct nlattr *nla) 161762306a36Sopenharmony_ci{ 161862306a36Sopenharmony_ci return *(__le32 *) nla_data(nla); 161962306a36Sopenharmony_ci} 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_ci/** 162262306a36Sopenharmony_ci * nla_get_u16 - return payload of u16 attribute 162362306a36Sopenharmony_ci * @nla: u16 netlink attribute 162462306a36Sopenharmony_ci */ 162562306a36Sopenharmony_cistatic inline u16 nla_get_u16(const struct nlattr *nla) 162662306a36Sopenharmony_ci{ 162762306a36Sopenharmony_ci return *(u16 *) nla_data(nla); 162862306a36Sopenharmony_ci} 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci/** 163162306a36Sopenharmony_ci * nla_get_be16 - return payload of __be16 attribute 163262306a36Sopenharmony_ci * @nla: __be16 netlink attribute 163362306a36Sopenharmony_ci */ 163462306a36Sopenharmony_cistatic inline __be16 nla_get_be16(const struct nlattr *nla) 163562306a36Sopenharmony_ci{ 163662306a36Sopenharmony_ci return *(__be16 *) nla_data(nla); 163762306a36Sopenharmony_ci} 163862306a36Sopenharmony_ci 163962306a36Sopenharmony_ci/** 164062306a36Sopenharmony_ci * nla_get_le16 - return payload of __le16 attribute 164162306a36Sopenharmony_ci * @nla: __le16 netlink attribute 164262306a36Sopenharmony_ci */ 164362306a36Sopenharmony_cistatic inline __le16 nla_get_le16(const struct nlattr *nla) 164462306a36Sopenharmony_ci{ 164562306a36Sopenharmony_ci return *(__le16 *) nla_data(nla); 164662306a36Sopenharmony_ci} 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci/** 164962306a36Sopenharmony_ci * nla_get_u8 - return payload of u8 attribute 165062306a36Sopenharmony_ci * @nla: u8 netlink attribute 165162306a36Sopenharmony_ci */ 165262306a36Sopenharmony_cistatic inline u8 nla_get_u8(const struct nlattr *nla) 165362306a36Sopenharmony_ci{ 165462306a36Sopenharmony_ci return *(u8 *) nla_data(nla); 165562306a36Sopenharmony_ci} 165662306a36Sopenharmony_ci 165762306a36Sopenharmony_ci/** 165862306a36Sopenharmony_ci * nla_get_u64 - return payload of u64 attribute 165962306a36Sopenharmony_ci * @nla: u64 netlink attribute 166062306a36Sopenharmony_ci */ 166162306a36Sopenharmony_cistatic inline u64 nla_get_u64(const struct nlattr *nla) 166262306a36Sopenharmony_ci{ 166362306a36Sopenharmony_ci u64 tmp; 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_ci nla_memcpy(&tmp, nla, sizeof(tmp)); 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci return tmp; 166862306a36Sopenharmony_ci} 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci/** 167162306a36Sopenharmony_ci * nla_get_be64 - return payload of __be64 attribute 167262306a36Sopenharmony_ci * @nla: __be64 netlink attribute 167362306a36Sopenharmony_ci */ 167462306a36Sopenharmony_cistatic inline __be64 nla_get_be64(const struct nlattr *nla) 167562306a36Sopenharmony_ci{ 167662306a36Sopenharmony_ci __be64 tmp; 167762306a36Sopenharmony_ci 167862306a36Sopenharmony_ci nla_memcpy(&tmp, nla, sizeof(tmp)); 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci return tmp; 168162306a36Sopenharmony_ci} 168262306a36Sopenharmony_ci 168362306a36Sopenharmony_ci/** 168462306a36Sopenharmony_ci * nla_get_le64 - return payload of __le64 attribute 168562306a36Sopenharmony_ci * @nla: __le64 netlink attribute 168662306a36Sopenharmony_ci */ 168762306a36Sopenharmony_cistatic inline __le64 nla_get_le64(const struct nlattr *nla) 168862306a36Sopenharmony_ci{ 168962306a36Sopenharmony_ci return *(__le64 *) nla_data(nla); 169062306a36Sopenharmony_ci} 169162306a36Sopenharmony_ci 169262306a36Sopenharmony_ci/** 169362306a36Sopenharmony_ci * nla_get_s32 - return payload of s32 attribute 169462306a36Sopenharmony_ci * @nla: s32 netlink attribute 169562306a36Sopenharmony_ci */ 169662306a36Sopenharmony_cistatic inline s32 nla_get_s32(const struct nlattr *nla) 169762306a36Sopenharmony_ci{ 169862306a36Sopenharmony_ci return *(s32 *) nla_data(nla); 169962306a36Sopenharmony_ci} 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci/** 170262306a36Sopenharmony_ci * nla_get_s16 - return payload of s16 attribute 170362306a36Sopenharmony_ci * @nla: s16 netlink attribute 170462306a36Sopenharmony_ci */ 170562306a36Sopenharmony_cistatic inline s16 nla_get_s16(const struct nlattr *nla) 170662306a36Sopenharmony_ci{ 170762306a36Sopenharmony_ci return *(s16 *) nla_data(nla); 170862306a36Sopenharmony_ci} 170962306a36Sopenharmony_ci 171062306a36Sopenharmony_ci/** 171162306a36Sopenharmony_ci * nla_get_s8 - return payload of s8 attribute 171262306a36Sopenharmony_ci * @nla: s8 netlink attribute 171362306a36Sopenharmony_ci */ 171462306a36Sopenharmony_cistatic inline s8 nla_get_s8(const struct nlattr *nla) 171562306a36Sopenharmony_ci{ 171662306a36Sopenharmony_ci return *(s8 *) nla_data(nla); 171762306a36Sopenharmony_ci} 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci/** 172062306a36Sopenharmony_ci * nla_get_s64 - return payload of s64 attribute 172162306a36Sopenharmony_ci * @nla: s64 netlink attribute 172262306a36Sopenharmony_ci */ 172362306a36Sopenharmony_cistatic inline s64 nla_get_s64(const struct nlattr *nla) 172462306a36Sopenharmony_ci{ 172562306a36Sopenharmony_ci s64 tmp; 172662306a36Sopenharmony_ci 172762306a36Sopenharmony_ci nla_memcpy(&tmp, nla, sizeof(tmp)); 172862306a36Sopenharmony_ci 172962306a36Sopenharmony_ci return tmp; 173062306a36Sopenharmony_ci} 173162306a36Sopenharmony_ci 173262306a36Sopenharmony_ci/** 173362306a36Sopenharmony_ci * nla_get_flag - return payload of flag attribute 173462306a36Sopenharmony_ci * @nla: flag netlink attribute 173562306a36Sopenharmony_ci */ 173662306a36Sopenharmony_cistatic inline int nla_get_flag(const struct nlattr *nla) 173762306a36Sopenharmony_ci{ 173862306a36Sopenharmony_ci return !!nla; 173962306a36Sopenharmony_ci} 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci/** 174262306a36Sopenharmony_ci * nla_get_msecs - return payload of msecs attribute 174362306a36Sopenharmony_ci * @nla: msecs netlink attribute 174462306a36Sopenharmony_ci * 174562306a36Sopenharmony_ci * Returns the number of milliseconds in jiffies. 174662306a36Sopenharmony_ci */ 174762306a36Sopenharmony_cistatic inline unsigned long nla_get_msecs(const struct nlattr *nla) 174862306a36Sopenharmony_ci{ 174962306a36Sopenharmony_ci u64 msecs = nla_get_u64(nla); 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci return msecs_to_jiffies((unsigned long) msecs); 175262306a36Sopenharmony_ci} 175362306a36Sopenharmony_ci 175462306a36Sopenharmony_ci/** 175562306a36Sopenharmony_ci * nla_get_in_addr - return payload of IPv4 address attribute 175662306a36Sopenharmony_ci * @nla: IPv4 address netlink attribute 175762306a36Sopenharmony_ci */ 175862306a36Sopenharmony_cistatic inline __be32 nla_get_in_addr(const struct nlattr *nla) 175962306a36Sopenharmony_ci{ 176062306a36Sopenharmony_ci return *(__be32 *) nla_data(nla); 176162306a36Sopenharmony_ci} 176262306a36Sopenharmony_ci 176362306a36Sopenharmony_ci/** 176462306a36Sopenharmony_ci * nla_get_in6_addr - return payload of IPv6 address attribute 176562306a36Sopenharmony_ci * @nla: IPv6 address netlink attribute 176662306a36Sopenharmony_ci */ 176762306a36Sopenharmony_cistatic inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla) 176862306a36Sopenharmony_ci{ 176962306a36Sopenharmony_ci struct in6_addr tmp; 177062306a36Sopenharmony_ci 177162306a36Sopenharmony_ci nla_memcpy(&tmp, nla, sizeof(tmp)); 177262306a36Sopenharmony_ci return tmp; 177362306a36Sopenharmony_ci} 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_ci/** 177662306a36Sopenharmony_ci * nla_get_bitfield32 - return payload of 32 bitfield attribute 177762306a36Sopenharmony_ci * @nla: nla_bitfield32 attribute 177862306a36Sopenharmony_ci */ 177962306a36Sopenharmony_cistatic inline struct nla_bitfield32 nla_get_bitfield32(const struct nlattr *nla) 178062306a36Sopenharmony_ci{ 178162306a36Sopenharmony_ci struct nla_bitfield32 tmp; 178262306a36Sopenharmony_ci 178362306a36Sopenharmony_ci nla_memcpy(&tmp, nla, sizeof(tmp)); 178462306a36Sopenharmony_ci return tmp; 178562306a36Sopenharmony_ci} 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_ci/** 178862306a36Sopenharmony_ci * nla_memdup - duplicate attribute memory (kmemdup) 178962306a36Sopenharmony_ci * @src: netlink attribute to duplicate from 179062306a36Sopenharmony_ci * @gfp: GFP mask 179162306a36Sopenharmony_ci */ 179262306a36Sopenharmony_cistatic inline void *nla_memdup(const struct nlattr *src, gfp_t gfp) 179362306a36Sopenharmony_ci{ 179462306a36Sopenharmony_ci return kmemdup(nla_data(src), nla_len(src), gfp); 179562306a36Sopenharmony_ci} 179662306a36Sopenharmony_ci 179762306a36Sopenharmony_ci/** 179862306a36Sopenharmony_ci * nla_nest_start_noflag - Start a new level of nested attributes 179962306a36Sopenharmony_ci * @skb: socket buffer to add attributes to 180062306a36Sopenharmony_ci * @attrtype: attribute type of container 180162306a36Sopenharmony_ci * 180262306a36Sopenharmony_ci * This function exists for backward compatibility to use in APIs which never 180362306a36Sopenharmony_ci * marked their nest attributes with NLA_F_NESTED flag. New APIs should use 180462306a36Sopenharmony_ci * nla_nest_start() which sets the flag. 180562306a36Sopenharmony_ci * 180662306a36Sopenharmony_ci * Returns the container attribute or NULL on error 180762306a36Sopenharmony_ci */ 180862306a36Sopenharmony_cistatic inline struct nlattr *nla_nest_start_noflag(struct sk_buff *skb, 180962306a36Sopenharmony_ci int attrtype) 181062306a36Sopenharmony_ci{ 181162306a36Sopenharmony_ci struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb); 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_ci if (nla_put(skb, attrtype, 0, NULL) < 0) 181462306a36Sopenharmony_ci return NULL; 181562306a36Sopenharmony_ci 181662306a36Sopenharmony_ci return start; 181762306a36Sopenharmony_ci} 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci/** 182062306a36Sopenharmony_ci * nla_nest_start - Start a new level of nested attributes, with NLA_F_NESTED 182162306a36Sopenharmony_ci * @skb: socket buffer to add attributes to 182262306a36Sopenharmony_ci * @attrtype: attribute type of container 182362306a36Sopenharmony_ci * 182462306a36Sopenharmony_ci * Unlike nla_nest_start_noflag(), mark the nest attribute with NLA_F_NESTED 182562306a36Sopenharmony_ci * flag. This is the preferred function to use in new code. 182662306a36Sopenharmony_ci * 182762306a36Sopenharmony_ci * Returns the container attribute or NULL on error 182862306a36Sopenharmony_ci */ 182962306a36Sopenharmony_cistatic inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype) 183062306a36Sopenharmony_ci{ 183162306a36Sopenharmony_ci return nla_nest_start_noflag(skb, attrtype | NLA_F_NESTED); 183262306a36Sopenharmony_ci} 183362306a36Sopenharmony_ci 183462306a36Sopenharmony_ci/** 183562306a36Sopenharmony_ci * nla_nest_end - Finalize nesting of attributes 183662306a36Sopenharmony_ci * @skb: socket buffer the attributes are stored in 183762306a36Sopenharmony_ci * @start: container attribute 183862306a36Sopenharmony_ci * 183962306a36Sopenharmony_ci * Corrects the container attribute header to include the all 184062306a36Sopenharmony_ci * appeneded attributes. 184162306a36Sopenharmony_ci * 184262306a36Sopenharmony_ci * Returns the total data length of the skb. 184362306a36Sopenharmony_ci */ 184462306a36Sopenharmony_cistatic inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start) 184562306a36Sopenharmony_ci{ 184662306a36Sopenharmony_ci start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start; 184762306a36Sopenharmony_ci return skb->len; 184862306a36Sopenharmony_ci} 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci/** 185162306a36Sopenharmony_ci * nla_nest_cancel - Cancel nesting of attributes 185262306a36Sopenharmony_ci * @skb: socket buffer the message is stored in 185362306a36Sopenharmony_ci * @start: container attribute 185462306a36Sopenharmony_ci * 185562306a36Sopenharmony_ci * Removes the container attribute and including all nested 185662306a36Sopenharmony_ci * attributes. Returns -EMSGSIZE 185762306a36Sopenharmony_ci */ 185862306a36Sopenharmony_cistatic inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) 185962306a36Sopenharmony_ci{ 186062306a36Sopenharmony_ci nlmsg_trim(skb, start); 186162306a36Sopenharmony_ci} 186262306a36Sopenharmony_ci 186362306a36Sopenharmony_ci/** 186462306a36Sopenharmony_ci * __nla_validate_nested - Validate a stream of nested attributes 186562306a36Sopenharmony_ci * @start: container attribute 186662306a36Sopenharmony_ci * @maxtype: maximum attribute type to be expected 186762306a36Sopenharmony_ci * @policy: validation policy 186862306a36Sopenharmony_ci * @validate: validation strictness 186962306a36Sopenharmony_ci * @extack: extended ACK report struct 187062306a36Sopenharmony_ci * 187162306a36Sopenharmony_ci * Validates all attributes in the nested attribute stream against the 187262306a36Sopenharmony_ci * specified policy. Attributes with a type exceeding maxtype will be 187362306a36Sopenharmony_ci * ignored. See documenation of struct nla_policy for more details. 187462306a36Sopenharmony_ci * 187562306a36Sopenharmony_ci * Returns 0 on success or a negative error code. 187662306a36Sopenharmony_ci */ 187762306a36Sopenharmony_cistatic inline int __nla_validate_nested(const struct nlattr *start, int maxtype, 187862306a36Sopenharmony_ci const struct nla_policy *policy, 187962306a36Sopenharmony_ci unsigned int validate, 188062306a36Sopenharmony_ci struct netlink_ext_ack *extack) 188162306a36Sopenharmony_ci{ 188262306a36Sopenharmony_ci return __nla_validate(nla_data(start), nla_len(start), maxtype, policy, 188362306a36Sopenharmony_ci validate, extack); 188462306a36Sopenharmony_ci} 188562306a36Sopenharmony_ci 188662306a36Sopenharmony_cistatic inline int 188762306a36Sopenharmony_cinla_validate_nested(const struct nlattr *start, int maxtype, 188862306a36Sopenharmony_ci const struct nla_policy *policy, 188962306a36Sopenharmony_ci struct netlink_ext_ack *extack) 189062306a36Sopenharmony_ci{ 189162306a36Sopenharmony_ci return __nla_validate_nested(start, maxtype, policy, 189262306a36Sopenharmony_ci NL_VALIDATE_STRICT, extack); 189362306a36Sopenharmony_ci} 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_cistatic inline int 189662306a36Sopenharmony_cinla_validate_nested_deprecated(const struct nlattr *start, int maxtype, 189762306a36Sopenharmony_ci const struct nla_policy *policy, 189862306a36Sopenharmony_ci struct netlink_ext_ack *extack) 189962306a36Sopenharmony_ci{ 190062306a36Sopenharmony_ci return __nla_validate_nested(start, maxtype, policy, 190162306a36Sopenharmony_ci NL_VALIDATE_LIBERAL, extack); 190262306a36Sopenharmony_ci} 190362306a36Sopenharmony_ci 190462306a36Sopenharmony_ci/** 190562306a36Sopenharmony_ci * nla_need_padding_for_64bit - test 64-bit alignment of the next attribute 190662306a36Sopenharmony_ci * @skb: socket buffer the message is stored in 190762306a36Sopenharmony_ci * 190862306a36Sopenharmony_ci * Return true if padding is needed to align the next attribute (nla_data()) to 190962306a36Sopenharmony_ci * a 64-bit aligned area. 191062306a36Sopenharmony_ci */ 191162306a36Sopenharmony_cistatic inline bool nla_need_padding_for_64bit(struct sk_buff *skb) 191262306a36Sopenharmony_ci{ 191362306a36Sopenharmony_ci#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 191462306a36Sopenharmony_ci /* The nlattr header is 4 bytes in size, that's why we test 191562306a36Sopenharmony_ci * if the skb->data _is_ aligned. A NOP attribute, plus 191662306a36Sopenharmony_ci * nlattr header for next attribute, will make nla_data() 191762306a36Sopenharmony_ci * 8-byte aligned. 191862306a36Sopenharmony_ci */ 191962306a36Sopenharmony_ci if (IS_ALIGNED((unsigned long)skb_tail_pointer(skb), 8)) 192062306a36Sopenharmony_ci return true; 192162306a36Sopenharmony_ci#endif 192262306a36Sopenharmony_ci return false; 192362306a36Sopenharmony_ci} 192462306a36Sopenharmony_ci 192562306a36Sopenharmony_ci/** 192662306a36Sopenharmony_ci * nla_align_64bit - 64-bit align the nla_data() of next attribute 192762306a36Sopenharmony_ci * @skb: socket buffer the message is stored in 192862306a36Sopenharmony_ci * @padattr: attribute type for the padding 192962306a36Sopenharmony_ci * 193062306a36Sopenharmony_ci * Conditionally emit a padding netlink attribute in order to make 193162306a36Sopenharmony_ci * the next attribute we emit have a 64-bit aligned nla_data() area. 193262306a36Sopenharmony_ci * This will only be done in architectures which do not have 193362306a36Sopenharmony_ci * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS defined. 193462306a36Sopenharmony_ci * 193562306a36Sopenharmony_ci * Returns zero on success or a negative error code. 193662306a36Sopenharmony_ci */ 193762306a36Sopenharmony_cistatic inline int nla_align_64bit(struct sk_buff *skb, int padattr) 193862306a36Sopenharmony_ci{ 193962306a36Sopenharmony_ci if (nla_need_padding_for_64bit(skb) && 194062306a36Sopenharmony_ci !nla_reserve(skb, padattr, 0)) 194162306a36Sopenharmony_ci return -EMSGSIZE; 194262306a36Sopenharmony_ci 194362306a36Sopenharmony_ci return 0; 194462306a36Sopenharmony_ci} 194562306a36Sopenharmony_ci 194662306a36Sopenharmony_ci/** 194762306a36Sopenharmony_ci * nla_total_size_64bit - total length of attribute including padding 194862306a36Sopenharmony_ci * @payload: length of payload 194962306a36Sopenharmony_ci */ 195062306a36Sopenharmony_cistatic inline int nla_total_size_64bit(int payload) 195162306a36Sopenharmony_ci{ 195262306a36Sopenharmony_ci return NLA_ALIGN(nla_attr_size(payload)) 195362306a36Sopenharmony_ci#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 195462306a36Sopenharmony_ci + NLA_ALIGN(nla_attr_size(0)) 195562306a36Sopenharmony_ci#endif 195662306a36Sopenharmony_ci ; 195762306a36Sopenharmony_ci} 195862306a36Sopenharmony_ci 195962306a36Sopenharmony_ci/** 196062306a36Sopenharmony_ci * nla_for_each_attr - iterate over a stream of attributes 196162306a36Sopenharmony_ci * @pos: loop counter, set to current attribute 196262306a36Sopenharmony_ci * @head: head of attribute stream 196362306a36Sopenharmony_ci * @len: length of attribute stream 196462306a36Sopenharmony_ci * @rem: initialized to len, holds bytes currently remaining in stream 196562306a36Sopenharmony_ci */ 196662306a36Sopenharmony_ci#define nla_for_each_attr(pos, head, len, rem) \ 196762306a36Sopenharmony_ci for (pos = head, rem = len; \ 196862306a36Sopenharmony_ci nla_ok(pos, rem); \ 196962306a36Sopenharmony_ci pos = nla_next(pos, &(rem))) 197062306a36Sopenharmony_ci 197162306a36Sopenharmony_ci/** 197262306a36Sopenharmony_ci * nla_for_each_nested - iterate over nested attributes 197362306a36Sopenharmony_ci * @pos: loop counter, set to current attribute 197462306a36Sopenharmony_ci * @nla: attribute containing the nested attributes 197562306a36Sopenharmony_ci * @rem: initialized to len, holds bytes currently remaining in stream 197662306a36Sopenharmony_ci */ 197762306a36Sopenharmony_ci#define nla_for_each_nested(pos, nla, rem) \ 197862306a36Sopenharmony_ci nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem) 197962306a36Sopenharmony_ci 198062306a36Sopenharmony_ci/** 198162306a36Sopenharmony_ci * nla_is_last - Test if attribute is last in stream 198262306a36Sopenharmony_ci * @nla: attribute to test 198362306a36Sopenharmony_ci * @rem: bytes remaining in stream 198462306a36Sopenharmony_ci */ 198562306a36Sopenharmony_cistatic inline bool nla_is_last(const struct nlattr *nla, int rem) 198662306a36Sopenharmony_ci{ 198762306a36Sopenharmony_ci return nla->nla_len == rem; 198862306a36Sopenharmony_ci} 198962306a36Sopenharmony_ci 199062306a36Sopenharmony_civoid nla_get_range_unsigned(const struct nla_policy *pt, 199162306a36Sopenharmony_ci struct netlink_range_validation *range); 199262306a36Sopenharmony_civoid nla_get_range_signed(const struct nla_policy *pt, 199362306a36Sopenharmony_ci struct netlink_range_validation_signed *range); 199462306a36Sopenharmony_ci 199562306a36Sopenharmony_cistruct netlink_policy_dump_state; 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_ciint netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate, 199862306a36Sopenharmony_ci const struct nla_policy *policy, 199962306a36Sopenharmony_ci unsigned int maxtype); 200062306a36Sopenharmony_ciint netlink_policy_dump_get_policy_idx(struct netlink_policy_dump_state *state, 200162306a36Sopenharmony_ci const struct nla_policy *policy, 200262306a36Sopenharmony_ci unsigned int maxtype); 200362306a36Sopenharmony_cibool netlink_policy_dump_loop(struct netlink_policy_dump_state *state); 200462306a36Sopenharmony_ciint netlink_policy_dump_write(struct sk_buff *skb, 200562306a36Sopenharmony_ci struct netlink_policy_dump_state *state); 200662306a36Sopenharmony_ciint netlink_policy_dump_attr_size_estimate(const struct nla_policy *pt); 200762306a36Sopenharmony_ciint netlink_policy_dump_write_attr(struct sk_buff *skb, 200862306a36Sopenharmony_ci const struct nla_policy *pt, 200962306a36Sopenharmony_ci int nestattr); 201062306a36Sopenharmony_civoid netlink_policy_dump_free(struct netlink_policy_dump_state *state); 201162306a36Sopenharmony_ci 201262306a36Sopenharmony_ci#endif 2013