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