18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __NET_NETLINK_H
38c2ecf20Sopenharmony_ci#define __NET_NETLINK_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/types.h>
68c2ecf20Sopenharmony_ci#include <linux/netlink.h>
78c2ecf20Sopenharmony_ci#include <linux/jiffies.h>
88c2ecf20Sopenharmony_ci#include <linux/in6.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/* ========================================================================
118c2ecf20Sopenharmony_ci *         Netlink Messages and Attributes Interface (As Seen On TV)
128c2ecf20Sopenharmony_ci * ------------------------------------------------------------------------
138c2ecf20Sopenharmony_ci *                          Messages Interface
148c2ecf20Sopenharmony_ci * ------------------------------------------------------------------------
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * Message Format:
178c2ecf20Sopenharmony_ci *    <--- nlmsg_total_size(payload)  --->
188c2ecf20Sopenharmony_ci *    <-- nlmsg_msg_size(payload) ->
198c2ecf20Sopenharmony_ci *   +----------+- - -+-------------+- - -+-------- - -
208c2ecf20Sopenharmony_ci *   | nlmsghdr | Pad |   Payload   | Pad | nlmsghdr
218c2ecf20Sopenharmony_ci *   +----------+- - -+-------------+- - -+-------- - -
228c2ecf20Sopenharmony_ci *   nlmsg_data(nlh)---^                   ^
238c2ecf20Sopenharmony_ci *   nlmsg_next(nlh)-----------------------+
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * Payload Format:
268c2ecf20Sopenharmony_ci *    <---------------------- nlmsg_len(nlh) --------------------->
278c2ecf20Sopenharmony_ci *    <------ hdrlen ------>       <- nlmsg_attrlen(nlh, hdrlen) ->
288c2ecf20Sopenharmony_ci *   +----------------------+- - -+--------------------------------+
298c2ecf20Sopenharmony_ci *   |     Family Header    | Pad |           Attributes           |
308c2ecf20Sopenharmony_ci *   +----------------------+- - -+--------------------------------+
318c2ecf20Sopenharmony_ci *   nlmsg_attrdata(nlh, hdrlen)---^
328c2ecf20Sopenharmony_ci *
338c2ecf20Sopenharmony_ci * Data Structures:
348c2ecf20Sopenharmony_ci *   struct nlmsghdr			netlink message header
358c2ecf20Sopenharmony_ci *
368c2ecf20Sopenharmony_ci * Message Construction:
378c2ecf20Sopenharmony_ci *   nlmsg_new()			create a new netlink message
388c2ecf20Sopenharmony_ci *   nlmsg_put()			add a netlink message to an skb
398c2ecf20Sopenharmony_ci *   nlmsg_put_answer()			callback based nlmsg_put()
408c2ecf20Sopenharmony_ci *   nlmsg_end()			finalize netlink message
418c2ecf20Sopenharmony_ci *   nlmsg_get_pos()			return current position in message
428c2ecf20Sopenharmony_ci *   nlmsg_trim()			trim part of message
438c2ecf20Sopenharmony_ci *   nlmsg_cancel()			cancel message construction
448c2ecf20Sopenharmony_ci *   nlmsg_free()			free a netlink message
458c2ecf20Sopenharmony_ci *
468c2ecf20Sopenharmony_ci * Message Sending:
478c2ecf20Sopenharmony_ci *   nlmsg_multicast()			multicast message to several groups
488c2ecf20Sopenharmony_ci *   nlmsg_unicast()			unicast a message to a single socket
498c2ecf20Sopenharmony_ci *   nlmsg_notify()			send notification message
508c2ecf20Sopenharmony_ci *
518c2ecf20Sopenharmony_ci * Message Length Calculations:
528c2ecf20Sopenharmony_ci *   nlmsg_msg_size(payload)		length of message w/o padding
538c2ecf20Sopenharmony_ci *   nlmsg_total_size(payload)		length of message w/ padding
548c2ecf20Sopenharmony_ci *   nlmsg_padlen(payload)		length of padding at tail
558c2ecf20Sopenharmony_ci *
568c2ecf20Sopenharmony_ci * Message Payload Access:
578c2ecf20Sopenharmony_ci *   nlmsg_data(nlh)			head of message payload
588c2ecf20Sopenharmony_ci *   nlmsg_len(nlh)			length of message payload
598c2ecf20Sopenharmony_ci *   nlmsg_attrdata(nlh, hdrlen)	head of attributes data
608c2ecf20Sopenharmony_ci *   nlmsg_attrlen(nlh, hdrlen)		length of attributes data
618c2ecf20Sopenharmony_ci *
628c2ecf20Sopenharmony_ci * Message Parsing:
638c2ecf20Sopenharmony_ci *   nlmsg_ok(nlh, remaining)		does nlh fit into remaining bytes?
648c2ecf20Sopenharmony_ci *   nlmsg_next(nlh, remaining)		get next netlink message
658c2ecf20Sopenharmony_ci *   nlmsg_parse()			parse attributes of a message
668c2ecf20Sopenharmony_ci *   nlmsg_find_attr()			find an attribute in a message
678c2ecf20Sopenharmony_ci *   nlmsg_for_each_msg()		loop over all messages
688c2ecf20Sopenharmony_ci *   nlmsg_validate()			validate netlink message incl. attrs
698c2ecf20Sopenharmony_ci *   nlmsg_for_each_attr()		loop over all attributes
708c2ecf20Sopenharmony_ci *
718c2ecf20Sopenharmony_ci * Misc:
728c2ecf20Sopenharmony_ci *   nlmsg_report()			report back to application?
738c2ecf20Sopenharmony_ci *
748c2ecf20Sopenharmony_ci * ------------------------------------------------------------------------
758c2ecf20Sopenharmony_ci *                          Attributes Interface
768c2ecf20Sopenharmony_ci * ------------------------------------------------------------------------
778c2ecf20Sopenharmony_ci *
788c2ecf20Sopenharmony_ci * Attribute Format:
798c2ecf20Sopenharmony_ci *    <------- nla_total_size(payload) ------->
808c2ecf20Sopenharmony_ci *    <---- nla_attr_size(payload) ----->
818c2ecf20Sopenharmony_ci *   +----------+- - -+- - - - - - - - - +- - -+-------- - -
828c2ecf20Sopenharmony_ci *   |  Header  | Pad |     Payload      | Pad |  Header
838c2ecf20Sopenharmony_ci *   +----------+- - -+- - - - - - - - - +- - -+-------- - -
848c2ecf20Sopenharmony_ci *                     <- nla_len(nla) ->      ^
858c2ecf20Sopenharmony_ci *   nla_data(nla)----^                        |
868c2ecf20Sopenharmony_ci *   nla_next(nla)-----------------------------'
878c2ecf20Sopenharmony_ci *
888c2ecf20Sopenharmony_ci * Data Structures:
898c2ecf20Sopenharmony_ci *   struct nlattr			netlink attribute header
908c2ecf20Sopenharmony_ci *
918c2ecf20Sopenharmony_ci * Attribute Construction:
928c2ecf20Sopenharmony_ci *   nla_reserve(skb, type, len)	reserve room for an attribute
938c2ecf20Sopenharmony_ci *   nla_reserve_nohdr(skb, len)	reserve room for an attribute w/o hdr
948c2ecf20Sopenharmony_ci *   nla_put(skb, type, len, data)	add attribute to skb
958c2ecf20Sopenharmony_ci *   nla_put_nohdr(skb, len, data)	add attribute w/o hdr
968c2ecf20Sopenharmony_ci *   nla_append(skb, len, data)		append data to skb
978c2ecf20Sopenharmony_ci *
988c2ecf20Sopenharmony_ci * Attribute Construction for Basic Types:
998c2ecf20Sopenharmony_ci *   nla_put_u8(skb, type, value)	add u8 attribute to skb
1008c2ecf20Sopenharmony_ci *   nla_put_u16(skb, type, value)	add u16 attribute to skb
1018c2ecf20Sopenharmony_ci *   nla_put_u32(skb, type, value)	add u32 attribute to skb
1028c2ecf20Sopenharmony_ci *   nla_put_u64_64bit(skb, type,
1038c2ecf20Sopenharmony_ci *                     value, padattr)	add u64 attribute to skb
1048c2ecf20Sopenharmony_ci *   nla_put_s8(skb, type, value)	add s8 attribute to skb
1058c2ecf20Sopenharmony_ci *   nla_put_s16(skb, type, value)	add s16 attribute to skb
1068c2ecf20Sopenharmony_ci *   nla_put_s32(skb, type, value)	add s32 attribute to skb
1078c2ecf20Sopenharmony_ci *   nla_put_s64(skb, type, value,
1088c2ecf20Sopenharmony_ci *               padattr)		add s64 attribute to skb
1098c2ecf20Sopenharmony_ci *   nla_put_string(skb, type, str)	add string attribute to skb
1108c2ecf20Sopenharmony_ci *   nla_put_flag(skb, type)		add flag attribute to skb
1118c2ecf20Sopenharmony_ci *   nla_put_msecs(skb, type, jiffies,
1128c2ecf20Sopenharmony_ci *                 padattr)		add msecs attribute to skb
1138c2ecf20Sopenharmony_ci *   nla_put_in_addr(skb, type, addr)	add IPv4 address attribute to skb
1148c2ecf20Sopenharmony_ci *   nla_put_in6_addr(skb, type, addr)	add IPv6 address attribute to skb
1158c2ecf20Sopenharmony_ci *
1168c2ecf20Sopenharmony_ci * Nested Attributes Construction:
1178c2ecf20Sopenharmony_ci *   nla_nest_start(skb, type)		start a nested attribute
1188c2ecf20Sopenharmony_ci *   nla_nest_end(skb, nla)		finalize a nested attribute
1198c2ecf20Sopenharmony_ci *   nla_nest_cancel(skb, nla)		cancel nested attribute construction
1208c2ecf20Sopenharmony_ci *
1218c2ecf20Sopenharmony_ci * Attribute Length Calculations:
1228c2ecf20Sopenharmony_ci *   nla_attr_size(payload)		length of attribute w/o padding
1238c2ecf20Sopenharmony_ci *   nla_total_size(payload)		length of attribute w/ padding
1248c2ecf20Sopenharmony_ci *   nla_padlen(payload)		length of padding
1258c2ecf20Sopenharmony_ci *
1268c2ecf20Sopenharmony_ci * Attribute Payload Access:
1278c2ecf20Sopenharmony_ci *   nla_data(nla)			head of attribute payload
1288c2ecf20Sopenharmony_ci *   nla_len(nla)			length of attribute payload
1298c2ecf20Sopenharmony_ci *
1308c2ecf20Sopenharmony_ci * Attribute Payload Access for Basic Types:
1318c2ecf20Sopenharmony_ci *   nla_get_u8(nla)			get payload for a u8 attribute
1328c2ecf20Sopenharmony_ci *   nla_get_u16(nla)			get payload for a u16 attribute
1338c2ecf20Sopenharmony_ci *   nla_get_u32(nla)			get payload for a u32 attribute
1348c2ecf20Sopenharmony_ci *   nla_get_u64(nla)			get payload for a u64 attribute
1358c2ecf20Sopenharmony_ci *   nla_get_s8(nla)			get payload for a s8 attribute
1368c2ecf20Sopenharmony_ci *   nla_get_s16(nla)			get payload for a s16 attribute
1378c2ecf20Sopenharmony_ci *   nla_get_s32(nla)			get payload for a s32 attribute
1388c2ecf20Sopenharmony_ci *   nla_get_s64(nla)			get payload for a s64 attribute
1398c2ecf20Sopenharmony_ci *   nla_get_flag(nla)			return 1 if flag is true
1408c2ecf20Sopenharmony_ci *   nla_get_msecs(nla)			get payload for a msecs attribute
1418c2ecf20Sopenharmony_ci *
1428c2ecf20Sopenharmony_ci * Attribute Misc:
1438c2ecf20Sopenharmony_ci *   nla_memcpy(dest, nla, count)	copy attribute into memory
1448c2ecf20Sopenharmony_ci *   nla_memcmp(nla, data, size)	compare attribute with memory area
1458c2ecf20Sopenharmony_ci *   nla_strlcpy(dst, nla, size)	copy attribute to a sized string
1468c2ecf20Sopenharmony_ci *   nla_strcmp(nla, str)		compare attribute with string
1478c2ecf20Sopenharmony_ci *
1488c2ecf20Sopenharmony_ci * Attribute Parsing:
1498c2ecf20Sopenharmony_ci *   nla_ok(nla, remaining)		does nla fit into remaining bytes?
1508c2ecf20Sopenharmony_ci *   nla_next(nla, remaining)		get next netlink attribute
1518c2ecf20Sopenharmony_ci *   nla_validate()			validate a stream of attributes
1528c2ecf20Sopenharmony_ci *   nla_validate_nested()		validate a stream of nested attributes
1538c2ecf20Sopenharmony_ci *   nla_find()				find attribute in stream of attributes
1548c2ecf20Sopenharmony_ci *   nla_find_nested()			find attribute in nested attributes
1558c2ecf20Sopenharmony_ci *   nla_parse()			parse and validate stream of attrs
1568c2ecf20Sopenharmony_ci *   nla_parse_nested()			parse nested attributes
1578c2ecf20Sopenharmony_ci *   nla_for_each_attr()		loop over all attributes
1588c2ecf20Sopenharmony_ci *   nla_for_each_nested()		loop over the nested attributes
1598c2ecf20Sopenharmony_ci *=========================================================================
1608c2ecf20Sopenharmony_ci */
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci /**
1638c2ecf20Sopenharmony_ci  * Standard attribute types to specify validation policy
1648c2ecf20Sopenharmony_ci  */
1658c2ecf20Sopenharmony_cienum {
1668c2ecf20Sopenharmony_ci	NLA_UNSPEC,
1678c2ecf20Sopenharmony_ci	NLA_U8,
1688c2ecf20Sopenharmony_ci	NLA_U16,
1698c2ecf20Sopenharmony_ci	NLA_U32,
1708c2ecf20Sopenharmony_ci	NLA_U64,
1718c2ecf20Sopenharmony_ci	NLA_STRING,
1728c2ecf20Sopenharmony_ci	NLA_FLAG,
1738c2ecf20Sopenharmony_ci	NLA_MSECS,
1748c2ecf20Sopenharmony_ci	NLA_NESTED,
1758c2ecf20Sopenharmony_ci	NLA_NESTED_ARRAY,
1768c2ecf20Sopenharmony_ci	NLA_NUL_STRING,
1778c2ecf20Sopenharmony_ci	NLA_BINARY,
1788c2ecf20Sopenharmony_ci	NLA_S8,
1798c2ecf20Sopenharmony_ci	NLA_S16,
1808c2ecf20Sopenharmony_ci	NLA_S32,
1818c2ecf20Sopenharmony_ci	NLA_S64,
1828c2ecf20Sopenharmony_ci	NLA_BITFIELD32,
1838c2ecf20Sopenharmony_ci	NLA_REJECT,
1848c2ecf20Sopenharmony_ci	__NLA_TYPE_MAX,
1858c2ecf20Sopenharmony_ci};
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_cistruct netlink_range_validation {
1908c2ecf20Sopenharmony_ci	u64 min, max;
1918c2ecf20Sopenharmony_ci};
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_cistruct netlink_range_validation_signed {
1948c2ecf20Sopenharmony_ci	s64 min, max;
1958c2ecf20Sopenharmony_ci};
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_cienum nla_policy_validation {
1988c2ecf20Sopenharmony_ci	NLA_VALIDATE_NONE,
1998c2ecf20Sopenharmony_ci	NLA_VALIDATE_RANGE,
2008c2ecf20Sopenharmony_ci	NLA_VALIDATE_RANGE_WARN_TOO_LONG,
2018c2ecf20Sopenharmony_ci	NLA_VALIDATE_MIN,
2028c2ecf20Sopenharmony_ci	NLA_VALIDATE_MAX,
2038c2ecf20Sopenharmony_ci	NLA_VALIDATE_MASK,
2048c2ecf20Sopenharmony_ci	NLA_VALIDATE_RANGE_PTR,
2058c2ecf20Sopenharmony_ci	NLA_VALIDATE_FUNCTION,
2068c2ecf20Sopenharmony_ci};
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci/**
2098c2ecf20Sopenharmony_ci * struct nla_policy - attribute validation policy
2108c2ecf20Sopenharmony_ci * @type: Type of attribute or NLA_UNSPEC
2118c2ecf20Sopenharmony_ci * @validation_type: type of attribute validation done in addition to
2128c2ecf20Sopenharmony_ci *	type-specific validation (e.g. range, function call), see
2138c2ecf20Sopenharmony_ci *	&enum nla_policy_validation
2148c2ecf20Sopenharmony_ci * @len: Type specific length of payload
2158c2ecf20Sopenharmony_ci *
2168c2ecf20Sopenharmony_ci * Policies are defined as arrays of this struct, the array must be
2178c2ecf20Sopenharmony_ci * accessible by attribute type up to the highest identifier to be expected.
2188c2ecf20Sopenharmony_ci *
2198c2ecf20Sopenharmony_ci * Meaning of `len' field:
2208c2ecf20Sopenharmony_ci *    NLA_STRING           Maximum length of string
2218c2ecf20Sopenharmony_ci *    NLA_NUL_STRING       Maximum length of string (excluding NUL)
2228c2ecf20Sopenharmony_ci *    NLA_FLAG             Unused
2238c2ecf20Sopenharmony_ci *    NLA_BINARY           Maximum length of attribute payload
2248c2ecf20Sopenharmony_ci *                         (but see also below with the validation type)
2258c2ecf20Sopenharmony_ci *    NLA_NESTED,
2268c2ecf20Sopenharmony_ci *    NLA_NESTED_ARRAY     Length verification is done by checking len of
2278c2ecf20Sopenharmony_ci *                         nested header (or empty); len field is used if
2288c2ecf20Sopenharmony_ci *                         nested_policy is also used, for the max attr
2298c2ecf20Sopenharmony_ci *                         number in the nested policy.
2308c2ecf20Sopenharmony_ci *    NLA_U8, NLA_U16,
2318c2ecf20Sopenharmony_ci *    NLA_U32, NLA_U64,
2328c2ecf20Sopenharmony_ci *    NLA_S8, NLA_S16,
2338c2ecf20Sopenharmony_ci *    NLA_S32, NLA_S64,
2348c2ecf20Sopenharmony_ci *    NLA_MSECS            Leaving the length field zero will verify the
2358c2ecf20Sopenharmony_ci *                         given type fits, using it verifies minimum length
2368c2ecf20Sopenharmony_ci *                         just like "All other"
2378c2ecf20Sopenharmony_ci *    NLA_BITFIELD32       Unused
2388c2ecf20Sopenharmony_ci *    NLA_REJECT           Unused
2398c2ecf20Sopenharmony_ci *    All other            Minimum length of attribute payload
2408c2ecf20Sopenharmony_ci *
2418c2ecf20Sopenharmony_ci * Meaning of validation union:
2428c2ecf20Sopenharmony_ci *    NLA_BITFIELD32       This is a 32-bit bitmap/bitselector attribute and
2438c2ecf20Sopenharmony_ci *                         `bitfield32_valid' is the u32 value of valid flags
2448c2ecf20Sopenharmony_ci *    NLA_REJECT           This attribute is always rejected and `reject_message'
2458c2ecf20Sopenharmony_ci *                         may point to a string to report as the error instead
2468c2ecf20Sopenharmony_ci *                         of the generic one in extended ACK.
2478c2ecf20Sopenharmony_ci *    NLA_NESTED           `nested_policy' to a nested policy to validate, must
2488c2ecf20Sopenharmony_ci *                         also set `len' to the max attribute number. Use the
2498c2ecf20Sopenharmony_ci *                         provided NLA_POLICY_NESTED() macro.
2508c2ecf20Sopenharmony_ci *                         Note that nla_parse() will validate, but of course not
2518c2ecf20Sopenharmony_ci *                         parse, the nested sub-policies.
2528c2ecf20Sopenharmony_ci *    NLA_NESTED_ARRAY     `nested_policy' points to a nested policy to validate,
2538c2ecf20Sopenharmony_ci *                         must also set `len' to the max attribute number. Use
2548c2ecf20Sopenharmony_ci *                         the provided NLA_POLICY_NESTED_ARRAY() macro.
2558c2ecf20Sopenharmony_ci *                         The difference to NLA_NESTED is the structure:
2568c2ecf20Sopenharmony_ci *                         NLA_NESTED has the nested attributes directly inside
2578c2ecf20Sopenharmony_ci *                         while an array has the nested attributes at another
2588c2ecf20Sopenharmony_ci *                         level down and the attribute types directly in the
2598c2ecf20Sopenharmony_ci *                         nesting don't matter.
2608c2ecf20Sopenharmony_ci *    NLA_U8,
2618c2ecf20Sopenharmony_ci *    NLA_U16,
2628c2ecf20Sopenharmony_ci *    NLA_U32,
2638c2ecf20Sopenharmony_ci *    NLA_U64,
2648c2ecf20Sopenharmony_ci *    NLA_S8,
2658c2ecf20Sopenharmony_ci *    NLA_S16,
2668c2ecf20Sopenharmony_ci *    NLA_S32,
2678c2ecf20Sopenharmony_ci *    NLA_S64              The `min' and `max' fields are used depending on the
2688c2ecf20Sopenharmony_ci *                         validation_type field, if that is min/max/range then
2698c2ecf20Sopenharmony_ci *                         the min, max or both are used (respectively) to check
2708c2ecf20Sopenharmony_ci *                         the value of the integer attribute.
2718c2ecf20Sopenharmony_ci *                         Note that in the interest of code simplicity and
2728c2ecf20Sopenharmony_ci *                         struct size both limits are s16, so you cannot
2738c2ecf20Sopenharmony_ci *                         enforce a range that doesn't fall within the range
2748c2ecf20Sopenharmony_ci *                         of s16 - do that as usual in the code instead.
2758c2ecf20Sopenharmony_ci *                         Use the NLA_POLICY_MIN(), NLA_POLICY_MAX() and
2768c2ecf20Sopenharmony_ci *                         NLA_POLICY_RANGE() macros.
2778c2ecf20Sopenharmony_ci *    NLA_U8,
2788c2ecf20Sopenharmony_ci *    NLA_U16,
2798c2ecf20Sopenharmony_ci *    NLA_U32,
2808c2ecf20Sopenharmony_ci *    NLA_U64              If the validation_type field instead is set to
2818c2ecf20Sopenharmony_ci *                         NLA_VALIDATE_RANGE_PTR, `range' must be a pointer
2828c2ecf20Sopenharmony_ci *                         to a struct netlink_range_validation that indicates
2838c2ecf20Sopenharmony_ci *                         the min/max values.
2848c2ecf20Sopenharmony_ci *                         Use NLA_POLICY_FULL_RANGE().
2858c2ecf20Sopenharmony_ci *    NLA_S8,
2868c2ecf20Sopenharmony_ci *    NLA_S16,
2878c2ecf20Sopenharmony_ci *    NLA_S32,
2888c2ecf20Sopenharmony_ci *    NLA_S64              If the validation_type field instead is set to
2898c2ecf20Sopenharmony_ci *                         NLA_VALIDATE_RANGE_PTR, `range_signed' must be a
2908c2ecf20Sopenharmony_ci *                         pointer to a struct netlink_range_validation_signed
2918c2ecf20Sopenharmony_ci *                         that indicates the min/max values.
2928c2ecf20Sopenharmony_ci *                         Use NLA_POLICY_FULL_RANGE_SIGNED().
2938c2ecf20Sopenharmony_ci *
2948c2ecf20Sopenharmony_ci *    NLA_BINARY           If the validation type is like the ones for integers
2958c2ecf20Sopenharmony_ci *                         above, then the min/max length (not value like for
2968c2ecf20Sopenharmony_ci *                         integers) of the attribute is enforced.
2978c2ecf20Sopenharmony_ci *
2988c2ecf20Sopenharmony_ci *    All other            Unused - but note that it's a union
2998c2ecf20Sopenharmony_ci *
3008c2ecf20Sopenharmony_ci * Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN:
3018c2ecf20Sopenharmony_ci *    NLA_BINARY           Validation function called for the attribute.
3028c2ecf20Sopenharmony_ci *    All other            Unused - but note that it's a union
3038c2ecf20Sopenharmony_ci *
3048c2ecf20Sopenharmony_ci * Example:
3058c2ecf20Sopenharmony_ci *
3068c2ecf20Sopenharmony_ci * static const u32 myvalidflags = 0xff231023;
3078c2ecf20Sopenharmony_ci *
3088c2ecf20Sopenharmony_ci * static const struct nla_policy my_policy[ATTR_MAX+1] = {
3098c2ecf20Sopenharmony_ci * 	[ATTR_FOO] = { .type = NLA_U16 },
3108c2ecf20Sopenharmony_ci *	[ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ },
3118c2ecf20Sopenharmony_ci *	[ATTR_BAZ] = NLA_POLICY_EXACT_LEN(sizeof(struct mystruct)),
3128c2ecf20Sopenharmony_ci *	[ATTR_GOO] = NLA_POLICY_BITFIELD32(myvalidflags),
3138c2ecf20Sopenharmony_ci * };
3148c2ecf20Sopenharmony_ci */
3158c2ecf20Sopenharmony_cistruct nla_policy {
3168c2ecf20Sopenharmony_ci	u8		type;
3178c2ecf20Sopenharmony_ci	u8		validation_type;
3188c2ecf20Sopenharmony_ci	u16		len;
3198c2ecf20Sopenharmony_ci	union {
3208c2ecf20Sopenharmony_ci		const u32 bitfield32_valid;
3218c2ecf20Sopenharmony_ci		const u32 mask;
3228c2ecf20Sopenharmony_ci		const char *reject_message;
3238c2ecf20Sopenharmony_ci		const struct nla_policy *nested_policy;
3248c2ecf20Sopenharmony_ci		struct netlink_range_validation *range;
3258c2ecf20Sopenharmony_ci		struct netlink_range_validation_signed *range_signed;
3268c2ecf20Sopenharmony_ci		struct {
3278c2ecf20Sopenharmony_ci			s16 min, max;
3288c2ecf20Sopenharmony_ci		};
3298c2ecf20Sopenharmony_ci		int (*validate)(const struct nlattr *attr,
3308c2ecf20Sopenharmony_ci				struct netlink_ext_ack *extack);
3318c2ecf20Sopenharmony_ci		/* This entry is special, and used for the attribute at index 0
3328c2ecf20Sopenharmony_ci		 * only, and specifies special data about the policy, namely it
3338c2ecf20Sopenharmony_ci		 * specifies the "boundary type" where strict length validation
3348c2ecf20Sopenharmony_ci		 * starts for any attribute types >= this value, also, strict
3358c2ecf20Sopenharmony_ci		 * nesting validation starts here.
3368c2ecf20Sopenharmony_ci		 *
3378c2ecf20Sopenharmony_ci		 * Additionally, it means that NLA_UNSPEC is actually NLA_REJECT
3388c2ecf20Sopenharmony_ci		 * for any types >= this, so need to use NLA_POLICY_MIN_LEN() to
3398c2ecf20Sopenharmony_ci		 * get the previous pure { .len = xyz } behaviour. The advantage
3408c2ecf20Sopenharmony_ci		 * of this is that types not specified in the policy will be
3418c2ecf20Sopenharmony_ci		 * rejected.
3428c2ecf20Sopenharmony_ci		 *
3438c2ecf20Sopenharmony_ci		 * For completely new families it should be set to 1 so that the
3448c2ecf20Sopenharmony_ci		 * validation is enforced for all attributes. For existing ones
3458c2ecf20Sopenharmony_ci		 * it should be set at least when new attributes are added to
3468c2ecf20Sopenharmony_ci		 * the enum used by the policy, and be set to the new value that
3478c2ecf20Sopenharmony_ci		 * was added to enforce strict validation from thereon.
3488c2ecf20Sopenharmony_ci		 */
3498c2ecf20Sopenharmony_ci		u16 strict_start_type;
3508c2ecf20Sopenharmony_ci	};
3518c2ecf20Sopenharmony_ci};
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci#define NLA_POLICY_ETH_ADDR		NLA_POLICY_EXACT_LEN(ETH_ALEN)
3548c2ecf20Sopenharmony_ci#define NLA_POLICY_ETH_ADDR_COMPAT	NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci#define _NLA_POLICY_NESTED(maxattr, policy) \
3578c2ecf20Sopenharmony_ci	{ .type = NLA_NESTED, .nested_policy = policy, .len = maxattr }
3588c2ecf20Sopenharmony_ci#define _NLA_POLICY_NESTED_ARRAY(maxattr, policy) \
3598c2ecf20Sopenharmony_ci	{ .type = NLA_NESTED_ARRAY, .nested_policy = policy, .len = maxattr }
3608c2ecf20Sopenharmony_ci#define NLA_POLICY_NESTED(policy) \
3618c2ecf20Sopenharmony_ci	_NLA_POLICY_NESTED(ARRAY_SIZE(policy) - 1, policy)
3628c2ecf20Sopenharmony_ci#define NLA_POLICY_NESTED_ARRAY(policy) \
3638c2ecf20Sopenharmony_ci	_NLA_POLICY_NESTED_ARRAY(ARRAY_SIZE(policy) - 1, policy)
3648c2ecf20Sopenharmony_ci#define NLA_POLICY_BITFIELD32(valid) \
3658c2ecf20Sopenharmony_ci	{ .type = NLA_BITFIELD32, .bitfield32_valid = valid }
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci#define __NLA_IS_UINT_TYPE(tp)						\
3688c2ecf20Sopenharmony_ci	(tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 || tp == NLA_U64)
3698c2ecf20Sopenharmony_ci#define __NLA_IS_SINT_TYPE(tp)						\
3708c2ecf20Sopenharmony_ci	(tp == NLA_S8 || tp == NLA_S16 || tp == NLA_S32 || tp == NLA_S64)
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci#define __NLA_ENSURE(condition) BUILD_BUG_ON_ZERO(!(condition))
3738c2ecf20Sopenharmony_ci#define NLA_ENSURE_UINT_TYPE(tp)			\
3748c2ecf20Sopenharmony_ci	(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp)) + tp)
3758c2ecf20Sopenharmony_ci#define NLA_ENSURE_UINT_OR_BINARY_TYPE(tp)		\
3768c2ecf20Sopenharmony_ci	(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) ||	\
3778c2ecf20Sopenharmony_ci		      tp == NLA_MSECS ||		\
3788c2ecf20Sopenharmony_ci		      tp == NLA_BINARY) + tp)
3798c2ecf20Sopenharmony_ci#define NLA_ENSURE_SINT_TYPE(tp)			\
3808c2ecf20Sopenharmony_ci	(__NLA_ENSURE(__NLA_IS_SINT_TYPE(tp)) + tp)
3818c2ecf20Sopenharmony_ci#define NLA_ENSURE_INT_OR_BINARY_TYPE(tp)		\
3828c2ecf20Sopenharmony_ci	(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) ||		\
3838c2ecf20Sopenharmony_ci		      __NLA_IS_SINT_TYPE(tp) ||		\
3848c2ecf20Sopenharmony_ci		      tp == NLA_MSECS ||		\
3858c2ecf20Sopenharmony_ci		      tp == NLA_BINARY) + tp)
3868c2ecf20Sopenharmony_ci#define NLA_ENSURE_NO_VALIDATION_PTR(tp)		\
3878c2ecf20Sopenharmony_ci	(__NLA_ENSURE(tp != NLA_BITFIELD32 &&		\
3888c2ecf20Sopenharmony_ci		      tp != NLA_REJECT &&		\
3898c2ecf20Sopenharmony_ci		      tp != NLA_NESTED &&		\
3908c2ecf20Sopenharmony_ci		      tp != NLA_NESTED_ARRAY) + tp)
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci#define NLA_POLICY_RANGE(tp, _min, _max) {		\
3938c2ecf20Sopenharmony_ci	.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp),	\
3948c2ecf20Sopenharmony_ci	.validation_type = NLA_VALIDATE_RANGE,		\
3958c2ecf20Sopenharmony_ci	.min = _min,					\
3968c2ecf20Sopenharmony_ci	.max = _max					\
3978c2ecf20Sopenharmony_ci}
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci#define NLA_POLICY_FULL_RANGE(tp, _range) {		\
4008c2ecf20Sopenharmony_ci	.type = NLA_ENSURE_UINT_OR_BINARY_TYPE(tp),	\
4018c2ecf20Sopenharmony_ci	.validation_type = NLA_VALIDATE_RANGE_PTR,	\
4028c2ecf20Sopenharmony_ci	.range = _range,				\
4038c2ecf20Sopenharmony_ci}
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci#define NLA_POLICY_FULL_RANGE_SIGNED(tp, _range) {	\
4068c2ecf20Sopenharmony_ci	.type = NLA_ENSURE_SINT_TYPE(tp),		\
4078c2ecf20Sopenharmony_ci	.validation_type = NLA_VALIDATE_RANGE_PTR,	\
4088c2ecf20Sopenharmony_ci	.range_signed = _range,				\
4098c2ecf20Sopenharmony_ci}
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci#define NLA_POLICY_MIN(tp, _min) {			\
4128c2ecf20Sopenharmony_ci	.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp),	\
4138c2ecf20Sopenharmony_ci	.validation_type = NLA_VALIDATE_MIN,		\
4148c2ecf20Sopenharmony_ci	.min = _min,					\
4158c2ecf20Sopenharmony_ci}
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ci#define NLA_POLICY_MAX(tp, _max) {			\
4188c2ecf20Sopenharmony_ci	.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp),	\
4198c2ecf20Sopenharmony_ci	.validation_type = NLA_VALIDATE_MAX,		\
4208c2ecf20Sopenharmony_ci	.max = _max,					\
4218c2ecf20Sopenharmony_ci}
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_ci#define NLA_POLICY_MASK(tp, _mask) {			\
4248c2ecf20Sopenharmony_ci	.type = NLA_ENSURE_UINT_TYPE(tp),		\
4258c2ecf20Sopenharmony_ci	.validation_type = NLA_VALIDATE_MASK,		\
4268c2ecf20Sopenharmony_ci	.mask = _mask,					\
4278c2ecf20Sopenharmony_ci}
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci#define NLA_POLICY_VALIDATE_FN(tp, fn, ...) {		\
4308c2ecf20Sopenharmony_ci	.type = NLA_ENSURE_NO_VALIDATION_PTR(tp),	\
4318c2ecf20Sopenharmony_ci	.validation_type = NLA_VALIDATE_FUNCTION,	\
4328c2ecf20Sopenharmony_ci	.validate = fn,					\
4338c2ecf20Sopenharmony_ci	.len = __VA_ARGS__ + 0,				\
4348c2ecf20Sopenharmony_ci}
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci#define NLA_POLICY_EXACT_LEN(_len)	NLA_POLICY_RANGE(NLA_BINARY, _len, _len)
4378c2ecf20Sopenharmony_ci#define NLA_POLICY_EXACT_LEN_WARN(_len) {			\
4388c2ecf20Sopenharmony_ci	.type = NLA_BINARY,					\
4398c2ecf20Sopenharmony_ci	.validation_type = NLA_VALIDATE_RANGE_WARN_TOO_LONG,	\
4408c2ecf20Sopenharmony_ci	.min = _len,						\
4418c2ecf20Sopenharmony_ci	.max = _len						\
4428c2ecf20Sopenharmony_ci}
4438c2ecf20Sopenharmony_ci#define NLA_POLICY_MIN_LEN(_len)	NLA_POLICY_MIN(NLA_BINARY, _len)
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci/**
4468c2ecf20Sopenharmony_ci * struct nl_info - netlink source information
4478c2ecf20Sopenharmony_ci * @nlh: Netlink message header of original request
4488c2ecf20Sopenharmony_ci * @nl_net: Network namespace
4498c2ecf20Sopenharmony_ci * @portid: Netlink PORTID of requesting application
4508c2ecf20Sopenharmony_ci * @skip_notify: Skip netlink notifications to user space
4518c2ecf20Sopenharmony_ci * @skip_notify_kernel: Skip selected in-kernel notifications
4528c2ecf20Sopenharmony_ci */
4538c2ecf20Sopenharmony_cistruct nl_info {
4548c2ecf20Sopenharmony_ci	struct nlmsghdr		*nlh;
4558c2ecf20Sopenharmony_ci	struct net		*nl_net;
4568c2ecf20Sopenharmony_ci	u32			portid;
4578c2ecf20Sopenharmony_ci	u8			skip_notify:1,
4588c2ecf20Sopenharmony_ci				skip_notify_kernel:1;
4598c2ecf20Sopenharmony_ci};
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci/**
4628c2ecf20Sopenharmony_ci * enum netlink_validation - netlink message/attribute validation levels
4638c2ecf20Sopenharmony_ci * @NL_VALIDATE_LIBERAL: Old-style "be liberal" validation, not caring about
4648c2ecf20Sopenharmony_ci *	extra data at the end of the message, attributes being longer than
4658c2ecf20Sopenharmony_ci *	they should be, or unknown attributes being present.
4668c2ecf20Sopenharmony_ci * @NL_VALIDATE_TRAILING: Reject junk data encountered after attribute parsing.
4678c2ecf20Sopenharmony_ci * @NL_VALIDATE_MAXTYPE: Reject attributes > max type; Together with _TRAILING
4688c2ecf20Sopenharmony_ci *	this is equivalent to the old nla_parse_strict()/nlmsg_parse_strict().
4698c2ecf20Sopenharmony_ci * @NL_VALIDATE_UNSPEC: Reject attributes with NLA_UNSPEC in the policy.
4708c2ecf20Sopenharmony_ci *	This can safely be set by the kernel when the given policy has no
4718c2ecf20Sopenharmony_ci *	NLA_UNSPEC anymore, and can thus be used to ensure policy entries
4728c2ecf20Sopenharmony_ci *	are enforced going forward.
4738c2ecf20Sopenharmony_ci * @NL_VALIDATE_STRICT_ATTRS: strict attribute policy parsing (e.g.
4748c2ecf20Sopenharmony_ci *	U8, U16, U32 must have exact size, etc.)
4758c2ecf20Sopenharmony_ci * @NL_VALIDATE_NESTED: Check that NLA_F_NESTED is set for NLA_NESTED(_ARRAY)
4768c2ecf20Sopenharmony_ci *	and unset for other policies.
4778c2ecf20Sopenharmony_ci */
4788c2ecf20Sopenharmony_cienum netlink_validation {
4798c2ecf20Sopenharmony_ci	NL_VALIDATE_LIBERAL = 0,
4808c2ecf20Sopenharmony_ci	NL_VALIDATE_TRAILING = BIT(0),
4818c2ecf20Sopenharmony_ci	NL_VALIDATE_MAXTYPE = BIT(1),
4828c2ecf20Sopenharmony_ci	NL_VALIDATE_UNSPEC = BIT(2),
4838c2ecf20Sopenharmony_ci	NL_VALIDATE_STRICT_ATTRS = BIT(3),
4848c2ecf20Sopenharmony_ci	NL_VALIDATE_NESTED = BIT(4),
4858c2ecf20Sopenharmony_ci};
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci#define NL_VALIDATE_DEPRECATED_STRICT (NL_VALIDATE_TRAILING |\
4888c2ecf20Sopenharmony_ci				       NL_VALIDATE_MAXTYPE)
4898c2ecf20Sopenharmony_ci#define NL_VALIDATE_STRICT (NL_VALIDATE_TRAILING |\
4908c2ecf20Sopenharmony_ci			    NL_VALIDATE_MAXTYPE |\
4918c2ecf20Sopenharmony_ci			    NL_VALIDATE_UNSPEC |\
4928c2ecf20Sopenharmony_ci			    NL_VALIDATE_STRICT_ATTRS |\
4938c2ecf20Sopenharmony_ci			    NL_VALIDATE_NESTED)
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ciint netlink_rcv_skb(struct sk_buff *skb,
4968c2ecf20Sopenharmony_ci		    int (*cb)(struct sk_buff *, struct nlmsghdr *,
4978c2ecf20Sopenharmony_ci			      struct netlink_ext_ack *));
4988c2ecf20Sopenharmony_ciint nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
4998c2ecf20Sopenharmony_ci		 unsigned int group, int report, gfp_t flags);
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ciint __nla_validate(const struct nlattr *head, int len, int maxtype,
5028c2ecf20Sopenharmony_ci		   const struct nla_policy *policy, unsigned int validate,
5038c2ecf20Sopenharmony_ci		   struct netlink_ext_ack *extack);
5048c2ecf20Sopenharmony_ciint __nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
5058c2ecf20Sopenharmony_ci		int len, const struct nla_policy *policy, unsigned int validate,
5068c2ecf20Sopenharmony_ci		struct netlink_ext_ack *extack);
5078c2ecf20Sopenharmony_ciint nla_policy_len(const struct nla_policy *, int);
5088c2ecf20Sopenharmony_cistruct nlattr *nla_find(const struct nlattr *head, int len, int attrtype);
5098c2ecf20Sopenharmony_cisize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
5108c2ecf20Sopenharmony_cichar *nla_strdup(const struct nlattr *nla, gfp_t flags);
5118c2ecf20Sopenharmony_ciint nla_memcpy(void *dest, const struct nlattr *src, int count);
5128c2ecf20Sopenharmony_ciint nla_memcmp(const struct nlattr *nla, const void *data, size_t size);
5138c2ecf20Sopenharmony_ciint nla_strcmp(const struct nlattr *nla, const char *str);
5148c2ecf20Sopenharmony_cistruct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen);
5158c2ecf20Sopenharmony_cistruct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype,
5168c2ecf20Sopenharmony_ci				   int attrlen, int padattr);
5178c2ecf20Sopenharmony_civoid *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen);
5188c2ecf20Sopenharmony_cistruct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen);
5198c2ecf20Sopenharmony_cistruct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype,
5208c2ecf20Sopenharmony_ci				 int attrlen, int padattr);
5218c2ecf20Sopenharmony_civoid *nla_reserve_nohdr(struct sk_buff *skb, int attrlen);
5228c2ecf20Sopenharmony_civoid __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
5238c2ecf20Sopenharmony_ci	       const void *data);
5248c2ecf20Sopenharmony_civoid __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
5258c2ecf20Sopenharmony_ci		     const void *data, int padattr);
5268c2ecf20Sopenharmony_civoid __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data);
5278c2ecf20Sopenharmony_ciint nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data);
5288c2ecf20Sopenharmony_ciint nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
5298c2ecf20Sopenharmony_ci		  const void *data, int padattr);
5308c2ecf20Sopenharmony_ciint nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data);
5318c2ecf20Sopenharmony_ciint nla_append(struct sk_buff *skb, int attrlen, const void *data);
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci/**************************************************************************
5348c2ecf20Sopenharmony_ci * Netlink Messages
5358c2ecf20Sopenharmony_ci **************************************************************************/
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci/**
5388c2ecf20Sopenharmony_ci * nlmsg_msg_size - length of netlink message not including padding
5398c2ecf20Sopenharmony_ci * @payload: length of message payload
5408c2ecf20Sopenharmony_ci */
5418c2ecf20Sopenharmony_cistatic inline int nlmsg_msg_size(int payload)
5428c2ecf20Sopenharmony_ci{
5438c2ecf20Sopenharmony_ci	return NLMSG_HDRLEN + payload;
5448c2ecf20Sopenharmony_ci}
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci/**
5478c2ecf20Sopenharmony_ci * nlmsg_total_size - length of netlink message including padding
5488c2ecf20Sopenharmony_ci * @payload: length of message payload
5498c2ecf20Sopenharmony_ci */
5508c2ecf20Sopenharmony_cistatic inline int nlmsg_total_size(int payload)
5518c2ecf20Sopenharmony_ci{
5528c2ecf20Sopenharmony_ci	return NLMSG_ALIGN(nlmsg_msg_size(payload));
5538c2ecf20Sopenharmony_ci}
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci/**
5568c2ecf20Sopenharmony_ci * nlmsg_padlen - length of padding at the message's tail
5578c2ecf20Sopenharmony_ci * @payload: length of message payload
5588c2ecf20Sopenharmony_ci */
5598c2ecf20Sopenharmony_cistatic inline int nlmsg_padlen(int payload)
5608c2ecf20Sopenharmony_ci{
5618c2ecf20Sopenharmony_ci	return nlmsg_total_size(payload) - nlmsg_msg_size(payload);
5628c2ecf20Sopenharmony_ci}
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci/**
5658c2ecf20Sopenharmony_ci * nlmsg_data - head of message payload
5668c2ecf20Sopenharmony_ci * @nlh: netlink message header
5678c2ecf20Sopenharmony_ci */
5688c2ecf20Sopenharmony_cistatic inline void *nlmsg_data(const struct nlmsghdr *nlh)
5698c2ecf20Sopenharmony_ci{
5708c2ecf20Sopenharmony_ci	return (unsigned char *) nlh + NLMSG_HDRLEN;
5718c2ecf20Sopenharmony_ci}
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_ci/**
5748c2ecf20Sopenharmony_ci * nlmsg_len - length of message payload
5758c2ecf20Sopenharmony_ci * @nlh: netlink message header
5768c2ecf20Sopenharmony_ci */
5778c2ecf20Sopenharmony_cistatic inline int nlmsg_len(const struct nlmsghdr *nlh)
5788c2ecf20Sopenharmony_ci{
5798c2ecf20Sopenharmony_ci	return nlh->nlmsg_len - NLMSG_HDRLEN;
5808c2ecf20Sopenharmony_ci}
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_ci/**
5838c2ecf20Sopenharmony_ci * nlmsg_attrdata - head of attributes data
5848c2ecf20Sopenharmony_ci * @nlh: netlink message header
5858c2ecf20Sopenharmony_ci * @hdrlen: length of family specific header
5868c2ecf20Sopenharmony_ci */
5878c2ecf20Sopenharmony_cistatic inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
5888c2ecf20Sopenharmony_ci					    int hdrlen)
5898c2ecf20Sopenharmony_ci{
5908c2ecf20Sopenharmony_ci	unsigned char *data = nlmsg_data(nlh);
5918c2ecf20Sopenharmony_ci	return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
5928c2ecf20Sopenharmony_ci}
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_ci/**
5958c2ecf20Sopenharmony_ci * nlmsg_attrlen - length of attributes data
5968c2ecf20Sopenharmony_ci * @nlh: netlink message header
5978c2ecf20Sopenharmony_ci * @hdrlen: length of family specific header
5988c2ecf20Sopenharmony_ci */
5998c2ecf20Sopenharmony_cistatic inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
6008c2ecf20Sopenharmony_ci{
6018c2ecf20Sopenharmony_ci	return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
6028c2ecf20Sopenharmony_ci}
6038c2ecf20Sopenharmony_ci
6048c2ecf20Sopenharmony_ci/**
6058c2ecf20Sopenharmony_ci * nlmsg_ok - check if the netlink message fits into the remaining bytes
6068c2ecf20Sopenharmony_ci * @nlh: netlink message header
6078c2ecf20Sopenharmony_ci * @remaining: number of bytes remaining in message stream
6088c2ecf20Sopenharmony_ci */
6098c2ecf20Sopenharmony_cistatic inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
6108c2ecf20Sopenharmony_ci{
6118c2ecf20Sopenharmony_ci	return (remaining >= (int) sizeof(struct nlmsghdr) &&
6128c2ecf20Sopenharmony_ci		nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
6138c2ecf20Sopenharmony_ci		nlh->nlmsg_len <= remaining);
6148c2ecf20Sopenharmony_ci}
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_ci/**
6178c2ecf20Sopenharmony_ci * nlmsg_next - next netlink message in message stream
6188c2ecf20Sopenharmony_ci * @nlh: netlink message header
6198c2ecf20Sopenharmony_ci * @remaining: number of bytes remaining in message stream
6208c2ecf20Sopenharmony_ci *
6218c2ecf20Sopenharmony_ci * Returns the next netlink message in the message stream and
6228c2ecf20Sopenharmony_ci * decrements remaining by the size of the current message.
6238c2ecf20Sopenharmony_ci */
6248c2ecf20Sopenharmony_cistatic inline struct nlmsghdr *
6258c2ecf20Sopenharmony_cinlmsg_next(const struct nlmsghdr *nlh, int *remaining)
6268c2ecf20Sopenharmony_ci{
6278c2ecf20Sopenharmony_ci	int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
6288c2ecf20Sopenharmony_ci
6298c2ecf20Sopenharmony_ci	*remaining -= totlen;
6308c2ecf20Sopenharmony_ci
6318c2ecf20Sopenharmony_ci	return (struct nlmsghdr *) ((unsigned char *) nlh + totlen);
6328c2ecf20Sopenharmony_ci}
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_ci/**
6358c2ecf20Sopenharmony_ci * nla_parse - Parse a stream of attributes into a tb buffer
6368c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
6378c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
6388c2ecf20Sopenharmony_ci * @head: head of attribute stream
6398c2ecf20Sopenharmony_ci * @len: length of attribute stream
6408c2ecf20Sopenharmony_ci * @policy: validation policy
6418c2ecf20Sopenharmony_ci * @extack: extended ACK pointer
6428c2ecf20Sopenharmony_ci *
6438c2ecf20Sopenharmony_ci * Parses a stream of attributes and stores a pointer to each attribute in
6448c2ecf20Sopenharmony_ci * the tb array accessible via the attribute type. Attributes with a type
6458c2ecf20Sopenharmony_ci * exceeding maxtype will be rejected, policy must be specified, attributes
6468c2ecf20Sopenharmony_ci * will be validated in the strictest way possible.
6478c2ecf20Sopenharmony_ci *
6488c2ecf20Sopenharmony_ci * Returns 0 on success or a negative error code.
6498c2ecf20Sopenharmony_ci */
6508c2ecf20Sopenharmony_cistatic inline int nla_parse(struct nlattr **tb, int maxtype,
6518c2ecf20Sopenharmony_ci			    const struct nlattr *head, int len,
6528c2ecf20Sopenharmony_ci			    const struct nla_policy *policy,
6538c2ecf20Sopenharmony_ci			    struct netlink_ext_ack *extack)
6548c2ecf20Sopenharmony_ci{
6558c2ecf20Sopenharmony_ci	return __nla_parse(tb, maxtype, head, len, policy,
6568c2ecf20Sopenharmony_ci			   NL_VALIDATE_STRICT, extack);
6578c2ecf20Sopenharmony_ci}
6588c2ecf20Sopenharmony_ci
6598c2ecf20Sopenharmony_ci/**
6608c2ecf20Sopenharmony_ci * nla_parse_deprecated - Parse a stream of attributes into a tb buffer
6618c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
6628c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
6638c2ecf20Sopenharmony_ci * @head: head of attribute stream
6648c2ecf20Sopenharmony_ci * @len: length of attribute stream
6658c2ecf20Sopenharmony_ci * @policy: validation policy
6668c2ecf20Sopenharmony_ci * @extack: extended ACK pointer
6678c2ecf20Sopenharmony_ci *
6688c2ecf20Sopenharmony_ci * Parses a stream of attributes and stores a pointer to each attribute in
6698c2ecf20Sopenharmony_ci * the tb array accessible via the attribute type. Attributes with a type
6708c2ecf20Sopenharmony_ci * exceeding maxtype will be ignored and attributes from the policy are not
6718c2ecf20Sopenharmony_ci * always strictly validated (only for new attributes).
6728c2ecf20Sopenharmony_ci *
6738c2ecf20Sopenharmony_ci * Returns 0 on success or a negative error code.
6748c2ecf20Sopenharmony_ci */
6758c2ecf20Sopenharmony_cistatic inline int nla_parse_deprecated(struct nlattr **tb, int maxtype,
6768c2ecf20Sopenharmony_ci				       const struct nlattr *head, int len,
6778c2ecf20Sopenharmony_ci				       const struct nla_policy *policy,
6788c2ecf20Sopenharmony_ci				       struct netlink_ext_ack *extack)
6798c2ecf20Sopenharmony_ci{
6808c2ecf20Sopenharmony_ci	return __nla_parse(tb, maxtype, head, len, policy,
6818c2ecf20Sopenharmony_ci			   NL_VALIDATE_LIBERAL, extack);
6828c2ecf20Sopenharmony_ci}
6838c2ecf20Sopenharmony_ci
6848c2ecf20Sopenharmony_ci/**
6858c2ecf20Sopenharmony_ci * nla_parse_deprecated_strict - Parse a stream of attributes into a tb buffer
6868c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
6878c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
6888c2ecf20Sopenharmony_ci * @head: head of attribute stream
6898c2ecf20Sopenharmony_ci * @len: length of attribute stream
6908c2ecf20Sopenharmony_ci * @policy: validation policy
6918c2ecf20Sopenharmony_ci * @extack: extended ACK pointer
6928c2ecf20Sopenharmony_ci *
6938c2ecf20Sopenharmony_ci * Parses a stream of attributes and stores a pointer to each attribute in
6948c2ecf20Sopenharmony_ci * the tb array accessible via the attribute type. Attributes with a type
6958c2ecf20Sopenharmony_ci * exceeding maxtype will be rejected as well as trailing data, but the
6968c2ecf20Sopenharmony_ci * policy is not completely strictly validated (only for new attributes).
6978c2ecf20Sopenharmony_ci *
6988c2ecf20Sopenharmony_ci * Returns 0 on success or a negative error code.
6998c2ecf20Sopenharmony_ci */
7008c2ecf20Sopenharmony_cistatic inline int nla_parse_deprecated_strict(struct nlattr **tb, int maxtype,
7018c2ecf20Sopenharmony_ci					      const struct nlattr *head,
7028c2ecf20Sopenharmony_ci					      int len,
7038c2ecf20Sopenharmony_ci					      const struct nla_policy *policy,
7048c2ecf20Sopenharmony_ci					      struct netlink_ext_ack *extack)
7058c2ecf20Sopenharmony_ci{
7068c2ecf20Sopenharmony_ci	return __nla_parse(tb, maxtype, head, len, policy,
7078c2ecf20Sopenharmony_ci			   NL_VALIDATE_DEPRECATED_STRICT, extack);
7088c2ecf20Sopenharmony_ci}
7098c2ecf20Sopenharmony_ci
7108c2ecf20Sopenharmony_ci/**
7118c2ecf20Sopenharmony_ci * __nlmsg_parse - parse attributes of a netlink message
7128c2ecf20Sopenharmony_ci * @nlh: netlink message header
7138c2ecf20Sopenharmony_ci * @hdrlen: length of family specific header
7148c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
7158c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
7168c2ecf20Sopenharmony_ci * @policy: validation policy
7178c2ecf20Sopenharmony_ci * @validate: validation strictness
7188c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
7198c2ecf20Sopenharmony_ci *
7208c2ecf20Sopenharmony_ci * See nla_parse()
7218c2ecf20Sopenharmony_ci */
7228c2ecf20Sopenharmony_cistatic inline int __nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen,
7238c2ecf20Sopenharmony_ci				struct nlattr *tb[], int maxtype,
7248c2ecf20Sopenharmony_ci				const struct nla_policy *policy,
7258c2ecf20Sopenharmony_ci				unsigned int validate,
7268c2ecf20Sopenharmony_ci				struct netlink_ext_ack *extack)
7278c2ecf20Sopenharmony_ci{
7288c2ecf20Sopenharmony_ci	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) {
7298c2ecf20Sopenharmony_ci		NL_SET_ERR_MSG(extack, "Invalid header length");
7308c2ecf20Sopenharmony_ci		return -EINVAL;
7318c2ecf20Sopenharmony_ci	}
7328c2ecf20Sopenharmony_ci
7338c2ecf20Sopenharmony_ci	return __nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
7348c2ecf20Sopenharmony_ci			   nlmsg_attrlen(nlh, hdrlen), policy, validate,
7358c2ecf20Sopenharmony_ci			   extack);
7368c2ecf20Sopenharmony_ci}
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_ci/**
7398c2ecf20Sopenharmony_ci * nlmsg_parse - parse attributes of a netlink message
7408c2ecf20Sopenharmony_ci * @nlh: netlink message header
7418c2ecf20Sopenharmony_ci * @hdrlen: length of family specific header
7428c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
7438c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
7448c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
7458c2ecf20Sopenharmony_ci *
7468c2ecf20Sopenharmony_ci * See nla_parse()
7478c2ecf20Sopenharmony_ci */
7488c2ecf20Sopenharmony_cistatic inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen,
7498c2ecf20Sopenharmony_ci			      struct nlattr *tb[], int maxtype,
7508c2ecf20Sopenharmony_ci			      const struct nla_policy *policy,
7518c2ecf20Sopenharmony_ci			      struct netlink_ext_ack *extack)
7528c2ecf20Sopenharmony_ci{
7538c2ecf20Sopenharmony_ci	return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy,
7548c2ecf20Sopenharmony_ci			     NL_VALIDATE_STRICT, extack);
7558c2ecf20Sopenharmony_ci}
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_ci/**
7588c2ecf20Sopenharmony_ci * nlmsg_parse_deprecated - parse attributes of a netlink message
7598c2ecf20Sopenharmony_ci * @nlh: netlink message header
7608c2ecf20Sopenharmony_ci * @hdrlen: length of family specific header
7618c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
7628c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
7638c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
7648c2ecf20Sopenharmony_ci *
7658c2ecf20Sopenharmony_ci * See nla_parse_deprecated()
7668c2ecf20Sopenharmony_ci */
7678c2ecf20Sopenharmony_cistatic inline int nlmsg_parse_deprecated(const struct nlmsghdr *nlh, int hdrlen,
7688c2ecf20Sopenharmony_ci					 struct nlattr *tb[], int maxtype,
7698c2ecf20Sopenharmony_ci					 const struct nla_policy *policy,
7708c2ecf20Sopenharmony_ci					 struct netlink_ext_ack *extack)
7718c2ecf20Sopenharmony_ci{
7728c2ecf20Sopenharmony_ci	return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy,
7738c2ecf20Sopenharmony_ci			     NL_VALIDATE_LIBERAL, extack);
7748c2ecf20Sopenharmony_ci}
7758c2ecf20Sopenharmony_ci
7768c2ecf20Sopenharmony_ci/**
7778c2ecf20Sopenharmony_ci * nlmsg_parse_deprecated_strict - parse attributes of a netlink message
7788c2ecf20Sopenharmony_ci * @nlh: netlink message header
7798c2ecf20Sopenharmony_ci * @hdrlen: length of family specific header
7808c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
7818c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
7828c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
7838c2ecf20Sopenharmony_ci *
7848c2ecf20Sopenharmony_ci * See nla_parse_deprecated_strict()
7858c2ecf20Sopenharmony_ci */
7868c2ecf20Sopenharmony_cistatic inline int
7878c2ecf20Sopenharmony_cinlmsg_parse_deprecated_strict(const struct nlmsghdr *nlh, int hdrlen,
7888c2ecf20Sopenharmony_ci			      struct nlattr *tb[], int maxtype,
7898c2ecf20Sopenharmony_ci			      const struct nla_policy *policy,
7908c2ecf20Sopenharmony_ci			      struct netlink_ext_ack *extack)
7918c2ecf20Sopenharmony_ci{
7928c2ecf20Sopenharmony_ci	return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy,
7938c2ecf20Sopenharmony_ci			     NL_VALIDATE_DEPRECATED_STRICT, extack);
7948c2ecf20Sopenharmony_ci}
7958c2ecf20Sopenharmony_ci
7968c2ecf20Sopenharmony_ci/**
7978c2ecf20Sopenharmony_ci * nlmsg_find_attr - find a specific attribute in a netlink message
7988c2ecf20Sopenharmony_ci * @nlh: netlink message header
7998c2ecf20Sopenharmony_ci * @hdrlen: length of familiy specific header
8008c2ecf20Sopenharmony_ci * @attrtype: type of attribute to look for
8018c2ecf20Sopenharmony_ci *
8028c2ecf20Sopenharmony_ci * Returns the first attribute which matches the specified type.
8038c2ecf20Sopenharmony_ci */
8048c2ecf20Sopenharmony_cistatic inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh,
8058c2ecf20Sopenharmony_ci					     int hdrlen, int attrtype)
8068c2ecf20Sopenharmony_ci{
8078c2ecf20Sopenharmony_ci	return nla_find(nlmsg_attrdata(nlh, hdrlen),
8088c2ecf20Sopenharmony_ci			nlmsg_attrlen(nlh, hdrlen), attrtype);
8098c2ecf20Sopenharmony_ci}
8108c2ecf20Sopenharmony_ci
8118c2ecf20Sopenharmony_ci/**
8128c2ecf20Sopenharmony_ci * nla_validate_deprecated - Validate a stream of attributes
8138c2ecf20Sopenharmony_ci * @head: head of attribute stream
8148c2ecf20Sopenharmony_ci * @len: length of attribute stream
8158c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
8168c2ecf20Sopenharmony_ci * @policy: validation policy
8178c2ecf20Sopenharmony_ci * @validate: validation strictness
8188c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
8198c2ecf20Sopenharmony_ci *
8208c2ecf20Sopenharmony_ci * Validates all attributes in the specified attribute stream against the
8218c2ecf20Sopenharmony_ci * specified policy. Validation is done in liberal mode.
8228c2ecf20Sopenharmony_ci * See documenation of struct nla_policy for more details.
8238c2ecf20Sopenharmony_ci *
8248c2ecf20Sopenharmony_ci * Returns 0 on success or a negative error code.
8258c2ecf20Sopenharmony_ci */
8268c2ecf20Sopenharmony_cistatic inline int nla_validate_deprecated(const struct nlattr *head, int len,
8278c2ecf20Sopenharmony_ci					  int maxtype,
8288c2ecf20Sopenharmony_ci					  const struct nla_policy *policy,
8298c2ecf20Sopenharmony_ci					  struct netlink_ext_ack *extack)
8308c2ecf20Sopenharmony_ci{
8318c2ecf20Sopenharmony_ci	return __nla_validate(head, len, maxtype, policy, NL_VALIDATE_LIBERAL,
8328c2ecf20Sopenharmony_ci			      extack);
8338c2ecf20Sopenharmony_ci}
8348c2ecf20Sopenharmony_ci
8358c2ecf20Sopenharmony_ci/**
8368c2ecf20Sopenharmony_ci * nla_validate - Validate a stream of attributes
8378c2ecf20Sopenharmony_ci * @head: head of attribute stream
8388c2ecf20Sopenharmony_ci * @len: length of attribute stream
8398c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
8408c2ecf20Sopenharmony_ci * @policy: validation policy
8418c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
8428c2ecf20Sopenharmony_ci *
8438c2ecf20Sopenharmony_ci * Validates all attributes in the specified attribute stream against the
8448c2ecf20Sopenharmony_ci * specified policy. Validation is done in strict mode.
8458c2ecf20Sopenharmony_ci * See documenation of struct nla_policy for more details.
8468c2ecf20Sopenharmony_ci *
8478c2ecf20Sopenharmony_ci * Returns 0 on success or a negative error code.
8488c2ecf20Sopenharmony_ci */
8498c2ecf20Sopenharmony_cistatic inline int nla_validate(const struct nlattr *head, int len, int maxtype,
8508c2ecf20Sopenharmony_ci			       const struct nla_policy *policy,
8518c2ecf20Sopenharmony_ci			       struct netlink_ext_ack *extack)
8528c2ecf20Sopenharmony_ci{
8538c2ecf20Sopenharmony_ci	return __nla_validate(head, len, maxtype, policy, NL_VALIDATE_STRICT,
8548c2ecf20Sopenharmony_ci			      extack);
8558c2ecf20Sopenharmony_ci}
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci/**
8588c2ecf20Sopenharmony_ci * nlmsg_validate_deprecated - validate a netlink message including attributes
8598c2ecf20Sopenharmony_ci * @nlh: netlinket message header
8608c2ecf20Sopenharmony_ci * @hdrlen: length of familiy specific header
8618c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
8628c2ecf20Sopenharmony_ci * @policy: validation policy
8638c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
8648c2ecf20Sopenharmony_ci */
8658c2ecf20Sopenharmony_cistatic inline int nlmsg_validate_deprecated(const struct nlmsghdr *nlh,
8668c2ecf20Sopenharmony_ci					    int hdrlen, int maxtype,
8678c2ecf20Sopenharmony_ci					    const struct nla_policy *policy,
8688c2ecf20Sopenharmony_ci					    struct netlink_ext_ack *extack)
8698c2ecf20Sopenharmony_ci{
8708c2ecf20Sopenharmony_ci	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
8718c2ecf20Sopenharmony_ci		return -EINVAL;
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci	return __nla_validate(nlmsg_attrdata(nlh, hdrlen),
8748c2ecf20Sopenharmony_ci			      nlmsg_attrlen(nlh, hdrlen), maxtype,
8758c2ecf20Sopenharmony_ci			      policy, NL_VALIDATE_LIBERAL, extack);
8768c2ecf20Sopenharmony_ci}
8778c2ecf20Sopenharmony_ci
8788c2ecf20Sopenharmony_ci
8798c2ecf20Sopenharmony_ci
8808c2ecf20Sopenharmony_ci/**
8818c2ecf20Sopenharmony_ci * nlmsg_report - need to report back to application?
8828c2ecf20Sopenharmony_ci * @nlh: netlink message header
8838c2ecf20Sopenharmony_ci *
8848c2ecf20Sopenharmony_ci * Returns 1 if a report back to the application is requested.
8858c2ecf20Sopenharmony_ci */
8868c2ecf20Sopenharmony_cistatic inline int nlmsg_report(const struct nlmsghdr *nlh)
8878c2ecf20Sopenharmony_ci{
8888c2ecf20Sopenharmony_ci	return !!(nlh->nlmsg_flags & NLM_F_ECHO);
8898c2ecf20Sopenharmony_ci}
8908c2ecf20Sopenharmony_ci
8918c2ecf20Sopenharmony_ci/**
8928c2ecf20Sopenharmony_ci * nlmsg_for_each_attr - iterate over a stream of attributes
8938c2ecf20Sopenharmony_ci * @pos: loop counter, set to current attribute
8948c2ecf20Sopenharmony_ci * @nlh: netlink message header
8958c2ecf20Sopenharmony_ci * @hdrlen: length of familiy specific header
8968c2ecf20Sopenharmony_ci * @rem: initialized to len, holds bytes currently remaining in stream
8978c2ecf20Sopenharmony_ci */
8988c2ecf20Sopenharmony_ci#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
8998c2ecf20Sopenharmony_ci	nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
9008c2ecf20Sopenharmony_ci			  nlmsg_attrlen(nlh, hdrlen), rem)
9018c2ecf20Sopenharmony_ci
9028c2ecf20Sopenharmony_ci/**
9038c2ecf20Sopenharmony_ci * nlmsg_put - Add a new netlink message to an skb
9048c2ecf20Sopenharmony_ci * @skb: socket buffer to store message in
9058c2ecf20Sopenharmony_ci * @portid: netlink PORTID of requesting application
9068c2ecf20Sopenharmony_ci * @seq: sequence number of message
9078c2ecf20Sopenharmony_ci * @type: message type
9088c2ecf20Sopenharmony_ci * @payload: length of message payload
9098c2ecf20Sopenharmony_ci * @flags: message flags
9108c2ecf20Sopenharmony_ci *
9118c2ecf20Sopenharmony_ci * Returns NULL if the tailroom of the skb is insufficient to store
9128c2ecf20Sopenharmony_ci * the message header and payload.
9138c2ecf20Sopenharmony_ci */
9148c2ecf20Sopenharmony_cistatic inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
9158c2ecf20Sopenharmony_ci					 int type, int payload, int flags)
9168c2ecf20Sopenharmony_ci{
9178c2ecf20Sopenharmony_ci	if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
9188c2ecf20Sopenharmony_ci		return NULL;
9198c2ecf20Sopenharmony_ci
9208c2ecf20Sopenharmony_ci	return __nlmsg_put(skb, portid, seq, type, payload, flags);
9218c2ecf20Sopenharmony_ci}
9228c2ecf20Sopenharmony_ci
9238c2ecf20Sopenharmony_ci/**
9248c2ecf20Sopenharmony_ci * nlmsg_put_answer - Add a new callback based netlink message to an skb
9258c2ecf20Sopenharmony_ci * @skb: socket buffer to store message in
9268c2ecf20Sopenharmony_ci * @cb: netlink callback
9278c2ecf20Sopenharmony_ci * @type: message type
9288c2ecf20Sopenharmony_ci * @payload: length of message payload
9298c2ecf20Sopenharmony_ci * @flags: message flags
9308c2ecf20Sopenharmony_ci *
9318c2ecf20Sopenharmony_ci * Returns NULL if the tailroom of the skb is insufficient to store
9328c2ecf20Sopenharmony_ci * the message header and payload.
9338c2ecf20Sopenharmony_ci */
9348c2ecf20Sopenharmony_cistatic inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
9358c2ecf20Sopenharmony_ci						struct netlink_callback *cb,
9368c2ecf20Sopenharmony_ci						int type, int payload,
9378c2ecf20Sopenharmony_ci						int flags)
9388c2ecf20Sopenharmony_ci{
9398c2ecf20Sopenharmony_ci	return nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
9408c2ecf20Sopenharmony_ci			 type, payload, flags);
9418c2ecf20Sopenharmony_ci}
9428c2ecf20Sopenharmony_ci
9438c2ecf20Sopenharmony_ci/**
9448c2ecf20Sopenharmony_ci * nlmsg_new - Allocate a new netlink message
9458c2ecf20Sopenharmony_ci * @payload: size of the message payload
9468c2ecf20Sopenharmony_ci * @flags: the type of memory to allocate.
9478c2ecf20Sopenharmony_ci *
9488c2ecf20Sopenharmony_ci * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known
9498c2ecf20Sopenharmony_ci * and a good default is needed.
9508c2ecf20Sopenharmony_ci */
9518c2ecf20Sopenharmony_cistatic inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags)
9528c2ecf20Sopenharmony_ci{
9538c2ecf20Sopenharmony_ci	return alloc_skb(nlmsg_total_size(payload), flags);
9548c2ecf20Sopenharmony_ci}
9558c2ecf20Sopenharmony_ci
9568c2ecf20Sopenharmony_ci/**
9578c2ecf20Sopenharmony_ci * nlmsg_end - Finalize a netlink message
9588c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in
9598c2ecf20Sopenharmony_ci * @nlh: netlink message header
9608c2ecf20Sopenharmony_ci *
9618c2ecf20Sopenharmony_ci * Corrects the netlink message header to include the appeneded
9628c2ecf20Sopenharmony_ci * attributes. Only necessary if attributes have been added to
9638c2ecf20Sopenharmony_ci * the message.
9648c2ecf20Sopenharmony_ci */
9658c2ecf20Sopenharmony_cistatic inline void nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
9668c2ecf20Sopenharmony_ci{
9678c2ecf20Sopenharmony_ci	nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh;
9688c2ecf20Sopenharmony_ci}
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_ci/**
9718c2ecf20Sopenharmony_ci * nlmsg_get_pos - return current position in netlink message
9728c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in
9738c2ecf20Sopenharmony_ci *
9748c2ecf20Sopenharmony_ci * Returns a pointer to the current tail of the message.
9758c2ecf20Sopenharmony_ci */
9768c2ecf20Sopenharmony_cistatic inline void *nlmsg_get_pos(struct sk_buff *skb)
9778c2ecf20Sopenharmony_ci{
9788c2ecf20Sopenharmony_ci	return skb_tail_pointer(skb);
9798c2ecf20Sopenharmony_ci}
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci/**
9828c2ecf20Sopenharmony_ci * nlmsg_trim - Trim message to a mark
9838c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in
9848c2ecf20Sopenharmony_ci * @mark: mark to trim to
9858c2ecf20Sopenharmony_ci *
9868c2ecf20Sopenharmony_ci * Trims the message to the provided mark.
9878c2ecf20Sopenharmony_ci */
9888c2ecf20Sopenharmony_cistatic inline void nlmsg_trim(struct sk_buff *skb, const void *mark)
9898c2ecf20Sopenharmony_ci{
9908c2ecf20Sopenharmony_ci	if (mark) {
9918c2ecf20Sopenharmony_ci		WARN_ON((unsigned char *) mark < skb->data);
9928c2ecf20Sopenharmony_ci		skb_trim(skb, (unsigned char *) mark - skb->data);
9938c2ecf20Sopenharmony_ci	}
9948c2ecf20Sopenharmony_ci}
9958c2ecf20Sopenharmony_ci
9968c2ecf20Sopenharmony_ci/**
9978c2ecf20Sopenharmony_ci * nlmsg_cancel - Cancel construction of a netlink message
9988c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in
9998c2ecf20Sopenharmony_ci * @nlh: netlink message header
10008c2ecf20Sopenharmony_ci *
10018c2ecf20Sopenharmony_ci * Removes the complete netlink message including all
10028c2ecf20Sopenharmony_ci * attributes from the socket buffer again.
10038c2ecf20Sopenharmony_ci */
10048c2ecf20Sopenharmony_cistatic inline void nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
10058c2ecf20Sopenharmony_ci{
10068c2ecf20Sopenharmony_ci	nlmsg_trim(skb, nlh);
10078c2ecf20Sopenharmony_ci}
10088c2ecf20Sopenharmony_ci
10098c2ecf20Sopenharmony_ci/**
10108c2ecf20Sopenharmony_ci * nlmsg_free - free a netlink message
10118c2ecf20Sopenharmony_ci * @skb: socket buffer of netlink message
10128c2ecf20Sopenharmony_ci */
10138c2ecf20Sopenharmony_cistatic inline void nlmsg_free(struct sk_buff *skb)
10148c2ecf20Sopenharmony_ci{
10158c2ecf20Sopenharmony_ci	kfree_skb(skb);
10168c2ecf20Sopenharmony_ci}
10178c2ecf20Sopenharmony_ci
10188c2ecf20Sopenharmony_ci/**
10198c2ecf20Sopenharmony_ci * nlmsg_multicast - multicast a netlink message
10208c2ecf20Sopenharmony_ci * @sk: netlink socket to spread messages to
10218c2ecf20Sopenharmony_ci * @skb: netlink message as socket buffer
10228c2ecf20Sopenharmony_ci * @portid: own netlink portid to avoid sending to yourself
10238c2ecf20Sopenharmony_ci * @group: multicast group id
10248c2ecf20Sopenharmony_ci * @flags: allocation flags
10258c2ecf20Sopenharmony_ci */
10268c2ecf20Sopenharmony_cistatic inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
10278c2ecf20Sopenharmony_ci				  u32 portid, unsigned int group, gfp_t flags)
10288c2ecf20Sopenharmony_ci{
10298c2ecf20Sopenharmony_ci	int err;
10308c2ecf20Sopenharmony_ci
10318c2ecf20Sopenharmony_ci	NETLINK_CB(skb).dst_group = group;
10328c2ecf20Sopenharmony_ci
10338c2ecf20Sopenharmony_ci	err = netlink_broadcast(sk, skb, portid, group, flags);
10348c2ecf20Sopenharmony_ci	if (err > 0)
10358c2ecf20Sopenharmony_ci		err = 0;
10368c2ecf20Sopenharmony_ci
10378c2ecf20Sopenharmony_ci	return err;
10388c2ecf20Sopenharmony_ci}
10398c2ecf20Sopenharmony_ci
10408c2ecf20Sopenharmony_ci/**
10418c2ecf20Sopenharmony_ci * nlmsg_unicast - unicast a netlink message
10428c2ecf20Sopenharmony_ci * @sk: netlink socket to spread message to
10438c2ecf20Sopenharmony_ci * @skb: netlink message as socket buffer
10448c2ecf20Sopenharmony_ci * @portid: netlink portid of the destination socket
10458c2ecf20Sopenharmony_ci */
10468c2ecf20Sopenharmony_cistatic inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 portid)
10478c2ecf20Sopenharmony_ci{
10488c2ecf20Sopenharmony_ci	int err;
10498c2ecf20Sopenharmony_ci
10508c2ecf20Sopenharmony_ci	err = netlink_unicast(sk, skb, portid, MSG_DONTWAIT);
10518c2ecf20Sopenharmony_ci	if (err > 0)
10528c2ecf20Sopenharmony_ci		err = 0;
10538c2ecf20Sopenharmony_ci
10548c2ecf20Sopenharmony_ci	return err;
10558c2ecf20Sopenharmony_ci}
10568c2ecf20Sopenharmony_ci
10578c2ecf20Sopenharmony_ci/**
10588c2ecf20Sopenharmony_ci * nlmsg_for_each_msg - iterate over a stream of messages
10598c2ecf20Sopenharmony_ci * @pos: loop counter, set to current message
10608c2ecf20Sopenharmony_ci * @head: head of message stream
10618c2ecf20Sopenharmony_ci * @len: length of message stream
10628c2ecf20Sopenharmony_ci * @rem: initialized to len, holds bytes currently remaining in stream
10638c2ecf20Sopenharmony_ci */
10648c2ecf20Sopenharmony_ci#define nlmsg_for_each_msg(pos, head, len, rem) \
10658c2ecf20Sopenharmony_ci	for (pos = head, rem = len; \
10668c2ecf20Sopenharmony_ci	     nlmsg_ok(pos, rem); \
10678c2ecf20Sopenharmony_ci	     pos = nlmsg_next(pos, &(rem)))
10688c2ecf20Sopenharmony_ci
10698c2ecf20Sopenharmony_ci/**
10708c2ecf20Sopenharmony_ci * nl_dump_check_consistent - check if sequence is consistent and advertise if not
10718c2ecf20Sopenharmony_ci * @cb: netlink callback structure that stores the sequence number
10728c2ecf20Sopenharmony_ci * @nlh: netlink message header to write the flag to
10738c2ecf20Sopenharmony_ci *
10748c2ecf20Sopenharmony_ci * This function checks if the sequence (generation) number changed during dump
10758c2ecf20Sopenharmony_ci * and if it did, advertises it in the netlink message header.
10768c2ecf20Sopenharmony_ci *
10778c2ecf20Sopenharmony_ci * The correct way to use it is to set cb->seq to the generation counter when
10788c2ecf20Sopenharmony_ci * all locks for dumping have been acquired, and then call this function for
10798c2ecf20Sopenharmony_ci * each message that is generated.
10808c2ecf20Sopenharmony_ci *
10818c2ecf20Sopenharmony_ci * Note that due to initialisation concerns, 0 is an invalid sequence number
10828c2ecf20Sopenharmony_ci * and must not be used by code that uses this functionality.
10838c2ecf20Sopenharmony_ci */
10848c2ecf20Sopenharmony_cistatic inline void
10858c2ecf20Sopenharmony_cinl_dump_check_consistent(struct netlink_callback *cb,
10868c2ecf20Sopenharmony_ci			 struct nlmsghdr *nlh)
10878c2ecf20Sopenharmony_ci{
10888c2ecf20Sopenharmony_ci	if (cb->prev_seq && cb->seq != cb->prev_seq)
10898c2ecf20Sopenharmony_ci		nlh->nlmsg_flags |= NLM_F_DUMP_INTR;
10908c2ecf20Sopenharmony_ci	cb->prev_seq = cb->seq;
10918c2ecf20Sopenharmony_ci}
10928c2ecf20Sopenharmony_ci
10938c2ecf20Sopenharmony_ci/**************************************************************************
10948c2ecf20Sopenharmony_ci * Netlink Attributes
10958c2ecf20Sopenharmony_ci **************************************************************************/
10968c2ecf20Sopenharmony_ci
10978c2ecf20Sopenharmony_ci/**
10988c2ecf20Sopenharmony_ci * nla_attr_size - length of attribute not including padding
10998c2ecf20Sopenharmony_ci * @payload: length of payload
11008c2ecf20Sopenharmony_ci */
11018c2ecf20Sopenharmony_cistatic inline int nla_attr_size(int payload)
11028c2ecf20Sopenharmony_ci{
11038c2ecf20Sopenharmony_ci	return NLA_HDRLEN + payload;
11048c2ecf20Sopenharmony_ci}
11058c2ecf20Sopenharmony_ci
11068c2ecf20Sopenharmony_ci/**
11078c2ecf20Sopenharmony_ci * nla_total_size - total length of attribute including padding
11088c2ecf20Sopenharmony_ci * @payload: length of payload
11098c2ecf20Sopenharmony_ci */
11108c2ecf20Sopenharmony_cistatic inline int nla_total_size(int payload)
11118c2ecf20Sopenharmony_ci{
11128c2ecf20Sopenharmony_ci	return NLA_ALIGN(nla_attr_size(payload));
11138c2ecf20Sopenharmony_ci}
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci/**
11168c2ecf20Sopenharmony_ci * nla_padlen - length of padding at the tail of attribute
11178c2ecf20Sopenharmony_ci * @payload: length of payload
11188c2ecf20Sopenharmony_ci */
11198c2ecf20Sopenharmony_cistatic inline int nla_padlen(int payload)
11208c2ecf20Sopenharmony_ci{
11218c2ecf20Sopenharmony_ci	return nla_total_size(payload) - nla_attr_size(payload);
11228c2ecf20Sopenharmony_ci}
11238c2ecf20Sopenharmony_ci
11248c2ecf20Sopenharmony_ci/**
11258c2ecf20Sopenharmony_ci * nla_type - attribute type
11268c2ecf20Sopenharmony_ci * @nla: netlink attribute
11278c2ecf20Sopenharmony_ci */
11288c2ecf20Sopenharmony_cistatic inline int nla_type(const struct nlattr *nla)
11298c2ecf20Sopenharmony_ci{
11308c2ecf20Sopenharmony_ci	return nla->nla_type & NLA_TYPE_MASK;
11318c2ecf20Sopenharmony_ci}
11328c2ecf20Sopenharmony_ci
11338c2ecf20Sopenharmony_ci/**
11348c2ecf20Sopenharmony_ci * nla_data - head of payload
11358c2ecf20Sopenharmony_ci * @nla: netlink attribute
11368c2ecf20Sopenharmony_ci */
11378c2ecf20Sopenharmony_cistatic inline void *nla_data(const struct nlattr *nla)
11388c2ecf20Sopenharmony_ci{
11398c2ecf20Sopenharmony_ci	return (char *) nla + NLA_HDRLEN;
11408c2ecf20Sopenharmony_ci}
11418c2ecf20Sopenharmony_ci
11428c2ecf20Sopenharmony_ci/**
11438c2ecf20Sopenharmony_ci * nla_len - length of payload
11448c2ecf20Sopenharmony_ci * @nla: netlink attribute
11458c2ecf20Sopenharmony_ci */
11468c2ecf20Sopenharmony_cistatic inline int nla_len(const struct nlattr *nla)
11478c2ecf20Sopenharmony_ci{
11488c2ecf20Sopenharmony_ci	return nla->nla_len - NLA_HDRLEN;
11498c2ecf20Sopenharmony_ci}
11508c2ecf20Sopenharmony_ci
11518c2ecf20Sopenharmony_ci/**
11528c2ecf20Sopenharmony_ci * nla_ok - check if the netlink attribute fits into the remaining bytes
11538c2ecf20Sopenharmony_ci * @nla: netlink attribute
11548c2ecf20Sopenharmony_ci * @remaining: number of bytes remaining in attribute stream
11558c2ecf20Sopenharmony_ci */
11568c2ecf20Sopenharmony_cistatic inline int nla_ok(const struct nlattr *nla, int remaining)
11578c2ecf20Sopenharmony_ci{
11588c2ecf20Sopenharmony_ci	return remaining >= (int) sizeof(*nla) &&
11598c2ecf20Sopenharmony_ci	       nla->nla_len >= sizeof(*nla) &&
11608c2ecf20Sopenharmony_ci	       nla->nla_len <= remaining;
11618c2ecf20Sopenharmony_ci}
11628c2ecf20Sopenharmony_ci
11638c2ecf20Sopenharmony_ci/**
11648c2ecf20Sopenharmony_ci * nla_next - next netlink attribute in attribute stream
11658c2ecf20Sopenharmony_ci * @nla: netlink attribute
11668c2ecf20Sopenharmony_ci * @remaining: number of bytes remaining in attribute stream
11678c2ecf20Sopenharmony_ci *
11688c2ecf20Sopenharmony_ci * Returns the next netlink attribute in the attribute stream and
11698c2ecf20Sopenharmony_ci * decrements remaining by the size of the current attribute.
11708c2ecf20Sopenharmony_ci */
11718c2ecf20Sopenharmony_cistatic inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
11728c2ecf20Sopenharmony_ci{
11738c2ecf20Sopenharmony_ci	unsigned int totlen = NLA_ALIGN(nla->nla_len);
11748c2ecf20Sopenharmony_ci
11758c2ecf20Sopenharmony_ci	*remaining -= totlen;
11768c2ecf20Sopenharmony_ci	return (struct nlattr *) ((char *) nla + totlen);
11778c2ecf20Sopenharmony_ci}
11788c2ecf20Sopenharmony_ci
11798c2ecf20Sopenharmony_ci/**
11808c2ecf20Sopenharmony_ci * nla_find_nested - find attribute in a set of nested attributes
11818c2ecf20Sopenharmony_ci * @nla: attribute containing the nested attributes
11828c2ecf20Sopenharmony_ci * @attrtype: type of attribute to look for
11838c2ecf20Sopenharmony_ci *
11848c2ecf20Sopenharmony_ci * Returns the first attribute which matches the specified type.
11858c2ecf20Sopenharmony_ci */
11868c2ecf20Sopenharmony_cistatic inline struct nlattr *
11878c2ecf20Sopenharmony_cinla_find_nested(const struct nlattr *nla, int attrtype)
11888c2ecf20Sopenharmony_ci{
11898c2ecf20Sopenharmony_ci	return nla_find(nla_data(nla), nla_len(nla), attrtype);
11908c2ecf20Sopenharmony_ci}
11918c2ecf20Sopenharmony_ci
11928c2ecf20Sopenharmony_ci/**
11938c2ecf20Sopenharmony_ci * nla_parse_nested - parse nested attributes
11948c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
11958c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
11968c2ecf20Sopenharmony_ci * @nla: attribute containing the nested attributes
11978c2ecf20Sopenharmony_ci * @policy: validation policy
11988c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
11998c2ecf20Sopenharmony_ci *
12008c2ecf20Sopenharmony_ci * See nla_parse()
12018c2ecf20Sopenharmony_ci */
12028c2ecf20Sopenharmony_cistatic inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
12038c2ecf20Sopenharmony_ci				   const struct nlattr *nla,
12048c2ecf20Sopenharmony_ci				   const struct nla_policy *policy,
12058c2ecf20Sopenharmony_ci				   struct netlink_ext_ack *extack)
12068c2ecf20Sopenharmony_ci{
12078c2ecf20Sopenharmony_ci	if (!(nla->nla_type & NLA_F_NESTED)) {
12088c2ecf20Sopenharmony_ci		NL_SET_ERR_MSG_ATTR(extack, nla, "NLA_F_NESTED is missing");
12098c2ecf20Sopenharmony_ci		return -EINVAL;
12108c2ecf20Sopenharmony_ci	}
12118c2ecf20Sopenharmony_ci
12128c2ecf20Sopenharmony_ci	return __nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy,
12138c2ecf20Sopenharmony_ci			   NL_VALIDATE_STRICT, extack);
12148c2ecf20Sopenharmony_ci}
12158c2ecf20Sopenharmony_ci
12168c2ecf20Sopenharmony_ci/**
12178c2ecf20Sopenharmony_ci * nla_parse_nested_deprecated - parse nested attributes
12188c2ecf20Sopenharmony_ci * @tb: destination array with maxtype+1 elements
12198c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
12208c2ecf20Sopenharmony_ci * @nla: attribute containing the nested attributes
12218c2ecf20Sopenharmony_ci * @policy: validation policy
12228c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
12238c2ecf20Sopenharmony_ci *
12248c2ecf20Sopenharmony_ci * See nla_parse_deprecated()
12258c2ecf20Sopenharmony_ci */
12268c2ecf20Sopenharmony_cistatic inline int nla_parse_nested_deprecated(struct nlattr *tb[], int maxtype,
12278c2ecf20Sopenharmony_ci					      const struct nlattr *nla,
12288c2ecf20Sopenharmony_ci					      const struct nla_policy *policy,
12298c2ecf20Sopenharmony_ci					      struct netlink_ext_ack *extack)
12308c2ecf20Sopenharmony_ci{
12318c2ecf20Sopenharmony_ci	return __nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy,
12328c2ecf20Sopenharmony_ci			   NL_VALIDATE_LIBERAL, extack);
12338c2ecf20Sopenharmony_ci}
12348c2ecf20Sopenharmony_ci
12358c2ecf20Sopenharmony_ci/**
12368c2ecf20Sopenharmony_ci * nla_put_u8 - Add a u8 netlink attribute to a socket buffer
12378c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
12388c2ecf20Sopenharmony_ci * @attrtype: attribute type
12398c2ecf20Sopenharmony_ci * @value: numeric value
12408c2ecf20Sopenharmony_ci */
12418c2ecf20Sopenharmony_cistatic inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
12428c2ecf20Sopenharmony_ci{
12438c2ecf20Sopenharmony_ci	/* temporary variables to work around GCC PR81715 with asan-stack=1 */
12448c2ecf20Sopenharmony_ci	u8 tmp = value;
12458c2ecf20Sopenharmony_ci
12468c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(u8), &tmp);
12478c2ecf20Sopenharmony_ci}
12488c2ecf20Sopenharmony_ci
12498c2ecf20Sopenharmony_ci/**
12508c2ecf20Sopenharmony_ci * nla_put_u16 - Add a u16 netlink attribute to a socket buffer
12518c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
12528c2ecf20Sopenharmony_ci * @attrtype: attribute type
12538c2ecf20Sopenharmony_ci * @value: numeric value
12548c2ecf20Sopenharmony_ci */
12558c2ecf20Sopenharmony_cistatic inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
12568c2ecf20Sopenharmony_ci{
12578c2ecf20Sopenharmony_ci	u16 tmp = value;
12588c2ecf20Sopenharmony_ci
12598c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(u16), &tmp);
12608c2ecf20Sopenharmony_ci}
12618c2ecf20Sopenharmony_ci
12628c2ecf20Sopenharmony_ci/**
12638c2ecf20Sopenharmony_ci * nla_put_be16 - Add a __be16 netlink attribute to a socket buffer
12648c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
12658c2ecf20Sopenharmony_ci * @attrtype: attribute type
12668c2ecf20Sopenharmony_ci * @value: numeric value
12678c2ecf20Sopenharmony_ci */
12688c2ecf20Sopenharmony_cistatic inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
12698c2ecf20Sopenharmony_ci{
12708c2ecf20Sopenharmony_ci	__be16 tmp = value;
12718c2ecf20Sopenharmony_ci
12728c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(__be16), &tmp);
12738c2ecf20Sopenharmony_ci}
12748c2ecf20Sopenharmony_ci
12758c2ecf20Sopenharmony_ci/**
12768c2ecf20Sopenharmony_ci * nla_put_net16 - Add 16-bit network byte order netlink attribute to a socket buffer
12778c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
12788c2ecf20Sopenharmony_ci * @attrtype: attribute type
12798c2ecf20Sopenharmony_ci * @value: numeric value
12808c2ecf20Sopenharmony_ci */
12818c2ecf20Sopenharmony_cistatic inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value)
12828c2ecf20Sopenharmony_ci{
12838c2ecf20Sopenharmony_ci	__be16 tmp = value;
12848c2ecf20Sopenharmony_ci
12858c2ecf20Sopenharmony_ci	return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, tmp);
12868c2ecf20Sopenharmony_ci}
12878c2ecf20Sopenharmony_ci
12888c2ecf20Sopenharmony_ci/**
12898c2ecf20Sopenharmony_ci * nla_put_le16 - Add a __le16 netlink attribute to a socket buffer
12908c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
12918c2ecf20Sopenharmony_ci * @attrtype: attribute type
12928c2ecf20Sopenharmony_ci * @value: numeric value
12938c2ecf20Sopenharmony_ci */
12948c2ecf20Sopenharmony_cistatic inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value)
12958c2ecf20Sopenharmony_ci{
12968c2ecf20Sopenharmony_ci	__le16 tmp = value;
12978c2ecf20Sopenharmony_ci
12988c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(__le16), &tmp);
12998c2ecf20Sopenharmony_ci}
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_ci/**
13028c2ecf20Sopenharmony_ci * nla_put_u32 - Add a u32 netlink attribute to a socket buffer
13038c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
13048c2ecf20Sopenharmony_ci * @attrtype: attribute type
13058c2ecf20Sopenharmony_ci * @value: numeric value
13068c2ecf20Sopenharmony_ci */
13078c2ecf20Sopenharmony_cistatic inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
13088c2ecf20Sopenharmony_ci{
13098c2ecf20Sopenharmony_ci	u32 tmp = value;
13108c2ecf20Sopenharmony_ci
13118c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(u32), &tmp);
13128c2ecf20Sopenharmony_ci}
13138c2ecf20Sopenharmony_ci
13148c2ecf20Sopenharmony_ci/**
13158c2ecf20Sopenharmony_ci * nla_put_be32 - Add a __be32 netlink attribute to a socket buffer
13168c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
13178c2ecf20Sopenharmony_ci * @attrtype: attribute type
13188c2ecf20Sopenharmony_ci * @value: numeric value
13198c2ecf20Sopenharmony_ci */
13208c2ecf20Sopenharmony_cistatic inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
13218c2ecf20Sopenharmony_ci{
13228c2ecf20Sopenharmony_ci	__be32 tmp = value;
13238c2ecf20Sopenharmony_ci
13248c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(__be32), &tmp);
13258c2ecf20Sopenharmony_ci}
13268c2ecf20Sopenharmony_ci
13278c2ecf20Sopenharmony_ci/**
13288c2ecf20Sopenharmony_ci * nla_put_net32 - Add 32-bit network byte order netlink attribute to a socket buffer
13298c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
13308c2ecf20Sopenharmony_ci * @attrtype: attribute type
13318c2ecf20Sopenharmony_ci * @value: numeric value
13328c2ecf20Sopenharmony_ci */
13338c2ecf20Sopenharmony_cistatic inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value)
13348c2ecf20Sopenharmony_ci{
13358c2ecf20Sopenharmony_ci	__be32 tmp = value;
13368c2ecf20Sopenharmony_ci
13378c2ecf20Sopenharmony_ci	return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, tmp);
13388c2ecf20Sopenharmony_ci}
13398c2ecf20Sopenharmony_ci
13408c2ecf20Sopenharmony_ci/**
13418c2ecf20Sopenharmony_ci * nla_put_le32 - Add a __le32 netlink attribute to a socket buffer
13428c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
13438c2ecf20Sopenharmony_ci * @attrtype: attribute type
13448c2ecf20Sopenharmony_ci * @value: numeric value
13458c2ecf20Sopenharmony_ci */
13468c2ecf20Sopenharmony_cistatic inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value)
13478c2ecf20Sopenharmony_ci{
13488c2ecf20Sopenharmony_ci	__le32 tmp = value;
13498c2ecf20Sopenharmony_ci
13508c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(__le32), &tmp);
13518c2ecf20Sopenharmony_ci}
13528c2ecf20Sopenharmony_ci
13538c2ecf20Sopenharmony_ci/**
13548c2ecf20Sopenharmony_ci * nla_put_u64_64bit - Add a u64 netlink attribute to a skb and align it
13558c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
13568c2ecf20Sopenharmony_ci * @attrtype: attribute type
13578c2ecf20Sopenharmony_ci * @value: numeric value
13588c2ecf20Sopenharmony_ci * @padattr: attribute type for the padding
13598c2ecf20Sopenharmony_ci */
13608c2ecf20Sopenharmony_cistatic inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
13618c2ecf20Sopenharmony_ci				    u64 value, int padattr)
13628c2ecf20Sopenharmony_ci{
13638c2ecf20Sopenharmony_ci	u64 tmp = value;
13648c2ecf20Sopenharmony_ci
13658c2ecf20Sopenharmony_ci	return nla_put_64bit(skb, attrtype, sizeof(u64), &tmp, padattr);
13668c2ecf20Sopenharmony_ci}
13678c2ecf20Sopenharmony_ci
13688c2ecf20Sopenharmony_ci/**
13698c2ecf20Sopenharmony_ci * nla_put_be64 - Add a __be64 netlink attribute to a socket buffer and align it
13708c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
13718c2ecf20Sopenharmony_ci * @attrtype: attribute type
13728c2ecf20Sopenharmony_ci * @value: numeric value
13738c2ecf20Sopenharmony_ci * @padattr: attribute type for the padding
13748c2ecf20Sopenharmony_ci */
13758c2ecf20Sopenharmony_cistatic inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value,
13768c2ecf20Sopenharmony_ci			       int padattr)
13778c2ecf20Sopenharmony_ci{
13788c2ecf20Sopenharmony_ci	__be64 tmp = value;
13798c2ecf20Sopenharmony_ci
13808c2ecf20Sopenharmony_ci	return nla_put_64bit(skb, attrtype, sizeof(__be64), &tmp, padattr);
13818c2ecf20Sopenharmony_ci}
13828c2ecf20Sopenharmony_ci
13838c2ecf20Sopenharmony_ci/**
13848c2ecf20Sopenharmony_ci * nla_put_net64 - Add 64-bit network byte order nlattr to a skb and align it
13858c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
13868c2ecf20Sopenharmony_ci * @attrtype: attribute type
13878c2ecf20Sopenharmony_ci * @value: numeric value
13888c2ecf20Sopenharmony_ci * @padattr: attribute type for the padding
13898c2ecf20Sopenharmony_ci */
13908c2ecf20Sopenharmony_cistatic inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value,
13918c2ecf20Sopenharmony_ci				int padattr)
13928c2ecf20Sopenharmony_ci{
13938c2ecf20Sopenharmony_ci	__be64 tmp = value;
13948c2ecf20Sopenharmony_ci
13958c2ecf20Sopenharmony_ci	return nla_put_be64(skb, attrtype | NLA_F_NET_BYTEORDER, tmp,
13968c2ecf20Sopenharmony_ci			    padattr);
13978c2ecf20Sopenharmony_ci}
13988c2ecf20Sopenharmony_ci
13998c2ecf20Sopenharmony_ci/**
14008c2ecf20Sopenharmony_ci * nla_put_le64 - Add a __le64 netlink attribute to a socket buffer and align it
14018c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
14028c2ecf20Sopenharmony_ci * @attrtype: attribute type
14038c2ecf20Sopenharmony_ci * @value: numeric value
14048c2ecf20Sopenharmony_ci * @padattr: attribute type for the padding
14058c2ecf20Sopenharmony_ci */
14068c2ecf20Sopenharmony_cistatic inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value,
14078c2ecf20Sopenharmony_ci			       int padattr)
14088c2ecf20Sopenharmony_ci{
14098c2ecf20Sopenharmony_ci	__le64 tmp = value;
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_ci	return nla_put_64bit(skb, attrtype, sizeof(__le64), &tmp, padattr);
14128c2ecf20Sopenharmony_ci}
14138c2ecf20Sopenharmony_ci
14148c2ecf20Sopenharmony_ci/**
14158c2ecf20Sopenharmony_ci * nla_put_s8 - Add a s8 netlink attribute to a socket buffer
14168c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
14178c2ecf20Sopenharmony_ci * @attrtype: attribute type
14188c2ecf20Sopenharmony_ci * @value: numeric value
14198c2ecf20Sopenharmony_ci */
14208c2ecf20Sopenharmony_cistatic inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
14218c2ecf20Sopenharmony_ci{
14228c2ecf20Sopenharmony_ci	s8 tmp = value;
14238c2ecf20Sopenharmony_ci
14248c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(s8), &tmp);
14258c2ecf20Sopenharmony_ci}
14268c2ecf20Sopenharmony_ci
14278c2ecf20Sopenharmony_ci/**
14288c2ecf20Sopenharmony_ci * nla_put_s16 - Add a s16 netlink attribute to a socket buffer
14298c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
14308c2ecf20Sopenharmony_ci * @attrtype: attribute type
14318c2ecf20Sopenharmony_ci * @value: numeric value
14328c2ecf20Sopenharmony_ci */
14338c2ecf20Sopenharmony_cistatic inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
14348c2ecf20Sopenharmony_ci{
14358c2ecf20Sopenharmony_ci	s16 tmp = value;
14368c2ecf20Sopenharmony_ci
14378c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(s16), &tmp);
14388c2ecf20Sopenharmony_ci}
14398c2ecf20Sopenharmony_ci
14408c2ecf20Sopenharmony_ci/**
14418c2ecf20Sopenharmony_ci * nla_put_s32 - Add a s32 netlink attribute to a socket buffer
14428c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
14438c2ecf20Sopenharmony_ci * @attrtype: attribute type
14448c2ecf20Sopenharmony_ci * @value: numeric value
14458c2ecf20Sopenharmony_ci */
14468c2ecf20Sopenharmony_cistatic inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
14478c2ecf20Sopenharmony_ci{
14488c2ecf20Sopenharmony_ci	s32 tmp = value;
14498c2ecf20Sopenharmony_ci
14508c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(s32), &tmp);
14518c2ecf20Sopenharmony_ci}
14528c2ecf20Sopenharmony_ci
14538c2ecf20Sopenharmony_ci/**
14548c2ecf20Sopenharmony_ci * nla_put_s64 - Add a s64 netlink attribute to a socket buffer and align it
14558c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
14568c2ecf20Sopenharmony_ci * @attrtype: attribute type
14578c2ecf20Sopenharmony_ci * @value: numeric value
14588c2ecf20Sopenharmony_ci * @padattr: attribute type for the padding
14598c2ecf20Sopenharmony_ci */
14608c2ecf20Sopenharmony_cistatic inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value,
14618c2ecf20Sopenharmony_ci			      int padattr)
14628c2ecf20Sopenharmony_ci{
14638c2ecf20Sopenharmony_ci	s64 tmp = value;
14648c2ecf20Sopenharmony_ci
14658c2ecf20Sopenharmony_ci	return nla_put_64bit(skb, attrtype, sizeof(s64), &tmp, padattr);
14668c2ecf20Sopenharmony_ci}
14678c2ecf20Sopenharmony_ci
14688c2ecf20Sopenharmony_ci/**
14698c2ecf20Sopenharmony_ci * nla_put_string - Add a string netlink attribute to a socket buffer
14708c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
14718c2ecf20Sopenharmony_ci * @attrtype: attribute type
14728c2ecf20Sopenharmony_ci * @str: NUL terminated string
14738c2ecf20Sopenharmony_ci */
14748c2ecf20Sopenharmony_cistatic inline int nla_put_string(struct sk_buff *skb, int attrtype,
14758c2ecf20Sopenharmony_ci				 const char *str)
14768c2ecf20Sopenharmony_ci{
14778c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, strlen(str) + 1, str);
14788c2ecf20Sopenharmony_ci}
14798c2ecf20Sopenharmony_ci
14808c2ecf20Sopenharmony_ci/**
14818c2ecf20Sopenharmony_ci * nla_put_flag - Add a flag netlink attribute to a socket buffer
14828c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
14838c2ecf20Sopenharmony_ci * @attrtype: attribute type
14848c2ecf20Sopenharmony_ci */
14858c2ecf20Sopenharmony_cistatic inline int nla_put_flag(struct sk_buff *skb, int attrtype)
14868c2ecf20Sopenharmony_ci{
14878c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, 0, NULL);
14888c2ecf20Sopenharmony_ci}
14898c2ecf20Sopenharmony_ci
14908c2ecf20Sopenharmony_ci/**
14918c2ecf20Sopenharmony_ci * nla_put_msecs - Add a msecs netlink attribute to a skb and align it
14928c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
14938c2ecf20Sopenharmony_ci * @attrtype: attribute type
14948c2ecf20Sopenharmony_ci * @njiffies: number of jiffies to convert to msecs
14958c2ecf20Sopenharmony_ci * @padattr: attribute type for the padding
14968c2ecf20Sopenharmony_ci */
14978c2ecf20Sopenharmony_cistatic inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
14988c2ecf20Sopenharmony_ci				unsigned long njiffies, int padattr)
14998c2ecf20Sopenharmony_ci{
15008c2ecf20Sopenharmony_ci	u64 tmp = jiffies_to_msecs(njiffies);
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	return nla_put_64bit(skb, attrtype, sizeof(u64), &tmp, padattr);
15038c2ecf20Sopenharmony_ci}
15048c2ecf20Sopenharmony_ci
15058c2ecf20Sopenharmony_ci/**
15068c2ecf20Sopenharmony_ci * nla_put_in_addr - Add an IPv4 address netlink attribute to a socket
15078c2ecf20Sopenharmony_ci * buffer
15088c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
15098c2ecf20Sopenharmony_ci * @attrtype: attribute type
15108c2ecf20Sopenharmony_ci * @addr: IPv4 address
15118c2ecf20Sopenharmony_ci */
15128c2ecf20Sopenharmony_cistatic inline int nla_put_in_addr(struct sk_buff *skb, int attrtype,
15138c2ecf20Sopenharmony_ci				  __be32 addr)
15148c2ecf20Sopenharmony_ci{
15158c2ecf20Sopenharmony_ci	__be32 tmp = addr;
15168c2ecf20Sopenharmony_ci
15178c2ecf20Sopenharmony_ci	return nla_put_be32(skb, attrtype, tmp);
15188c2ecf20Sopenharmony_ci}
15198c2ecf20Sopenharmony_ci
15208c2ecf20Sopenharmony_ci/**
15218c2ecf20Sopenharmony_ci * nla_put_in6_addr - Add an IPv6 address netlink attribute to a socket
15228c2ecf20Sopenharmony_ci * buffer
15238c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
15248c2ecf20Sopenharmony_ci * @attrtype: attribute type
15258c2ecf20Sopenharmony_ci * @addr: IPv6 address
15268c2ecf20Sopenharmony_ci */
15278c2ecf20Sopenharmony_cistatic inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype,
15288c2ecf20Sopenharmony_ci				   const struct in6_addr *addr)
15298c2ecf20Sopenharmony_ci{
15308c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(*addr), addr);
15318c2ecf20Sopenharmony_ci}
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_ci/**
15348c2ecf20Sopenharmony_ci * nla_put_bitfield32 - Add a bitfield32 netlink attribute to a socket buffer
15358c2ecf20Sopenharmony_ci * @skb: socket buffer to add attribute to
15368c2ecf20Sopenharmony_ci * @attrtype: attribute type
15378c2ecf20Sopenharmony_ci * @value: value carrying bits
15388c2ecf20Sopenharmony_ci * @selector: selector of valid bits
15398c2ecf20Sopenharmony_ci */
15408c2ecf20Sopenharmony_cistatic inline int nla_put_bitfield32(struct sk_buff *skb, int attrtype,
15418c2ecf20Sopenharmony_ci				     __u32 value, __u32 selector)
15428c2ecf20Sopenharmony_ci{
15438c2ecf20Sopenharmony_ci	struct nla_bitfield32 tmp = { value, selector, };
15448c2ecf20Sopenharmony_ci
15458c2ecf20Sopenharmony_ci	return nla_put(skb, attrtype, sizeof(tmp), &tmp);
15468c2ecf20Sopenharmony_ci}
15478c2ecf20Sopenharmony_ci
15488c2ecf20Sopenharmony_ci/**
15498c2ecf20Sopenharmony_ci * nla_get_u32 - return payload of u32 attribute
15508c2ecf20Sopenharmony_ci * @nla: u32 netlink attribute
15518c2ecf20Sopenharmony_ci */
15528c2ecf20Sopenharmony_cistatic inline u32 nla_get_u32(const struct nlattr *nla)
15538c2ecf20Sopenharmony_ci{
15548c2ecf20Sopenharmony_ci	return *(u32 *) nla_data(nla);
15558c2ecf20Sopenharmony_ci}
15568c2ecf20Sopenharmony_ci
15578c2ecf20Sopenharmony_ci/**
15588c2ecf20Sopenharmony_ci * nla_get_be32 - return payload of __be32 attribute
15598c2ecf20Sopenharmony_ci * @nla: __be32 netlink attribute
15608c2ecf20Sopenharmony_ci */
15618c2ecf20Sopenharmony_cistatic inline __be32 nla_get_be32(const struct nlattr *nla)
15628c2ecf20Sopenharmony_ci{
15638c2ecf20Sopenharmony_ci	return *(__be32 *) nla_data(nla);
15648c2ecf20Sopenharmony_ci}
15658c2ecf20Sopenharmony_ci
15668c2ecf20Sopenharmony_ci/**
15678c2ecf20Sopenharmony_ci * nla_get_le32 - return payload of __le32 attribute
15688c2ecf20Sopenharmony_ci * @nla: __le32 netlink attribute
15698c2ecf20Sopenharmony_ci */
15708c2ecf20Sopenharmony_cistatic inline __le32 nla_get_le32(const struct nlattr *nla)
15718c2ecf20Sopenharmony_ci{
15728c2ecf20Sopenharmony_ci	return *(__le32 *) nla_data(nla);
15738c2ecf20Sopenharmony_ci}
15748c2ecf20Sopenharmony_ci
15758c2ecf20Sopenharmony_ci/**
15768c2ecf20Sopenharmony_ci * nla_get_u16 - return payload of u16 attribute
15778c2ecf20Sopenharmony_ci * @nla: u16 netlink attribute
15788c2ecf20Sopenharmony_ci */
15798c2ecf20Sopenharmony_cistatic inline u16 nla_get_u16(const struct nlattr *nla)
15808c2ecf20Sopenharmony_ci{
15818c2ecf20Sopenharmony_ci	return *(u16 *) nla_data(nla);
15828c2ecf20Sopenharmony_ci}
15838c2ecf20Sopenharmony_ci
15848c2ecf20Sopenharmony_ci/**
15858c2ecf20Sopenharmony_ci * nla_get_be16 - return payload of __be16 attribute
15868c2ecf20Sopenharmony_ci * @nla: __be16 netlink attribute
15878c2ecf20Sopenharmony_ci */
15888c2ecf20Sopenharmony_cistatic inline __be16 nla_get_be16(const struct nlattr *nla)
15898c2ecf20Sopenharmony_ci{
15908c2ecf20Sopenharmony_ci	return *(__be16 *) nla_data(nla);
15918c2ecf20Sopenharmony_ci}
15928c2ecf20Sopenharmony_ci
15938c2ecf20Sopenharmony_ci/**
15948c2ecf20Sopenharmony_ci * nla_get_le16 - return payload of __le16 attribute
15958c2ecf20Sopenharmony_ci * @nla: __le16 netlink attribute
15968c2ecf20Sopenharmony_ci */
15978c2ecf20Sopenharmony_cistatic inline __le16 nla_get_le16(const struct nlattr *nla)
15988c2ecf20Sopenharmony_ci{
15998c2ecf20Sopenharmony_ci	return *(__le16 *) nla_data(nla);
16008c2ecf20Sopenharmony_ci}
16018c2ecf20Sopenharmony_ci
16028c2ecf20Sopenharmony_ci/**
16038c2ecf20Sopenharmony_ci * nla_get_u8 - return payload of u8 attribute
16048c2ecf20Sopenharmony_ci * @nla: u8 netlink attribute
16058c2ecf20Sopenharmony_ci */
16068c2ecf20Sopenharmony_cistatic inline u8 nla_get_u8(const struct nlattr *nla)
16078c2ecf20Sopenharmony_ci{
16088c2ecf20Sopenharmony_ci	return *(u8 *) nla_data(nla);
16098c2ecf20Sopenharmony_ci}
16108c2ecf20Sopenharmony_ci
16118c2ecf20Sopenharmony_ci/**
16128c2ecf20Sopenharmony_ci * nla_get_u64 - return payload of u64 attribute
16138c2ecf20Sopenharmony_ci * @nla: u64 netlink attribute
16148c2ecf20Sopenharmony_ci */
16158c2ecf20Sopenharmony_cistatic inline u64 nla_get_u64(const struct nlattr *nla)
16168c2ecf20Sopenharmony_ci{
16178c2ecf20Sopenharmony_ci	u64 tmp;
16188c2ecf20Sopenharmony_ci
16198c2ecf20Sopenharmony_ci	nla_memcpy(&tmp, nla, sizeof(tmp));
16208c2ecf20Sopenharmony_ci
16218c2ecf20Sopenharmony_ci	return tmp;
16228c2ecf20Sopenharmony_ci}
16238c2ecf20Sopenharmony_ci
16248c2ecf20Sopenharmony_ci/**
16258c2ecf20Sopenharmony_ci * nla_get_be64 - return payload of __be64 attribute
16268c2ecf20Sopenharmony_ci * @nla: __be64 netlink attribute
16278c2ecf20Sopenharmony_ci */
16288c2ecf20Sopenharmony_cistatic inline __be64 nla_get_be64(const struct nlattr *nla)
16298c2ecf20Sopenharmony_ci{
16308c2ecf20Sopenharmony_ci	__be64 tmp;
16318c2ecf20Sopenharmony_ci
16328c2ecf20Sopenharmony_ci	nla_memcpy(&tmp, nla, sizeof(tmp));
16338c2ecf20Sopenharmony_ci
16348c2ecf20Sopenharmony_ci	return tmp;
16358c2ecf20Sopenharmony_ci}
16368c2ecf20Sopenharmony_ci
16378c2ecf20Sopenharmony_ci/**
16388c2ecf20Sopenharmony_ci * nla_get_le64 - return payload of __le64 attribute
16398c2ecf20Sopenharmony_ci * @nla: __le64 netlink attribute
16408c2ecf20Sopenharmony_ci */
16418c2ecf20Sopenharmony_cistatic inline __le64 nla_get_le64(const struct nlattr *nla)
16428c2ecf20Sopenharmony_ci{
16438c2ecf20Sopenharmony_ci	return *(__le64 *) nla_data(nla);
16448c2ecf20Sopenharmony_ci}
16458c2ecf20Sopenharmony_ci
16468c2ecf20Sopenharmony_ci/**
16478c2ecf20Sopenharmony_ci * nla_get_s32 - return payload of s32 attribute
16488c2ecf20Sopenharmony_ci * @nla: s32 netlink attribute
16498c2ecf20Sopenharmony_ci */
16508c2ecf20Sopenharmony_cistatic inline s32 nla_get_s32(const struct nlattr *nla)
16518c2ecf20Sopenharmony_ci{
16528c2ecf20Sopenharmony_ci	return *(s32 *) nla_data(nla);
16538c2ecf20Sopenharmony_ci}
16548c2ecf20Sopenharmony_ci
16558c2ecf20Sopenharmony_ci/**
16568c2ecf20Sopenharmony_ci * nla_get_s16 - return payload of s16 attribute
16578c2ecf20Sopenharmony_ci * @nla: s16 netlink attribute
16588c2ecf20Sopenharmony_ci */
16598c2ecf20Sopenharmony_cistatic inline s16 nla_get_s16(const struct nlattr *nla)
16608c2ecf20Sopenharmony_ci{
16618c2ecf20Sopenharmony_ci	return *(s16 *) nla_data(nla);
16628c2ecf20Sopenharmony_ci}
16638c2ecf20Sopenharmony_ci
16648c2ecf20Sopenharmony_ci/**
16658c2ecf20Sopenharmony_ci * nla_get_s8 - return payload of s8 attribute
16668c2ecf20Sopenharmony_ci * @nla: s8 netlink attribute
16678c2ecf20Sopenharmony_ci */
16688c2ecf20Sopenharmony_cistatic inline s8 nla_get_s8(const struct nlattr *nla)
16698c2ecf20Sopenharmony_ci{
16708c2ecf20Sopenharmony_ci	return *(s8 *) nla_data(nla);
16718c2ecf20Sopenharmony_ci}
16728c2ecf20Sopenharmony_ci
16738c2ecf20Sopenharmony_ci/**
16748c2ecf20Sopenharmony_ci * nla_get_s64 - return payload of s64 attribute
16758c2ecf20Sopenharmony_ci * @nla: s64 netlink attribute
16768c2ecf20Sopenharmony_ci */
16778c2ecf20Sopenharmony_cistatic inline s64 nla_get_s64(const struct nlattr *nla)
16788c2ecf20Sopenharmony_ci{
16798c2ecf20Sopenharmony_ci	s64 tmp;
16808c2ecf20Sopenharmony_ci
16818c2ecf20Sopenharmony_ci	nla_memcpy(&tmp, nla, sizeof(tmp));
16828c2ecf20Sopenharmony_ci
16838c2ecf20Sopenharmony_ci	return tmp;
16848c2ecf20Sopenharmony_ci}
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_ci/**
16878c2ecf20Sopenharmony_ci * nla_get_flag - return payload of flag attribute
16888c2ecf20Sopenharmony_ci * @nla: flag netlink attribute
16898c2ecf20Sopenharmony_ci */
16908c2ecf20Sopenharmony_cistatic inline int nla_get_flag(const struct nlattr *nla)
16918c2ecf20Sopenharmony_ci{
16928c2ecf20Sopenharmony_ci	return !!nla;
16938c2ecf20Sopenharmony_ci}
16948c2ecf20Sopenharmony_ci
16958c2ecf20Sopenharmony_ci/**
16968c2ecf20Sopenharmony_ci * nla_get_msecs - return payload of msecs attribute
16978c2ecf20Sopenharmony_ci * @nla: msecs netlink attribute
16988c2ecf20Sopenharmony_ci *
16998c2ecf20Sopenharmony_ci * Returns the number of milliseconds in jiffies.
17008c2ecf20Sopenharmony_ci */
17018c2ecf20Sopenharmony_cistatic inline unsigned long nla_get_msecs(const struct nlattr *nla)
17028c2ecf20Sopenharmony_ci{
17038c2ecf20Sopenharmony_ci	u64 msecs = nla_get_u64(nla);
17048c2ecf20Sopenharmony_ci
17058c2ecf20Sopenharmony_ci	return msecs_to_jiffies((unsigned long) msecs);
17068c2ecf20Sopenharmony_ci}
17078c2ecf20Sopenharmony_ci
17088c2ecf20Sopenharmony_ci/**
17098c2ecf20Sopenharmony_ci * nla_get_in_addr - return payload of IPv4 address attribute
17108c2ecf20Sopenharmony_ci * @nla: IPv4 address netlink attribute
17118c2ecf20Sopenharmony_ci */
17128c2ecf20Sopenharmony_cistatic inline __be32 nla_get_in_addr(const struct nlattr *nla)
17138c2ecf20Sopenharmony_ci{
17148c2ecf20Sopenharmony_ci	return *(__be32 *) nla_data(nla);
17158c2ecf20Sopenharmony_ci}
17168c2ecf20Sopenharmony_ci
17178c2ecf20Sopenharmony_ci/**
17188c2ecf20Sopenharmony_ci * nla_get_in6_addr - return payload of IPv6 address attribute
17198c2ecf20Sopenharmony_ci * @nla: IPv6 address netlink attribute
17208c2ecf20Sopenharmony_ci */
17218c2ecf20Sopenharmony_cistatic inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla)
17228c2ecf20Sopenharmony_ci{
17238c2ecf20Sopenharmony_ci	struct in6_addr tmp;
17248c2ecf20Sopenharmony_ci
17258c2ecf20Sopenharmony_ci	nla_memcpy(&tmp, nla, sizeof(tmp));
17268c2ecf20Sopenharmony_ci	return tmp;
17278c2ecf20Sopenharmony_ci}
17288c2ecf20Sopenharmony_ci
17298c2ecf20Sopenharmony_ci/**
17308c2ecf20Sopenharmony_ci * nla_get_bitfield32 - return payload of 32 bitfield attribute
17318c2ecf20Sopenharmony_ci * @nla: nla_bitfield32 attribute
17328c2ecf20Sopenharmony_ci */
17338c2ecf20Sopenharmony_cistatic inline struct nla_bitfield32 nla_get_bitfield32(const struct nlattr *nla)
17348c2ecf20Sopenharmony_ci{
17358c2ecf20Sopenharmony_ci	struct nla_bitfield32 tmp;
17368c2ecf20Sopenharmony_ci
17378c2ecf20Sopenharmony_ci	nla_memcpy(&tmp, nla, sizeof(tmp));
17388c2ecf20Sopenharmony_ci	return tmp;
17398c2ecf20Sopenharmony_ci}
17408c2ecf20Sopenharmony_ci
17418c2ecf20Sopenharmony_ci/**
17428c2ecf20Sopenharmony_ci * nla_memdup - duplicate attribute memory (kmemdup)
17438c2ecf20Sopenharmony_ci * @src: netlink attribute to duplicate from
17448c2ecf20Sopenharmony_ci * @gfp: GFP mask
17458c2ecf20Sopenharmony_ci */
17468c2ecf20Sopenharmony_cistatic inline void *nla_memdup(const struct nlattr *src, gfp_t gfp)
17478c2ecf20Sopenharmony_ci{
17488c2ecf20Sopenharmony_ci	return kmemdup(nla_data(src), nla_len(src), gfp);
17498c2ecf20Sopenharmony_ci}
17508c2ecf20Sopenharmony_ci
17518c2ecf20Sopenharmony_ci/**
17528c2ecf20Sopenharmony_ci * nla_nest_start_noflag - Start a new level of nested attributes
17538c2ecf20Sopenharmony_ci * @skb: socket buffer to add attributes to
17548c2ecf20Sopenharmony_ci * @attrtype: attribute type of container
17558c2ecf20Sopenharmony_ci *
17568c2ecf20Sopenharmony_ci * This function exists for backward compatibility to use in APIs which never
17578c2ecf20Sopenharmony_ci * marked their nest attributes with NLA_F_NESTED flag. New APIs should use
17588c2ecf20Sopenharmony_ci * nla_nest_start() which sets the flag.
17598c2ecf20Sopenharmony_ci *
17608c2ecf20Sopenharmony_ci * Returns the container attribute or NULL on error
17618c2ecf20Sopenharmony_ci */
17628c2ecf20Sopenharmony_cistatic inline struct nlattr *nla_nest_start_noflag(struct sk_buff *skb,
17638c2ecf20Sopenharmony_ci						   int attrtype)
17648c2ecf20Sopenharmony_ci{
17658c2ecf20Sopenharmony_ci	struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb);
17668c2ecf20Sopenharmony_ci
17678c2ecf20Sopenharmony_ci	if (nla_put(skb, attrtype, 0, NULL) < 0)
17688c2ecf20Sopenharmony_ci		return NULL;
17698c2ecf20Sopenharmony_ci
17708c2ecf20Sopenharmony_ci	return start;
17718c2ecf20Sopenharmony_ci}
17728c2ecf20Sopenharmony_ci
17738c2ecf20Sopenharmony_ci/**
17748c2ecf20Sopenharmony_ci * nla_nest_start - Start a new level of nested attributes, with NLA_F_NESTED
17758c2ecf20Sopenharmony_ci * @skb: socket buffer to add attributes to
17768c2ecf20Sopenharmony_ci * @attrtype: attribute type of container
17778c2ecf20Sopenharmony_ci *
17788c2ecf20Sopenharmony_ci * Unlike nla_nest_start_noflag(), mark the nest attribute with NLA_F_NESTED
17798c2ecf20Sopenharmony_ci * flag. This is the preferred function to use in new code.
17808c2ecf20Sopenharmony_ci *
17818c2ecf20Sopenharmony_ci * Returns the container attribute or NULL on error
17828c2ecf20Sopenharmony_ci */
17838c2ecf20Sopenharmony_cistatic inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
17848c2ecf20Sopenharmony_ci{
17858c2ecf20Sopenharmony_ci	return nla_nest_start_noflag(skb, attrtype | NLA_F_NESTED);
17868c2ecf20Sopenharmony_ci}
17878c2ecf20Sopenharmony_ci
17888c2ecf20Sopenharmony_ci/**
17898c2ecf20Sopenharmony_ci * nla_nest_end - Finalize nesting of attributes
17908c2ecf20Sopenharmony_ci * @skb: socket buffer the attributes are stored in
17918c2ecf20Sopenharmony_ci * @start: container attribute
17928c2ecf20Sopenharmony_ci *
17938c2ecf20Sopenharmony_ci * Corrects the container attribute header to include the all
17948c2ecf20Sopenharmony_ci * appeneded attributes.
17958c2ecf20Sopenharmony_ci *
17968c2ecf20Sopenharmony_ci * Returns the total data length of the skb.
17978c2ecf20Sopenharmony_ci */
17988c2ecf20Sopenharmony_cistatic inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
17998c2ecf20Sopenharmony_ci{
18008c2ecf20Sopenharmony_ci	start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start;
18018c2ecf20Sopenharmony_ci	return skb->len;
18028c2ecf20Sopenharmony_ci}
18038c2ecf20Sopenharmony_ci
18048c2ecf20Sopenharmony_ci/**
18058c2ecf20Sopenharmony_ci * nla_nest_cancel - Cancel nesting of attributes
18068c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in
18078c2ecf20Sopenharmony_ci * @start: container attribute
18088c2ecf20Sopenharmony_ci *
18098c2ecf20Sopenharmony_ci * Removes the container attribute and including all nested
18108c2ecf20Sopenharmony_ci * attributes. Returns -EMSGSIZE
18118c2ecf20Sopenharmony_ci */
18128c2ecf20Sopenharmony_cistatic inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
18138c2ecf20Sopenharmony_ci{
18148c2ecf20Sopenharmony_ci	nlmsg_trim(skb, start);
18158c2ecf20Sopenharmony_ci}
18168c2ecf20Sopenharmony_ci
18178c2ecf20Sopenharmony_ci/**
18188c2ecf20Sopenharmony_ci * __nla_validate_nested - Validate a stream of nested attributes
18198c2ecf20Sopenharmony_ci * @start: container attribute
18208c2ecf20Sopenharmony_ci * @maxtype: maximum attribute type to be expected
18218c2ecf20Sopenharmony_ci * @policy: validation policy
18228c2ecf20Sopenharmony_ci * @validate: validation strictness
18238c2ecf20Sopenharmony_ci * @extack: extended ACK report struct
18248c2ecf20Sopenharmony_ci *
18258c2ecf20Sopenharmony_ci * Validates all attributes in the nested attribute stream against the
18268c2ecf20Sopenharmony_ci * specified policy. Attributes with a type exceeding maxtype will be
18278c2ecf20Sopenharmony_ci * ignored. See documenation of struct nla_policy for more details.
18288c2ecf20Sopenharmony_ci *
18298c2ecf20Sopenharmony_ci * Returns 0 on success or a negative error code.
18308c2ecf20Sopenharmony_ci */
18318c2ecf20Sopenharmony_cistatic inline int __nla_validate_nested(const struct nlattr *start, int maxtype,
18328c2ecf20Sopenharmony_ci					const struct nla_policy *policy,
18338c2ecf20Sopenharmony_ci					unsigned int validate,
18348c2ecf20Sopenharmony_ci					struct netlink_ext_ack *extack)
18358c2ecf20Sopenharmony_ci{
18368c2ecf20Sopenharmony_ci	return __nla_validate(nla_data(start), nla_len(start), maxtype, policy,
18378c2ecf20Sopenharmony_ci			      validate, extack);
18388c2ecf20Sopenharmony_ci}
18398c2ecf20Sopenharmony_ci
18408c2ecf20Sopenharmony_cistatic inline int
18418c2ecf20Sopenharmony_cinla_validate_nested(const struct nlattr *start, int maxtype,
18428c2ecf20Sopenharmony_ci		    const struct nla_policy *policy,
18438c2ecf20Sopenharmony_ci		    struct netlink_ext_ack *extack)
18448c2ecf20Sopenharmony_ci{
18458c2ecf20Sopenharmony_ci	return __nla_validate_nested(start, maxtype, policy,
18468c2ecf20Sopenharmony_ci				     NL_VALIDATE_STRICT, extack);
18478c2ecf20Sopenharmony_ci}
18488c2ecf20Sopenharmony_ci
18498c2ecf20Sopenharmony_cistatic inline int
18508c2ecf20Sopenharmony_cinla_validate_nested_deprecated(const struct nlattr *start, int maxtype,
18518c2ecf20Sopenharmony_ci			       const struct nla_policy *policy,
18528c2ecf20Sopenharmony_ci			       struct netlink_ext_ack *extack)
18538c2ecf20Sopenharmony_ci{
18548c2ecf20Sopenharmony_ci	return __nla_validate_nested(start, maxtype, policy,
18558c2ecf20Sopenharmony_ci				     NL_VALIDATE_LIBERAL, extack);
18568c2ecf20Sopenharmony_ci}
18578c2ecf20Sopenharmony_ci
18588c2ecf20Sopenharmony_ci/**
18598c2ecf20Sopenharmony_ci * nla_need_padding_for_64bit - test 64-bit alignment of the next attribute
18608c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in
18618c2ecf20Sopenharmony_ci *
18628c2ecf20Sopenharmony_ci * Return true if padding is needed to align the next attribute (nla_data()) to
18638c2ecf20Sopenharmony_ci * a 64-bit aligned area.
18648c2ecf20Sopenharmony_ci */
18658c2ecf20Sopenharmony_cistatic inline bool nla_need_padding_for_64bit(struct sk_buff *skb)
18668c2ecf20Sopenharmony_ci{
18678c2ecf20Sopenharmony_ci#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
18688c2ecf20Sopenharmony_ci	/* The nlattr header is 4 bytes in size, that's why we test
18698c2ecf20Sopenharmony_ci	 * if the skb->data _is_ aligned.  A NOP attribute, plus
18708c2ecf20Sopenharmony_ci	 * nlattr header for next attribute, will make nla_data()
18718c2ecf20Sopenharmony_ci	 * 8-byte aligned.
18728c2ecf20Sopenharmony_ci	 */
18738c2ecf20Sopenharmony_ci	if (IS_ALIGNED((unsigned long)skb_tail_pointer(skb), 8))
18748c2ecf20Sopenharmony_ci		return true;
18758c2ecf20Sopenharmony_ci#endif
18768c2ecf20Sopenharmony_ci	return false;
18778c2ecf20Sopenharmony_ci}
18788c2ecf20Sopenharmony_ci
18798c2ecf20Sopenharmony_ci/**
18808c2ecf20Sopenharmony_ci * nla_align_64bit - 64-bit align the nla_data() of next attribute
18818c2ecf20Sopenharmony_ci * @skb: socket buffer the message is stored in
18828c2ecf20Sopenharmony_ci * @padattr: attribute type for the padding
18838c2ecf20Sopenharmony_ci *
18848c2ecf20Sopenharmony_ci * Conditionally emit a padding netlink attribute in order to make
18858c2ecf20Sopenharmony_ci * the next attribute we emit have a 64-bit aligned nla_data() area.
18868c2ecf20Sopenharmony_ci * This will only be done in architectures which do not have
18878c2ecf20Sopenharmony_ci * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS defined.
18888c2ecf20Sopenharmony_ci *
18898c2ecf20Sopenharmony_ci * Returns zero on success or a negative error code.
18908c2ecf20Sopenharmony_ci */
18918c2ecf20Sopenharmony_cistatic inline int nla_align_64bit(struct sk_buff *skb, int padattr)
18928c2ecf20Sopenharmony_ci{
18938c2ecf20Sopenharmony_ci	if (nla_need_padding_for_64bit(skb) &&
18948c2ecf20Sopenharmony_ci	    !nla_reserve(skb, padattr, 0))
18958c2ecf20Sopenharmony_ci		return -EMSGSIZE;
18968c2ecf20Sopenharmony_ci
18978c2ecf20Sopenharmony_ci	return 0;
18988c2ecf20Sopenharmony_ci}
18998c2ecf20Sopenharmony_ci
19008c2ecf20Sopenharmony_ci/**
19018c2ecf20Sopenharmony_ci * nla_total_size_64bit - total length of attribute including padding
19028c2ecf20Sopenharmony_ci * @payload: length of payload
19038c2ecf20Sopenharmony_ci */
19048c2ecf20Sopenharmony_cistatic inline int nla_total_size_64bit(int payload)
19058c2ecf20Sopenharmony_ci{
19068c2ecf20Sopenharmony_ci	return NLA_ALIGN(nla_attr_size(payload))
19078c2ecf20Sopenharmony_ci#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
19088c2ecf20Sopenharmony_ci		+ NLA_ALIGN(nla_attr_size(0))
19098c2ecf20Sopenharmony_ci#endif
19108c2ecf20Sopenharmony_ci		;
19118c2ecf20Sopenharmony_ci}
19128c2ecf20Sopenharmony_ci
19138c2ecf20Sopenharmony_ci/**
19148c2ecf20Sopenharmony_ci * nla_for_each_attr - iterate over a stream of attributes
19158c2ecf20Sopenharmony_ci * @pos: loop counter, set to current attribute
19168c2ecf20Sopenharmony_ci * @head: head of attribute stream
19178c2ecf20Sopenharmony_ci * @len: length of attribute stream
19188c2ecf20Sopenharmony_ci * @rem: initialized to len, holds bytes currently remaining in stream
19198c2ecf20Sopenharmony_ci */
19208c2ecf20Sopenharmony_ci#define nla_for_each_attr(pos, head, len, rem) \
19218c2ecf20Sopenharmony_ci	for (pos = head, rem = len; \
19228c2ecf20Sopenharmony_ci	     nla_ok(pos, rem); \
19238c2ecf20Sopenharmony_ci	     pos = nla_next(pos, &(rem)))
19248c2ecf20Sopenharmony_ci
19258c2ecf20Sopenharmony_ci/**
19268c2ecf20Sopenharmony_ci * nla_for_each_nested - iterate over nested attributes
19278c2ecf20Sopenharmony_ci * @pos: loop counter, set to current attribute
19288c2ecf20Sopenharmony_ci * @nla: attribute containing the nested attributes
19298c2ecf20Sopenharmony_ci * @rem: initialized to len, holds bytes currently remaining in stream
19308c2ecf20Sopenharmony_ci */
19318c2ecf20Sopenharmony_ci#define nla_for_each_nested(pos, nla, rem) \
19328c2ecf20Sopenharmony_ci	nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem)
19338c2ecf20Sopenharmony_ci
19348c2ecf20Sopenharmony_ci/**
19358c2ecf20Sopenharmony_ci * nla_is_last - Test if attribute is last in stream
19368c2ecf20Sopenharmony_ci * @nla: attribute to test
19378c2ecf20Sopenharmony_ci * @rem: bytes remaining in stream
19388c2ecf20Sopenharmony_ci */
19398c2ecf20Sopenharmony_cistatic inline bool nla_is_last(const struct nlattr *nla, int rem)
19408c2ecf20Sopenharmony_ci{
19418c2ecf20Sopenharmony_ci	return nla->nla_len == rem;
19428c2ecf20Sopenharmony_ci}
19438c2ecf20Sopenharmony_ci
19448c2ecf20Sopenharmony_civoid nla_get_range_unsigned(const struct nla_policy *pt,
19458c2ecf20Sopenharmony_ci			    struct netlink_range_validation *range);
19468c2ecf20Sopenharmony_civoid nla_get_range_signed(const struct nla_policy *pt,
19478c2ecf20Sopenharmony_ci			  struct netlink_range_validation_signed *range);
19488c2ecf20Sopenharmony_ci
19498c2ecf20Sopenharmony_cistruct netlink_policy_dump_state;
19508c2ecf20Sopenharmony_ci
19518c2ecf20Sopenharmony_ciint netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,
19528c2ecf20Sopenharmony_ci				   const struct nla_policy *policy,
19538c2ecf20Sopenharmony_ci				   unsigned int maxtype);
19548c2ecf20Sopenharmony_ciint netlink_policy_dump_get_policy_idx(struct netlink_policy_dump_state *state,
19558c2ecf20Sopenharmony_ci				       const struct nla_policy *policy,
19568c2ecf20Sopenharmony_ci				       unsigned int maxtype);
19578c2ecf20Sopenharmony_cibool netlink_policy_dump_loop(struct netlink_policy_dump_state *state);
19588c2ecf20Sopenharmony_ciint netlink_policy_dump_write(struct sk_buff *skb,
19598c2ecf20Sopenharmony_ci			      struct netlink_policy_dump_state *state);
19608c2ecf20Sopenharmony_ciint netlink_policy_dump_attr_size_estimate(const struct nla_policy *pt);
19618c2ecf20Sopenharmony_ciint netlink_policy_dump_write_attr(struct sk_buff *skb,
19628c2ecf20Sopenharmony_ci				   const struct nla_policy *pt,
19638c2ecf20Sopenharmony_ci				   int nestattr);
19648c2ecf20Sopenharmony_civoid netlink_policy_dump_free(struct netlink_policy_dump_state *state);
19658c2ecf20Sopenharmony_ci
19668c2ecf20Sopenharmony_ci#endif
1967