Blame view

include/net/netlink.h 32.3 KB
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1
2
3
4
5
  #ifndef __NET_NETLINK_H
  #define __NET_NETLINK_H
  
  #include <linux/types.h>
  #include <linux/netlink.h>
d7fe0f241   Al Viro   [PATCH] severing ...
6
  #include <linux/jiffies.h>
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
  
  /* ========================================================================
   *         Netlink Messages and Attributes Interface (As Seen On TV)
   * ------------------------------------------------------------------------
   *                          Messages Interface
   * ------------------------------------------------------------------------
   *
   * Message Format:
   *    <--- nlmsg_total_size(payload)  --->
   *    <-- nlmsg_msg_size(payload) ->
   *   +----------+- - -+-------------+- - -+-------- - -
   *   | nlmsghdr | Pad |   Payload   | Pad | nlmsghdr
   *   +----------+- - -+-------------+- - -+-------- - -
   *   nlmsg_data(nlh)---^                   ^
   *   nlmsg_next(nlh)-----------------------+
   *
   * Payload Format:
   *    <---------------------- nlmsg_len(nlh) --------------------->
   *    <------ hdrlen ------>       <- nlmsg_attrlen(nlh, hdrlen) ->
   *   +----------------------+- - -+--------------------------------+
   *   |     Family Header    | Pad |           Attributes           |
   *   +----------------------+- - -+--------------------------------+
   *   nlmsg_attrdata(nlh, hdrlen)---^
   *
   * Data Structures:
   *   struct nlmsghdr			netlink message header
   *
   * Message Construction:
   *   nlmsg_new()			create a new netlink message
   *   nlmsg_put()			add a netlink message to an skb
   *   nlmsg_put_answer()			callback based nlmsg_put()
1dc8d8c06   Justin P. Mattock   net: Fix a typo i...
38
   *   nlmsg_end()			finalize netlink message
fe4944e59   Thomas Graf   [NETLINK]: Extend...
39
40
   *   nlmsg_get_pos()			return current position in message
   *   nlmsg_trim()			trim part of message
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
41
42
43
44
45
46
   *   nlmsg_cancel()			cancel message construction
   *   nlmsg_free()			free a netlink message
   *
   * Message Sending:
   *   nlmsg_multicast()			multicast message to several groups
   *   nlmsg_unicast()			unicast a message to a single socket
d387f6ad1   Thomas Graf   [NETLINK]: Add no...
47
   *   nlmsg_notify()			send notification message
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
   *
   * Message Length Calculations:
   *   nlmsg_msg_size(payload)		length of message w/o padding
   *   nlmsg_total_size(payload)		length of message w/ padding
   *   nlmsg_padlen(payload)		length of padding at tail
   *
   * Message Payload Access:
   *   nlmsg_data(nlh)			head of message payload
   *   nlmsg_len(nlh)			length of message payload
   *   nlmsg_attrdata(nlh, hdrlen)	head of attributes data
   *   nlmsg_attrlen(nlh, hdrlen)		length of attributes data
   *
   * Message Parsing:
   *   nlmsg_ok(nlh, remaining)		does nlh fit into remaining bytes?
   *   nlmsg_next(nlh, remaining)		get next netlink message
   *   nlmsg_parse()			parse attributes of a message
   *   nlmsg_find_attr()			find an attribute in a message
   *   nlmsg_for_each_msg()		loop over all messages
   *   nlmsg_validate()			validate netlink message incl. attrs
   *   nlmsg_for_each_attr()		loop over all attributes
   *
97676b6b5   Thomas Graf   [RTNETLINK]: Add ...
69
70
71
   * Misc:
   *   nlmsg_report()			report back to application?
   *
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
   * ------------------------------------------------------------------------
   *                          Attributes Interface
   * ------------------------------------------------------------------------
   *
   * Attribute Format:
   *    <------- nla_total_size(payload) ------->
   *    <---- nla_attr_size(payload) ----->
   *   +----------+- - -+- - - - - - - - - +- - -+-------- - -
   *   |  Header  | Pad |     Payload      | Pad |  Header
   *   +----------+- - -+- - - - - - - - - +- - -+-------- - -
   *                     <- nla_len(nla) ->      ^
   *   nla_data(nla)----^                        |
   *   nla_next(nla)-----------------------------'
   *
   * Data Structures:
d1ec3b772   Pierre Ynard   [NETLINK]: Fix ty...
87
   *   struct nlattr			netlink attribute header
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
88
89
   *
   * Attribute Construction:
fe4944e59   Thomas Graf   [NETLINK]: Extend...
90
91
   *   nla_reserve(skb, type, len)	reserve room for an attribute
   *   nla_reserve_nohdr(skb, len)	reserve room for an attribute w/o hdr
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
92
   *   nla_put(skb, type, len, data)	add attribute to skb
fe4944e59   Thomas Graf   [NETLINK]: Extend...
93
   *   nla_put_nohdr(skb, len, data)	add attribute w/o hdr
01480e1cf   Patrick McHardy   [NETLINK]: Add nl...
94
   *   nla_append(skb, len, data)		append data to skb
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
   *
   * Attribute Construction for Basic Types:
   *   nla_put_u8(skb, type, value)	add u8 attribute to skb
   *   nla_put_u16(skb, type, value)	add u16 attribute to skb
   *   nla_put_u32(skb, type, value)	add u32 attribute to skb
   *   nla_put_u64(skb, type, value)	add u64 attribute to skb
   *   nla_put_string(skb, type, str)	add string attribute to skb
   *   nla_put_flag(skb, type)		add flag attribute to skb
   *   nla_put_msecs(skb, type, jiffies)	add msecs attribute to skb
   *
   * Exceptions Based Attribute Construction:
   *   NLA_PUT(skb, type, len, data)	add attribute to skb
   *   NLA_PUT_U8(skb, type, value)	add u8 attribute to skb
   *   NLA_PUT_U16(skb, type, value)	add u16 attribute to skb
   *   NLA_PUT_U32(skb, type, value)	add u32 attribute to skb
   *   NLA_PUT_U64(skb, type, value)	add u64 attribute to skb
   *   NLA_PUT_STRING(skb, type, str)	add string attribute to skb
   *   NLA_PUT_FLAG(skb, type)		add flag attribute to skb
   *   NLA_PUT_MSECS(skb, type, jiffies)	add msecs attribute to skb
   *
   *   The meaning of these functions is equal to their lower case
   *   variants but they jump to the label nla_put_failure in case
   *   of a failure.
   *
   * Nested Attributes Construction:
   *   nla_nest_start(skb, type)		start a nested attribute
   *   nla_nest_end(skb, nla)		finalize a nested attribute
   *   nla_nest_cancel(skb, nla)		cancel nested attribute construction
   *
   * Attribute Length Calculations:
   *   nla_attr_size(payload)		length of attribute w/o padding
   *   nla_total_size(payload)		length of attribute w/ padding
   *   nla_padlen(payload)		length of padding
   *
   * Attribute Payload Access:
   *   nla_data(nla)			head of attribute payload
   *   nla_len(nla)			length of attribute payload
   *
   * Attribute Payload Access for Basic Types:
   *   nla_get_u8(nla)			get payload for a u8 attribute
   *   nla_get_u16(nla)			get payload for a u16 attribute
   *   nla_get_u32(nla)			get payload for a u32 attribute
   *   nla_get_u64(nla)			get payload for a u64 attribute
   *   nla_get_flag(nla)			return 1 if flag is true
   *   nla_get_msecs(nla)			get payload for a msecs attribute
   *
   * Attribute Misc:
   *   nla_memcpy(dest, nla, count)	copy attribute into memory
   *   nla_memcmp(nla, data, size)	compare attribute with memory area
   *   nla_strlcpy(dst, nla, size)	copy attribute to a sized string
   *   nla_strcmp(nla, str)		compare attribute with string
   *
   * Attribute Parsing:
   *   nla_ok(nla, remaining)		does nla fit into remaining bytes?
   *   nla_next(nla, remaining)		get next netlink attribute
   *   nla_validate()			validate a stream of attributes
4fe5d5c07   Paul Moore   [Netlink]: add nl...
151
   *   nla_validate_nested()		validate a stream of nested attributes
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
152
   *   nla_find()				find attribute in stream of attributes
fe4944e59   Thomas Graf   [NETLINK]: Extend...
153
   *   nla_find_nested()			find attribute in nested attributes
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
154
155
156
   *   nla_parse()			parse and validate stream of attrs
   *   nla_parse_nested()			parse nested attribuets
   *   nla_for_each_attr()		loop over all attributes
22acb19a9   Paul Moore   [NETLINK]: add nl...
157
   *   nla_for_each_nested()		loop over the nested attributes
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
   *=========================================================================
   */
  
   /**
    * Standard attribute types to specify validation policy
    */
  enum {
  	NLA_UNSPEC,
  	NLA_U8,
  	NLA_U16,
  	NLA_U32,
  	NLA_U64,
  	NLA_STRING,
  	NLA_FLAG,
  	NLA_MSECS,
  	NLA_NESTED,
1092cb219   Patrick McHardy   [NETLINK]: attr: ...
174
  	NLA_NESTED_COMPAT,
a5531a5d8   Thomas Graf   [NETLINK]: Improv...
175
  	NLA_NUL_STRING,
d30045a0b   Johannes Berg   [NETLINK]: introd...
176
  	NLA_BINARY,
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
177
178
179
180
181
182
183
184
  	__NLA_TYPE_MAX,
  };
  
  #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
  
  /**
   * struct nla_policy - attribute validation policy
   * @type: Type of attribute or NLA_UNSPEC
a5531a5d8   Thomas Graf   [NETLINK]: Improv...
185
   * @len: Type specific length of payload
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
186
187
188
189
   *
   * Policies are defined as arrays of this struct, the array must be
   * accessible by attribute type up to the highest identifier to be expected.
   *
a5531a5d8   Thomas Graf   [NETLINK]: Improv...
190
191
192
193
   * Meaning of `len' field:
   *    NLA_STRING           Maximum length of string
   *    NLA_NUL_STRING       Maximum length of string (excluding NUL)
   *    NLA_FLAG             Unused
d30045a0b   Johannes Berg   [NETLINK]: introd...
194
   *    NLA_BINARY           Maximum length of attribute payload
4b6cc7284   Johannes Berg   netlink: clarify ...
195
196
197
198
199
200
201
202
203
   *    NLA_NESTED           Don't use `len' field -- length verification is
   *                         done by checking len of nested header (or empty)
   *    NLA_NESTED_COMPAT    Minimum length of structure payload
   *    NLA_U8, NLA_U16,
   *    NLA_U32, NLA_U64,
   *    NLA_MSECS            Leaving the length field zero will verify the
   *                         given type fits, using it verifies minimum length
   *                         just like "All other"
   *    All other            Minimum length of attribute payload
a5531a5d8   Thomas Graf   [NETLINK]: Improv...
204
   *
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
205
   * Example:
b54452b07   Alexey Dobriyan   const: struct nla...
206
   * static const struct nla_policy my_policy[ATTR_MAX+1] = {
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
207
   * 	[ATTR_FOO] = { .type = NLA_U16 },
d30045a0b   Johannes Berg   [NETLINK]: introd...
208
   *	[ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ },
a5531a5d8   Thomas Graf   [NETLINK]: Improv...
209
   *	[ATTR_BAZ] = { .len = sizeof(struct mystruct) },
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
210
211
212
213
   * };
   */
  struct nla_policy {
  	u16		type;
a5531a5d8   Thomas Graf   [NETLINK]: Improv...
214
  	u16		len;
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
215
  };
