xref: /aosp_15_r20/external/libnl/lib/attr.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2003-2013 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
7*4dc78e53SAndroid Build Coastguard Worker 
8*4dc78e53SAndroid Build Coastguard Worker #include <linux/socket.h>
9*4dc78e53SAndroid Build Coastguard Worker 
10*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
11*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
12*4dc78e53SAndroid Build Coastguard Worker #include <netlink/addr.h>
13*4dc78e53SAndroid Build Coastguard Worker #include <netlink/attr.h>
14*4dc78e53SAndroid Build Coastguard Worker #include <netlink/msg.h>
15*4dc78e53SAndroid Build Coastguard Worker 
16*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/nl-core.h"
17*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-core/nl-core.h"
18*4dc78e53SAndroid Build Coastguard Worker 
19*4dc78e53SAndroid Build Coastguard Worker /**
20*4dc78e53SAndroid Build Coastguard Worker  * @ingroup msg
21*4dc78e53SAndroid Build Coastguard Worker  * @defgroup attr Attributes
22*4dc78e53SAndroid Build Coastguard Worker  * Netlink Attributes Construction/Parsing Interface
23*4dc78e53SAndroid Build Coastguard Worker  *
24*4dc78e53SAndroid Build Coastguard Worker  * Related sections in the development guide:
25*4dc78e53SAndroid Build Coastguard Worker  * - @core_doc{core_attr,Netlink Attributes}
26*4dc78e53SAndroid Build Coastguard Worker  *
27*4dc78e53SAndroid Build Coastguard Worker  * @{
28*4dc78e53SAndroid Build Coastguard Worker  *
29*4dc78e53SAndroid Build Coastguard Worker  * Header
30*4dc78e53SAndroid Build Coastguard Worker  * ------
31*4dc78e53SAndroid Build Coastguard Worker  * ~~~~{.c}
32*4dc78e53SAndroid Build Coastguard Worker  * #include <netlink/attr.h>
33*4dc78e53SAndroid Build Coastguard Worker  * ~~~~
34*4dc78e53SAndroid Build Coastguard Worker  */
35*4dc78e53SAndroid Build Coastguard Worker 
36*4dc78e53SAndroid Build Coastguard Worker /**
37*4dc78e53SAndroid Build Coastguard Worker  * @name Attribute Size Calculation
38*4dc78e53SAndroid Build Coastguard Worker  * @{
39*4dc78e53SAndroid Build Coastguard Worker  */
40*4dc78e53SAndroid Build Coastguard Worker 
41*4dc78e53SAndroid Build Coastguard Worker /**
42*4dc78e53SAndroid Build Coastguard Worker  * Return size of attribute whithout padding.
43*4dc78e53SAndroid Build Coastguard Worker  * @arg payload		Payload length of attribute.
44*4dc78e53SAndroid Build Coastguard Worker  *
45*4dc78e53SAndroid Build Coastguard Worker  * @code
46*4dc78e53SAndroid Build Coastguard Worker  *    <-------- nla_attr_size(payload) --------->
47*4dc78e53SAndroid Build Coastguard Worker  *   +------------------+- - -+- - - - - - - - - +- - -+
48*4dc78e53SAndroid Build Coastguard Worker  *   | Attribute Header | Pad |     Payload      | Pad |
49*4dc78e53SAndroid Build Coastguard Worker  *   +------------------+- - -+- - - - - - - - - +- - -+
50*4dc78e53SAndroid Build Coastguard Worker  * @endcode
51*4dc78e53SAndroid Build Coastguard Worker  *
52*4dc78e53SAndroid Build Coastguard Worker  * @return Size of attribute in bytes without padding.
53*4dc78e53SAndroid Build Coastguard Worker  */
nla_attr_size(int payload)54*4dc78e53SAndroid Build Coastguard Worker int nla_attr_size(int payload)
55*4dc78e53SAndroid Build Coastguard Worker {
56*4dc78e53SAndroid Build Coastguard Worker 	return NLA_HDRLEN + payload;
57*4dc78e53SAndroid Build Coastguard Worker }
58*4dc78e53SAndroid Build Coastguard Worker 
59*4dc78e53SAndroid Build Coastguard Worker /**
60*4dc78e53SAndroid Build Coastguard Worker  * Return size of attribute including padding.
61*4dc78e53SAndroid Build Coastguard Worker  * @arg payload		Payload length of attribute.
62*4dc78e53SAndroid Build Coastguard Worker  *
63*4dc78e53SAndroid Build Coastguard Worker  * @code
64*4dc78e53SAndroid Build Coastguard Worker  *    <----------- nla_total_size(payload) ----------->
65*4dc78e53SAndroid Build Coastguard Worker  *   +------------------+- - -+- - - - - - - - - +- - -+
66*4dc78e53SAndroid Build Coastguard Worker  *   | Attribute Header | Pad |     Payload      | Pad |
67*4dc78e53SAndroid Build Coastguard Worker  *   +------------------+- - -+- - - - - - - - - +- - -+
68*4dc78e53SAndroid Build Coastguard Worker  * @endcode
69*4dc78e53SAndroid Build Coastguard Worker  *
70*4dc78e53SAndroid Build Coastguard Worker  * @return Size of attribute in bytes.
71*4dc78e53SAndroid Build Coastguard Worker  */
nla_total_size(int payload)72*4dc78e53SAndroid Build Coastguard Worker int nla_total_size(int payload)
73*4dc78e53SAndroid Build Coastguard Worker {
74*4dc78e53SAndroid Build Coastguard Worker 	return NLA_ALIGN(nla_attr_size(payload));
75*4dc78e53SAndroid Build Coastguard Worker }
76*4dc78e53SAndroid Build Coastguard Worker 
77*4dc78e53SAndroid Build Coastguard Worker /**
78*4dc78e53SAndroid Build Coastguard Worker  * Return length of padding at the tail of the attribute.
79*4dc78e53SAndroid Build Coastguard Worker  * @arg payload		Payload length of attribute.
80*4dc78e53SAndroid Build Coastguard Worker  *
81*4dc78e53SAndroid Build Coastguard Worker  * @code
82*4dc78e53SAndroid Build Coastguard Worker  *   +------------------+- - -+- - - - - - - - - +- - -+
83*4dc78e53SAndroid Build Coastguard Worker  *   | Attribute Header | Pad |     Payload      | Pad |
84*4dc78e53SAndroid Build Coastguard Worker  *   +------------------+- - -+- - - - - - - - - +- - -+
85*4dc78e53SAndroid Build Coastguard Worker  *                                                <--->
86*4dc78e53SAndroid Build Coastguard Worker  * @endcode
87*4dc78e53SAndroid Build Coastguard Worker  *
88*4dc78e53SAndroid Build Coastguard Worker  * @return Length of padding in bytes.
89*4dc78e53SAndroid Build Coastguard Worker  */
nla_padlen(int payload)90*4dc78e53SAndroid Build Coastguard Worker int nla_padlen(int payload)
91*4dc78e53SAndroid Build Coastguard Worker {
92*4dc78e53SAndroid Build Coastguard Worker 	return nla_total_size(payload) - nla_attr_size(payload);
93*4dc78e53SAndroid Build Coastguard Worker }
94*4dc78e53SAndroid Build Coastguard Worker 
95*4dc78e53SAndroid Build Coastguard Worker /** @} */
96*4dc78e53SAndroid Build Coastguard Worker 
97*4dc78e53SAndroid Build Coastguard Worker /**
98*4dc78e53SAndroid Build Coastguard Worker  * @name Parsing Attributes
99*4dc78e53SAndroid Build Coastguard Worker  * @{
100*4dc78e53SAndroid Build Coastguard Worker  */
101*4dc78e53SAndroid Build Coastguard Worker 
102*4dc78e53SAndroid Build Coastguard Worker /**
103*4dc78e53SAndroid Build Coastguard Worker  * Return type of the attribute.
104*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Attribute.
105*4dc78e53SAndroid Build Coastguard Worker  *
106*4dc78e53SAndroid Build Coastguard Worker  * @return Type of attribute.
107*4dc78e53SAndroid Build Coastguard Worker  */
nla_type(const struct nlattr * nla)108*4dc78e53SAndroid Build Coastguard Worker int nla_type(const struct nlattr *nla)
109*4dc78e53SAndroid Build Coastguard Worker {
110*4dc78e53SAndroid Build Coastguard Worker 	return nla->nla_type & NLA_TYPE_MASK;
111*4dc78e53SAndroid Build Coastguard Worker }
112*4dc78e53SAndroid Build Coastguard Worker 
113*4dc78e53SAndroid Build Coastguard Worker /**
114*4dc78e53SAndroid Build Coastguard Worker  * Return pointer to the payload section.
115*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Attribute.
116*4dc78e53SAndroid Build Coastguard Worker  *
117*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to start of payload section.
118*4dc78e53SAndroid Build Coastguard Worker  */
nla_data(const struct nlattr * nla)119*4dc78e53SAndroid Build Coastguard Worker void *nla_data(const struct nlattr *nla)
120*4dc78e53SAndroid Build Coastguard Worker {
121*4dc78e53SAndroid Build Coastguard Worker 	return (char *) nla + NLA_HDRLEN;
122*4dc78e53SAndroid Build Coastguard Worker }
123*4dc78e53SAndroid Build Coastguard Worker 
124*4dc78e53SAndroid Build Coastguard Worker /**
125*4dc78e53SAndroid Build Coastguard Worker  * Return length of the payload .
126*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Attribute
127*4dc78e53SAndroid Build Coastguard Worker  *
128*4dc78e53SAndroid Build Coastguard Worker  * @return Length of payload in bytes.
129*4dc78e53SAndroid Build Coastguard Worker  */
nla_len(const struct nlattr * nla)130*4dc78e53SAndroid Build Coastguard Worker int nla_len(const struct nlattr *nla)
131*4dc78e53SAndroid Build Coastguard Worker {
132*4dc78e53SAndroid Build Coastguard Worker 	return _nla_len(nla);
133*4dc78e53SAndroid Build Coastguard Worker }
134*4dc78e53SAndroid Build Coastguard Worker 
135*4dc78e53SAndroid Build Coastguard Worker /**
136*4dc78e53SAndroid Build Coastguard Worker  * Check if the attribute header and payload can be accessed safely.
137*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Attribute of any kind.
138*4dc78e53SAndroid Build Coastguard Worker  * @arg remaining	Number of bytes remaining in attribute stream.
139*4dc78e53SAndroid Build Coastguard Worker  *
140*4dc78e53SAndroid Build Coastguard Worker  * Verifies that the header and payload do not exceed the number of
141*4dc78e53SAndroid Build Coastguard Worker  * bytes left in the attribute stream. This function must be called
142*4dc78e53SAndroid Build Coastguard Worker  * before access the attribute header or payload when iterating over
143*4dc78e53SAndroid Build Coastguard Worker  * the attribute stream using nla_next().
144*4dc78e53SAndroid Build Coastguard Worker  *
145*4dc78e53SAndroid Build Coastguard Worker  * @return True if the attribute can be accessed safely, false otherwise.
146*4dc78e53SAndroid Build Coastguard Worker  */
nla_ok(const struct nlattr * nla,int remaining)147*4dc78e53SAndroid Build Coastguard Worker int nla_ok(const struct nlattr *nla, int remaining)
148*4dc78e53SAndroid Build Coastguard Worker {
149*4dc78e53SAndroid Build Coastguard Worker 	_NL_STATIC_ASSERT(sizeof(*nla) == NLA_HDRLEN);
150*4dc78e53SAndroid Build Coastguard Worker 
151*4dc78e53SAndroid Build Coastguard Worker 	return remaining >= (int) sizeof(*nla) &&
152*4dc78e53SAndroid Build Coastguard Worker 	       nla->nla_len >= sizeof(*nla) &&
153*4dc78e53SAndroid Build Coastguard Worker 	       nla->nla_len <= remaining;
154*4dc78e53SAndroid Build Coastguard Worker }
155*4dc78e53SAndroid Build Coastguard Worker 
156*4dc78e53SAndroid Build Coastguard Worker /**
157*4dc78e53SAndroid Build Coastguard Worker  * Return next attribute in a stream of attributes.
158*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Attribute of any kind.
159*4dc78e53SAndroid Build Coastguard Worker  * @arg remaining	Variable to count remaining bytes in stream.
160*4dc78e53SAndroid Build Coastguard Worker  *
161*4dc78e53SAndroid Build Coastguard Worker  * Calculates the offset to the next attribute based on the attribute
162*4dc78e53SAndroid Build Coastguard Worker  * given. The attribute provided is assumed to be accessible, the
163*4dc78e53SAndroid Build Coastguard Worker  * caller is responsible to use nla_ok() beforehand. The offset (length
164*4dc78e53SAndroid Build Coastguard Worker  * of specified attribute including padding) is then subtracted from
165*4dc78e53SAndroid Build Coastguard Worker  * the remaining bytes variable and a pointer to the next attribute is
166*4dc78e53SAndroid Build Coastguard Worker  * returned.
167*4dc78e53SAndroid Build Coastguard Worker  *
168*4dc78e53SAndroid Build Coastguard Worker  * nla_next() can be called as long as remainig is >0.
169*4dc78e53SAndroid Build Coastguard Worker  *
170*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to next attribute.
171*4dc78e53SAndroid Build Coastguard Worker  */
nla_next(const struct nlattr * nla,int * remaining)172*4dc78e53SAndroid Build Coastguard Worker struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
173*4dc78e53SAndroid Build Coastguard Worker {
174*4dc78e53SAndroid Build Coastguard Worker 	int totlen = NLA_ALIGN(nla->nla_len);
175*4dc78e53SAndroid Build Coastguard Worker 
176*4dc78e53SAndroid Build Coastguard Worker 	*remaining -= totlen;
177*4dc78e53SAndroid Build Coastguard Worker 	return (struct nlattr *) ((char *) nla + totlen);
178*4dc78e53SAndroid Build Coastguard Worker }
179*4dc78e53SAndroid Build Coastguard Worker 
180*4dc78e53SAndroid Build Coastguard Worker static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
181*4dc78e53SAndroid Build Coastguard Worker 	[NLA_U8]	= sizeof(uint8_t),
182*4dc78e53SAndroid Build Coastguard Worker 	[NLA_U16]	= sizeof(uint16_t),
183*4dc78e53SAndroid Build Coastguard Worker 	[NLA_U32]	= sizeof(uint32_t),
184*4dc78e53SAndroid Build Coastguard Worker 	[NLA_U64]	= sizeof(uint64_t),
185*4dc78e53SAndroid Build Coastguard Worker 	[NLA_STRING]	= 1,
186*4dc78e53SAndroid Build Coastguard Worker 	[NLA_FLAG]	= 0,
187*4dc78e53SAndroid Build Coastguard Worker };
188*4dc78e53SAndroid Build Coastguard Worker 
validate_nla(const struct nlattr * nla,int maxtype,const struct nla_policy * policy)189*4dc78e53SAndroid Build Coastguard Worker static int validate_nla(const struct nlattr *nla, int maxtype,
190*4dc78e53SAndroid Build Coastguard Worker 			const struct nla_policy *policy)
191*4dc78e53SAndroid Build Coastguard Worker {
192*4dc78e53SAndroid Build Coastguard Worker 	const struct nla_policy *pt;
193*4dc78e53SAndroid Build Coastguard Worker 	unsigned int minlen = 0;
194*4dc78e53SAndroid Build Coastguard Worker 	int type = nla_type(nla);
195*4dc78e53SAndroid Build Coastguard Worker 
196*4dc78e53SAndroid Build Coastguard Worker 	if (type < 0 || type > maxtype)
197*4dc78e53SAndroid Build Coastguard Worker 		return 0;
198*4dc78e53SAndroid Build Coastguard Worker 
199*4dc78e53SAndroid Build Coastguard Worker 	pt = &policy[type];
200*4dc78e53SAndroid Build Coastguard Worker 
201*4dc78e53SAndroid Build Coastguard Worker 	if (pt->type > NLA_TYPE_MAX)
202*4dc78e53SAndroid Build Coastguard Worker 		BUG();
203*4dc78e53SAndroid Build Coastguard Worker 
204*4dc78e53SAndroid Build Coastguard Worker 	if (pt->minlen)
205*4dc78e53SAndroid Build Coastguard Worker 		minlen = pt->minlen;
206*4dc78e53SAndroid Build Coastguard Worker 	else if (pt->type != NLA_UNSPEC)
207*4dc78e53SAndroid Build Coastguard Worker 		minlen = nla_attr_minlen[pt->type];
208*4dc78e53SAndroid Build Coastguard Worker 
209*4dc78e53SAndroid Build Coastguard Worker 	if (_nla_len(nla) < minlen)
210*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
211*4dc78e53SAndroid Build Coastguard Worker 
212*4dc78e53SAndroid Build Coastguard Worker 	if (pt->maxlen && nla_len(nla) > pt->maxlen)
213*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
214*4dc78e53SAndroid Build Coastguard Worker 
215*4dc78e53SAndroid Build Coastguard Worker 	if (pt->type == NLA_STRING) {
216*4dc78e53SAndroid Build Coastguard Worker 		const char *data = nla_data(nla);
217*4dc78e53SAndroid Build Coastguard Worker 		if (data[nla_len(nla) - 1] != '\0')
218*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_INVAL;
219*4dc78e53SAndroid Build Coastguard Worker 	}
220*4dc78e53SAndroid Build Coastguard Worker 
221*4dc78e53SAndroid Build Coastguard Worker 	return 0;
222*4dc78e53SAndroid Build Coastguard Worker }
223*4dc78e53SAndroid Build Coastguard Worker 
224*4dc78e53SAndroid Build Coastguard Worker 
225*4dc78e53SAndroid Build Coastguard Worker /**
226*4dc78e53SAndroid Build Coastguard Worker  * Create attribute index based on a stream of attributes.
227*4dc78e53SAndroid Build Coastguard Worker  * @arg tb		Index array to be filled (maxtype+1 elements).
228*4dc78e53SAndroid Build Coastguard Worker  * @arg maxtype		Maximum attribute type expected and accepted.
229*4dc78e53SAndroid Build Coastguard Worker  * @arg head		Head of attribute stream.
230*4dc78e53SAndroid Build Coastguard Worker  * @arg len		Length of attribute stream.
231*4dc78e53SAndroid Build Coastguard Worker  * @arg policy		Attribute validation policy.
232*4dc78e53SAndroid Build Coastguard Worker  *
233*4dc78e53SAndroid Build Coastguard Worker  * Iterates over the stream of attributes and stores a pointer to each
234*4dc78e53SAndroid Build Coastguard Worker  * attribute in the index array using the attribute type as index to
235*4dc78e53SAndroid Build Coastguard Worker  * the array. Attribute with a type greater than the maximum type
236*4dc78e53SAndroid Build Coastguard Worker  * specified will be silently ignored in order to maintain backwards
237*4dc78e53SAndroid Build Coastguard Worker  * compatibility. If \a policy is not NULL, the attribute will be
238*4dc78e53SAndroid Build Coastguard Worker  * validated using the specified policy.
239*4dc78e53SAndroid Build Coastguard Worker  *
240*4dc78e53SAndroid Build Coastguard Worker  * @see nla_validate
241*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
242*4dc78e53SAndroid Build Coastguard Worker  */
nla_parse(struct nlattr * tb[],int maxtype,struct nlattr * head,int len,const struct nla_policy * policy)243*4dc78e53SAndroid Build Coastguard Worker int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
244*4dc78e53SAndroid Build Coastguard Worker 	      const struct nla_policy *policy)
245*4dc78e53SAndroid Build Coastguard Worker {
246*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *nla;
247*4dc78e53SAndroid Build Coastguard Worker 	int rem, err;
248*4dc78e53SAndroid Build Coastguard Worker 
249*4dc78e53SAndroid Build Coastguard Worker 	memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
250*4dc78e53SAndroid Build Coastguard Worker 
251*4dc78e53SAndroid Build Coastguard Worker 	nla_for_each_attr(nla, head, len, rem) {
252*4dc78e53SAndroid Build Coastguard Worker 		int type = nla_type(nla);
253*4dc78e53SAndroid Build Coastguard Worker 
254*4dc78e53SAndroid Build Coastguard Worker 		if (type > maxtype)
255*4dc78e53SAndroid Build Coastguard Worker 			continue;
256*4dc78e53SAndroid Build Coastguard Worker 
257*4dc78e53SAndroid Build Coastguard Worker 		if (policy) {
258*4dc78e53SAndroid Build Coastguard Worker 			err = validate_nla(nla, maxtype, policy);
259*4dc78e53SAndroid Build Coastguard Worker 			if (err < 0)
260*4dc78e53SAndroid Build Coastguard Worker 				return err;
261*4dc78e53SAndroid Build Coastguard Worker 		}
262*4dc78e53SAndroid Build Coastguard Worker 
263*4dc78e53SAndroid Build Coastguard Worker 		if (tb[type])
264*4dc78e53SAndroid Build Coastguard Worker 			NL_DBG(1, "Attribute of type %#x found multiple times in message, "
265*4dc78e53SAndroid Build Coastguard Worker 				  "previous attribute is being ignored.\n", type);
266*4dc78e53SAndroid Build Coastguard Worker 
267*4dc78e53SAndroid Build Coastguard Worker 		tb[type] = nla;
268*4dc78e53SAndroid Build Coastguard Worker 	}
269*4dc78e53SAndroid Build Coastguard Worker 
270*4dc78e53SAndroid Build Coastguard Worker 	if (rem > 0) {
271*4dc78e53SAndroid Build Coastguard Worker 		NL_DBG(1, "netlink: %d bytes leftover after parsing "
272*4dc78e53SAndroid Build Coastguard Worker 		       "attributes.\n", rem);
273*4dc78e53SAndroid Build Coastguard Worker 	}
274*4dc78e53SAndroid Build Coastguard Worker 
275*4dc78e53SAndroid Build Coastguard Worker 	return 0;
276*4dc78e53SAndroid Build Coastguard Worker }
277*4dc78e53SAndroid Build Coastguard Worker 
278*4dc78e53SAndroid Build Coastguard Worker /**
279*4dc78e53SAndroid Build Coastguard Worker  * Validate a stream of attributes.
280*4dc78e53SAndroid Build Coastguard Worker  * @arg head		Head of attributes stream.
281*4dc78e53SAndroid Build Coastguard Worker  * @arg len		Length of attributes stream.
282*4dc78e53SAndroid Build Coastguard Worker  * @arg maxtype		Maximum attribute type expected and accepted.
283*4dc78e53SAndroid Build Coastguard Worker  * @arg policy		Validation policy.
284*4dc78e53SAndroid Build Coastguard Worker  *
285*4dc78e53SAndroid Build Coastguard Worker  * Iterates over the stream of attributes and validates each attribute
286*4dc78e53SAndroid Build Coastguard Worker  * one by one using the specified policy. Attributes with a type greater
287*4dc78e53SAndroid Build Coastguard Worker  * than the maximum type specified will be silently ignored in order to
288*4dc78e53SAndroid Build Coastguard Worker  * maintain backwards compatibility.
289*4dc78e53SAndroid Build Coastguard Worker  *
290*4dc78e53SAndroid Build Coastguard Worker  * See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
291*4dc78e53SAndroid Build Coastguard Worker  *
292*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
293*4dc78e53SAndroid Build Coastguard Worker  */
nla_validate(const struct nlattr * head,int len,int maxtype,const struct nla_policy * policy)294*4dc78e53SAndroid Build Coastguard Worker int nla_validate(const struct nlattr *head, int len, int maxtype,
295*4dc78e53SAndroid Build Coastguard Worker 		 const struct nla_policy *policy)
296*4dc78e53SAndroid Build Coastguard Worker {
297*4dc78e53SAndroid Build Coastguard Worker 	const struct nlattr *nla;
298*4dc78e53SAndroid Build Coastguard Worker 	int rem, err;
299*4dc78e53SAndroid Build Coastguard Worker 
300*4dc78e53SAndroid Build Coastguard Worker 	nla_for_each_attr(nla, head, len, rem) {
301*4dc78e53SAndroid Build Coastguard Worker 		err = validate_nla(nla, maxtype, policy);
302*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
303*4dc78e53SAndroid Build Coastguard Worker 			goto errout;
304*4dc78e53SAndroid Build Coastguard Worker 	}
305*4dc78e53SAndroid Build Coastguard Worker 
306*4dc78e53SAndroid Build Coastguard Worker 	err = 0;
307*4dc78e53SAndroid Build Coastguard Worker errout:
308*4dc78e53SAndroid Build Coastguard Worker 	return err;
309*4dc78e53SAndroid Build Coastguard Worker }
310*4dc78e53SAndroid Build Coastguard Worker 
311*4dc78e53SAndroid Build Coastguard Worker /**
312*4dc78e53SAndroid Build Coastguard Worker  * Find a single attribute in a stream of attributes.
313*4dc78e53SAndroid Build Coastguard Worker  * @arg head		Head of attributes stream.
314*4dc78e53SAndroid Build Coastguard Worker  * @arg len		Length of attributes stream.
315*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type to look for.
316*4dc78e53SAndroid Build Coastguard Worker  *
317*4dc78e53SAndroid Build Coastguard Worker  * Iterates over the stream of attributes and compares each type with
318*4dc78e53SAndroid Build Coastguard Worker  * the type specified. Returns the first attribute which matches the
319*4dc78e53SAndroid Build Coastguard Worker  * type.
320*4dc78e53SAndroid Build Coastguard Worker  *
321*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to attribute found or NULL.
322*4dc78e53SAndroid Build Coastguard Worker  */
nla_find(const struct nlattr * head,int len,int attrtype)323*4dc78e53SAndroid Build Coastguard Worker struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
324*4dc78e53SAndroid Build Coastguard Worker {
325*4dc78e53SAndroid Build Coastguard Worker 	const struct nlattr *nla;
326*4dc78e53SAndroid Build Coastguard Worker 	int rem;
327*4dc78e53SAndroid Build Coastguard Worker 
328*4dc78e53SAndroid Build Coastguard Worker 	nla_for_each_attr(nla, head, len, rem)
329*4dc78e53SAndroid Build Coastguard Worker 		if (nla_type(nla) == attrtype)
330*4dc78e53SAndroid Build Coastguard Worker 			return (struct nlattr*)nla;
331*4dc78e53SAndroid Build Coastguard Worker 
332*4dc78e53SAndroid Build Coastguard Worker 	return NULL;
333*4dc78e53SAndroid Build Coastguard Worker }
334*4dc78e53SAndroid Build Coastguard Worker 
335*4dc78e53SAndroid Build Coastguard Worker /** @} */
336*4dc78e53SAndroid Build Coastguard Worker 
337*4dc78e53SAndroid Build Coastguard Worker /**
338*4dc78e53SAndroid Build Coastguard Worker  * @name Helper Functions
339*4dc78e53SAndroid Build Coastguard Worker  * @{
340*4dc78e53SAndroid Build Coastguard Worker  */
341*4dc78e53SAndroid Build Coastguard Worker 
342*4dc78e53SAndroid Build Coastguard Worker /**
343*4dc78e53SAndroid Build Coastguard Worker  * Copy attribute payload to another memory area.
344*4dc78e53SAndroid Build Coastguard Worker  * @arg dest		Pointer to destination memory area.
345*4dc78e53SAndroid Build Coastguard Worker  * @arg src		Attribute
346*4dc78e53SAndroid Build Coastguard Worker  * @arg count		Number of bytes to copy at most.
347*4dc78e53SAndroid Build Coastguard Worker  *
348*4dc78e53SAndroid Build Coastguard Worker  * Note: The number of bytes copied is limited by the length of
349*4dc78e53SAndroid Build Coastguard Worker  *       the attribute payload.
350*4dc78e53SAndroid Build Coastguard Worker  *
351*4dc78e53SAndroid Build Coastguard Worker  * @return The number of bytes copied to dest.
352*4dc78e53SAndroid Build Coastguard Worker  */
nla_memcpy(void * dest,const struct nlattr * src,int count)353*4dc78e53SAndroid Build Coastguard Worker int nla_memcpy(void *dest, const struct nlattr *src, int count)
354*4dc78e53SAndroid Build Coastguard Worker {
355*4dc78e53SAndroid Build Coastguard Worker 	int minlen;
356*4dc78e53SAndroid Build Coastguard Worker 
357*4dc78e53SAndroid Build Coastguard Worker 	if (!src)
358*4dc78e53SAndroid Build Coastguard Worker 		return 0;
359*4dc78e53SAndroid Build Coastguard Worker 
360*4dc78e53SAndroid Build Coastguard Worker 	minlen = _NL_MIN(count, nla_len(src));
361*4dc78e53SAndroid Build Coastguard Worker 
362*4dc78e53SAndroid Build Coastguard Worker 	if (minlen <= 0)
363*4dc78e53SAndroid Build Coastguard Worker 		return 0;
364*4dc78e53SAndroid Build Coastguard Worker 
365*4dc78e53SAndroid Build Coastguard Worker 	memcpy(dest, nla_data(src), minlen);
366*4dc78e53SAndroid Build Coastguard Worker 	return minlen;
367*4dc78e53SAndroid Build Coastguard Worker }
368*4dc78e53SAndroid Build Coastguard Worker 
369*4dc78e53SAndroid Build Coastguard Worker /**
370*4dc78e53SAndroid Build Coastguard Worker  * Copy string attribute payload to a buffer.
371*4dc78e53SAndroid Build Coastguard Worker  * @arg dst		Pointer to destination buffer.
372*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Attribute of type NLA_STRING.
373*4dc78e53SAndroid Build Coastguard Worker  * @arg dstsize		Size of destination buffer in bytes.
374*4dc78e53SAndroid Build Coastguard Worker  *
375*4dc78e53SAndroid Build Coastguard Worker  * Copies at most dstsize - 1 bytes to the destination buffer.
376*4dc78e53SAndroid Build Coastguard Worker  * The result is always a valid NUL terminated string. Unlike
377*4dc78e53SAndroid Build Coastguard Worker  * strlcpy the destination buffer is always padded out.
378*4dc78e53SAndroid Build Coastguard Worker  *
379*4dc78e53SAndroid Build Coastguard Worker  * @return The length of string attribute without the terminating NUL.
380*4dc78e53SAndroid Build Coastguard Worker  */
nla_strlcpy(char * dst,const struct nlattr * nla,size_t dstsize)381*4dc78e53SAndroid Build Coastguard Worker size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
382*4dc78e53SAndroid Build Coastguard Worker {
383*4dc78e53SAndroid Build Coastguard Worker 	size_t srclen = nla_len(nla);
384*4dc78e53SAndroid Build Coastguard Worker 	const char *src = nla_data(nla);
385*4dc78e53SAndroid Build Coastguard Worker 
386*4dc78e53SAndroid Build Coastguard Worker 	if (srclen > 0 && src[srclen - 1] == '\0')
387*4dc78e53SAndroid Build Coastguard Worker 		srclen--;
388*4dc78e53SAndroid Build Coastguard Worker 
389*4dc78e53SAndroid Build Coastguard Worker 	if (dstsize > 0) {
390*4dc78e53SAndroid Build Coastguard Worker 		size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
391*4dc78e53SAndroid Build Coastguard Worker 
392*4dc78e53SAndroid Build Coastguard Worker 		memset(dst, 0, dstsize);
393*4dc78e53SAndroid Build Coastguard Worker 		memcpy(dst, src, len);
394*4dc78e53SAndroid Build Coastguard Worker 	}
395*4dc78e53SAndroid Build Coastguard Worker 
396*4dc78e53SAndroid Build Coastguard Worker 	return srclen;
397*4dc78e53SAndroid Build Coastguard Worker }
398*4dc78e53SAndroid Build Coastguard Worker 
399*4dc78e53SAndroid Build Coastguard Worker /**
400*4dc78e53SAndroid Build Coastguard Worker  * Compare attribute payload with memory area.
401*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Attribute.
402*4dc78e53SAndroid Build Coastguard Worker  * @arg data		Memory area to compare to.
403*4dc78e53SAndroid Build Coastguard Worker  * @arg size		Number of bytes to compare.
404*4dc78e53SAndroid Build Coastguard Worker  *
405*4dc78e53SAndroid Build Coastguard Worker  * @see memcmp(3)
406*4dc78e53SAndroid Build Coastguard Worker  * @return An integer less than, equal to, or greater than zero.
407*4dc78e53SAndroid Build Coastguard Worker  */
nla_memcmp(const struct nlattr * nla,const void * data,size_t size)408*4dc78e53SAndroid Build Coastguard Worker int nla_memcmp(const struct nlattr *nla, const void *data, size_t size)
409*4dc78e53SAndroid Build Coastguard Worker {
410*4dc78e53SAndroid Build Coastguard Worker 	int d = nla_len(nla) - size;
411*4dc78e53SAndroid Build Coastguard Worker 
412*4dc78e53SAndroid Build Coastguard Worker 	if (d == 0)
413*4dc78e53SAndroid Build Coastguard Worker 		d = memcmp(nla_data(nla), data, size);
414*4dc78e53SAndroid Build Coastguard Worker 
415*4dc78e53SAndroid Build Coastguard Worker 	return d;
416*4dc78e53SAndroid Build Coastguard Worker }
417*4dc78e53SAndroid Build Coastguard Worker 
418*4dc78e53SAndroid Build Coastguard Worker /**
419*4dc78e53SAndroid Build Coastguard Worker  * Compare string attribute payload with string
420*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Attribute of type NLA_STRING.
421*4dc78e53SAndroid Build Coastguard Worker  * @arg str		NUL terminated string.
422*4dc78e53SAndroid Build Coastguard Worker  *
423*4dc78e53SAndroid Build Coastguard Worker  * @see strcmp(3)
424*4dc78e53SAndroid Build Coastguard Worker  * @return An integer less than, equal to, or greater than zero.
425*4dc78e53SAndroid Build Coastguard Worker  */
nla_strcmp(const struct nlattr * nla,const char * str)426*4dc78e53SAndroid Build Coastguard Worker int nla_strcmp(const struct nlattr *nla, const char *str)
427*4dc78e53SAndroid Build Coastguard Worker {
428*4dc78e53SAndroid Build Coastguard Worker 	int len = strlen(str) + 1;
429*4dc78e53SAndroid Build Coastguard Worker 	int d = nla_len(nla) - len;
430*4dc78e53SAndroid Build Coastguard Worker 
431*4dc78e53SAndroid Build Coastguard Worker 	if (d == 0)
432*4dc78e53SAndroid Build Coastguard Worker 		d = memcmp(nla_data(nla), str, len);
433*4dc78e53SAndroid Build Coastguard Worker 
434*4dc78e53SAndroid Build Coastguard Worker 	return d;
435*4dc78e53SAndroid Build Coastguard Worker }
436*4dc78e53SAndroid Build Coastguard Worker 
437*4dc78e53SAndroid Build Coastguard Worker /** @} */
438*4dc78e53SAndroid Build Coastguard Worker 
439*4dc78e53SAndroid Build Coastguard Worker /**
440*4dc78e53SAndroid Build Coastguard Worker  * @name Unspecific Attribute
441*4dc78e53SAndroid Build Coastguard Worker  * @{
442*4dc78e53SAndroid Build Coastguard Worker  */
443*4dc78e53SAndroid Build Coastguard Worker 
444*4dc78e53SAndroid Build Coastguard Worker /**
445*4dc78e53SAndroid Build Coastguard Worker  * Reserve space for a attribute.
446*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink Message.
447*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute Type.
448*4dc78e53SAndroid Build Coastguard Worker  * @arg attrlen		Length of payload.
449*4dc78e53SAndroid Build Coastguard Worker  *
450*4dc78e53SAndroid Build Coastguard Worker  * Reserves room for a attribute in the specified netlink message and
451*4dc78e53SAndroid Build Coastguard Worker  * fills in the attribute header (type, length). Returns NULL if there
452*4dc78e53SAndroid Build Coastguard Worker  * is unsuficient space for the attribute.
453*4dc78e53SAndroid Build Coastguard Worker  *
454*4dc78e53SAndroid Build Coastguard Worker  * Any padding between payload and the start of the next attribute is
455*4dc78e53SAndroid Build Coastguard Worker  * zeroed out.
456*4dc78e53SAndroid Build Coastguard Worker  *
457*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to start of attribute or NULL on failure.
458*4dc78e53SAndroid Build Coastguard Worker  */
nla_reserve(struct nl_msg * msg,int attrtype,int attrlen)459*4dc78e53SAndroid Build Coastguard Worker struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen)
460*4dc78e53SAndroid Build Coastguard Worker {
461*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *nla;
462*4dc78e53SAndroid Build Coastguard Worker 	size_t tlen;
463*4dc78e53SAndroid Build Coastguard Worker 
464*4dc78e53SAndroid Build Coastguard Worker 	if (attrlen < 0)
465*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
466*4dc78e53SAndroid Build Coastguard Worker 
467*4dc78e53SAndroid Build Coastguard Worker 	tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
468*4dc78e53SAndroid Build Coastguard Worker 
469*4dc78e53SAndroid Build Coastguard Worker 	if (tlen > msg->nm_size || tlen > UINT32_MAX)
470*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
471*4dc78e53SAndroid Build Coastguard Worker 
472*4dc78e53SAndroid Build Coastguard Worker 	nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
473*4dc78e53SAndroid Build Coastguard Worker 	nla->nla_type = attrtype;
474*4dc78e53SAndroid Build Coastguard Worker 	nla->nla_len = nla_attr_size(attrlen);
475*4dc78e53SAndroid Build Coastguard Worker 
476*4dc78e53SAndroid Build Coastguard Worker 	if (attrlen)
477*4dc78e53SAndroid Build Coastguard Worker 		memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
478*4dc78e53SAndroid Build Coastguard Worker 	msg->nm_nlh->nlmsg_len = tlen;
479*4dc78e53SAndroid Build Coastguard Worker 
480*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(2, "msg %p: attr <%p> %d: Reserved %d (%d) bytes at offset +%td "
481*4dc78e53SAndroid Build Coastguard Worker 		  "nlmsg_len=%d\n", msg, nla, nla->nla_type,
482*4dc78e53SAndroid Build Coastguard Worker 		  nla_total_size(attrlen), attrlen,
483*4dc78e53SAndroid Build Coastguard Worker 		  (char *) nla - (char *) nlmsg_data(msg->nm_nlh),
484*4dc78e53SAndroid Build Coastguard Worker 		  msg->nm_nlh->nlmsg_len);
485*4dc78e53SAndroid Build Coastguard Worker 
486*4dc78e53SAndroid Build Coastguard Worker 	return nla;
487*4dc78e53SAndroid Build Coastguard Worker }
488*4dc78e53SAndroid Build Coastguard Worker 
489*4dc78e53SAndroid Build Coastguard Worker /**
490*4dc78e53SAndroid Build Coastguard Worker  * Add a unspecific attribute to netlink message.
491*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
492*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
493*4dc78e53SAndroid Build Coastguard Worker  * @arg datalen		Length of data to be used as payload.
494*4dc78e53SAndroid Build Coastguard Worker  * @arg data		Pointer to data to be used as attribute payload.
495*4dc78e53SAndroid Build Coastguard Worker  *
496*4dc78e53SAndroid Build Coastguard Worker  * Reserves room for a unspecific attribute and copies the provided data
497*4dc78e53SAndroid Build Coastguard Worker  * into the message as payload of the attribute. Returns an error if there
498*4dc78e53SAndroid Build Coastguard Worker  * is insufficient space for the attribute.
499*4dc78e53SAndroid Build Coastguard Worker  *
500*4dc78e53SAndroid Build Coastguard Worker  * @see nla_reserve
501*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
502*4dc78e53SAndroid Build Coastguard Worker  */
nla_put(struct nl_msg * msg,int attrtype,int datalen,const void * data)503*4dc78e53SAndroid Build Coastguard Worker int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
504*4dc78e53SAndroid Build Coastguard Worker {
505*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *nla;
506*4dc78e53SAndroid Build Coastguard Worker 
507*4dc78e53SAndroid Build Coastguard Worker 	nla = nla_reserve(msg, attrtype, datalen);
508*4dc78e53SAndroid Build Coastguard Worker 	if (!nla) {
509*4dc78e53SAndroid Build Coastguard Worker 		if (datalen < 0)
510*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_INVAL;
511*4dc78e53SAndroid Build Coastguard Worker 
512*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
513*4dc78e53SAndroid Build Coastguard Worker 	}
514*4dc78e53SAndroid Build Coastguard Worker 
515*4dc78e53SAndroid Build Coastguard Worker 	if (datalen > 0) {
516*4dc78e53SAndroid Build Coastguard Worker 		memcpy(nla_data(nla), data, datalen);
517*4dc78e53SAndroid Build Coastguard Worker 		NL_DBG(2, "msg %p: attr <%p> %d: Wrote %d bytes at offset +%td\n",
518*4dc78e53SAndroid Build Coastguard Worker 		       msg, nla, nla->nla_type, datalen,
519*4dc78e53SAndroid Build Coastguard Worker 		       (char *) nla - (char *) nlmsg_data(msg->nm_nlh));
520*4dc78e53SAndroid Build Coastguard Worker 	}
521*4dc78e53SAndroid Build Coastguard Worker 
522*4dc78e53SAndroid Build Coastguard Worker 	return 0;
523*4dc78e53SAndroid Build Coastguard Worker }
524*4dc78e53SAndroid Build Coastguard Worker 
525*4dc78e53SAndroid Build Coastguard Worker /**
526*4dc78e53SAndroid Build Coastguard Worker  * Add abstract data as unspecific attribute to netlink message.
527*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
528*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
529*4dc78e53SAndroid Build Coastguard Worker  * @arg data		Abstract data object.
530*4dc78e53SAndroid Build Coastguard Worker  *
531*4dc78e53SAndroid Build Coastguard Worker  * Equivalent to nla_put() except that the length of the payload is
532*4dc78e53SAndroid Build Coastguard Worker  * derived from the abstract data object.
533*4dc78e53SAndroid Build Coastguard Worker  *
534*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
535*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
536*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_data(struct nl_msg * msg,int attrtype,const struct nl_data * data)537*4dc78e53SAndroid Build Coastguard Worker int nla_put_data(struct nl_msg *msg, int attrtype, const struct nl_data *data)
538*4dc78e53SAndroid Build Coastguard Worker {
539*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, nl_data_get_size(data),
540*4dc78e53SAndroid Build Coastguard Worker 		       nl_data_get(data));
541*4dc78e53SAndroid Build Coastguard Worker }
542*4dc78e53SAndroid Build Coastguard Worker 
543*4dc78e53SAndroid Build Coastguard Worker /**
544*4dc78e53SAndroid Build Coastguard Worker  * Add abstract address as unspecific attribute to netlink message.
545*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
546*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
547*4dc78e53SAndroid Build Coastguard Worker  * @arg addr		Abstract address object.
548*4dc78e53SAndroid Build Coastguard Worker  *
549*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
550*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
551*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_addr(struct nl_msg * msg,int attrtype,struct nl_addr * addr)552*4dc78e53SAndroid Build Coastguard Worker int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr)
553*4dc78e53SAndroid Build Coastguard Worker {
554*4dc78e53SAndroid Build Coastguard Worker 	if (nl_addr_get_len(addr) == 0)
555*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
556*4dc78e53SAndroid Build Coastguard Worker 
557*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, nl_addr_get_len(addr),
558*4dc78e53SAndroid Build Coastguard Worker 		       nl_addr_get_binary_addr(addr));
559*4dc78e53SAndroid Build Coastguard Worker }
560*4dc78e53SAndroid Build Coastguard Worker 
561*4dc78e53SAndroid Build Coastguard Worker /** @} */
562*4dc78e53SAndroid Build Coastguard Worker 
563*4dc78e53SAndroid Build Coastguard Worker /**
564*4dc78e53SAndroid Build Coastguard Worker  * @name Integer Attributes
565*4dc78e53SAndroid Build Coastguard Worker  */
566*4dc78e53SAndroid Build Coastguard Worker 
567*4dc78e53SAndroid Build Coastguard Worker /**
568*4dc78e53SAndroid Build Coastguard Worker  * Add 8 bit signed integer attribute to netlink message.
569*4dc78e53SAndroid Build Coastguard Worker  * @arg msg             Netlink message.
570*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype        Attribute type.
571*4dc78e53SAndroid Build Coastguard Worker  * @arg value           Numeric value to store as payload.
572*4dc78e53SAndroid Build Coastguard Worker  *
573*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
574*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
575*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_s8(struct nl_msg * msg,int attrtype,int8_t value)576*4dc78e53SAndroid Build Coastguard Worker int nla_put_s8(struct nl_msg *msg, int attrtype, int8_t value)
577*4dc78e53SAndroid Build Coastguard Worker {
578*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, sizeof(int8_t), &value);
579*4dc78e53SAndroid Build Coastguard Worker }
580*4dc78e53SAndroid Build Coastguard Worker 
581*4dc78e53SAndroid Build Coastguard Worker /**
582*4dc78e53SAndroid Build Coastguard Worker  * Return value of 8 bit signed integer attribute.
583*4dc78e53SAndroid Build Coastguard Worker  * @arg nla             8 bit integer attribute
584*4dc78e53SAndroid Build Coastguard Worker  *
585*4dc78e53SAndroid Build Coastguard Worker  * @return Payload as 8 bit integer.
586*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_s8(const struct nlattr * nla)587*4dc78e53SAndroid Build Coastguard Worker int8_t nla_get_s8(const struct nlattr *nla)
588*4dc78e53SAndroid Build Coastguard Worker {
589*4dc78e53SAndroid Build Coastguard Worker 	return *(const int8_t *) nla_data(nla);
590*4dc78e53SAndroid Build Coastguard Worker }
591*4dc78e53SAndroid Build Coastguard Worker 
592*4dc78e53SAndroid Build Coastguard Worker /**
593*4dc78e53SAndroid Build Coastguard Worker  * Add 8 bit integer attribute to netlink message.
594*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
595*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
596*4dc78e53SAndroid Build Coastguard Worker  * @arg value		Numeric value to store as payload.
597*4dc78e53SAndroid Build Coastguard Worker  *
598*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
599*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
600*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_u8(struct nl_msg * msg,int attrtype,uint8_t value)601*4dc78e53SAndroid Build Coastguard Worker int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value)
602*4dc78e53SAndroid Build Coastguard Worker {
603*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, sizeof(uint8_t), &value);
604*4dc78e53SAndroid Build Coastguard Worker }
605*4dc78e53SAndroid Build Coastguard Worker 
606*4dc78e53SAndroid Build Coastguard Worker /**
607*4dc78e53SAndroid Build Coastguard Worker  * Return value of 8 bit integer attribute.
608*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		8 bit integer attribute
609*4dc78e53SAndroid Build Coastguard Worker  *
610*4dc78e53SAndroid Build Coastguard Worker  * @return Payload as 8 bit integer.
611*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_u8(const struct nlattr * nla)612*4dc78e53SAndroid Build Coastguard Worker uint8_t nla_get_u8(const struct nlattr *nla)
613*4dc78e53SAndroid Build Coastguard Worker {
614*4dc78e53SAndroid Build Coastguard Worker 	return *(const uint8_t *) nla_data(nla);
615*4dc78e53SAndroid Build Coastguard Worker }
616*4dc78e53SAndroid Build Coastguard Worker 
617*4dc78e53SAndroid Build Coastguard Worker /**
618*4dc78e53SAndroid Build Coastguard Worker  * Add 16 bit signed integer attribute to netlink message.
619*4dc78e53SAndroid Build Coastguard Worker  * @arg msg             Netlink message.
620*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype        Attribute type.
621*4dc78e53SAndroid Build Coastguard Worker  * @arg value           Numeric value to store as payload.
622*4dc78e53SAndroid Build Coastguard Worker  *
623*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
624*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
625*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_s16(struct nl_msg * msg,int attrtype,int16_t value)626*4dc78e53SAndroid Build Coastguard Worker int nla_put_s16(struct nl_msg *msg, int attrtype, int16_t value)
627*4dc78e53SAndroid Build Coastguard Worker {
628*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, sizeof(int16_t), &value);
629*4dc78e53SAndroid Build Coastguard Worker }
630*4dc78e53SAndroid Build Coastguard Worker 
631*4dc78e53SAndroid Build Coastguard Worker /**
632*4dc78e53SAndroid Build Coastguard Worker  * Return payload of 16 bit signed integer attribute.
633*4dc78e53SAndroid Build Coastguard Worker  * @arg nla             16 bit integer attribute
634*4dc78e53SAndroid Build Coastguard Worker  *
635*4dc78e53SAndroid Build Coastguard Worker  * @return Payload as 16 bit integer.
636*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_s16(const struct nlattr * nla)637*4dc78e53SAndroid Build Coastguard Worker int16_t nla_get_s16(const struct nlattr *nla)
638*4dc78e53SAndroid Build Coastguard Worker {
639*4dc78e53SAndroid Build Coastguard Worker 	return *(const int16_t *) nla_data(nla);
640*4dc78e53SAndroid Build Coastguard Worker }
641*4dc78e53SAndroid Build Coastguard Worker 
642*4dc78e53SAndroid Build Coastguard Worker /**
643*4dc78e53SAndroid Build Coastguard Worker  * Add 16 bit integer attribute to netlink message.
644*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
645*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
646*4dc78e53SAndroid Build Coastguard Worker  * @arg value		Numeric value to store as payload.
647*4dc78e53SAndroid Build Coastguard Worker  *
648*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
649*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
650*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_u16(struct nl_msg * msg,int attrtype,uint16_t value)651*4dc78e53SAndroid Build Coastguard Worker int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
652*4dc78e53SAndroid Build Coastguard Worker {
653*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, sizeof(uint16_t), &value);
654*4dc78e53SAndroid Build Coastguard Worker }
655*4dc78e53SAndroid Build Coastguard Worker 
656*4dc78e53SAndroid Build Coastguard Worker /**
657*4dc78e53SAndroid Build Coastguard Worker  * Return payload of 16 bit integer attribute.
658*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		16 bit integer attribute
659*4dc78e53SAndroid Build Coastguard Worker  *
660*4dc78e53SAndroid Build Coastguard Worker  * @return Payload as 16 bit integer.
661*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_u16(const struct nlattr * nla)662*4dc78e53SAndroid Build Coastguard Worker uint16_t nla_get_u16(const struct nlattr *nla)
663*4dc78e53SAndroid Build Coastguard Worker {
664*4dc78e53SAndroid Build Coastguard Worker 	return *(const uint16_t *) nla_data(nla);
665*4dc78e53SAndroid Build Coastguard Worker }
666*4dc78e53SAndroid Build Coastguard Worker 
667*4dc78e53SAndroid Build Coastguard Worker /**
668*4dc78e53SAndroid Build Coastguard Worker  * Add 32 bit signed integer attribute to netlink message.
669*4dc78e53SAndroid Build Coastguard Worker  * @arg msg             Netlink message.
670*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype        Attribute type.
671*4dc78e53SAndroid Build Coastguard Worker  * @arg value           Numeric value to store as payload.
672*4dc78e53SAndroid Build Coastguard Worker  *
673*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
674*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
675*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_s32(struct nl_msg * msg,int attrtype,int32_t value)676*4dc78e53SAndroid Build Coastguard Worker int nla_put_s32(struct nl_msg *msg, int attrtype, int32_t value)
677*4dc78e53SAndroid Build Coastguard Worker {
678*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, sizeof(int32_t), &value);
679*4dc78e53SAndroid Build Coastguard Worker }
680*4dc78e53SAndroid Build Coastguard Worker 
681*4dc78e53SAndroid Build Coastguard Worker /**
682*4dc78e53SAndroid Build Coastguard Worker  * Return payload of 32 bit signed integer attribute.
683*4dc78e53SAndroid Build Coastguard Worker  * @arg nla             32 bit integer attribute.
684*4dc78e53SAndroid Build Coastguard Worker  *
685*4dc78e53SAndroid Build Coastguard Worker  * @return Payload as 32 bit integer.
686*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_s32(const struct nlattr * nla)687*4dc78e53SAndroid Build Coastguard Worker int32_t nla_get_s32(const struct nlattr *nla)
688*4dc78e53SAndroid Build Coastguard Worker {
689*4dc78e53SAndroid Build Coastguard Worker 	return *(const int32_t *) nla_data(nla);
690*4dc78e53SAndroid Build Coastguard Worker }
691*4dc78e53SAndroid Build Coastguard Worker 
692*4dc78e53SAndroid Build Coastguard Worker /**
693*4dc78e53SAndroid Build Coastguard Worker  * Add 32 bit integer attribute to netlink message.
694*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
695*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
696*4dc78e53SAndroid Build Coastguard Worker  * @arg value		Numeric value to store as payload.
697*4dc78e53SAndroid Build Coastguard Worker  *
698*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
699*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
700*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_u32(struct nl_msg * msg,int attrtype,uint32_t value)701*4dc78e53SAndroid Build Coastguard Worker int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
702*4dc78e53SAndroid Build Coastguard Worker {
703*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, sizeof(uint32_t), &value);
704*4dc78e53SAndroid Build Coastguard Worker }
705*4dc78e53SAndroid Build Coastguard Worker 
706*4dc78e53SAndroid Build Coastguard Worker /**
707*4dc78e53SAndroid Build Coastguard Worker  * Return payload of 32 bit integer attribute.
708*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		32 bit integer attribute.
709*4dc78e53SAndroid Build Coastguard Worker  *
710*4dc78e53SAndroid Build Coastguard Worker  * @return Payload as 32 bit integer.
711*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_u32(const struct nlattr * nla)712*4dc78e53SAndroid Build Coastguard Worker uint32_t nla_get_u32(const struct nlattr *nla)
713*4dc78e53SAndroid Build Coastguard Worker {
714*4dc78e53SAndroid Build Coastguard Worker 	return *(const uint32_t *) nla_data(nla);
715*4dc78e53SAndroid Build Coastguard Worker }
716*4dc78e53SAndroid Build Coastguard Worker 
717*4dc78e53SAndroid Build Coastguard Worker /**
718*4dc78e53SAndroid Build Coastguard Worker  * Add 64 bit signed integer attribute to netlink message.
719*4dc78e53SAndroid Build Coastguard Worker  * @arg msg             Netlink message.
720*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype        Attribute type.
721*4dc78e53SAndroid Build Coastguard Worker  * @arg value           Numeric value to store as payload.
722*4dc78e53SAndroid Build Coastguard Worker  *
723*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
724*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
725*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_s64(struct nl_msg * msg,int attrtype,int64_t value)726*4dc78e53SAndroid Build Coastguard Worker int nla_put_s64(struct nl_msg *msg, int attrtype, int64_t value)
727*4dc78e53SAndroid Build Coastguard Worker {
728*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, sizeof(int64_t), &value);
729*4dc78e53SAndroid Build Coastguard Worker }
730*4dc78e53SAndroid Build Coastguard Worker 
731*4dc78e53SAndroid Build Coastguard Worker /**
732*4dc78e53SAndroid Build Coastguard Worker  * Return payload of s64 attribute
733*4dc78e53SAndroid Build Coastguard Worker  * @arg nla             s64 netlink attribute
734*4dc78e53SAndroid Build Coastguard Worker  *
735*4dc78e53SAndroid Build Coastguard Worker  * @return Payload as 64 bit integer.
736*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_s64(const struct nlattr * nla)737*4dc78e53SAndroid Build Coastguard Worker int64_t nla_get_s64(const struct nlattr *nla)
738*4dc78e53SAndroid Build Coastguard Worker {
739*4dc78e53SAndroid Build Coastguard Worker 	int64_t tmp = 0;
740*4dc78e53SAndroid Build Coastguard Worker 
741*4dc78e53SAndroid Build Coastguard Worker 	if (nla && _nla_len(nla) >= sizeof(tmp))
742*4dc78e53SAndroid Build Coastguard Worker 		memcpy(&tmp, nla_data(nla), sizeof(tmp));
743*4dc78e53SAndroid Build Coastguard Worker 
744*4dc78e53SAndroid Build Coastguard Worker 	return tmp;
745*4dc78e53SAndroid Build Coastguard Worker }
746*4dc78e53SAndroid Build Coastguard Worker 
747*4dc78e53SAndroid Build Coastguard Worker /**
748*4dc78e53SAndroid Build Coastguard Worker  * Add 64 bit integer attribute to netlink message.
749*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
750*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
751*4dc78e53SAndroid Build Coastguard Worker  * @arg value		Numeric value to store as payload.
752*4dc78e53SAndroid Build Coastguard Worker  *
753*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
754*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
755*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_u64(struct nl_msg * msg,int attrtype,uint64_t value)756*4dc78e53SAndroid Build Coastguard Worker int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value)
757*4dc78e53SAndroid Build Coastguard Worker {
758*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, sizeof(uint64_t), &value);
759*4dc78e53SAndroid Build Coastguard Worker }
760*4dc78e53SAndroid Build Coastguard Worker 
761*4dc78e53SAndroid Build Coastguard Worker /**
762*4dc78e53SAndroid Build Coastguard Worker  * Return payload of u64 attribute
763*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		u64 netlink attribute
764*4dc78e53SAndroid Build Coastguard Worker  *
765*4dc78e53SAndroid Build Coastguard Worker  * @return Payload as 64 bit integer.
766*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_u64(const struct nlattr * nla)767*4dc78e53SAndroid Build Coastguard Worker uint64_t nla_get_u64(const struct nlattr *nla)
768*4dc78e53SAndroid Build Coastguard Worker {
769*4dc78e53SAndroid Build Coastguard Worker 	uint64_t tmp = 0;
770*4dc78e53SAndroid Build Coastguard Worker 
771*4dc78e53SAndroid Build Coastguard Worker 	if (nla && _nla_len(nla) >= sizeof(tmp))
772*4dc78e53SAndroid Build Coastguard Worker 		memcpy(&tmp, nla_data(nla), sizeof(tmp));
773*4dc78e53SAndroid Build Coastguard Worker 
774*4dc78e53SAndroid Build Coastguard Worker 	return tmp;
775*4dc78e53SAndroid Build Coastguard Worker }
776*4dc78e53SAndroid Build Coastguard Worker 
777*4dc78e53SAndroid Build Coastguard Worker /** @} */
778*4dc78e53SAndroid Build Coastguard Worker 
779*4dc78e53SAndroid Build Coastguard Worker /**
780*4dc78e53SAndroid Build Coastguard Worker  * @name String Attribute
781*4dc78e53SAndroid Build Coastguard Worker  */
782*4dc78e53SAndroid Build Coastguard Worker 
783*4dc78e53SAndroid Build Coastguard Worker /**
784*4dc78e53SAndroid Build Coastguard Worker  * Add string attribute to netlink message.
785*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
786*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
787*4dc78e53SAndroid Build Coastguard Worker  * @arg str		NUL terminated string.
788*4dc78e53SAndroid Build Coastguard Worker  *
789*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
790*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
791*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_string(struct nl_msg * msg,int attrtype,const char * str)792*4dc78e53SAndroid Build Coastguard Worker int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
793*4dc78e53SAndroid Build Coastguard Worker {
794*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, strlen(str) + 1, str);
795*4dc78e53SAndroid Build Coastguard Worker }
796*4dc78e53SAndroid Build Coastguard Worker 
797*4dc78e53SAndroid Build Coastguard Worker /**
798*4dc78e53SAndroid Build Coastguard Worker  * Return payload of string attribute.
799*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		String attribute.
800*4dc78e53SAndroid Build Coastguard Worker  *
801*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to attribute payload.
802*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_string(const struct nlattr * nla)803*4dc78e53SAndroid Build Coastguard Worker char *nla_get_string(const struct nlattr *nla)
804*4dc78e53SAndroid Build Coastguard Worker {
805*4dc78e53SAndroid Build Coastguard Worker 	return (char *) nla_data(nla);
806*4dc78e53SAndroid Build Coastguard Worker }
807*4dc78e53SAndroid Build Coastguard Worker 
nla_strdup(const struct nlattr * nla)808*4dc78e53SAndroid Build Coastguard Worker char *nla_strdup(const struct nlattr *nla)
809*4dc78e53SAndroid Build Coastguard Worker {
810*4dc78e53SAndroid Build Coastguard Worker 	return strdup(nla_get_string(nla));
811*4dc78e53SAndroid Build Coastguard Worker }
812*4dc78e53SAndroid Build Coastguard Worker 
813*4dc78e53SAndroid Build Coastguard Worker /** @} */
814*4dc78e53SAndroid Build Coastguard Worker 
815*4dc78e53SAndroid Build Coastguard Worker /**
816*4dc78e53SAndroid Build Coastguard Worker  * @name Flag Attribute
817*4dc78e53SAndroid Build Coastguard Worker  */
818*4dc78e53SAndroid Build Coastguard Worker 
819*4dc78e53SAndroid Build Coastguard Worker /**
820*4dc78e53SAndroid Build Coastguard Worker  * Add flag netlink attribute to netlink message.
821*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
822*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
823*4dc78e53SAndroid Build Coastguard Worker  *
824*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
825*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
826*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_flag(struct nl_msg * msg,int attrtype)827*4dc78e53SAndroid Build Coastguard Worker int nla_put_flag(struct nl_msg *msg, int attrtype)
828*4dc78e53SAndroid Build Coastguard Worker {
829*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, 0, NULL);
830*4dc78e53SAndroid Build Coastguard Worker }
831*4dc78e53SAndroid Build Coastguard Worker 
832*4dc78e53SAndroid Build Coastguard Worker /**
833*4dc78e53SAndroid Build Coastguard Worker  * Return true if flag attribute is set.
834*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Flag netlink attribute.
835*4dc78e53SAndroid Build Coastguard Worker  *
836*4dc78e53SAndroid Build Coastguard Worker  * @return True if flag is set, otherwise false.
837*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_flag(const struct nlattr * nla)838*4dc78e53SAndroid Build Coastguard Worker int nla_get_flag(const struct nlattr *nla)
839*4dc78e53SAndroid Build Coastguard Worker {
840*4dc78e53SAndroid Build Coastguard Worker 	return !!nla;
841*4dc78e53SAndroid Build Coastguard Worker }
842*4dc78e53SAndroid Build Coastguard Worker 
843*4dc78e53SAndroid Build Coastguard Worker /** @} */
844*4dc78e53SAndroid Build Coastguard Worker 
845*4dc78e53SAndroid Build Coastguard Worker /**
846*4dc78e53SAndroid Build Coastguard Worker  * @name Microseconds Attribute
847*4dc78e53SAndroid Build Coastguard Worker  */
848*4dc78e53SAndroid Build Coastguard Worker 
849*4dc78e53SAndroid Build Coastguard Worker /**
850*4dc78e53SAndroid Build Coastguard Worker  * Add a msecs netlink attribute to a netlink message
851*4dc78e53SAndroid Build Coastguard Worker  * @arg n		netlink message
852*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	attribute type
853*4dc78e53SAndroid Build Coastguard Worker  * @arg msecs 		number of msecs
854*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_msecs(struct nl_msg * n,int attrtype,unsigned long msecs)855*4dc78e53SAndroid Build Coastguard Worker int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
856*4dc78e53SAndroid Build Coastguard Worker {
857*4dc78e53SAndroid Build Coastguard Worker 	return nla_put_u64(n, attrtype, msecs);
858*4dc78e53SAndroid Build Coastguard Worker }
859*4dc78e53SAndroid Build Coastguard Worker 
860*4dc78e53SAndroid Build Coastguard Worker /**
861*4dc78e53SAndroid Build Coastguard Worker  * Return payload of msecs attribute
862*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		msecs netlink attribute
863*4dc78e53SAndroid Build Coastguard Worker  *
864*4dc78e53SAndroid Build Coastguard Worker  * @return the number of milliseconds.
865*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_msecs(const struct nlattr * nla)866*4dc78e53SAndroid Build Coastguard Worker unsigned long nla_get_msecs(const struct nlattr *nla)
867*4dc78e53SAndroid Build Coastguard Worker {
868*4dc78e53SAndroid Build Coastguard Worker 	return nla_get_u64(nla);
869*4dc78e53SAndroid Build Coastguard Worker }
870*4dc78e53SAndroid Build Coastguard Worker 
871*4dc78e53SAndroid Build Coastguard Worker /** @} */
872*4dc78e53SAndroid Build Coastguard Worker 
873*4dc78e53SAndroid Build Coastguard Worker /**
874*4dc78e53SAndroid Build Coastguard Worker  * @name Nested Attribute
875*4dc78e53SAndroid Build Coastguard Worker  */
876*4dc78e53SAndroid Build Coastguard Worker 
877*4dc78e53SAndroid Build Coastguard Worker /**
878*4dc78e53SAndroid Build Coastguard Worker  * Add nested attributes to netlink message.
879*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
880*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type.
881*4dc78e53SAndroid Build Coastguard Worker  * @arg nested		Message containing attributes to be nested.
882*4dc78e53SAndroid Build Coastguard Worker  *
883*4dc78e53SAndroid Build Coastguard Worker  * Takes the attributes found in the \a nested message and appends them
884*4dc78e53SAndroid Build Coastguard Worker  * to the message \a msg nested in a container of the type \a attrtype.
885*4dc78e53SAndroid Build Coastguard Worker  * The \a nested message may not have a family specific header.
886*4dc78e53SAndroid Build Coastguard Worker  *
887*4dc78e53SAndroid Build Coastguard Worker  * @see nla_put
888*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
889*4dc78e53SAndroid Build Coastguard Worker  */
nla_put_nested(struct nl_msg * msg,int attrtype,const struct nl_msg * nested)890*4dc78e53SAndroid Build Coastguard Worker int nla_put_nested(struct nl_msg *msg, int attrtype,
891*4dc78e53SAndroid Build Coastguard Worker 		   const struct nl_msg *nested)
892*4dc78e53SAndroid Build Coastguard Worker {
893*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(2, "msg %p: attr <> %d: adding msg %p as nested attribute\n",
894*4dc78e53SAndroid Build Coastguard Worker 		msg, attrtype, nested);
895*4dc78e53SAndroid Build Coastguard Worker 
896*4dc78e53SAndroid Build Coastguard Worker 	return nla_put(msg, attrtype, nlmsg_datalen(nested->nm_nlh),
897*4dc78e53SAndroid Build Coastguard Worker 		       nlmsg_data(nested->nm_nlh));
898*4dc78e53SAndroid Build Coastguard Worker }
899*4dc78e53SAndroid Build Coastguard Worker 
900*4dc78e53SAndroid Build Coastguard Worker 
901*4dc78e53SAndroid Build Coastguard Worker /**
902*4dc78e53SAndroid Build Coastguard Worker  * Start a new level of nested attributes.
903*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
904*4dc78e53SAndroid Build Coastguard Worker  * @arg attrtype	Attribute type of container.
905*4dc78e53SAndroid Build Coastguard Worker  *
906*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to container attribute.
907*4dc78e53SAndroid Build Coastguard Worker  */
nla_nest_start(struct nl_msg * msg,int attrtype)908*4dc78e53SAndroid Build Coastguard Worker struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype)
909*4dc78e53SAndroid Build Coastguard Worker {
910*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
911*4dc78e53SAndroid Build Coastguard Worker 
912*4dc78e53SAndroid Build Coastguard Worker 	if (nla_put(msg, NLA_F_NESTED | attrtype, 0, NULL) < 0)
913*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
914*4dc78e53SAndroid Build Coastguard Worker 
915*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(2, "msg %p: attr <%p> %d: starting nesting\n",
916*4dc78e53SAndroid Build Coastguard Worker 		msg, start, start->nla_type);
917*4dc78e53SAndroid Build Coastguard Worker 
918*4dc78e53SAndroid Build Coastguard Worker 	return start;
919*4dc78e53SAndroid Build Coastguard Worker }
920*4dc78e53SAndroid Build Coastguard Worker 
_nest_end(struct nl_msg * msg,struct nlattr * start,int keep_empty)921*4dc78e53SAndroid Build Coastguard Worker static int _nest_end(struct nl_msg *msg, struct nlattr *start, int keep_empty)
922*4dc78e53SAndroid Build Coastguard Worker {
923*4dc78e53SAndroid Build Coastguard Worker 	size_t pad, len;
924*4dc78e53SAndroid Build Coastguard Worker 
925*4dc78e53SAndroid Build Coastguard Worker 	len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) start;
926*4dc78e53SAndroid Build Coastguard Worker 
927*4dc78e53SAndroid Build Coastguard Worker 	if (   len > USHRT_MAX
928*4dc78e53SAndroid Build Coastguard Worker 	    || (!keep_empty && len == NLA_HDRLEN)) {
929*4dc78e53SAndroid Build Coastguard Worker 		/*
930*4dc78e53SAndroid Build Coastguard Worker 		 * Max nlattr size exceeded or empty nested attribute, trim the
931*4dc78e53SAndroid Build Coastguard Worker 		 * attribute header again
932*4dc78e53SAndroid Build Coastguard Worker 		 */
933*4dc78e53SAndroid Build Coastguard Worker 		nla_nest_cancel(msg, start);
934*4dc78e53SAndroid Build Coastguard Worker 
935*4dc78e53SAndroid Build Coastguard Worker 		/* Return error only if nlattr size was exceeded */
936*4dc78e53SAndroid Build Coastguard Worker 		return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE;
937*4dc78e53SAndroid Build Coastguard Worker 	}
938*4dc78e53SAndroid Build Coastguard Worker 
939*4dc78e53SAndroid Build Coastguard Worker 	start->nla_len = len;
940*4dc78e53SAndroid Build Coastguard Worker 
941*4dc78e53SAndroid Build Coastguard Worker 	pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len;
942*4dc78e53SAndroid Build Coastguard Worker 	if (pad > 0) {
943*4dc78e53SAndroid Build Coastguard Worker 		/*
944*4dc78e53SAndroid Build Coastguard Worker 		 * Data inside attribute does not end at a alignment boundry.
945*4dc78e53SAndroid Build Coastguard Worker 		 * Pad accordingly and accoun for the additional space in
946*4dc78e53SAndroid Build Coastguard Worker 		 * the message. nlmsg_reserve() may never fail in this situation,
947*4dc78e53SAndroid Build Coastguard Worker 		 * the allocate message buffer must be a multiple of NLMSG_ALIGNTO.
948*4dc78e53SAndroid Build Coastguard Worker 		 */
949*4dc78e53SAndroid Build Coastguard Worker 		if (!nlmsg_reserve(msg, pad, 0))
950*4dc78e53SAndroid Build Coastguard Worker 			BUG();
951*4dc78e53SAndroid Build Coastguard Worker 
952*4dc78e53SAndroid Build Coastguard Worker 		NL_DBG(2, "msg %p: attr <%p> %d: added %zu bytes of padding\n",
953*4dc78e53SAndroid Build Coastguard Worker 			msg, start, start->nla_type, pad);
954*4dc78e53SAndroid Build Coastguard Worker 	}
955*4dc78e53SAndroid Build Coastguard Worker 
956*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(2, "msg %p: attr <%p> %d: closing nesting, len=%u\n",
957*4dc78e53SAndroid Build Coastguard Worker 		msg, start, start->nla_type, start->nla_len);
958*4dc78e53SAndroid Build Coastguard Worker 
959*4dc78e53SAndroid Build Coastguard Worker 	return 0;
960*4dc78e53SAndroid Build Coastguard Worker }
961*4dc78e53SAndroid Build Coastguard Worker 
962*4dc78e53SAndroid Build Coastguard Worker /**
963*4dc78e53SAndroid Build Coastguard Worker  * Finalize nesting of attributes.
964*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
965*4dc78e53SAndroid Build Coastguard Worker  * @arg start		Container attribute as returned from nla_nest_start().
966*4dc78e53SAndroid Build Coastguard Worker  *
967*4dc78e53SAndroid Build Coastguard Worker  * Corrects the container attribute header to include the appeneded attributes.
968*4dc78e53SAndroid Build Coastguard Worker  *
969*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
970*4dc78e53SAndroid Build Coastguard Worker  */
nla_nest_end(struct nl_msg * msg,struct nlattr * start)971*4dc78e53SAndroid Build Coastguard Worker int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
972*4dc78e53SAndroid Build Coastguard Worker {
973*4dc78e53SAndroid Build Coastguard Worker 	return _nest_end (msg, start, 0);
974*4dc78e53SAndroid Build Coastguard Worker }
975*4dc78e53SAndroid Build Coastguard Worker 
976*4dc78e53SAndroid Build Coastguard Worker /**
977*4dc78e53SAndroid Build Coastguard Worker  * Finalize nesting of attributes without stripping off empty attributes.
978*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message.
979*4dc78e53SAndroid Build Coastguard Worker  * @arg start		Container attribute as returned from nla_nest_start().
980*4dc78e53SAndroid Build Coastguard Worker  *
981*4dc78e53SAndroid Build Coastguard Worker  * Corrects the container attribute header to include the appeneded attributes.
982*4dc78e53SAndroid Build Coastguard Worker  * Keep empty attribute if NO actual attribute payload exists.
983*4dc78e53SAndroid Build Coastguard Worker  *
984*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
985*4dc78e53SAndroid Build Coastguard Worker  */
nla_nest_end_keep_empty(struct nl_msg * msg,struct nlattr * start)986*4dc78e53SAndroid Build Coastguard Worker int nla_nest_end_keep_empty(struct nl_msg *msg, struct nlattr *start)
987*4dc78e53SAndroid Build Coastguard Worker {
988*4dc78e53SAndroid Build Coastguard Worker 	return _nest_end (msg, start, 1);
989*4dc78e53SAndroid Build Coastguard Worker }
990*4dc78e53SAndroid Build Coastguard Worker 
991*4dc78e53SAndroid Build Coastguard Worker /**
992*4dc78e53SAndroid Build Coastguard Worker  * Cancel the addition of a nested attribute
993*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message
994*4dc78e53SAndroid Build Coastguard Worker  * @arg attr		Nested netlink attribute
995*4dc78e53SAndroid Build Coastguard Worker  *
996*4dc78e53SAndroid Build Coastguard Worker  * Removes any partially added nested Netlink attribute from the message
997*4dc78e53SAndroid Build Coastguard Worker  * by resetting the message to the size before the call to nla_nest_start()
998*4dc78e53SAndroid Build Coastguard Worker  * and by overwriting any potentially touched message segments with 0.
999*4dc78e53SAndroid Build Coastguard Worker  */
nla_nest_cancel(struct nl_msg * msg,const struct nlattr * attr)1000*4dc78e53SAndroid Build Coastguard Worker void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr)
1001*4dc78e53SAndroid Build Coastguard Worker {
1002*4dc78e53SAndroid Build Coastguard Worker 	ssize_t len;
1003*4dc78e53SAndroid Build Coastguard Worker 
1004*4dc78e53SAndroid Build Coastguard Worker 	if (!attr) {
1005*4dc78e53SAndroid Build Coastguard Worker 		/* For robustness, allow a NULL attr to do nothing. NULL is also
1006*4dc78e53SAndroid Build Coastguard Worker 		 * what nla_nest_start() when out of buffer space.
1007*4dc78e53SAndroid Build Coastguard Worker 		 *
1008*4dc78e53SAndroid Build Coastguard Worker 		 * Warning, before libnl-3.8, the function did not accept NULL!
1009*4dc78e53SAndroid Build Coastguard Worker 		 * If you care, catch NULL yourself. */
1010*4dc78e53SAndroid Build Coastguard Worker 		return;
1011*4dc78e53SAndroid Build Coastguard Worker 	}
1012*4dc78e53SAndroid Build Coastguard Worker 
1013*4dc78e53SAndroid Build Coastguard Worker 	len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) attr;
1014*4dc78e53SAndroid Build Coastguard Worker 	if (len < 0)
1015*4dc78e53SAndroid Build Coastguard Worker 		BUG();
1016*4dc78e53SAndroid Build Coastguard Worker 	else if (len > 0) {
1017*4dc78e53SAndroid Build Coastguard Worker 		msg->nm_nlh->nlmsg_len -= len;
1018*4dc78e53SAndroid Build Coastguard Worker 		memset(nlmsg_tail(msg->nm_nlh), 0, len);
1019*4dc78e53SAndroid Build Coastguard Worker 	}
1020*4dc78e53SAndroid Build Coastguard Worker }
1021*4dc78e53SAndroid Build Coastguard Worker 
1022*4dc78e53SAndroid Build Coastguard Worker /**
1023*4dc78e53SAndroid Build Coastguard Worker  * Create attribute index based on nested attribute
1024*4dc78e53SAndroid Build Coastguard Worker  * @arg tb		Index array to be filled (maxtype+1 elements).
1025*4dc78e53SAndroid Build Coastguard Worker  * @arg maxtype		Maximum attribute type expected and accepted.
1026*4dc78e53SAndroid Build Coastguard Worker  * @arg nla		Nested Attribute.
1027*4dc78e53SAndroid Build Coastguard Worker  * @arg policy		Attribute validation policy.
1028*4dc78e53SAndroid Build Coastguard Worker  *
1029*4dc78e53SAndroid Build Coastguard Worker  * Feeds the stream of attributes nested into the specified attribute
1030*4dc78e53SAndroid Build Coastguard Worker  * to nla_parse().
1031*4dc78e53SAndroid Build Coastguard Worker  *
1032*4dc78e53SAndroid Build Coastguard Worker  * @see nla_parse
1033*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
1034*4dc78e53SAndroid Build Coastguard Worker  */
nla_parse_nested(struct nlattr * tb[],int maxtype,struct nlattr * nla,const struct nla_policy * policy)1035*4dc78e53SAndroid Build Coastguard Worker int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
1036*4dc78e53SAndroid Build Coastguard Worker 		     const struct nla_policy *policy)
1037*4dc78e53SAndroid Build Coastguard Worker {
1038*4dc78e53SAndroid Build Coastguard Worker 	return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
1039*4dc78e53SAndroid Build Coastguard Worker }
1040*4dc78e53SAndroid Build Coastguard Worker 
1041*4dc78e53SAndroid Build Coastguard Worker /**
1042*4dc78e53SAndroid Build Coastguard Worker  * Return true if attribute has NLA_F_NESTED flag set
1043*4dc78e53SAndroid Build Coastguard Worker  * @arg attr		Netlink attribute
1044*4dc78e53SAndroid Build Coastguard Worker  *
1045*4dc78e53SAndroid Build Coastguard Worker  * @return True if attribute has NLA_F_NESTED flag set, oterhwise False.
1046*4dc78e53SAndroid Build Coastguard Worker  */
nla_is_nested(const struct nlattr * attr)1047*4dc78e53SAndroid Build Coastguard Worker int nla_is_nested(const struct nlattr *attr)
1048*4dc78e53SAndroid Build Coastguard Worker {
1049*4dc78e53SAndroid Build Coastguard Worker 	return !!(attr->nla_type & NLA_F_NESTED);
1050*4dc78e53SAndroid Build Coastguard Worker }
1051*4dc78e53SAndroid Build Coastguard Worker 
1052*4dc78e53SAndroid Build Coastguard Worker /** @} */
1053*4dc78e53SAndroid Build Coastguard Worker 
1054*4dc78e53SAndroid Build Coastguard Worker /** @} */
1055