xref: /openbmc/linux/include/net/netlink.h (revision b4391db4)
1bfa83a9eSThomas Graf #ifndef __NET_NETLINK_H
2bfa83a9eSThomas Graf #define __NET_NETLINK_H
3bfa83a9eSThomas Graf 
4bfa83a9eSThomas Graf #include <linux/types.h>
5bfa83a9eSThomas Graf #include <linux/netlink.h>
6d7fe0f24SAl Viro #include <linux/jiffies.h>
7930345eaSJiri Benc #include <linux/in6.h>
8bfa83a9eSThomas Graf 
9bfa83a9eSThomas Graf /* ========================================================================
10bfa83a9eSThomas Graf  *         Netlink Messages and Attributes Interface (As Seen On TV)
11bfa83a9eSThomas Graf  * ------------------------------------------------------------------------
12bfa83a9eSThomas Graf  *                          Messages Interface
13bfa83a9eSThomas Graf  * ------------------------------------------------------------------------
14bfa83a9eSThomas Graf  *
15bfa83a9eSThomas Graf  * Message Format:
16bfa83a9eSThomas Graf  *    <--- nlmsg_total_size(payload)  --->
17bfa83a9eSThomas Graf  *    <-- nlmsg_msg_size(payload) ->
18bfa83a9eSThomas Graf  *   +----------+- - -+-------------+- - -+-------- - -
19bfa83a9eSThomas Graf  *   | nlmsghdr | Pad |   Payload   | Pad | nlmsghdr
20bfa83a9eSThomas Graf  *   +----------+- - -+-------------+- - -+-------- - -
21bfa83a9eSThomas Graf  *   nlmsg_data(nlh)---^                   ^
22bfa83a9eSThomas Graf  *   nlmsg_next(nlh)-----------------------+
23bfa83a9eSThomas Graf  *
24bfa83a9eSThomas Graf  * Payload Format:
25bfa83a9eSThomas Graf  *    <---------------------- nlmsg_len(nlh) --------------------->
26bfa83a9eSThomas Graf  *    <------ hdrlen ------>       <- nlmsg_attrlen(nlh, hdrlen) ->
27bfa83a9eSThomas Graf  *   +----------------------+- - -+--------------------------------+
28bfa83a9eSThomas Graf  *   |     Family Header    | Pad |           Attributes           |
29bfa83a9eSThomas Graf  *   +----------------------+- - -+--------------------------------+
30bfa83a9eSThomas Graf  *   nlmsg_attrdata(nlh, hdrlen)---^
31bfa83a9eSThomas Graf  *
32bfa83a9eSThomas Graf  * Data Structures:
33bfa83a9eSThomas Graf  *   struct nlmsghdr			netlink message header
34bfa83a9eSThomas Graf  *
35bfa83a9eSThomas Graf  * Message Construction:
36bfa83a9eSThomas Graf  *   nlmsg_new()			create a new netlink message
37bfa83a9eSThomas Graf  *   nlmsg_put()			add a netlink message to an skb
38bfa83a9eSThomas Graf  *   nlmsg_put_answer()			callback based nlmsg_put()
391dc8d8c0SJustin P. Mattock  *   nlmsg_end()			finalize netlink message
40fe4944e5SThomas Graf  *   nlmsg_get_pos()			return current position in message
41fe4944e5SThomas Graf  *   nlmsg_trim()			trim part of message
42bfa83a9eSThomas Graf  *   nlmsg_cancel()			cancel message construction
43bfa83a9eSThomas Graf  *   nlmsg_free()			free a netlink message
44bfa83a9eSThomas Graf  *
45bfa83a9eSThomas Graf  * Message Sending:
46bfa83a9eSThomas Graf  *   nlmsg_multicast()			multicast message to several groups
47bfa83a9eSThomas Graf  *   nlmsg_unicast()			unicast a message to a single socket
48d387f6adSThomas Graf  *   nlmsg_notify()			send notification message
49bfa83a9eSThomas Graf  *
50bfa83a9eSThomas Graf  * Message Length Calculations:
51bfa83a9eSThomas Graf  *   nlmsg_msg_size(payload)		length of message w/o padding
52bfa83a9eSThomas Graf  *   nlmsg_total_size(payload)		length of message w/ padding
53bfa83a9eSThomas Graf  *   nlmsg_padlen(payload)		length of padding at tail
54bfa83a9eSThomas Graf  *
55bfa83a9eSThomas Graf  * Message Payload Access:
56bfa83a9eSThomas Graf  *   nlmsg_data(nlh)			head of message payload
57bfa83a9eSThomas Graf  *   nlmsg_len(nlh)			length of message payload
58bfa83a9eSThomas Graf  *   nlmsg_attrdata(nlh, hdrlen)	head of attributes data
59bfa83a9eSThomas Graf  *   nlmsg_attrlen(nlh, hdrlen)		length of attributes data
60bfa83a9eSThomas Graf  *
61bfa83a9eSThomas Graf  * Message Parsing:
62bfa83a9eSThomas Graf  *   nlmsg_ok(nlh, remaining)		does nlh fit into remaining bytes?
63bfa83a9eSThomas Graf  *   nlmsg_next(nlh, remaining)		get next netlink message
64bfa83a9eSThomas Graf  *   nlmsg_parse()			parse attributes of a message
65bfa83a9eSThomas Graf  *   nlmsg_find_attr()			find an attribute in a message
66bfa83a9eSThomas Graf  *   nlmsg_for_each_msg()		loop over all messages
67bfa83a9eSThomas Graf  *   nlmsg_validate()			validate netlink message incl. attrs
68bfa83a9eSThomas Graf  *   nlmsg_for_each_attr()		loop over all attributes
69bfa83a9eSThomas Graf  *
7097676b6bSThomas Graf  * Misc:
7197676b6bSThomas Graf  *   nlmsg_report()			report back to application?
7297676b6bSThomas Graf  *
73bfa83a9eSThomas Graf  * ------------------------------------------------------------------------
74bfa83a9eSThomas Graf  *                          Attributes Interface
75bfa83a9eSThomas Graf  * ------------------------------------------------------------------------
76bfa83a9eSThomas Graf  *
77bfa83a9eSThomas Graf  * Attribute Format:
78bfa83a9eSThomas Graf  *    <------- nla_total_size(payload) ------->
79bfa83a9eSThomas Graf  *    <---- nla_attr_size(payload) ----->
80bfa83a9eSThomas Graf  *   +----------+- - -+- - - - - - - - - +- - -+-------- - -
81bfa83a9eSThomas Graf  *   |  Header  | Pad |     Payload      | Pad |  Header
82bfa83a9eSThomas Graf  *   +----------+- - -+- - - - - - - - - +- - -+-------- - -
83bfa83a9eSThomas Graf  *                     <- nla_len(nla) ->      ^
84bfa83a9eSThomas Graf  *   nla_data(nla)----^                        |
85bfa83a9eSThomas Graf  *   nla_next(nla)-----------------------------'
86bfa83a9eSThomas Graf  *
87bfa83a9eSThomas Graf  * Data Structures:
88d1ec3b77SPierre Ynard  *   struct nlattr			netlink attribute header
89bfa83a9eSThomas Graf  *
90bfa83a9eSThomas Graf  * Attribute Construction:
91fe4944e5SThomas Graf  *   nla_reserve(skb, type, len)	reserve room for an attribute
92fe4944e5SThomas Graf  *   nla_reserve_nohdr(skb, len)	reserve room for an attribute w/o hdr
93bfa83a9eSThomas Graf  *   nla_put(skb, type, len, data)	add attribute to skb
94fe4944e5SThomas Graf  *   nla_put_nohdr(skb, len, data)	add attribute w/o hdr
9501480e1cSPatrick McHardy  *   nla_append(skb, len, data)		append data to skb
96bfa83a9eSThomas Graf  *
97bfa83a9eSThomas Graf  * Attribute Construction for Basic Types:
98bfa83a9eSThomas Graf  *   nla_put_u8(skb, type, value)	add u8 attribute to skb
99bfa83a9eSThomas Graf  *   nla_put_u16(skb, type, value)	add u16 attribute to skb
100bfa83a9eSThomas Graf  *   nla_put_u32(skb, type, value)	add u32 attribute to skb
10126837012SRolf Eike Beer  *   nla_put_u64_64bit(skb, type,
10250225243SNicolas Dichtel  *                     value, padattr)	add u64 attribute to skb
1034778e0beSJiri Pirko  *   nla_put_s8(skb, type, value)	add s8 attribute to skb
1044778e0beSJiri Pirko  *   nla_put_s16(skb, type, value)	add s16 attribute to skb
1054778e0beSJiri Pirko  *   nla_put_s32(skb, type, value)	add s32 attribute to skb
106756a2f59SNicolas Dichtel  *   nla_put_s64(skb, type, value,
107756a2f59SNicolas Dichtel  *               padattr)		add s64 attribute to skb
108bfa83a9eSThomas Graf  *   nla_put_string(skb, type, str)	add string attribute to skb
109bfa83a9eSThomas Graf  *   nla_put_flag(skb, type)		add flag attribute to skb
1102175d87cSNicolas Dichtel  *   nla_put_msecs(skb, type, jiffies,
1112175d87cSNicolas Dichtel  *                 padattr)		add msecs attribute to skb
112930345eaSJiri Benc  *   nla_put_in_addr(skb, type, addr)	add IPv4 address attribute to skb
113930345eaSJiri Benc  *   nla_put_in6_addr(skb, type, addr)	add IPv6 address attribute to skb
114bfa83a9eSThomas Graf  *
115bfa83a9eSThomas Graf  * Nested Attributes Construction:
116bfa83a9eSThomas Graf  *   nla_nest_start(skb, type)		start a nested attribute
117bfa83a9eSThomas Graf  *   nla_nest_end(skb, nla)		finalize a nested attribute
118bfa83a9eSThomas Graf  *   nla_nest_cancel(skb, nla)		cancel nested attribute construction
119bfa83a9eSThomas Graf  *
120bfa83a9eSThomas Graf  * Attribute Length Calculations:
121bfa83a9eSThomas Graf  *   nla_attr_size(payload)		length of attribute w/o padding
122bfa83a9eSThomas Graf  *   nla_total_size(payload)		length of attribute w/ padding
123bfa83a9eSThomas Graf  *   nla_padlen(payload)		length of padding
124bfa83a9eSThomas Graf  *
125bfa83a9eSThomas Graf  * Attribute Payload Access:
126bfa83a9eSThomas Graf  *   nla_data(nla)			head of attribute payload
127bfa83a9eSThomas Graf  *   nla_len(nla)			length of attribute payload
128bfa83a9eSThomas Graf  *
129bfa83a9eSThomas Graf  * Attribute Payload Access for Basic Types:
130bfa83a9eSThomas Graf  *   nla_get_u8(nla)			get payload for a u8 attribute
131bfa83a9eSThomas Graf  *   nla_get_u16(nla)			get payload for a u16 attribute
132bfa83a9eSThomas Graf  *   nla_get_u32(nla)			get payload for a u32 attribute
133bfa83a9eSThomas Graf  *   nla_get_u64(nla)			get payload for a u64 attribute
1344778e0beSJiri Pirko  *   nla_get_s8(nla)			get payload for a s8 attribute
1354778e0beSJiri Pirko  *   nla_get_s16(nla)			get payload for a s16 attribute
1364778e0beSJiri Pirko  *   nla_get_s32(nla)			get payload for a s32 attribute
1374778e0beSJiri Pirko  *   nla_get_s64(nla)			get payload for a s64 attribute
138bfa83a9eSThomas Graf  *   nla_get_flag(nla)			return 1 if flag is true
139bfa83a9eSThomas Graf  *   nla_get_msecs(nla)			get payload for a msecs attribute
140bfa83a9eSThomas Graf  *
141bfa83a9eSThomas Graf  * Attribute Misc:
142bfa83a9eSThomas Graf  *   nla_memcpy(dest, nla, count)	copy attribute into memory
143bfa83a9eSThomas Graf  *   nla_memcmp(nla, data, size)	compare attribute with memory area
144bfa83a9eSThomas Graf  *   nla_strlcpy(dst, nla, size)	copy attribute to a sized string
145bfa83a9eSThomas Graf  *   nla_strcmp(nla, str)		compare attribute with string
146bfa83a9eSThomas Graf  *
147bfa83a9eSThomas Graf  * Attribute Parsing:
148bfa83a9eSThomas Graf  *   nla_ok(nla, remaining)		does nla fit into remaining bytes?
149bfa83a9eSThomas Graf  *   nla_next(nla, remaining)		get next netlink attribute
150bfa83a9eSThomas Graf  *   nla_validate()			validate a stream of attributes
1514fe5d5c0SPaul Moore  *   nla_validate_nested()		validate a stream of nested attributes
152bfa83a9eSThomas Graf  *   nla_find()				find attribute in stream of attributes
153fe4944e5SThomas Graf  *   nla_find_nested()			find attribute in nested attributes
154bfa83a9eSThomas Graf  *   nla_parse()			parse and validate stream of attrs
155bfa83a9eSThomas Graf  *   nla_parse_nested()			parse nested attribuets
156bfa83a9eSThomas Graf  *   nla_for_each_attr()		loop over all attributes
15722acb19aSPaul Moore  *   nla_for_each_nested()		loop over the nested attributes
158bfa83a9eSThomas Graf  *=========================================================================
159bfa83a9eSThomas Graf  */
160bfa83a9eSThomas Graf 
161bfa83a9eSThomas Graf  /**
162bfa83a9eSThomas Graf   * Standard attribute types to specify validation policy
163bfa83a9eSThomas Graf   */
164bfa83a9eSThomas Graf enum {
165bfa83a9eSThomas Graf 	NLA_UNSPEC,
166bfa83a9eSThomas Graf 	NLA_U8,
167bfa83a9eSThomas Graf 	NLA_U16,
168bfa83a9eSThomas Graf 	NLA_U32,
169bfa83a9eSThomas Graf 	NLA_U64,
170bfa83a9eSThomas Graf 	NLA_STRING,
171bfa83a9eSThomas Graf 	NLA_FLAG,
172bfa83a9eSThomas Graf 	NLA_MSECS,
173bfa83a9eSThomas Graf 	NLA_NESTED,
1741092cb21SPatrick McHardy 	NLA_NESTED_COMPAT,
175a5531a5dSThomas Graf 	NLA_NUL_STRING,
176d30045a0SJohannes Berg 	NLA_BINARY,
1774778e0beSJiri Pirko 	NLA_S8,
1784778e0beSJiri Pirko 	NLA_S16,
1794778e0beSJiri Pirko 	NLA_S32,
1804778e0beSJiri Pirko 	NLA_S64,
18164c83d83SJamal Hadi Salim 	NLA_BITFIELD32,
182bfa83a9eSThomas Graf 	__NLA_TYPE_MAX,
183bfa83a9eSThomas Graf };
184bfa83a9eSThomas Graf 
185bfa83a9eSThomas Graf #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
186bfa83a9eSThomas Graf 
187bfa83a9eSThomas Graf /**
188bfa83a9eSThomas Graf  * struct nla_policy - attribute validation policy
189bfa83a9eSThomas Graf  * @type: Type of attribute or NLA_UNSPEC
190a5531a5dSThomas Graf  * @len: Type specific length of payload
191bfa83a9eSThomas Graf  *
192bfa83a9eSThomas Graf  * Policies are defined as arrays of this struct, the array must be
193bfa83a9eSThomas Graf  * accessible by attribute type up to the highest identifier to be expected.
194bfa83a9eSThomas Graf  *
195a5531a5dSThomas Graf  * Meaning of `len' field:
196a5531a5dSThomas Graf  *    NLA_STRING           Maximum length of string
197a5531a5dSThomas Graf  *    NLA_NUL_STRING       Maximum length of string (excluding NUL)
198a5531a5dSThomas Graf  *    NLA_FLAG             Unused
199d30045a0SJohannes Berg  *    NLA_BINARY           Maximum length of attribute payload
2004b6cc728SJohannes Berg  *    NLA_NESTED           Don't use `len' field -- length verification is
2014b6cc728SJohannes Berg  *                         done by checking len of nested header (or empty)
2024b6cc728SJohannes Berg  *    NLA_NESTED_COMPAT    Minimum length of structure payload
2034b6cc728SJohannes Berg  *    NLA_U8, NLA_U16,
2044b6cc728SJohannes Berg  *    NLA_U32, NLA_U64,
2054778e0beSJiri Pirko  *    NLA_S8, NLA_S16,
2064778e0beSJiri Pirko  *    NLA_S32, NLA_S64,
2074b6cc728SJohannes Berg  *    NLA_MSECS            Leaving the length field zero will verify the
2084b6cc728SJohannes Berg  *                         given type fits, using it verifies minimum length
2094b6cc728SJohannes Berg  *                         just like "All other"
21064c83d83SJamal Hadi Salim  *    NLA_BITFIELD32      A 32-bit bitmap/bitselector attribute
2114b6cc728SJohannes Berg  *    All other            Minimum length of attribute payload
212a5531a5dSThomas Graf  *
213bfa83a9eSThomas Graf  * Example:
214b54452b0SAlexey Dobriyan  * static const struct nla_policy my_policy[ATTR_MAX+1] = {
215bfa83a9eSThomas Graf  * 	[ATTR_FOO] = { .type = NLA_U16 },
216d30045a0SJohannes Berg  *	[ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ },
217a5531a5dSThomas Graf  *	[ATTR_BAZ] = { .len = sizeof(struct mystruct) },
21864c83d83SJamal Hadi Salim  *	[ATTR_GOO] = { .type = NLA_BITFIELD32, .validation_data = &myvalidflags },
219bfa83a9eSThomas Graf  * };
220bfa83a9eSThomas Graf  */
221bfa83a9eSThomas Graf struct nla_policy {
222bfa83a9eSThomas Graf 	u16		type;
223a5531a5dSThomas Graf 	u16		len;
22464c83d83SJamal Hadi Salim 	void            *validation_data;
225bfa83a9eSThomas Graf };
226bfa83a9eSThomas Graf 
2274e902c57SThomas Graf /**
2284e902c57SThomas Graf  * struct nl_info - netlink source information
2294e902c57SThomas Graf  * @nlh: Netlink message header of original request
23015e47304SEric W. Biederman  * @portid: Netlink PORTID of requesting application
2314e902c57SThomas Graf  */
2324e902c57SThomas Graf struct nl_info {
2334e902c57SThomas Graf 	struct nlmsghdr		*nlh;
2344d1169c1SDenis V. Lunev 	struct net		*nl_net;
23515e47304SEric W. Biederman 	u32			portid;
2363b1137feSDavid Ahern 	bool			skip_notify;
2374e902c57SThomas Graf };
2384e902c57SThomas Graf 
2394f69053bSJoe Perches int netlink_rcv_skb(struct sk_buff *skb,
2402d4bc933SJohannes Berg 		    int (*cb)(struct sk_buff *, struct nlmsghdr *,
2412d4bc933SJohannes Berg 			      struct netlink_ext_ack *));
2424f69053bSJoe Perches int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
2434f69053bSJoe Perches 		 unsigned int group, int report, gfp_t flags);
24482ace47aSThomas Graf 
2454f69053bSJoe Perches int nla_validate(const struct nlattr *head, int len, int maxtype,
246fceb6435SJohannes Berg 		 const struct nla_policy *policy,
247fceb6435SJohannes Berg 		 struct netlink_ext_ack *extack);
2484f69053bSJoe Perches int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
249fceb6435SJohannes Berg 	      int len, const struct nla_policy *policy,
250fceb6435SJohannes Berg 	      struct netlink_ext_ack *extack);
2514f69053bSJoe Perches int nla_policy_len(const struct nla_policy *, int);
2524f69053bSJoe Perches struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype);
2534f69053bSJoe Perches size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
2542cf0c8b3SPhil Sutter char *nla_strdup(const struct nlattr *nla, gfp_t flags);
2554f69053bSJoe Perches int nla_memcpy(void *dest, const struct nlattr *src, int count);
2564f69053bSJoe Perches int nla_memcmp(const struct nlattr *nla, const void *data, size_t size);
2574f69053bSJoe Perches int nla_strcmp(const struct nlattr *nla, const char *str);
2584f69053bSJoe Perches struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen);
259089bf1a6SNicolas Dichtel struct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype,
260089bf1a6SNicolas Dichtel 				   int attrlen, int padattr);
2614f69053bSJoe Perches void *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen);
2624f69053bSJoe Perches struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen);
263089bf1a6SNicolas Dichtel struct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype,
264089bf1a6SNicolas Dichtel 				 int attrlen, int padattr);
2654f69053bSJoe Perches void *nla_reserve_nohdr(struct sk_buff *skb, int attrlen);
2664f69053bSJoe Perches void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
267fe4944e5SThomas Graf 	       const void *data);
268089bf1a6SNicolas Dichtel void __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
269089bf1a6SNicolas Dichtel 		     const void *data, int padattr);
2704f69053bSJoe Perches void __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data);
2714f69053bSJoe Perches int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data);
272089bf1a6SNicolas Dichtel int nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
273089bf1a6SNicolas Dichtel 		  const void *data, int padattr);
2744f69053bSJoe Perches int nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data);
2754f69053bSJoe Perches int nla_append(struct sk_buff *skb, int attrlen, const void *data);
276bfa83a9eSThomas Graf 
277bfa83a9eSThomas Graf /**************************************************************************
278bfa83a9eSThomas Graf  * Netlink Messages
279bfa83a9eSThomas Graf  **************************************************************************/
280bfa83a9eSThomas Graf 
281bfa83a9eSThomas Graf /**
282bfa83a9eSThomas Graf  * nlmsg_msg_size - length of netlink message not including padding
283bfa83a9eSThomas Graf  * @payload: length of message payload
284bfa83a9eSThomas Graf  */
285bfa83a9eSThomas Graf static inline int nlmsg_msg_size(int payload)
286bfa83a9eSThomas Graf {
287bfa83a9eSThomas Graf 	return NLMSG_HDRLEN + payload;
288bfa83a9eSThomas Graf }
289bfa83a9eSThomas Graf 
290bfa83a9eSThomas Graf /**
291bfa83a9eSThomas Graf  * nlmsg_total_size - length of netlink message including padding
292bfa83a9eSThomas Graf  * @payload: length of message payload
293bfa83a9eSThomas Graf  */
294bfa83a9eSThomas Graf static inline int nlmsg_total_size(int payload)
295bfa83a9eSThomas Graf {
296bfa83a9eSThomas Graf 	return NLMSG_ALIGN(nlmsg_msg_size(payload));
297bfa83a9eSThomas Graf }
298bfa83a9eSThomas Graf 
299bfa83a9eSThomas Graf /**
300bfa83a9eSThomas Graf  * nlmsg_padlen - length of padding at the message's tail
301bfa83a9eSThomas Graf  * @payload: length of message payload
302bfa83a9eSThomas Graf  */
303bfa83a9eSThomas Graf static inline int nlmsg_padlen(int payload)
304bfa83a9eSThomas Graf {
305bfa83a9eSThomas Graf 	return nlmsg_total_size(payload) - nlmsg_msg_size(payload);
306bfa83a9eSThomas Graf }
307bfa83a9eSThomas Graf 
308bfa83a9eSThomas Graf /**
309bfa83a9eSThomas Graf  * nlmsg_data - head of message payload
31070f23fd6SJustin P. Mattock  * @nlh: netlink message header
311bfa83a9eSThomas Graf  */
312bfa83a9eSThomas Graf static inline void *nlmsg_data(const struct nlmsghdr *nlh)
313bfa83a9eSThomas Graf {
314bfa83a9eSThomas Graf 	return (unsigned char *) nlh + NLMSG_HDRLEN;
315bfa83a9eSThomas Graf }
316bfa83a9eSThomas Graf 
317bfa83a9eSThomas Graf /**
318bfa83a9eSThomas Graf  * nlmsg_len - length of message payload
319bfa83a9eSThomas Graf  * @nlh: netlink message header
320bfa83a9eSThomas Graf  */
321bfa83a9eSThomas Graf static inline int nlmsg_len(const struct nlmsghdr *nlh)
322bfa83a9eSThomas Graf {
323bfa83a9eSThomas Graf 	return nlh->nlmsg_len - NLMSG_HDRLEN;
324bfa83a9eSThomas Graf }
325bfa83a9eSThomas Graf 
326bfa83a9eSThomas Graf /**
327bfa83a9eSThomas Graf  * nlmsg_attrdata - head of attributes data
328bfa83a9eSThomas Graf  * @nlh: netlink message header
329bfa83a9eSThomas Graf  * @hdrlen: length of family specific header
330bfa83a9eSThomas Graf  */
331bfa83a9eSThomas Graf static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
332bfa83a9eSThomas Graf 					    int hdrlen)
333bfa83a9eSThomas Graf {
334bfa83a9eSThomas Graf 	unsigned char *data = nlmsg_data(nlh);
335bfa83a9eSThomas Graf 	return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
336bfa83a9eSThomas Graf }
337bfa83a9eSThomas Graf 
338bfa83a9eSThomas Graf /**
339bfa83a9eSThomas Graf  * nlmsg_attrlen - length of attributes data
340bfa83a9eSThomas Graf  * @nlh: netlink message header
341bfa83a9eSThomas Graf  * @hdrlen: length of family specific header
342bfa83a9eSThomas Graf  */
343bfa83a9eSThomas Graf static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
344bfa83a9eSThomas Graf {
345bfa83a9eSThomas Graf 	return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
346bfa83a9eSThomas Graf }
347bfa83a9eSThomas Graf 
348bfa83a9eSThomas Graf /**
349bfa83a9eSThomas Graf  * nlmsg_ok - check if the netlink message fits into the remaining bytes
350bfa83a9eSThomas Graf  * @nlh: netlink message header
351bfa83a9eSThomas Graf  * @remaining: number of bytes remaining in message stream
352bfa83a9eSThomas Graf  */
353bfa83a9eSThomas Graf static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
354bfa83a9eSThomas Graf {
355619e803dSVegard Nossum 	return (remaining >= (int) sizeof(struct nlmsghdr) &&
356bfa83a9eSThomas Graf 		nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
357bfa83a9eSThomas Graf 		nlh->nlmsg_len <= remaining);
358bfa83a9eSThomas Graf }
359bfa83a9eSThomas Graf 
360bfa83a9eSThomas Graf /**
361bfa83a9eSThomas Graf  * nlmsg_next - next netlink message in message stream
362bfa83a9eSThomas Graf  * @nlh: netlink message header
363bfa83a9eSThomas Graf  * @remaining: number of bytes remaining in message stream
364bfa83a9eSThomas Graf  *
365bfa83a9eSThomas Graf  * Returns the next netlink message in the message stream and
366bfa83a9eSThomas Graf  * decrements remaining by the size of the current message.
367bfa83a9eSThomas Graf  */
3683654654fSJan Engelhardt static inline struct nlmsghdr *
3693654654fSJan Engelhardt nlmsg_next(const struct nlmsghdr *nlh, int *remaining)
370bfa83a9eSThomas Graf {
371bfa83a9eSThomas Graf 	int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
372bfa83a9eSThomas Graf 
373bfa83a9eSThomas Graf 	*remaining -= totlen;
374bfa83a9eSThomas Graf 
375bfa83a9eSThomas Graf 	return (struct nlmsghdr *) ((unsigned char *) nlh + totlen);
376bfa83a9eSThomas Graf }
377bfa83a9eSThomas Graf 
378bfa83a9eSThomas Graf /**
379bfa83a9eSThomas Graf  * nlmsg_parse - parse attributes of a netlink message
380bfa83a9eSThomas Graf  * @nlh: netlink message header
381bfa83a9eSThomas Graf  * @hdrlen: length of family specific header
382bfa83a9eSThomas Graf  * @tb: destination array with maxtype+1 elements
383bfa83a9eSThomas Graf  * @maxtype: maximum attribute type to be expected
384bfa83a9eSThomas Graf  * @policy: validation policy
385fceb6435SJohannes Berg  * @extack: extended ACK report struct
386bfa83a9eSThomas Graf  *
387bfa83a9eSThomas Graf  * See nla_parse()
388bfa83a9eSThomas Graf  */
3893a6c2b41SPatrick McHardy static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen,
390bfa83a9eSThomas Graf 			      struct nlattr *tb[], int maxtype,
391fceb6435SJohannes Berg 			      const struct nla_policy *policy,
392fceb6435SJohannes Berg 			      struct netlink_ext_ack *extack)
393bfa83a9eSThomas Graf {
394bfa83a9eSThomas Graf 	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
395bfa83a9eSThomas Graf 		return -EINVAL;
396bfa83a9eSThomas Graf 
397bfa83a9eSThomas Graf 	return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
398fceb6435SJohannes Berg 			 nlmsg_attrlen(nlh, hdrlen), policy, extack);
399bfa83a9eSThomas Graf }
400bfa83a9eSThomas Graf 
401bfa83a9eSThomas Graf /**
402bfa83a9eSThomas Graf  * nlmsg_find_attr - find a specific attribute in a netlink message
403bfa83a9eSThomas Graf  * @nlh: netlink message header
404bfa83a9eSThomas Graf  * @hdrlen: length of familiy specific header
405bfa83a9eSThomas Graf  * @attrtype: type of attribute to look for
406bfa83a9eSThomas Graf  *
407bfa83a9eSThomas Graf  * Returns the first attribute which matches the specified type.
408bfa83a9eSThomas Graf  */
4096b8c92baSNelson Elhage static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh,
410bfa83a9eSThomas Graf 					     int hdrlen, int attrtype)
411bfa83a9eSThomas Graf {
412bfa83a9eSThomas Graf 	return nla_find(nlmsg_attrdata(nlh, hdrlen),
413bfa83a9eSThomas Graf 			nlmsg_attrlen(nlh, hdrlen), attrtype);
414bfa83a9eSThomas Graf }
415bfa83a9eSThomas Graf 
416bfa83a9eSThomas Graf /**
417bfa83a9eSThomas Graf  * nlmsg_validate - validate a netlink message including attributes
418bfa83a9eSThomas Graf  * @nlh: netlinket message header
419bfa83a9eSThomas Graf  * @hdrlen: length of familiy specific header
420bfa83a9eSThomas Graf  * @maxtype: maximum attribute type to be expected
421bfa83a9eSThomas Graf  * @policy: validation policy
422fceb6435SJohannes Berg  * @extack: extended ACK report struct
423bfa83a9eSThomas Graf  */
4243654654fSJan Engelhardt static inline int nlmsg_validate(const struct nlmsghdr *nlh,
4253654654fSJan Engelhardt 				 int hdrlen, int maxtype,
426fceb6435SJohannes Berg 				 const struct nla_policy *policy,
427fceb6435SJohannes Berg 				 struct netlink_ext_ack *extack)
428bfa83a9eSThomas Graf {
429bfa83a9eSThomas Graf 	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
430bfa83a9eSThomas Graf 		return -EINVAL;
431bfa83a9eSThomas Graf 
432bfa83a9eSThomas Graf 	return nla_validate(nlmsg_attrdata(nlh, hdrlen),
433fceb6435SJohannes Berg 			    nlmsg_attrlen(nlh, hdrlen), maxtype, policy,
434fceb6435SJohannes Berg 			    extack);
435bfa83a9eSThomas Graf }
436bfa83a9eSThomas Graf 
437bfa83a9eSThomas Graf /**
43897676b6bSThomas Graf  * nlmsg_report - need to report back to application?
43997676b6bSThomas Graf  * @nlh: netlink message header
44097676b6bSThomas Graf  *
44197676b6bSThomas Graf  * Returns 1 if a report back to the application is requested.
44297676b6bSThomas Graf  */
4433a6c2b41SPatrick McHardy static inline int nlmsg_report(const struct nlmsghdr *nlh)
44497676b6bSThomas Graf {
44597676b6bSThomas Graf 	return !!(nlh->nlmsg_flags & NLM_F_ECHO);
44697676b6bSThomas Graf }
44797676b6bSThomas Graf 
44897676b6bSThomas Graf /**
449bfa83a9eSThomas Graf  * nlmsg_for_each_attr - iterate over a stream of attributes
450bfa83a9eSThomas Graf  * @pos: loop counter, set to current attribute
451bfa83a9eSThomas Graf  * @nlh: netlink message header
452bfa83a9eSThomas Graf  * @hdrlen: length of familiy specific header
453bfa83a9eSThomas Graf  * @rem: initialized to len, holds bytes currently remaining in stream
454bfa83a9eSThomas Graf  */
455bfa83a9eSThomas Graf #define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
456bfa83a9eSThomas Graf 	nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
457bfa83a9eSThomas Graf 			  nlmsg_attrlen(nlh, hdrlen), rem)
458bfa83a9eSThomas Graf 
459bfa83a9eSThomas Graf /**
460bfa83a9eSThomas Graf  * nlmsg_put - Add a new netlink message to an skb
461bfa83a9eSThomas Graf  * @skb: socket buffer to store message in
4622c6ba4b1SNicolas Dichtel  * @portid: netlink PORTID of requesting application
463bfa83a9eSThomas Graf  * @seq: sequence number of message
464bfa83a9eSThomas Graf  * @type: message type
465bfa83a9eSThomas Graf  * @payload: length of message payload
466bfa83a9eSThomas Graf  * @flags: message flags
467bfa83a9eSThomas Graf  *
468bfa83a9eSThomas Graf  * Returns NULL if the tailroom of the skb is insufficient to store
469bfa83a9eSThomas Graf  * the message header and payload.
470bfa83a9eSThomas Graf  */
47115e47304SEric W. Biederman static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
472bfa83a9eSThomas Graf 					 int type, int payload, int flags)
473bfa83a9eSThomas Graf {
474bfa83a9eSThomas Graf 	if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
475bfa83a9eSThomas Graf 		return NULL;
476bfa83a9eSThomas Graf 
47715e47304SEric W. Biederman 	return __nlmsg_put(skb, portid, seq, type, payload, flags);
478bfa83a9eSThomas Graf }
479bfa83a9eSThomas Graf 
480bfa83a9eSThomas Graf /**
481bfa83a9eSThomas Graf  * nlmsg_put_answer - Add a new callback based netlink message to an skb
482bfa83a9eSThomas Graf  * @skb: socket buffer to store message in
483bfa83a9eSThomas Graf  * @cb: netlink callback
484bfa83a9eSThomas Graf  * @type: message type
485bfa83a9eSThomas Graf  * @payload: length of message payload
486bfa83a9eSThomas Graf  * @flags: message flags
487bfa83a9eSThomas Graf  *
488bfa83a9eSThomas Graf  * Returns NULL if the tailroom of the skb is insufficient to store
489bfa83a9eSThomas Graf  * the message header and payload.
490bfa83a9eSThomas Graf  */
491bfa83a9eSThomas Graf static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
492bfa83a9eSThomas Graf 						struct netlink_callback *cb,
493bfa83a9eSThomas Graf 						int type, int payload,
494bfa83a9eSThomas Graf 						int flags)
495bfa83a9eSThomas Graf {
49615e47304SEric W. Biederman 	return nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
497bfa83a9eSThomas Graf 			 type, payload, flags);
498bfa83a9eSThomas Graf }
499bfa83a9eSThomas Graf 
500bfa83a9eSThomas Graf /**
501bfa83a9eSThomas Graf  * nlmsg_new - Allocate a new netlink message
502339bf98fSThomas Graf  * @payload: size of the message payload
503fe4944e5SThomas Graf  * @flags: the type of memory to allocate.
504bfa83a9eSThomas Graf  *
505339bf98fSThomas Graf  * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known
506339bf98fSThomas Graf  * and a good default is needed.
507bfa83a9eSThomas Graf  */
508339bf98fSThomas Graf static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags)
509bfa83a9eSThomas Graf {
510339bf98fSThomas Graf 	return alloc_skb(nlmsg_total_size(payload), flags);
511bfa83a9eSThomas Graf }
512bfa83a9eSThomas Graf 
513bfa83a9eSThomas Graf /**
514bfa83a9eSThomas Graf  * nlmsg_end - Finalize a netlink message
515bfa83a9eSThomas Graf  * @skb: socket buffer the message is stored in
516bfa83a9eSThomas Graf  * @nlh: netlink message header
517bfa83a9eSThomas Graf  *
518bfa83a9eSThomas Graf  * Corrects the netlink message header to include the appeneded
519bfa83a9eSThomas Graf  * attributes. Only necessary if attributes have been added to
520bfa83a9eSThomas Graf  * the message.
521bfa83a9eSThomas Graf  */
522053c095aSJohannes Berg static inline void nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
523bfa83a9eSThomas Graf {
52427a884dcSArnaldo Carvalho de Melo 	nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh;
525bfa83a9eSThomas Graf }
526bfa83a9eSThomas Graf 
527bfa83a9eSThomas Graf /**
528fe4944e5SThomas Graf  * nlmsg_get_pos - return current position in netlink message
529fe4944e5SThomas Graf  * @skb: socket buffer the message is stored in
530fe4944e5SThomas Graf  *
531fe4944e5SThomas Graf  * Returns a pointer to the current tail of the message.
532fe4944e5SThomas Graf  */
533fe4944e5SThomas Graf static inline void *nlmsg_get_pos(struct sk_buff *skb)
534fe4944e5SThomas Graf {
53527a884dcSArnaldo Carvalho de Melo 	return skb_tail_pointer(skb);
536fe4944e5SThomas Graf }
537fe4944e5SThomas Graf 
538fe4944e5SThomas Graf /**
539fe4944e5SThomas Graf  * nlmsg_trim - Trim message to a mark
540fe4944e5SThomas Graf  * @skb: socket buffer the message is stored in
541fe4944e5SThomas Graf  * @mark: mark to trim to
542fe4944e5SThomas Graf  *
543bc3ed28cSThomas Graf  * Trims the message to the provided mark.
544fe4944e5SThomas Graf  */
545bc3ed28cSThomas Graf static inline void nlmsg_trim(struct sk_buff *skb, const void *mark)
546fe4944e5SThomas Graf {
547149118d8SThomas Graf 	if (mark) {
548149118d8SThomas Graf 		WARN_ON((unsigned char *) mark < skb->data);
549fe4944e5SThomas Graf 		skb_trim(skb, (unsigned char *) mark - skb->data);
550fe4944e5SThomas Graf 	}
551149118d8SThomas Graf }
552fe4944e5SThomas Graf 
553fe4944e5SThomas Graf /**
554bfa83a9eSThomas Graf  * nlmsg_cancel - Cancel construction of a netlink message
555bfa83a9eSThomas Graf  * @skb: socket buffer the message is stored in
556bfa83a9eSThomas Graf  * @nlh: netlink message header
557bfa83a9eSThomas Graf  *
558bfa83a9eSThomas Graf  * Removes the complete netlink message including all
559bc3ed28cSThomas Graf  * attributes from the socket buffer again.
560bfa83a9eSThomas Graf  */
561bc3ed28cSThomas Graf static inline void nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
562bfa83a9eSThomas Graf {
563bc3ed28cSThomas Graf 	nlmsg_trim(skb, nlh);
564bfa83a9eSThomas Graf }
565bfa83a9eSThomas Graf 
566bfa83a9eSThomas Graf /**
567bfa83a9eSThomas Graf  * nlmsg_free - free a netlink message
568bfa83a9eSThomas Graf  * @skb: socket buffer of netlink message
569bfa83a9eSThomas Graf  */
570bfa83a9eSThomas Graf static inline void nlmsg_free(struct sk_buff *skb)
571bfa83a9eSThomas Graf {
572bfa83a9eSThomas Graf 	kfree_skb(skb);
573bfa83a9eSThomas Graf }
574bfa83a9eSThomas Graf 
575bfa83a9eSThomas Graf /**
576bfa83a9eSThomas Graf  * nlmsg_multicast - multicast a netlink message
577bfa83a9eSThomas Graf  * @sk: netlink socket to spread messages to
578bfa83a9eSThomas Graf  * @skb: netlink message as socket buffer
57915e47304SEric W. Biederman  * @portid: own netlink portid to avoid sending to yourself
580bfa83a9eSThomas Graf  * @group: multicast group id
581d387f6adSThomas Graf  * @flags: allocation flags
582bfa83a9eSThomas Graf  */
583bfa83a9eSThomas Graf static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
58415e47304SEric W. Biederman 				  u32 portid, unsigned int group, gfp_t flags)
585bfa83a9eSThomas Graf {
586bfa83a9eSThomas Graf 	int err;
587bfa83a9eSThomas Graf 
588bfa83a9eSThomas Graf 	NETLINK_CB(skb).dst_group = group;
589bfa83a9eSThomas Graf 
59015e47304SEric W. Biederman 	err = netlink_broadcast(sk, skb, portid, group, flags);
591bfa83a9eSThomas Graf 	if (err > 0)
592bfa83a9eSThomas Graf 		err = 0;
593bfa83a9eSThomas Graf 
594bfa83a9eSThomas Graf 	return err;
595bfa83a9eSThomas Graf }
596bfa83a9eSThomas Graf 
597bfa83a9eSThomas Graf /**
598bfa83a9eSThomas Graf  * nlmsg_unicast - unicast a netlink message
599bfa83a9eSThomas Graf  * @sk: netlink socket to spread message to
600bfa83a9eSThomas Graf  * @skb: netlink message as socket buffer
60115e47304SEric W. Biederman  * @portid: netlink portid of the destination socket
602bfa83a9eSThomas Graf  */
60315e47304SEric W. Biederman static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 portid)
604bfa83a9eSThomas Graf {
605bfa83a9eSThomas Graf 	int err;
606bfa83a9eSThomas Graf 
60715e47304SEric W. Biederman 	err = netlink_unicast(sk, skb, portid, MSG_DONTWAIT);
608bfa83a9eSThomas Graf 	if (err > 0)
609bfa83a9eSThomas Graf 		err = 0;
610bfa83a9eSThomas Graf 
611bfa83a9eSThomas Graf 	return err;
612bfa83a9eSThomas Graf }
613bfa83a9eSThomas Graf 
614bfa83a9eSThomas Graf /**
615bfa83a9eSThomas Graf  * nlmsg_for_each_msg - iterate over a stream of messages
616bfa83a9eSThomas Graf  * @pos: loop counter, set to current message
617bfa83a9eSThomas Graf  * @head: head of message stream
618bfa83a9eSThomas Graf  * @len: length of message stream
619bfa83a9eSThomas Graf  * @rem: initialized to len, holds bytes currently remaining in stream
620bfa83a9eSThomas Graf  */
621bfa83a9eSThomas Graf #define nlmsg_for_each_msg(pos, head, len, rem) \
622bfa83a9eSThomas Graf 	for (pos = head, rem = len; \
623bfa83a9eSThomas Graf 	     nlmsg_ok(pos, rem); \
624bfa83a9eSThomas Graf 	     pos = nlmsg_next(pos, &(rem)))
625bfa83a9eSThomas Graf 
626670dc283SJohannes Berg /**
627670dc283SJohannes Berg  * nl_dump_check_consistent - check if sequence is consistent and advertise if not
628670dc283SJohannes Berg  * @cb: netlink callback structure that stores the sequence number
629670dc283SJohannes Berg  * @nlh: netlink message header to write the flag to
630670dc283SJohannes Berg  *
631670dc283SJohannes Berg  * This function checks if the sequence (generation) number changed during dump
632670dc283SJohannes Berg  * and if it did, advertises it in the netlink message header.
633670dc283SJohannes Berg  *
634670dc283SJohannes Berg  * The correct way to use it is to set cb->seq to the generation counter when
635670dc283SJohannes Berg  * all locks for dumping have been acquired, and then call this function for
636670dc283SJohannes Berg  * each message that is generated.
637670dc283SJohannes Berg  *
638670dc283SJohannes Berg  * Note that due to initialisation concerns, 0 is an invalid sequence number
639670dc283SJohannes Berg  * and must not be used by code that uses this functionality.
640670dc283SJohannes Berg  */
641670dc283SJohannes Berg static inline void
642670dc283SJohannes Berg nl_dump_check_consistent(struct netlink_callback *cb,
643670dc283SJohannes Berg 			 struct nlmsghdr *nlh)
644670dc283SJohannes Berg {
645670dc283SJohannes Berg 	if (cb->prev_seq && cb->seq != cb->prev_seq)
646670dc283SJohannes Berg 		nlh->nlmsg_flags |= NLM_F_DUMP_INTR;
647670dc283SJohannes Berg 	cb->prev_seq = cb->seq;
648670dc283SJohannes Berg }
649670dc283SJohannes Berg 
650bfa83a9eSThomas Graf /**************************************************************************
651bfa83a9eSThomas Graf  * Netlink Attributes
652bfa83a9eSThomas Graf  **************************************************************************/
653bfa83a9eSThomas Graf 
654bfa83a9eSThomas Graf /**
655bfa83a9eSThomas Graf  * nla_attr_size - length of attribute not including padding
656bfa83a9eSThomas Graf  * @payload: length of payload
657bfa83a9eSThomas Graf  */
658bfa83a9eSThomas Graf static inline int nla_attr_size(int payload)
659bfa83a9eSThomas Graf {
660bfa83a9eSThomas Graf 	return NLA_HDRLEN + payload;
661bfa83a9eSThomas Graf }
662bfa83a9eSThomas Graf 
663bfa83a9eSThomas Graf /**
664bfa83a9eSThomas Graf  * nla_total_size - total length of attribute including padding
665bfa83a9eSThomas Graf  * @payload: length of payload
666bfa83a9eSThomas Graf  */
667bfa83a9eSThomas Graf static inline int nla_total_size(int payload)
668bfa83a9eSThomas Graf {
669bfa83a9eSThomas Graf 	return NLA_ALIGN(nla_attr_size(payload));
670bfa83a9eSThomas Graf }
671bfa83a9eSThomas Graf 
672bfa83a9eSThomas Graf /**
673bfa83a9eSThomas Graf  * nla_padlen - length of padding at the tail of attribute
674bfa83a9eSThomas Graf  * @payload: length of payload
675bfa83a9eSThomas Graf  */
676bfa83a9eSThomas Graf static inline int nla_padlen(int payload)
677bfa83a9eSThomas Graf {
678bfa83a9eSThomas Graf 	return nla_total_size(payload) - nla_attr_size(payload);
679bfa83a9eSThomas Graf }
680bfa83a9eSThomas Graf 
681bfa83a9eSThomas Graf /**
6828f4c1f9bSThomas Graf  * nla_type - attribute type
6838f4c1f9bSThomas Graf  * @nla: netlink attribute
6848f4c1f9bSThomas Graf  */
6858f4c1f9bSThomas Graf static inline int nla_type(const struct nlattr *nla)
6868f4c1f9bSThomas Graf {
6878f4c1f9bSThomas Graf 	return nla->nla_type & NLA_TYPE_MASK;
6888f4c1f9bSThomas Graf }
6898f4c1f9bSThomas Graf 
6908f4c1f9bSThomas Graf /**
691bfa83a9eSThomas Graf  * nla_data - head of payload
692bfa83a9eSThomas Graf  * @nla: netlink attribute
693bfa83a9eSThomas Graf  */
694bfa83a9eSThomas Graf static inline void *nla_data(const struct nlattr *nla)
695bfa83a9eSThomas Graf {
696bfa83a9eSThomas Graf 	return (char *) nla + NLA_HDRLEN;
697bfa83a9eSThomas Graf }
698bfa83a9eSThomas Graf 
699bfa83a9eSThomas Graf /**
700bfa83a9eSThomas Graf  * nla_len - length of payload
701bfa83a9eSThomas Graf  * @nla: netlink attribute
702bfa83a9eSThomas Graf  */
703bfa83a9eSThomas Graf static inline int nla_len(const struct nlattr *nla)
704bfa83a9eSThomas Graf {
705bfa83a9eSThomas Graf 	return nla->nla_len - NLA_HDRLEN;
706bfa83a9eSThomas Graf }
707bfa83a9eSThomas Graf 
708bfa83a9eSThomas Graf /**
709bfa83a9eSThomas Graf  * nla_ok - check if the netlink attribute fits into the remaining bytes
710bfa83a9eSThomas Graf  * @nla: netlink attribute
711bfa83a9eSThomas Graf  * @remaining: number of bytes remaining in attribute stream
712bfa83a9eSThomas Graf  */
713bfa83a9eSThomas Graf static inline int nla_ok(const struct nlattr *nla, int remaining)
714bfa83a9eSThomas Graf {
7153e1ed981SAlexey Dobriyan 	return remaining >= (int) sizeof(*nla) &&
7163e1ed981SAlexey Dobriyan 	       nla->nla_len >= sizeof(*nla) &&
717bfa83a9eSThomas Graf 	       nla->nla_len <= remaining;
718bfa83a9eSThomas Graf }
719bfa83a9eSThomas Graf 
720bfa83a9eSThomas Graf /**
721d1ec3b77SPierre Ynard  * nla_next - next netlink attribute in attribute stream
722bfa83a9eSThomas Graf  * @nla: netlink attribute
723bfa83a9eSThomas Graf  * @remaining: number of bytes remaining in attribute stream
724bfa83a9eSThomas Graf  *
725bfa83a9eSThomas Graf  * Returns the next netlink attribute in the attribute stream and
726bfa83a9eSThomas Graf  * decrements remaining by the size of the current attribute.
727bfa83a9eSThomas Graf  */
728bfa83a9eSThomas Graf static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
729bfa83a9eSThomas Graf {
7303b2c75d3SAlexey Dobriyan 	unsigned int totlen = NLA_ALIGN(nla->nla_len);
731bfa83a9eSThomas Graf 
732bfa83a9eSThomas Graf 	*remaining -= totlen;
733bfa83a9eSThomas Graf 	return (struct nlattr *) ((char *) nla + totlen);
734bfa83a9eSThomas Graf }
735bfa83a9eSThomas Graf 
736bfa83a9eSThomas Graf /**
737fe4944e5SThomas Graf  * nla_find_nested - find attribute in a set of nested attributes
738fe4944e5SThomas Graf  * @nla: attribute containing the nested attributes
739fe4944e5SThomas Graf  * @attrtype: type of attribute to look for
740fe4944e5SThomas Graf  *
741fe4944e5SThomas Graf  * Returns the first attribute which matches the specified type.
742fe4944e5SThomas Graf  */
7433654654fSJan Engelhardt static inline struct nlattr *
7443654654fSJan Engelhardt nla_find_nested(const struct nlattr *nla, int attrtype)
745fe4944e5SThomas Graf {
746fe4944e5SThomas Graf 	return nla_find(nla_data(nla), nla_len(nla), attrtype);
747fe4944e5SThomas Graf }
748fe4944e5SThomas Graf 
749fe4944e5SThomas Graf /**
750bfa83a9eSThomas Graf  * nla_parse_nested - parse nested attributes
751bfa83a9eSThomas Graf  * @tb: destination array with maxtype+1 elements
752bfa83a9eSThomas Graf  * @maxtype: maximum attribute type to be expected
753bfa83a9eSThomas Graf  * @nla: attribute containing the nested attributes
754bfa83a9eSThomas Graf  * @policy: validation policy
755fceb6435SJohannes Berg  * @extack: extended ACK report struct
756bfa83a9eSThomas Graf  *
757bfa83a9eSThomas Graf  * See nla_parse()
758bfa83a9eSThomas Graf  */
759bfa83a9eSThomas Graf static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
760b057efd4SPatrick McHardy 				   const struct nlattr *nla,
761fceb6435SJohannes Berg 				   const struct nla_policy *policy,
762fceb6435SJohannes Berg 				   struct netlink_ext_ack *extack)
763bfa83a9eSThomas Graf {
764fceb6435SJohannes Berg 	return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy,
765fceb6435SJohannes Berg 			 extack);
766bfa83a9eSThomas Graf }
7671092cb21SPatrick McHardy 
7681092cb21SPatrick McHardy /**
769d1ec3b77SPierre Ynard  * nla_put_u8 - Add a u8 netlink attribute to a socket buffer
770bfa83a9eSThomas Graf  * @skb: socket buffer to add attribute to
771bfa83a9eSThomas Graf  * @attrtype: attribute type
772bfa83a9eSThomas Graf  * @value: numeric value
773bfa83a9eSThomas Graf  */
774bfa83a9eSThomas Graf static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
775bfa83a9eSThomas Graf {
776b4391db4SArnd Bergmann 	/* temporary variables to work around GCC PR81715 with asan-stack=1 */
777b4391db4SArnd Bergmann 	u8 tmp = value;
778b4391db4SArnd Bergmann 
779b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(u8), &tmp);
780bfa83a9eSThomas Graf }
781bfa83a9eSThomas Graf 
782bfa83a9eSThomas Graf /**
783bfa83a9eSThomas Graf  * nla_put_u16 - Add a u16 netlink attribute to a socket buffer
784bfa83a9eSThomas Graf  * @skb: socket buffer to add attribute to
785bfa83a9eSThomas Graf  * @attrtype: attribute type
786bfa83a9eSThomas Graf  * @value: numeric value
787bfa83a9eSThomas Graf  */
788bfa83a9eSThomas Graf static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
789bfa83a9eSThomas Graf {
790b4391db4SArnd Bergmann 	u16 tmp = value;
791b4391db4SArnd Bergmann 
792b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(u16), &tmp);
793bfa83a9eSThomas Graf }
794bfa83a9eSThomas Graf 
795bfa83a9eSThomas Graf /**
796569a8fc3SDavid S. Miller  * nla_put_be16 - Add a __be16 netlink attribute to a socket buffer
797569a8fc3SDavid S. Miller  * @skb: socket buffer to add attribute to
798569a8fc3SDavid S. Miller  * @attrtype: attribute type
799569a8fc3SDavid S. Miller  * @value: numeric value
800569a8fc3SDavid S. Miller  */
801569a8fc3SDavid S. Miller static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
802569a8fc3SDavid S. Miller {
803b4391db4SArnd Bergmann 	__be16 tmp = value;
804b4391db4SArnd Bergmann 
805b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(__be16), &tmp);
806569a8fc3SDavid S. Miller }
807569a8fc3SDavid S. Miller 
808569a8fc3SDavid S. Miller /**
8096c1dd3b6SDavid S. Miller  * nla_put_net16 - Add 16-bit network byte order netlink attribute to a socket buffer
8106c1dd3b6SDavid S. Miller  * @skb: socket buffer to add attribute to
8116c1dd3b6SDavid S. Miller  * @attrtype: attribute type
8126c1dd3b6SDavid S. Miller  * @value: numeric value
8136c1dd3b6SDavid S. Miller  */
8146c1dd3b6SDavid S. Miller static inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value)
8156c1dd3b6SDavid S. Miller {
816b4391db4SArnd Bergmann 	__be16 tmp = value;
817b4391db4SArnd Bergmann 
818b4391db4SArnd Bergmann 	return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, tmp);
8196c1dd3b6SDavid S. Miller }
8206c1dd3b6SDavid S. Miller 
8216c1dd3b6SDavid S. Miller /**
82224c410dcSDavid S. Miller  * nla_put_le16 - Add a __le16 netlink attribute to a socket buffer
82324c410dcSDavid S. Miller  * @skb: socket buffer to add attribute to
82424c410dcSDavid S. Miller  * @attrtype: attribute type
82524c410dcSDavid S. Miller  * @value: numeric value
82624c410dcSDavid S. Miller  */
82724c410dcSDavid S. Miller static inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value)
82824c410dcSDavid S. Miller {
829b4391db4SArnd Bergmann 	__le16 tmp = value;
830b4391db4SArnd Bergmann 
831b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(__le16), &tmp);
83224c410dcSDavid S. Miller }
83324c410dcSDavid S. Miller 
83424c410dcSDavid S. Miller /**
835bfa83a9eSThomas Graf  * nla_put_u32 - Add a u32 netlink attribute to a socket buffer
836bfa83a9eSThomas Graf  * @skb: socket buffer to add attribute to
837bfa83a9eSThomas Graf  * @attrtype: attribute type
838bfa83a9eSThomas Graf  * @value: numeric value
839bfa83a9eSThomas Graf  */
840bfa83a9eSThomas Graf static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
841bfa83a9eSThomas Graf {
842b4391db4SArnd Bergmann 	u32 tmp = value;
843b4391db4SArnd Bergmann 
844b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(u32), &tmp);
845bfa83a9eSThomas Graf }
846bfa83a9eSThomas Graf 
847bfa83a9eSThomas Graf /**
848569a8fc3SDavid S. Miller  * nla_put_be32 - Add a __be32 netlink attribute to a socket buffer
849569a8fc3SDavid S. Miller  * @skb: socket buffer to add attribute to
850569a8fc3SDavid S. Miller  * @attrtype: attribute type
851569a8fc3SDavid S. Miller  * @value: numeric value
852569a8fc3SDavid S. Miller  */
853569a8fc3SDavid S. Miller static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
854569a8fc3SDavid S. Miller {
855b4391db4SArnd Bergmann 	__be32 tmp = value;
856b4391db4SArnd Bergmann 
857b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(__be32), &tmp);
858569a8fc3SDavid S. Miller }
859569a8fc3SDavid S. Miller 
860569a8fc3SDavid S. Miller /**
8616c1dd3b6SDavid S. Miller  * nla_put_net32 - Add 32-bit network byte order netlink attribute to a socket buffer
8626c1dd3b6SDavid S. Miller  * @skb: socket buffer to add attribute to
8636c1dd3b6SDavid S. Miller  * @attrtype: attribute type
8646c1dd3b6SDavid S. Miller  * @value: numeric value
8656c1dd3b6SDavid S. Miller  */
8666c1dd3b6SDavid S. Miller static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value)
8676c1dd3b6SDavid S. Miller {
868b4391db4SArnd Bergmann 	__be32 tmp = value;
869b4391db4SArnd Bergmann 
870b4391db4SArnd Bergmann 	return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, tmp);
8716c1dd3b6SDavid S. Miller }
8726c1dd3b6SDavid S. Miller 
8736c1dd3b6SDavid S. Miller /**
87424c410dcSDavid S. Miller  * nla_put_le32 - Add a __le32 netlink attribute to a socket buffer
87524c410dcSDavid S. Miller  * @skb: socket buffer to add attribute to
87624c410dcSDavid S. Miller  * @attrtype: attribute type
87724c410dcSDavid S. Miller  * @value: numeric value
87824c410dcSDavid S. Miller  */
87924c410dcSDavid S. Miller static inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value)
88024c410dcSDavid S. Miller {
881b4391db4SArnd Bergmann 	__le32 tmp = value;
882b4391db4SArnd Bergmann 
883b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(__le32), &tmp);
88424c410dcSDavid S. Miller }
88524c410dcSDavid S. Miller 
88624c410dcSDavid S. Miller /**
88773520786SNicolas Dichtel  * nla_put_u64_64bit - Add a u64 netlink attribute to a skb and align it
88873520786SNicolas Dichtel  * @skb: socket buffer to add attribute to
88973520786SNicolas Dichtel  * @attrtype: attribute type
89073520786SNicolas Dichtel  * @value: numeric value
89173520786SNicolas Dichtel  * @padattr: attribute type for the padding
89273520786SNicolas Dichtel  */
89373520786SNicolas Dichtel static inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
89473520786SNicolas Dichtel 				    u64 value, int padattr)
89573520786SNicolas Dichtel {
896b4391db4SArnd Bergmann 	u64 tmp = value;
897b4391db4SArnd Bergmann 
898b4391db4SArnd Bergmann 	return nla_put_64bit(skb, attrtype, sizeof(u64), &tmp, padattr);
89973520786SNicolas Dichtel }
90073520786SNicolas Dichtel 
90173520786SNicolas Dichtel /**
902b46f6dedSNicolas Dichtel  * nla_put_be64 - Add a __be64 netlink attribute to a socket buffer and align it
903569a8fc3SDavid S. Miller  * @skb: socket buffer to add attribute to
904569a8fc3SDavid S. Miller  * @attrtype: attribute type
905569a8fc3SDavid S. Miller  * @value: numeric value
906b46f6dedSNicolas Dichtel  * @padattr: attribute type for the padding
907569a8fc3SDavid S. Miller  */
908b46f6dedSNicolas Dichtel static inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value,
909b46f6dedSNicolas Dichtel 			       int padattr)
910b46f6dedSNicolas Dichtel {
911b4391db4SArnd Bergmann 	__be64 tmp = value;
912b4391db4SArnd Bergmann 
913b4391db4SArnd Bergmann 	return nla_put_64bit(skb, attrtype, sizeof(__be64), &tmp, padattr);
914b46f6dedSNicolas Dichtel }
915b46f6dedSNicolas Dichtel 
916569a8fc3SDavid S. Miller /**
917e9bbe898SNicolas Dichtel  * nla_put_net64 - Add 64-bit network byte order nlattr to a skb and align it
9186c1dd3b6SDavid S. Miller  * @skb: socket buffer to add attribute to
9196c1dd3b6SDavid S. Miller  * @attrtype: attribute type
9206c1dd3b6SDavid S. Miller  * @value: numeric value
921e9bbe898SNicolas Dichtel  * @padattr: attribute type for the padding
9226c1dd3b6SDavid S. Miller  */
923e9bbe898SNicolas Dichtel static inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value,
924e9bbe898SNicolas Dichtel 				int padattr)
9256c1dd3b6SDavid S. Miller {
926b4391db4SArnd Bergmann 	__be64 tmp = value;
927b4391db4SArnd Bergmann 
928b4391db4SArnd Bergmann 	return nla_put_be64(skb, attrtype | NLA_F_NET_BYTEORDER, tmp,
929e9bbe898SNicolas Dichtel 			    padattr);
9306c1dd3b6SDavid S. Miller }
9316c1dd3b6SDavid S. Miller 
9326c1dd3b6SDavid S. Miller /**
933e7479122SNicolas Dichtel  * nla_put_le64 - Add a __le64 netlink attribute to a socket buffer and align it
93424c410dcSDavid S. Miller  * @skb: socket buffer to add attribute to
93524c410dcSDavid S. Miller  * @attrtype: attribute type
93624c410dcSDavid S. Miller  * @value: numeric value
937e7479122SNicolas Dichtel  * @padattr: attribute type for the padding
93824c410dcSDavid S. Miller  */
939e7479122SNicolas Dichtel static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value,
940e7479122SNicolas Dichtel 			       int padattr)
94124c410dcSDavid S. Miller {
942b4391db4SArnd Bergmann 	__le64 tmp = value;
943b4391db4SArnd Bergmann 
944b4391db4SArnd Bergmann 	return nla_put_64bit(skb, attrtype, sizeof(__le64), &tmp, padattr);
94524c410dcSDavid S. Miller }
94624c410dcSDavid S. Miller 
94724c410dcSDavid S. Miller /**
9484778e0beSJiri Pirko  * nla_put_s8 - Add a s8 netlink attribute to a socket buffer
9494778e0beSJiri Pirko  * @skb: socket buffer to add attribute to
9504778e0beSJiri Pirko  * @attrtype: attribute type
9514778e0beSJiri Pirko  * @value: numeric value
9524778e0beSJiri Pirko  */
9534778e0beSJiri Pirko static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
9544778e0beSJiri Pirko {
955b4391db4SArnd Bergmann 	s8 tmp = value;
956b4391db4SArnd Bergmann 
957b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(s8), &tmp);
9584778e0beSJiri Pirko }
9594778e0beSJiri Pirko 
9604778e0beSJiri Pirko /**
9614778e0beSJiri Pirko  * nla_put_s16 - Add a s16 netlink attribute to a socket buffer
9624778e0beSJiri Pirko  * @skb: socket buffer to add attribute to
9634778e0beSJiri Pirko  * @attrtype: attribute type
9644778e0beSJiri Pirko  * @value: numeric value
9654778e0beSJiri Pirko  */
9664778e0beSJiri Pirko static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
9674778e0beSJiri Pirko {
968b4391db4SArnd Bergmann 	s16 tmp = value;
969b4391db4SArnd Bergmann 
970b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(s16), &tmp);
9714778e0beSJiri Pirko }
9724778e0beSJiri Pirko 
9734778e0beSJiri Pirko /**
9744778e0beSJiri Pirko  * nla_put_s32 - Add a s32 netlink attribute to a socket buffer
9754778e0beSJiri Pirko  * @skb: socket buffer to add attribute to
9764778e0beSJiri Pirko  * @attrtype: attribute type
9774778e0beSJiri Pirko  * @value: numeric value
9784778e0beSJiri Pirko  */
9794778e0beSJiri Pirko static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
9804778e0beSJiri Pirko {
981b4391db4SArnd Bergmann 	s32 tmp = value;
982b4391db4SArnd Bergmann 
983b4391db4SArnd Bergmann 	return nla_put(skb, attrtype, sizeof(s32), &tmp);
9844778e0beSJiri Pirko }
9854778e0beSJiri Pirko 
9864778e0beSJiri Pirko /**
987756a2f59SNicolas Dichtel  * nla_put_s64 - Add a s64 netlink attribute to a socket buffer and align it
9884778e0beSJiri Pirko  * @skb: socket buffer to add attribute to
9894778e0beSJiri Pirko  * @attrtype: attribute type
9904778e0beSJiri Pirko  * @value: numeric value
991756a2f59SNicolas Dichtel  * @padattr: attribute type for the padding
9924778e0beSJiri Pirko  */
993756a2f59SNicolas Dichtel static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value,
994756a2f59SNicolas Dichtel 			      int padattr)
9954778e0beSJiri Pirko {
996b4391db4SArnd Bergmann 	s64 tmp = value;
997b4391db4SArnd Bergmann 
998b4391db4SArnd Bergmann 	return nla_put_64bit(skb, attrtype, sizeof(s64), &tmp, padattr);
9994778e0beSJiri Pirko }
10004778e0beSJiri Pirko 
10014778e0beSJiri Pirko /**
1002bfa83a9eSThomas Graf  * nla_put_string - Add a string netlink attribute to a socket buffer
1003bfa83a9eSThomas Graf  * @skb: socket buffer to add attribute to
1004bfa83a9eSThomas Graf  * @attrtype: attribute type
1005bfa83a9eSThomas Graf  * @str: NUL terminated string
1006bfa83a9eSThomas Graf  */
1007bfa83a9eSThomas Graf static inline int nla_put_string(struct sk_buff *skb, int attrtype,
1008bfa83a9eSThomas Graf 				 const char *str)
1009bfa83a9eSThomas Graf {
1010bfa83a9eSThomas Graf 	return nla_put(skb, attrtype, strlen(str) + 1, str);
1011bfa83a9eSThomas Graf }
1012bfa83a9eSThomas Graf 
1013bfa83a9eSThomas Graf /**
1014bfa83a9eSThomas Graf  * nla_put_flag - Add a flag netlink attribute to a socket buffer
1015bfa83a9eSThomas Graf  * @skb: socket buffer to add attribute to
1016bfa83a9eSThomas Graf  * @attrtype: attribute type
1017bfa83a9eSThomas Graf  */
1018bfa83a9eSThomas Graf static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
1019bfa83a9eSThomas Graf {
1020bfa83a9eSThomas Graf 	return nla_put(skb, attrtype, 0, NULL);
1021bfa83a9eSThomas Graf }
1022bfa83a9eSThomas Graf 
1023bfa83a9eSThomas Graf /**
10242175d87cSNicolas Dichtel  * nla_put_msecs - Add a msecs netlink attribute to a skb and align it
1025bfa83a9eSThomas Graf  * @skb: socket buffer to add attribute to
1026bfa83a9eSThomas Graf  * @attrtype: attribute type
1027d87de1f3SMark Rustad  * @njiffies: number of jiffies to convert to msecs
10282175d87cSNicolas Dichtel  * @padattr: attribute type for the padding
1029bfa83a9eSThomas Graf  */
1030bfa83a9eSThomas Graf static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
10312175d87cSNicolas Dichtel 				unsigned long njiffies, int padattr)
1032bfa83a9eSThomas Graf {
1033d87de1f3SMark Rustad 	u64 tmp = jiffies_to_msecs(njiffies);
10342175d87cSNicolas Dichtel 
10352175d87cSNicolas Dichtel 	return nla_put_64bit(skb, attrtype, sizeof(u64), &tmp, padattr);
1036bfa83a9eSThomas Graf }
1037bfa83a9eSThomas Graf 
1038bfa83a9eSThomas Graf /**
1039930345eaSJiri Benc  * nla_put_in_addr - Add an IPv4 address netlink attribute to a socket
1040930345eaSJiri Benc  * buffer
1041930345eaSJiri Benc  * @skb: socket buffer to add attribute to
1042930345eaSJiri Benc  * @attrtype: attribute type
1043930345eaSJiri Benc  * @addr: IPv4 address
1044930345eaSJiri Benc  */
1045930345eaSJiri Benc static inline int nla_put_in_addr(struct sk_buff *skb, int attrtype,
1046930345eaSJiri Benc 				  __be32 addr)
1047930345eaSJiri Benc {
1048b4391db4SArnd Bergmann 	__be32 tmp = addr;
1049b4391db4SArnd Bergmann 
1050b4391db4SArnd Bergmann 	return nla_put_be32(skb, attrtype, tmp);
1051930345eaSJiri Benc }
1052930345eaSJiri Benc 
1053930345eaSJiri Benc /**
1054930345eaSJiri Benc  * nla_put_in6_addr - Add an IPv6 address netlink attribute to a socket
1055930345eaSJiri Benc  * buffer
1056930345eaSJiri Benc  * @skb: socket buffer to add attribute to
1057930345eaSJiri Benc  * @attrtype: attribute type
1058930345eaSJiri Benc  * @addr: IPv6 address
1059930345eaSJiri Benc  */
1060930345eaSJiri Benc static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype,
1061930345eaSJiri Benc 				   const struct in6_addr *addr)
1062930345eaSJiri Benc {
1063930345eaSJiri Benc 	return nla_put(skb, attrtype, sizeof(*addr), addr);
1064930345eaSJiri Benc }
1065930345eaSJiri Benc 
1066930345eaSJiri Benc /**
1067bfa83a9eSThomas Graf  * nla_get_u32 - return payload of u32 attribute
1068bfa83a9eSThomas Graf  * @nla: u32 netlink attribute
1069bfa83a9eSThomas Graf  */
1070b057efd4SPatrick McHardy static inline u32 nla_get_u32(const struct nlattr *nla)
1071bfa83a9eSThomas Graf {
1072bfa83a9eSThomas Graf 	return *(u32 *) nla_data(nla);
1073bfa83a9eSThomas Graf }
1074bfa83a9eSThomas Graf 
1075bfa83a9eSThomas Graf /**
107600012e5bSAl Viro  * nla_get_be32 - return payload of __be32 attribute
107700012e5bSAl Viro  * @nla: __be32 netlink attribute
107800012e5bSAl Viro  */
1079b057efd4SPatrick McHardy static inline __be32 nla_get_be32(const struct nlattr *nla)
108000012e5bSAl Viro {
108100012e5bSAl Viro 	return *(__be32 *) nla_data(nla);
108200012e5bSAl Viro }
108300012e5bSAl Viro 
108400012e5bSAl Viro /**
1085c648a013SAlexander Aring  * nla_get_le32 - return payload of __le32 attribute
1086c648a013SAlexander Aring  * @nla: __le32 netlink attribute
1087c648a013SAlexander Aring  */
1088c648a013SAlexander Aring static inline __le32 nla_get_le32(const struct nlattr *nla)
1089c648a013SAlexander Aring {
1090c648a013SAlexander Aring 	return *(__le32 *) nla_data(nla);
1091c648a013SAlexander Aring }
1092c648a013SAlexander Aring 
1093c648a013SAlexander Aring /**
1094bfa83a9eSThomas Graf  * nla_get_u16 - return payload of u16 attribute
1095bfa83a9eSThomas Graf  * @nla: u16 netlink attribute
1096bfa83a9eSThomas Graf  */
1097b057efd4SPatrick McHardy static inline u16 nla_get_u16(const struct nlattr *nla)
1098bfa83a9eSThomas Graf {
1099bfa83a9eSThomas Graf 	return *(u16 *) nla_data(nla);
1100bfa83a9eSThomas Graf }
1101bfa83a9eSThomas Graf 
1102bfa83a9eSThomas Graf /**
1103838965baSPatrick McHardy  * nla_get_be16 - return payload of __be16 attribute
1104838965baSPatrick McHardy  * @nla: __be16 netlink attribute
1105838965baSPatrick McHardy  */
1106b057efd4SPatrick McHardy static inline __be16 nla_get_be16(const struct nlattr *nla)
1107838965baSPatrick McHardy {
1108838965baSPatrick McHardy 	return *(__be16 *) nla_data(nla);
1109838965baSPatrick McHardy }
1110838965baSPatrick McHardy 
1111838965baSPatrick McHardy /**
11124a89c256SThomas Graf  * nla_get_le16 - return payload of __le16 attribute
11134a89c256SThomas Graf  * @nla: __le16 netlink attribute
11144a89c256SThomas Graf  */
1115b057efd4SPatrick McHardy static inline __le16 nla_get_le16(const struct nlattr *nla)
11164a89c256SThomas Graf {
11174a89c256SThomas Graf 	return *(__le16 *) nla_data(nla);
11184a89c256SThomas Graf }
11194a89c256SThomas Graf 
11204a89c256SThomas Graf /**
1121bfa83a9eSThomas Graf  * nla_get_u8 - return payload of u8 attribute
1122bfa83a9eSThomas Graf  * @nla: u8 netlink attribute
1123bfa83a9eSThomas Graf  */
1124b057efd4SPatrick McHardy static inline u8 nla_get_u8(const struct nlattr *nla)
1125bfa83a9eSThomas Graf {
1126bfa83a9eSThomas Graf 	return *(u8 *) nla_data(nla);
1127bfa83a9eSThomas Graf }
1128bfa83a9eSThomas Graf 
1129bfa83a9eSThomas Graf /**
1130bfa83a9eSThomas Graf  * nla_get_u64 - return payload of u64 attribute
1131bfa83a9eSThomas Graf  * @nla: u64 netlink attribute
1132bfa83a9eSThomas Graf  */
1133b057efd4SPatrick McHardy static inline u64 nla_get_u64(const struct nlattr *nla)
1134bfa83a9eSThomas Graf {
1135bfa83a9eSThomas Graf 	u64 tmp;
1136bfa83a9eSThomas Graf 
1137bfa83a9eSThomas Graf 	nla_memcpy(&tmp, nla, sizeof(tmp));
1138bfa83a9eSThomas Graf 
1139bfa83a9eSThomas Graf 	return tmp;
1140bfa83a9eSThomas Graf }
1141bfa83a9eSThomas Graf 
1142bfa83a9eSThomas Graf /**
1143a17c8598SPablo Neira Ayuso  * nla_get_be64 - return payload of __be64 attribute
1144a17c8598SPablo Neira Ayuso  * @nla: __be64 netlink attribute
1145a17c8598SPablo Neira Ayuso  */
1146a17c8598SPablo Neira Ayuso static inline __be64 nla_get_be64(const struct nlattr *nla)
1147a17c8598SPablo Neira Ayuso {
1148f5d410f2SPablo Neira Ayuso 	__be64 tmp;
1149f5d410f2SPablo Neira Ayuso 
1150f5d410f2SPablo Neira Ayuso 	nla_memcpy(&tmp, nla, sizeof(tmp));
1151f5d410f2SPablo Neira Ayuso 
1152f5d410f2SPablo Neira Ayuso 	return tmp;
1153a17c8598SPablo Neira Ayuso }
1154a17c8598SPablo Neira Ayuso 
1155a17c8598SPablo Neira Ayuso /**
1156c648a013SAlexander Aring  * nla_get_le64 - return payload of __le64 attribute
1157c648a013SAlexander Aring  * @nla: __le64 netlink attribute
1158c648a013SAlexander Aring  */
1159c648a013SAlexander Aring static inline __le64 nla_get_le64(const struct nlattr *nla)
1160c648a013SAlexander Aring {
1161c648a013SAlexander Aring 	return *(__le64 *) nla_data(nla);
1162c648a013SAlexander Aring }
1163c648a013SAlexander Aring 
1164c648a013SAlexander Aring /**
11654778e0beSJiri Pirko  * nla_get_s32 - return payload of s32 attribute
11664778e0beSJiri Pirko  * @nla: s32 netlink attribute
11674778e0beSJiri Pirko  */
11684778e0beSJiri Pirko static inline s32 nla_get_s32(const struct nlattr *nla)
11694778e0beSJiri Pirko {
11704778e0beSJiri Pirko 	return *(s32 *) nla_data(nla);
11714778e0beSJiri Pirko }
11724778e0beSJiri Pirko 
11734778e0beSJiri Pirko /**
11744778e0beSJiri Pirko  * nla_get_s16 - return payload of s16 attribute
11754778e0beSJiri Pirko  * @nla: s16 netlink attribute
11764778e0beSJiri Pirko  */
11774778e0beSJiri Pirko static inline s16 nla_get_s16(const struct nlattr *nla)
11784778e0beSJiri Pirko {
11794778e0beSJiri Pirko 	return *(s16 *) nla_data(nla);
11804778e0beSJiri Pirko }
11814778e0beSJiri Pirko 
11824778e0beSJiri Pirko /**
11834778e0beSJiri Pirko  * nla_get_s8 - return payload of s8 attribute
11844778e0beSJiri Pirko  * @nla: s8 netlink attribute
11854778e0beSJiri Pirko  */
11864778e0beSJiri Pirko static inline s8 nla_get_s8(const struct nlattr *nla)
11874778e0beSJiri Pirko {
11884778e0beSJiri Pirko 	return *(s8 *) nla_data(nla);
11894778e0beSJiri Pirko }
11904778e0beSJiri Pirko 
11914778e0beSJiri Pirko /**
11924778e0beSJiri Pirko  * nla_get_s64 - return payload of s64 attribute
11934778e0beSJiri Pirko  * @nla: s64 netlink attribute
11944778e0beSJiri Pirko  */
11954778e0beSJiri Pirko static inline s64 nla_get_s64(const struct nlattr *nla)
11964778e0beSJiri Pirko {
11974778e0beSJiri Pirko 	s64 tmp;
11984778e0beSJiri Pirko 
11994778e0beSJiri Pirko 	nla_memcpy(&tmp, nla, sizeof(tmp));
12004778e0beSJiri Pirko 
12014778e0beSJiri Pirko 	return tmp;
12024778e0beSJiri Pirko }
12034778e0beSJiri Pirko 
12044778e0beSJiri Pirko /**
1205bfa83a9eSThomas Graf  * nla_get_flag - return payload of flag attribute
1206bfa83a9eSThomas Graf  * @nla: flag netlink attribute
1207bfa83a9eSThomas Graf  */
1208b057efd4SPatrick McHardy static inline int nla_get_flag(const struct nlattr *nla)
1209bfa83a9eSThomas Graf {
1210bfa83a9eSThomas Graf 	return !!nla;
1211bfa83a9eSThomas Graf }
1212bfa83a9eSThomas Graf 
1213bfa83a9eSThomas Graf /**
1214bfa83a9eSThomas Graf  * nla_get_msecs - return payload of msecs attribute
1215bfa83a9eSThomas Graf  * @nla: msecs netlink attribute
1216bfa83a9eSThomas Graf  *
1217bfa83a9eSThomas Graf  * Returns the number of milliseconds in jiffies.
1218bfa83a9eSThomas Graf  */
1219b057efd4SPatrick McHardy static inline unsigned long nla_get_msecs(const struct nlattr *nla)
1220bfa83a9eSThomas Graf {
1221bfa83a9eSThomas Graf 	u64 msecs = nla_get_u64(nla);
1222bfa83a9eSThomas Graf 
1223bfa83a9eSThomas Graf 	return msecs_to_jiffies((unsigned long) msecs);
1224bfa83a9eSThomas Graf }
1225bfa83a9eSThomas Graf 
1226bfa83a9eSThomas Graf /**
122767b61f6cSJiri Benc  * nla_get_in_addr - return payload of IPv4 address attribute
122867b61f6cSJiri Benc  * @nla: IPv4 address netlink attribute
122967b61f6cSJiri Benc  */
123067b61f6cSJiri Benc static inline __be32 nla_get_in_addr(const struct nlattr *nla)
123167b61f6cSJiri Benc {
123267b61f6cSJiri Benc 	return *(__be32 *) nla_data(nla);
123367b61f6cSJiri Benc }
123467b61f6cSJiri Benc 
123567b61f6cSJiri Benc /**
123667b61f6cSJiri Benc  * nla_get_in6_addr - return payload of IPv6 address attribute
123767b61f6cSJiri Benc  * @nla: IPv6 address netlink attribute
123867b61f6cSJiri Benc  */
123967b61f6cSJiri Benc static inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla)
124067b61f6cSJiri Benc {
124167b61f6cSJiri Benc 	struct in6_addr tmp;
124267b61f6cSJiri Benc 
124367b61f6cSJiri Benc 	nla_memcpy(&tmp, nla, sizeof(tmp));
124467b61f6cSJiri Benc 	return tmp;
124567b61f6cSJiri Benc }
124667b61f6cSJiri Benc 
124767b61f6cSJiri Benc /**
124864c83d83SJamal Hadi Salim  * nla_get_bitfield32 - return payload of 32 bitfield attribute
124964c83d83SJamal Hadi Salim  * @nla: nla_bitfield32 attribute
125064c83d83SJamal Hadi Salim  */
125164c83d83SJamal Hadi Salim static inline struct nla_bitfield32 nla_get_bitfield32(const struct nlattr *nla)
125264c83d83SJamal Hadi Salim {
125364c83d83SJamal Hadi Salim 	struct nla_bitfield32 tmp;
125464c83d83SJamal Hadi Salim 
125564c83d83SJamal Hadi Salim 	nla_memcpy(&tmp, nla, sizeof(tmp));
125664c83d83SJamal Hadi Salim 	return tmp;
125764c83d83SJamal Hadi Salim }
125864c83d83SJamal Hadi Salim 
125964c83d83SJamal Hadi Salim /**
1260b15ca182SThomas Graf  * nla_memdup - duplicate attribute memory (kmemdup)
1261b15ca182SThomas Graf  * @src: netlink attribute to duplicate from
1262b15ca182SThomas Graf  * @gfp: GFP mask
1263b15ca182SThomas Graf  */
1264b15ca182SThomas Graf static inline void *nla_memdup(const struct nlattr *src, gfp_t gfp)
1265b15ca182SThomas Graf {
1266b15ca182SThomas Graf 	return kmemdup(nla_data(src), nla_len(src), gfp);
1267b15ca182SThomas Graf }
1268b15ca182SThomas Graf 
1269b15ca182SThomas Graf /**
1270bfa83a9eSThomas Graf  * nla_nest_start - Start a new level of nested attributes
1271bfa83a9eSThomas Graf  * @skb: socket buffer to add attributes to
1272bfa83a9eSThomas Graf  * @attrtype: attribute type of container
1273bfa83a9eSThomas Graf  *
1274bfa83a9eSThomas Graf  * Returns the container attribute
1275bfa83a9eSThomas Graf  */
1276bfa83a9eSThomas Graf static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
1277bfa83a9eSThomas Graf {
127827a884dcSArnaldo Carvalho de Melo 	struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb);
1279bfa83a9eSThomas Graf 
1280bfa83a9eSThomas Graf 	if (nla_put(skb, attrtype, 0, NULL) < 0)
1281bfa83a9eSThomas Graf 		return NULL;
1282bfa83a9eSThomas Graf 
1283bfa83a9eSThomas Graf 	return start;
1284bfa83a9eSThomas Graf }
1285bfa83a9eSThomas Graf 
1286bfa83a9eSThomas Graf /**
1287bfa83a9eSThomas Graf  * nla_nest_end - Finalize nesting of attributes
1288d1ec3b77SPierre Ynard  * @skb: socket buffer the attributes are stored in
1289bfa83a9eSThomas Graf  * @start: container attribute
1290bfa83a9eSThomas Graf  *
1291bfa83a9eSThomas Graf  * Corrects the container attribute header to include the all
1292bfa83a9eSThomas Graf  * appeneded attributes.
1293bfa83a9eSThomas Graf  *
1294bfa83a9eSThomas Graf  * Returns the total data length of the skb.
1295bfa83a9eSThomas Graf  */
1296bfa83a9eSThomas Graf static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
1297bfa83a9eSThomas Graf {
129827a884dcSArnaldo Carvalho de Melo 	start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start;
1299bfa83a9eSThomas Graf 	return skb->len;
1300bfa83a9eSThomas Graf }
1301bfa83a9eSThomas Graf 
1302bfa83a9eSThomas Graf /**
1303bfa83a9eSThomas Graf  * nla_nest_cancel - Cancel nesting of attributes
1304bfa83a9eSThomas Graf  * @skb: socket buffer the message is stored in
1305bfa83a9eSThomas Graf  * @start: container attribute
1306bfa83a9eSThomas Graf  *
1307bfa83a9eSThomas Graf  * Removes the container attribute and including all nested
1308bc3ed28cSThomas Graf  * attributes. Returns -EMSGSIZE
1309bfa83a9eSThomas Graf  */
1310bc3ed28cSThomas Graf static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
1311bfa83a9eSThomas Graf {
1312bc3ed28cSThomas Graf 	nlmsg_trim(skb, start);
1313bfa83a9eSThomas Graf }
1314bfa83a9eSThomas Graf 
1315bfa83a9eSThomas Graf /**
13164fe5d5c0SPaul Moore  * nla_validate_nested - Validate a stream of nested attributes
13174fe5d5c0SPaul Moore  * @start: container attribute
13184fe5d5c0SPaul Moore  * @maxtype: maximum attribute type to be expected
13194fe5d5c0SPaul Moore  * @policy: validation policy
1320fceb6435SJohannes Berg  * @extack: extended ACK report struct
13214fe5d5c0SPaul Moore  *
13224fe5d5c0SPaul Moore  * Validates all attributes in the nested attribute stream against the
13234fe5d5c0SPaul Moore  * specified policy. Attributes with a type exceeding maxtype will be
13244fe5d5c0SPaul Moore  * ignored. See documenation of struct nla_policy for more details.
13254fe5d5c0SPaul Moore  *
13264fe5d5c0SPaul Moore  * Returns 0 on success or a negative error code.
13274fe5d5c0SPaul Moore  */
13283654654fSJan Engelhardt static inline int nla_validate_nested(const struct nlattr *start, int maxtype,
1329fceb6435SJohannes Berg 				      const struct nla_policy *policy,
1330fceb6435SJohannes Berg 				      struct netlink_ext_ack *extack)
13314fe5d5c0SPaul Moore {
1332fceb6435SJohannes Berg 	return nla_validate(nla_data(start), nla_len(start), maxtype, policy,
1333fceb6435SJohannes Berg 			    extack);
13344fe5d5c0SPaul Moore }
13354fe5d5c0SPaul Moore 
13364fe5d5c0SPaul Moore /**
1337089bf1a6SNicolas Dichtel  * nla_need_padding_for_64bit - test 64-bit alignment of the next attribute
1338089bf1a6SNicolas Dichtel  * @skb: socket buffer the message is stored in
1339089bf1a6SNicolas Dichtel  *
1340089bf1a6SNicolas Dichtel  * Return true if padding is needed to align the next attribute (nla_data()) to
1341089bf1a6SNicolas Dichtel  * a 64-bit aligned area.
1342089bf1a6SNicolas Dichtel  */
1343089bf1a6SNicolas Dichtel static inline bool nla_need_padding_for_64bit(struct sk_buff *skb)
1344089bf1a6SNicolas Dichtel {
1345089bf1a6SNicolas Dichtel #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
1346089bf1a6SNicolas Dichtel 	/* The nlattr header is 4 bytes in size, that's why we test
1347089bf1a6SNicolas Dichtel 	 * if the skb->data _is_ aligned.  A NOP attribute, plus
1348089bf1a6SNicolas Dichtel 	 * nlattr header for next attribute, will make nla_data()
1349089bf1a6SNicolas Dichtel 	 * 8-byte aligned.
1350089bf1a6SNicolas Dichtel 	 */
1351089bf1a6SNicolas Dichtel 	if (IS_ALIGNED((unsigned long)skb_tail_pointer(skb), 8))
1352089bf1a6SNicolas Dichtel 		return true;
1353089bf1a6SNicolas Dichtel #endif
1354089bf1a6SNicolas Dichtel 	return false;
1355089bf1a6SNicolas Dichtel }
1356089bf1a6SNicolas Dichtel 
1357089bf1a6SNicolas Dichtel /**
135835c58459SDavid S. Miller  * nla_align_64bit - 64-bit align the nla_data() of next attribute
135935c58459SDavid S. Miller  * @skb: socket buffer the message is stored in
136035c58459SDavid S. Miller  * @padattr: attribute type for the padding
136135c58459SDavid S. Miller  *
136235c58459SDavid S. Miller  * Conditionally emit a padding netlink attribute in order to make
136335c58459SDavid S. Miller  * the next attribute we emit have a 64-bit aligned nla_data() area.
136435c58459SDavid S. Miller  * This will only be done in architectures which do not have
1365cca1d815SEric Dumazet  * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS defined.
136635c58459SDavid S. Miller  *
136735c58459SDavid S. Miller  * Returns zero on success or a negative error code.
136835c58459SDavid S. Miller  */
136935c58459SDavid S. Miller static inline int nla_align_64bit(struct sk_buff *skb, int padattr)
137035c58459SDavid S. Miller {
1371089bf1a6SNicolas Dichtel 	if (nla_need_padding_for_64bit(skb) &&
1372cca1d815SEric Dumazet 	    !nla_reserve(skb, padattr, 0))
137335c58459SDavid S. Miller 		return -EMSGSIZE;
1374089bf1a6SNicolas Dichtel 
137535c58459SDavid S. Miller 	return 0;
137635c58459SDavid S. Miller }
137735c58459SDavid S. Miller 
137835c58459SDavid S. Miller /**
137935c58459SDavid S. Miller  * nla_total_size_64bit - total length of attribute including padding
138035c58459SDavid S. Miller  * @payload: length of payload
138135c58459SDavid S. Miller  */
138235c58459SDavid S. Miller static inline int nla_total_size_64bit(int payload)
138335c58459SDavid S. Miller {
138435c58459SDavid S. Miller 	return NLA_ALIGN(nla_attr_size(payload))
1385cca1d815SEric Dumazet #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
138635c58459SDavid S. Miller 		+ NLA_ALIGN(nla_attr_size(0))
138735c58459SDavid S. Miller #endif
138835c58459SDavid S. Miller 		;
138935c58459SDavid S. Miller }
139035c58459SDavid S. Miller 
139135c58459SDavid S. Miller /**
1392bfa83a9eSThomas Graf  * nla_for_each_attr - iterate over a stream of attributes
1393bfa83a9eSThomas Graf  * @pos: loop counter, set to current attribute
1394bfa83a9eSThomas Graf  * @head: head of attribute stream
1395bfa83a9eSThomas Graf  * @len: length of attribute stream
1396bfa83a9eSThomas Graf  * @rem: initialized to len, holds bytes currently remaining in stream
1397bfa83a9eSThomas Graf  */
1398bfa83a9eSThomas Graf #define nla_for_each_attr(pos, head, len, rem) \
1399bfa83a9eSThomas Graf 	for (pos = head, rem = len; \
1400bfa83a9eSThomas Graf 	     nla_ok(pos, rem); \
1401bfa83a9eSThomas Graf 	     pos = nla_next(pos, &(rem)))
1402bfa83a9eSThomas Graf 
1403fe4944e5SThomas Graf /**
1404fe4944e5SThomas Graf  * nla_for_each_nested - iterate over nested attributes
1405fe4944e5SThomas Graf  * @pos: loop counter, set to current attribute
1406fe4944e5SThomas Graf  * @nla: attribute containing the nested attributes
1407fe4944e5SThomas Graf  * @rem: initialized to len, holds bytes currently remaining in stream
1408fe4944e5SThomas Graf  */
1409fe4944e5SThomas Graf #define nla_for_each_nested(pos, nla, rem) \
1410fe4944e5SThomas Graf 	nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem)
1411fe4944e5SThomas Graf 
1412941d8ebcSSimon Horman /**
1413941d8ebcSSimon Horman  * nla_is_last - Test if attribute is last in stream
1414941d8ebcSSimon Horman  * @nla: attribute to test
1415941d8ebcSSimon Horman  * @rem: bytes remaining in stream
1416941d8ebcSSimon Horman  */
1417941d8ebcSSimon Horman static inline bool nla_is_last(const struct nlattr *nla, int rem)
1418941d8ebcSSimon Horman {
1419941d8ebcSSimon Horman 	return nla->nla_len == rem;
1420941d8ebcSSimon Horman }
1421941d8ebcSSimon Horman 
1422bfa83a9eSThomas Graf #endif
1423