4e902c574   Thomas Graf   [IPv4]: FIB confi...
216
217
218
219
220
221
222
  /**
   * struct nl_info - netlink source information
   * @nlh: Netlink message header of original request
   * @pid: Netlink PID of requesting application
   */
  struct nl_info {
  	struct nlmsghdr		*nlh;
4d1169c1e   Denis V. Lunev   [NETNS]: Add netn...
223
  	struct net		*nl_net;
4e902c574   Thomas Graf   [IPv4]: FIB confi...
224
225
  	u32			pid;
  };
cd40b7d39   Denis V. Lunev   [NET]: make netli...
226
227
228
  extern int		netlink_rcv_skb(struct sk_buff *skb,
  					int (*cb)(struct sk_buff *,
  						  struct nlmsghdr *));
97676b6b5   Thomas Graf   [RTNETLINK]: Add ...
229
230
231
  extern int		nlmsg_notify(struct sock *sk, struct sk_buff *skb,
  				     u32 pid, unsigned int group, int report,
  				     gfp_t flags);
82ace47a7   Thomas Graf   [NETLINK]: Generi...
232

3654654f7   Jan Engelhardt   netlink: let nlms...
233
234
  extern int		nla_validate(const struct nlattr *head,
  				     int len, int maxtype,
ef7c79ed6   Patrick McHardy   [NETLINK]: Mark n...
235
  				     const struct nla_policy *policy);
3654654f7   Jan Engelhardt   netlink: let nlms...
236
237
  extern int		nla_parse(struct nlattr **tb, int maxtype,
  				  const struct nlattr *head, int len,
ef7c79ed6   Patrick McHardy   [NETLINK]: Mark n...
238
  				  const struct nla_policy *policy);
e487eb99c   Holger Eitzenberger   netlink: add nla_...
239
  extern int		nla_policy_len(const struct nla_policy *, int);
3654654f7   Jan Engelhardt   netlink: let nlms...
240
241
  extern struct nlattr *	nla_find(const struct nlattr *head,
  				 int len, int attrtype);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
242
243
  extern size_t		nla_strlcpy(char *dst, const struct nlattr *nla,
  				    size_t dstsize);
b057efd4d   Patrick McHardy   netlink: constify...
244
  extern int		nla_memcpy(void *dest, const struct nlattr *src, int count);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
245
246
247
248
249
  extern int		nla_memcmp(const struct nlattr *nla, const void *data,
  				   size_t size);
  extern int		nla_strcmp(const struct nlattr *nla, const char *str);
  extern struct nlattr *	__nla_reserve(struct sk_buff *skb, int attrtype,
  				      int attrlen);
fe4944e59   Thomas Graf   [NETLINK]: Extend...
250
  extern void *		__nla_reserve_nohdr(struct sk_buff *skb, int attrlen);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
251
252
  extern struct nlattr *	nla_reserve(struct sk_buff *skb, int attrtype,
  				    int attrlen);
fe4944e59   Thomas Graf   [NETLINK]: Extend...
253
  extern void *		nla_reserve_nohdr(struct sk_buff *skb, int attrlen);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
254
255
  extern void		__nla_put(struct sk_buff *skb, int attrtype,
  				  int attrlen, const void *data);
fe4944e59   Thomas Graf   [NETLINK]: Extend...
256
257
  extern void		__nla_put_nohdr(struct sk_buff *skb, int attrlen,
  					const void *data);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
258
259
  extern int		nla_put(struct sk_buff *skb, int attrtype,
  				int attrlen, const void *data);
fe4944e59   Thomas Graf   [NETLINK]: Extend...
260
261
  extern int		nla_put_nohdr(struct sk_buff *skb, int attrlen,
  				      const void *data);
01480e1cf   Patrick McHardy   [NETLINK]: Add nl...
262
263
  extern int		nla_append(struct sk_buff *skb, int attrlen,
  				   const void *data);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
  
  /**************************************************************************
   * Netlink Messages
   **************************************************************************/
  
  /**
   * nlmsg_msg_size - length of netlink message not including padding
   * @payload: length of message payload
   */
  static inline int nlmsg_msg_size(int payload)
  {
  	return NLMSG_HDRLEN + payload;
  }
  
  /**
   * nlmsg_total_size - length of netlink message including padding
   * @payload: length of message payload
   */
  static inline int nlmsg_total_size(int payload)
  {
  	return NLMSG_ALIGN(nlmsg_msg_size(payload));
  }
  
  /**
   * nlmsg_padlen - length of padding at the message's tail
   * @payload: length of message payload
   */
  static inline int nlmsg_padlen(int payload)
  {
  	return nlmsg_total_size(payload) - nlmsg_msg_size(payload);
  }
  
  /**
   * nlmsg_data - head of message payload
70f23fd66   Justin P. Mattock   treewide: fix a f...
298
   * @nlh: netlink message header
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
   */
  static inline void *nlmsg_data(const struct nlmsghdr *nlh)
  {
  	return (unsigned char *) nlh + NLMSG_HDRLEN;
  }
  
  /**
   * nlmsg_len - length of message payload
   * @nlh: netlink message header
   */
  static inline int nlmsg_len(const struct nlmsghdr *nlh)
  {
  	return nlh->nlmsg_len - NLMSG_HDRLEN;
  }
  
  /**
   * nlmsg_attrdata - head of attributes data
   * @nlh: netlink message header
   * @hdrlen: length of family specific header
   */
  static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
  					    int hdrlen)
  {
  	unsigned char *data = nlmsg_data(nlh);
  	return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
  }
  
  /**
   * nlmsg_attrlen - length of attributes data
   * @nlh: netlink message header
   * @hdrlen: length of family specific header
   */
  static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
  {
  	return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
  }
  
  /**
   * nlmsg_ok - check if the netlink message fits into the remaining bytes
   * @nlh: netlink message header
   * @remaining: number of bytes remaining in message stream
   */
  static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
  {
619e803d3   Vegard Nossum   netlink: fix (the...
343
  	return (remaining >= (int) sizeof(struct nlmsghdr) &&
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
344
345
346
347
348
349
350
351
352
353
354
355
  		nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
  		nlh->nlmsg_len <= remaining);
  }
  
  /**
   * nlmsg_next - next netlink message in message stream
   * @nlh: netlink message header
   * @remaining: number of bytes remaining in message stream
   *
   * Returns the next netlink message in the message stream and
   * decrements remaining by the size of the current message.
   */
3654654f7   Jan Engelhardt   netlink: let nlms...
356
357
  static inline struct nlmsghdr *
  nlmsg_next(const struct nlmsghdr *nlh, int *remaining)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  {
  	int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
  
  	*remaining -= totlen;
  
  	return (struct nlmsghdr *) ((unsigned char *) nlh + totlen);
  }
  
  /**
   * nlmsg_parse - parse attributes of a netlink message
   * @nlh: netlink message header
   * @hdrlen: length of family specific header
   * @tb: destination array with maxtype+1 elements
   * @maxtype: maximum attribute type to be expected
   * @policy: validation policy
   *
   * See nla_parse()
   */
3a6c2b419   Patrick McHardy   netlink: constify...
376
  static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen,
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
377
  			      struct nlattr *tb[], int maxtype,
ef7c79ed6   Patrick McHardy   [NETLINK]: Mark n...
378
  			      const struct nla_policy *policy)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  {
  	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
  		return -EINVAL;
  
  	return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
  			 nlmsg_attrlen(nlh, hdrlen), policy);
  }
  
  /**
   * nlmsg_find_attr - find a specific attribute in a netlink message
   * @nlh: netlink message header
   * @hdrlen: length of familiy specific header
   * @attrtype: type of attribute to look for
   *
   * Returns the first attribute which matches the specified type.
   */
6b8c92ba0   Nelson Elhage   netlink: Make nlm...
395
  static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh,
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
396
397
398
399
400
401
402
403
404
405
406
407
408
  					     int hdrlen, int attrtype)
  {
  	return nla_find(nlmsg_attrdata(nlh, hdrlen),
  			nlmsg_attrlen(nlh, hdrlen), attrtype);
  }
  
  /**
   * nlmsg_validate - validate a netlink message including attributes
   * @nlh: netlinket message header
   * @hdrlen: length of familiy specific header
   * @maxtype: maximum attribute type to be expected
   * @policy: validation policy
   */
3654654f7   Jan Engelhardt   netlink: let nlms...
409
410
  static inline int nlmsg_validate(const struct nlmsghdr *nlh,
  				 int hdrlen, int maxtype,
ef7c79ed6   Patrick McHardy   [NETLINK]: Mark n...
411
  				 const struct nla_policy *policy)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
412
413
414
415
416
417
418
419
420
  {
  	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
  		return -EINVAL;
  
  	return nla_validate(nlmsg_attrdata(nlh, hdrlen),
  			    nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
  }
  
  /**
97676b6b5   Thomas Graf   [RTNETLINK]: Add ...
421
422
423
424
425
   * nlmsg_report - need to report back to application?
   * @nlh: netlink message header
   *
   * Returns 1 if a report back to the application is requested.
   */
3a6c2b419   Patrick McHardy   netlink: constify...
426
  static inline int nlmsg_report(const struct nlmsghdr *nlh)
97676b6b5   Thomas Graf   [RTNETLINK]: Add ...
427
428
429
430
431
  {
  	return !!(nlh->nlmsg_flags & NLM_F_ECHO);
  }
  
  /**
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
   * nlmsg_for_each_attr - iterate over a stream of attributes
   * @pos: loop counter, set to current attribute
   * @nlh: netlink message header
   * @hdrlen: length of familiy specific header
   * @rem: initialized to len, holds bytes currently remaining in stream
   */
  #define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
  	nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
  			  nlmsg_attrlen(nlh, hdrlen), rem)
  
  #if 0
  /* FIXME: Enable once all users have been converted */
  
  /**
   * __nlmsg_put - Add a new netlink message to an skb
   * @skb: socket buffer to store message in
   * @pid: netlink process id
   * @seq: sequence number of message
   * @type: message type
   * @payload: length of message payload
   * @flags: message flags
   *
   * The caller is responsible to ensure that the skb provides enough
   * tailroom for both the netlink header and payload.
   */
  static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid,
  					   u32 seq, int type, int payload,
  					   int flags)
  {
  	struct nlmsghdr *nlh;
  
  	nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload));
  	nlh->nlmsg_type = type;
  	nlh->nlmsg_len = nlmsg_msg_size(payload);
  	nlh->nlmsg_flags = flags;
  	nlh->nlmsg_pid = pid;
  	nlh->nlmsg_seq = seq;
  
  	memset((unsigned char *) nlmsg_data(nlh) + payload, 0,
  	       nlmsg_padlen(payload));
  
  	return nlh;
  }
  #endif
  
  /**
   * nlmsg_put - Add a new netlink message to an skb
   * @skb: socket buffer to store message in
   * @pid: netlink process id
   * @seq: sequence number of message
   * @type: message type
   * @payload: length of message payload
   * @flags: message flags
   *
   * Returns NULL if the tailroom of the skb is insufficient to store
   * the message header and payload.
   */
  static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
  					 int type, int payload, int flags)
  {
  	if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
  		return NULL;
  
  	return __nlmsg_put(skb, pid, seq, type, payload, flags);
  }
  
  /**
   * nlmsg_put_answer - Add a new callback based netlink message to an skb
   * @skb: socket buffer to store message in
   * @cb: netlink callback
   * @type: message type
   * @payload: length of message payload
   * @flags: message flags
   *
   * Returns NULL if the tailroom of the skb is insufficient to store
   * the message header and payload.
   */
  static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
  						struct netlink_callback *cb,
  						int type, int payload,
  						int flags)
  {
  	return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
  			 type, payload, flags);
  }
  
  /**
   * nlmsg_new - Allocate a new netlink message
339bf98ff   Thomas Graf   [NETLINK]: Do pre...
520
   * @payload: size of the message payload
fe4944e59   Thomas Graf   [NETLINK]: Extend...
521
   * @flags: the type of memory to allocate.
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
522
   *
339bf98ff   Thomas Graf   [NETLINK]: Do pre...
523
524
   * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known
   * and a good default is needed.
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
525
   */
339bf98ff   Thomas Graf   [NETLINK]: Do pre...
526
  static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
527
  {
339bf98ff   Thomas Graf   [NETLINK]: Do pre...
528
  	return alloc_skb(nlmsg_total_size(payload), flags);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
  }
  
  /**
   * nlmsg_end - Finalize a netlink message
   * @skb: socket buffer the message is stored in
   * @nlh: netlink message header
   *
   * Corrects the netlink message header to include the appeneded
   * attributes. Only necessary if attributes have been added to
   * the message.
   *
   * Returns the total data length of the skb.
   */
  static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
  {
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
544
  	nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh;
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
545
546
547
548
549
  
  	return skb->len;
  }
  
  /**
fe4944e59   Thomas Graf   [NETLINK]: Extend...
550
551
552
553
554
555
556
   * nlmsg_get_pos - return current position in netlink message
   * @skb: socket buffer the message is stored in
   *
   * Returns a pointer to the current tail of the message.
   */
  static inline void *nlmsg_get_pos(struct sk_buff *skb)
  {
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
557
  	return skb_tail_pointer(skb);
fe4944e59   Thomas Graf   [NETLINK]: Extend...
558
559
560
561
562
563
564
  }
  
  /**
   * nlmsg_trim - Trim message to a mark
   * @skb: socket buffer the message is stored in
   * @mark: mark to trim to
   *
bc3ed28ca   Thomas Graf   netlink: Improve ...
565
   * Trims the message to the provided mark.
fe4944e59   Thomas Graf   [NETLINK]: Extend...
566
   */
bc3ed28ca   Thomas Graf   netlink: Improve ...
567
  static inline void nlmsg_trim(struct sk_buff *skb, const void *mark)
fe4944e59   Thomas Graf   [NETLINK]: Extend...
568
569
570
  {
  	if (mark)
  		skb_trim(skb, (unsigned char *) mark - skb->data);
fe4944e59   Thomas Graf   [NETLINK]: Extend...
571
572
573
  }
  
  /**
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
574
575
576
577
578
   * nlmsg_cancel - Cancel construction of a netlink message
   * @skb: socket buffer the message is stored in
   * @nlh: netlink message header
   *
   * Removes the complete netlink message including all
bc3ed28ca   Thomas Graf   netlink: Improve ...
579
   * attributes from the socket buffer again.
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
580
   */
bc3ed28ca   Thomas Graf   netlink: Improve ...
581
  static inline void nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
582
  {
bc3ed28ca   Thomas Graf   netlink: Improve ...
583
  	nlmsg_trim(skb, nlh);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
  }
  
  /**
   * nlmsg_free - free a netlink message
   * @skb: socket buffer of netlink message
   */
  static inline void nlmsg_free(struct sk_buff *skb)
  {
  	kfree_skb(skb);
  }
  
  /**
   * nlmsg_multicast - multicast a netlink message
   * @sk: netlink socket to spread messages to
   * @skb: netlink message as socket buffer
   * @pid: own netlink pid to avoid sending to yourself
   * @group: multicast group id
d387f6ad1   Thomas Graf   [NETLINK]: Add no...
601
   * @flags: allocation flags
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
602
603
   */
  static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
d387f6ad1   Thomas Graf   [NETLINK]: Add no...
604
  				  u32 pid, unsigned int group, gfp_t flags)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
605
606
607
608
  {
  	int err;
  
  	NETLINK_CB(skb).dst_group = group;
d387f6ad1   Thomas Graf   [NETLINK]: Add no...
609
  	err = netlink_broadcast(sk, skb, pid, group, flags);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
  	if (err > 0)
  		err = 0;
  
  	return err;
  }
  
  /**
   * nlmsg_unicast - unicast a netlink message
   * @sk: netlink socket to spread message to
   * @skb: netlink message as socket buffer
   * @pid: netlink pid of the destination socket
   */
  static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid)
  {
  	int err;
  
  	err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
  	if (err > 0)
  		err = 0;
  
  	return err;
  }
  
  /**
   * nlmsg_for_each_msg - iterate over a stream of messages
   * @pos: loop counter, set to current message
   * @head: head of message stream
   * @len: length of message stream
   * @rem: initialized to len, holds bytes currently remaining in stream
   */
  #define nlmsg_for_each_msg(pos, head, len, rem) \
  	for (pos = head, rem = len; \
  	     nlmsg_ok(pos, rem); \
  	     pos = nlmsg_next(pos, &(rem)))
670dc2833   Johannes Berg   netlink: advertis...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
  /**
   * nl_dump_check_consistent - check if sequence is consistent and advertise if not
   * @cb: netlink callback structure that stores the sequence number
   * @nlh: netlink message header to write the flag to
   *
   * This function checks if the sequence (generation) number changed during dump
   * and if it did, advertises it in the netlink message header.
   *
   * The correct way to use it is to set cb->seq to the generation counter when
   * all locks for dumping have been acquired, and then call this function for
   * each message that is generated.
   *
   * Note that due to initialisation concerns, 0 is an invalid sequence number
   * and must not be used by code that uses this functionality.
   */
  static inline void
  nl_dump_check_consistent(struct netlink_callback *cb,
  			 struct nlmsghdr *nlh)
  {
  	if (cb->prev_seq && cb->seq != cb->prev_seq)
  		nlh->nlmsg_flags |= NLM_F_DUMP_INTR;
  	cb->prev_seq = cb->seq;
  }
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
  /**************************************************************************
   * Netlink Attributes
   **************************************************************************/
  
  /**
   * nla_attr_size - length of attribute not including padding
   * @payload: length of payload
   */
  static inline int nla_attr_size(int payload)
  {
  	return NLA_HDRLEN + payload;
  }
  
  /**
   * nla_total_size - total length of attribute including padding
   * @payload: length of payload
   */
  static inline int nla_total_size(int payload)
  {
  	return NLA_ALIGN(nla_attr_size(payload));
  }
  
  /**
   * nla_padlen - length of padding at the tail of attribute
   * @payload: length of payload
   */
  static inline int nla_padlen(int payload)
  {
  	return nla_total_size(payload) - nla_attr_size(payload);
  }
  
  /**
8f4c1f9b0   Thomas Graf   [NETLINK]: Introd...
699
700
701
702
703
704
705
706
707
   * nla_type - attribute type
   * @nla: netlink attribute
   */
  static inline int nla_type(const struct nlattr *nla)
  {
  	return nla->nla_type & NLA_TYPE_MASK;
  }
  
  /**
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
   * nla_data - head of payload
   * @nla: netlink attribute
   */
  static inline void *nla_data(const struct nlattr *nla)
  {
  	return (char *) nla + NLA_HDRLEN;
  }
  
  /**
   * nla_len - length of payload
   * @nla: netlink attribute
   */
  static inline int nla_len(const struct nlattr *nla)
  {
  	return nla->nla_len - NLA_HDRLEN;
  }
  
  /**
   * nla_ok - check if the netlink attribute fits into the remaining bytes
   * @nla: netlink attribute
   * @remaining: number of bytes remaining in attribute stream
   */
  static inline int nla_ok(const struct nlattr *nla, int remaining)
  {
1045b03e0   Vegard Nossum   netlink: fix over...
732
  	return remaining >= (int) sizeof(*nla) &&
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
733
734
735
736
737
  	       nla->nla_len >= sizeof(*nla) &&
  	       nla->nla_len <= remaining;
  }
  
  /**
d1ec3b772   Pierre Ynard   [NETLINK]: Fix ty...
738
   * nla_next - next netlink attribute in attribute stream
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
   * @nla: netlink attribute
   * @remaining: number of bytes remaining in attribute stream
   *
   * Returns the next netlink attribute in the attribute stream and
   * decrements remaining by the size of the current attribute.
   */
  static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
  {
  	int totlen = NLA_ALIGN(nla->nla_len);
  
  	*remaining -= totlen;
  	return (struct nlattr *) ((char *) nla + totlen);
  }
  
  /**
fe4944e59   Thomas Graf   [NETLINK]: Extend...
754
755
756
757
758
759
   * nla_find_nested - find attribute in a set of nested attributes
   * @nla: attribute containing the nested attributes
   * @attrtype: type of attribute to look for
   *
   * Returns the first attribute which matches the specified type.
   */
3654654f7   Jan Engelhardt   netlink: let nlms...
760
761
  static inline struct nlattr *
  nla_find_nested(const struct nlattr *nla, int attrtype)
fe4944e59   Thomas Graf   [NETLINK]: Extend...
762
763
764
765
766
  {
  	return nla_find(nla_data(nla), nla_len(nla), attrtype);
  }
  
  /**
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
767
768
769
770
771
772
773
774
775
   * nla_parse_nested - parse nested attributes
   * @tb: destination array with maxtype+1 elements
   * @maxtype: maximum attribute type to be expected
   * @nla: attribute containing the nested attributes
   * @policy: validation policy
   *
   * See nla_parse()
   */
  static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
b057efd4d   Patrick McHardy   netlink: constify...
776
  				   const struct nlattr *nla,
ef7c79ed6   Patrick McHardy   [NETLINK]: Mark n...
777
  				   const struct nla_policy *policy)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
778
779
780
  {
  	return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
  }
1092cb219   Patrick McHardy   [NETLINK]: attr: ...
781
782
  
  /**
d1ec3b772   Pierre Ynard   [NETLINK]: Fix ty...
783
   * nla_put_u8 - Add a u8 netlink attribute to a socket buffer
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
   * @skb: socket buffer to add attribute to
   * @attrtype: attribute type
   * @value: numeric value
   */
  static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
  {
  	return nla_put(skb, attrtype, sizeof(u8), &value);
  }
  
  /**
   * nla_put_u16 - Add a u16 netlink attribute to a socket buffer
   * @skb: socket buffer to add attribute to
   * @attrtype: attribute type
   * @value: numeric value
   */
  static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
  {
  	return nla_put(skb, attrtype, sizeof(u16), &value);
  }
  
  /**
   * nla_put_u32 - Add a u32 netlink attribute to a socket buffer
   * @skb: socket buffer to add attribute to
   * @attrtype: attribute type
   * @value: numeric value
   */
  static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
  {
  	return nla_put(skb, attrtype, sizeof(u32), &value);
  }
  
  /**
   * nla_put_64 - Add a u64 netlink attribute to a socket buffer
   * @skb: socket buffer to add attribute to
   * @attrtype: attribute type
   * @value: numeric value
   */
  static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)
  {
  	return nla_put(skb, attrtype, sizeof(u64), &value);
  }
  
  /**
   * nla_put_string - Add a string netlink attribute to a socket buffer
   * @skb: socket buffer to add attribute to
   * @attrtype: attribute type
   * @str: NUL terminated string
   */
  static inline int nla_put_string(struct sk_buff *skb, int attrtype,
  				 const char *str)
  {
  	return nla_put(skb, attrtype, strlen(str) + 1, str);
  }
  
  /**
   * nla_put_flag - Add a flag netlink attribute to a socket buffer
   * @skb: socket buffer to add attribute to
   * @attrtype: attribute type
   */
  static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
  {
  	return nla_put(skb, attrtype, 0, NULL);
  }
  
  /**
   * nla_put_msecs - Add a msecs netlink attribute to a socket buffer
   * @skb: socket buffer to add attribute to
   * @attrtype: attribute type
   * @jiffies: number of msecs in jiffies
   */
  static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
  				unsigned long jiffies)
  {
  	u64 tmp = jiffies_to_msecs(jiffies);
  	return nla_put(skb, attrtype, sizeof(u64), &tmp);
  }
  
  #define NLA_PUT(skb, attrtype, attrlen, data) \
  	do { \
f4d900a2c   Patrick McHardy   [NETLINK]: Mark a...
863
  		if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
864
865
866
867
868
869
870
871
872
873
874
875
876
877
  			goto nla_put_failure; \
  	} while(0)
  
  #define NLA_PUT_TYPE(skb, type, attrtype, value) \
  	do { \
  		type __tmp = value; \
  		NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
  	} while(0)
  
  #define NLA_PUT_U8(skb, attrtype, value) \
  	NLA_PUT_TYPE(skb, u8, attrtype, value)
  
  #define NLA_PUT_U16(skb, attrtype, value) \
  	NLA_PUT_TYPE(skb, u16, attrtype, value)
4a89c2562   Thomas Graf   [DECNET] address:...
878
879
  #define NLA_PUT_LE16(skb, attrtype, value) \
  	NLA_PUT_TYPE(skb, __le16, attrtype, value)
838965ba2   Patrick McHardy   [NETLINK]: Add NL...
880
881
  #define NLA_PUT_BE16(skb, attrtype, value) \
  	NLA_PUT_TYPE(skb, __be16, attrtype, value)
f703651ef   Jozsef Kadlecsik   netfilter: NFNL_S...
882
883
  #define NLA_PUT_NET16(skb, attrtype, value) \
  	NLA_PUT_BE16(skb, attrtype | NLA_F_NET_BYTEORDER, value)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
884
885
  #define NLA_PUT_U32(skb, attrtype, value) \
  	NLA_PUT_TYPE(skb, u32, attrtype, value)
00012e5bb   Al Viro   [IPV4]: introduce...
886
887
  #define NLA_PUT_BE32(skb, attrtype, value) \
  	NLA_PUT_TYPE(skb, __be32, attrtype, value)
f703651ef   Jozsef Kadlecsik   netfilter: NFNL_S...
888
889
  #define NLA_PUT_NET32(skb, attrtype, value) \
  	NLA_PUT_BE32(skb, attrtype | NLA_F_NET_BYTEORDER, value)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
890
891
  #define NLA_PUT_U64(skb, attrtype, value) \
  	NLA_PUT_TYPE(skb, u64, attrtype, value)
07a7c1070   Krzysztof Piotr Oledzki   netlink: add NLA_...
892
893
  #define NLA_PUT_BE64(skb, attrtype, value) \
  	NLA_PUT_TYPE(skb, __be64, attrtype, value)
f703651ef   Jozsef Kadlecsik   netfilter: NFNL_S...
894
895
  #define NLA_PUT_NET64(skb, attrtype, value) \
  	NLA_PUT_BE64(skb, attrtype | NLA_F_NET_BYTEORDER, value)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
896
897
  #define NLA_PUT_STRING(skb, attrtype, value) \
  	NLA_PUT(skb, attrtype, strlen(value) + 1, value)
ff5dfe736   Johannes Berg   [NETLINK]: remove...
898
  #define NLA_PUT_FLAG(skb, attrtype) \
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
899
900
901
902
903
904
905
906
907
  	NLA_PUT(skb, attrtype, 0, NULL)
  
  #define NLA_PUT_MSECS(skb, attrtype, jiffies) \
  	NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies))
  
  /**
   * nla_get_u32 - return payload of u32 attribute
   * @nla: u32 netlink attribute
   */
b057efd4d   Patrick McHardy   netlink: constify...
908
  static inline u32 nla_get_u32(const struct nlattr *nla)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
909
910
911
912
913
  {
  	return *(u32 *) nla_data(nla);
  }
  
  /**
00012e5bb   Al Viro   [IPV4]: introduce...
914
915
916
   * nla_get_be32 - return payload of __be32 attribute
   * @nla: __be32 netlink attribute
   */
b057efd4d   Patrick McHardy   netlink: constify...
917
  static inline __be32 nla_get_be32(const struct nlattr *nla)
00012e5bb   Al Viro   [IPV4]: introduce...
918
919
920
921
922
  {
  	return *(__be32 *) nla_data(nla);
  }
  
  /**
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
923
924
925
   * nla_get_u16 - return payload of u16 attribute
   * @nla: u16 netlink attribute
   */
b057efd4d   Patrick McHardy   netlink: constify...
926
  static inline u16 nla_get_u16(const struct nlattr *nla)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
927
928
929
930
931
  {
  	return *(u16 *) nla_data(nla);
  }
  
  /**
838965ba2   Patrick McHardy   [NETLINK]: Add NL...
932
933
934
   * nla_get_be16 - return payload of __be16 attribute
   * @nla: __be16 netlink attribute
   */
b057efd4d   Patrick McHardy   netlink: constify...
935
  static inline __be16 nla_get_be16(const struct nlattr *nla)
838965ba2   Patrick McHardy   [NETLINK]: Add NL...
936
937
938
939
940
  {
  	return *(__be16 *) nla_data(nla);
  }
  
  /**
4a89c2562   Thomas Graf   [DECNET] address:...
941
942
943
   * nla_get_le16 - return payload of __le16 attribute
   * @nla: __le16 netlink attribute
   */
b057efd4d   Patrick McHardy   netlink: constify...
944
  static inline __le16 nla_get_le16(const struct nlattr *nla)
4a89c2562   Thomas Graf   [DECNET] address:...
945
946
947
948
949
  {
  	return *(__le16 *) nla_data(nla);
  }
  
  /**
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
950
951
952
   * nla_get_u8 - return payload of u8 attribute
   * @nla: u8 netlink attribute
   */
b057efd4d   Patrick McHardy   netlink: constify...
953
  static inline u8 nla_get_u8(const struct nlattr *nla)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
954
955
956
957
958
959
960
961
  {
  	return *(u8 *) nla_data(nla);
  }
  
  /**
   * nla_get_u64 - return payload of u64 attribute
   * @nla: u64 netlink attribute
   */
b057efd4d   Patrick McHardy   netlink: constify...
962
  static inline u64 nla_get_u64(const struct nlattr *nla)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
963
964
965
966
967
968
969
970
971
  {
  	u64 tmp;
  
  	nla_memcpy(&tmp, nla, sizeof(tmp));
  
  	return tmp;
  }
  
  /**
a17c85984   Pablo Neira Ayuso   netfilter: conntr...
972
973
974
975
976
   * nla_get_be64 - return payload of __be64 attribute
   * @nla: __be64 netlink attribute
   */
  static inline __be64 nla_get_be64(const struct nlattr *nla)
  {
f5d410f2e   Pablo Neira Ayuso   netlink: fix unal...
977
978
979
980
981
  	__be64 tmp;
  
  	nla_memcpy(&tmp, nla, sizeof(tmp));
  
  	return tmp;
a17c85984   Pablo Neira Ayuso   netfilter: conntr...
982
983
984
  }
  
  /**
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
985
986
987
   * nla_get_flag - return payload of flag attribute
   * @nla: flag netlink attribute
   */
b057efd4d   Patrick McHardy   netlink: constify...
988
  static inline int nla_get_flag(const struct nlattr *nla)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
989
990
991
992
993
994
995
996
997
998
  {
  	return !!nla;
  }
  
  /**
   * nla_get_msecs - return payload of msecs attribute
   * @nla: msecs netlink attribute
   *
   * Returns the number of milliseconds in jiffies.
   */
b057efd4d   Patrick McHardy   netlink: constify...
999
  static inline unsigned long nla_get_msecs(const struct nlattr *nla)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
  {
  	u64 msecs = nla_get_u64(nla);
  
  	return msecs_to_jiffies((unsigned long) msecs);
  }
  
  /**
   * nla_nest_start - Start a new level of nested attributes
   * @skb: socket buffer to add attributes to
   * @attrtype: attribute type of container
   *
   * Returns the container attribute
   */
  static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
  {
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1015
  	struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1016
1017
1018
1019
1020
1021
1022
1023
1024
  
  	if (nla_put(skb, attrtype, 0, NULL) < 0)
  		return NULL;
  
  	return start;
  }
  
  /**
   * nla_nest_end - Finalize nesting of attributes
d1ec3b772   Pierre Ynard   [NETLINK]: Fix ty...
1025
   * @skb: socket buffer the attributes are stored in
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1026
1027
1028
1029
1030
1031
1032
1033
1034
   * @start: container attribute
   *
   * Corrects the container attribute header to include the all
   * appeneded attributes.
   *
   * Returns the total data length of the skb.
   */
  static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
  {
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
1035
  	start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start;
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1036
1037
1038
1039
1040
1041
1042
1043
1044
  	return skb->len;
  }
  
  /**
   * nla_nest_cancel - Cancel nesting of attributes
   * @skb: socket buffer the message is stored in
   * @start: container attribute
   *
   * Removes the container attribute and including all nested
bc3ed28ca   Thomas Graf   netlink: Improve ...
1045
   * attributes. Returns -EMSGSIZE
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1046
   */
bc3ed28ca   Thomas Graf   netlink: Improve ...
1047
  static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1048
  {
bc3ed28ca   Thomas Graf   netlink: Improve ...
1049
  	nlmsg_trim(skb, start);
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1050
1051
1052
  }
  
  /**
4fe5d5c07   Paul Moore   [Netlink]: add nl...
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
   * nla_validate_nested - Validate a stream of nested attributes
   * @start: container attribute
   * @maxtype: maximum attribute type to be expected
   * @policy: validation policy
   *
   * Validates all attributes in the nested attribute stream against the
   * specified policy. Attributes with a type exceeding maxtype will be
   * ignored. See documenation of struct nla_policy for more details.
   *
   * Returns 0 on success or a negative error code.
   */
3654654f7   Jan Engelhardt   netlink: let nlms...
1064
  static inline int nla_validate_nested(const struct nlattr *start, int maxtype,
ef7c79ed6   Patrick McHardy   [NETLINK]: Mark n...
1065
  				      const struct nla_policy *policy)
4fe5d5c07   Paul Moore   [Netlink]: add nl...
1066
1067
1068
1069
1070
  {
  	return nla_validate(nla_data(start), nla_len(start), maxtype, policy);
  }
  
  /**
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
   * nla_for_each_attr - iterate over a stream of attributes
   * @pos: loop counter, set to current attribute
   * @head: head of attribute stream
   * @len: length of attribute stream
   * @rem: initialized to len, holds bytes currently remaining in stream
   */
  #define nla_for_each_attr(pos, head, len, rem) \
  	for (pos = head, rem = len; \
  	     nla_ok(pos, rem); \
  	     pos = nla_next(pos, &(rem)))
fe4944e59   Thomas Graf   [NETLINK]: Extend...
1081
1082
1083
1084
1085
1086
1087
1088
  /**
   * nla_for_each_nested - iterate over nested attributes
   * @pos: loop counter, set to current attribute
   * @nla: attribute containing the nested attributes
   * @rem: initialized to len, holds bytes currently remaining in stream
   */
  #define nla_for_each_nested(pos, nla, rem) \
  	nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem)
bfa83a9e0   Thomas Graf   [NETLINK]: Type-s...
1089
  #endif