aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2005-11-09 20:25:51 -0500
committerThomas Graf <tgr@axs.localdomain>2005-11-09 20:26:40 -0500
commitbfa83a9e03cf8d501c6272999843470afecb32ed (patch)
tree1584441824b67bee52906a1345d8277e6965fe1b /include/net
parent9fb9cbb1082d6b31fb45aa1a14432449a0df6cf1 (diff)
[NETLINK]: Type-safe netlink messages/attributes interface
Introduces a new type-safe interface for netlink message and attributes handling. The interface is fully binary compatible with the old interface towards userspace. Besides type safety, this interface features attribute validation capabilities, simplified message contstruction, and documentation. The resulting netlink code should be smaller, less error prone and easier to understand. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/netlink.h877
1 files changed, 877 insertions, 0 deletions
diff --git a/include/net/netlink.h b/include/net/netlink.h
new file mode 100644
index 000000000000..c99e22db9632
--- /dev/null
+++ b/include/net/netlink.h
@@ -0,0 +1,877 @@
1#ifndef __NET_NETLINK_H
2#define __NET_NETLINK_H
3
4#include <linux/types.h>
5#include <linux/netlink.h>
6
7/* ========================================================================
8 * Netlink Messages and Attributes Interface (As Seen On TV)
9 * ------------------------------------------------------------------------
10 * Messages Interface
11 * ------------------------------------------------------------------------
12 *
13 * Message Format:
14 * <--- nlmsg_total_size(payload) --->
15 * <-- nlmsg_msg_size(payload) ->
16 * +----------+- - -+-------------+- - -+-------- - -
17 * | nlmsghdr | Pad | Payload | Pad | nlmsghdr
18 * +----------+- - -+-------------+- - -+-------- - -
19 * nlmsg_data(nlh)---^ ^
20 * nlmsg_next(nlh)-----------------------+
21 *
22 * Payload Format:
23 * <---------------------- nlmsg_len(nlh) --------------------->
24 * <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) ->
25 * +----------------------+- - -+--------------------------------+
26 * | Family Header | Pad | Attributes |
27 * +----------------------+- - -+--------------------------------+
28 * nlmsg_attrdata(nlh, hdrlen)---^
29 *
30 * Data Structures:
31 * struct nlmsghdr netlink message header
32 *
33 * Message Construction:
34 * nlmsg_new() create a new netlink message
35 * nlmsg_put() add a netlink message to an skb
36 * nlmsg_put_answer() callback based nlmsg_put()
37 * nlmsg_end() finanlize netlink message
38 * nlmsg_cancel() cancel message construction
39 * nlmsg_free() free a netlink message
40 *
41 * Message Sending:
42 * nlmsg_multicast() multicast message to several groups
43 * nlmsg_unicast() unicast a message to a single socket
44 *
45 * Message Length Calculations:
46 * nlmsg_msg_size(payload) length of message w/o padding
47 * nlmsg_total_size(payload) length of message w/ padding
48 * nlmsg_padlen(payload) length of padding at tail
49 *
50 * Message Payload Access:
51 * nlmsg_data(nlh) head of message payload
52 * nlmsg_len(nlh) length of message payload
53 * nlmsg_attrdata(nlh, hdrlen) head of attributes data
54 * nlmsg_attrlen(nlh, hdrlen) length of attributes data
55 *
56 * Message Parsing:
57 * nlmsg_ok(nlh, remaining) does nlh fit into remaining bytes?
58 * nlmsg_next(nlh, remaining) get next netlink message
59 * nlmsg_parse() parse attributes of a message
60 * nlmsg_find_attr() find an attribute in a message
61 * nlmsg_for_each_msg() loop over all messages
62 * nlmsg_validate() validate netlink message incl. attrs
63 * nlmsg_for_each_attr() loop over all attributes
64 *
65 * ------------------------------------------------------------------------
66 * Attributes Interface
67 * ------------------------------------------------------------------------
68 *
69 * Attribute Format:
70 * <------- nla_total_size(payload) ------->
71 * <---- nla_attr_size(payload) ----->
72 * +----------+- - -+- - - - - - - - - +- - -+-------- - -
73 * | Header | Pad | Payload | Pad | Header
74 * +----------+- - -+- - - - - - - - - +- - -+-------- - -
75 * <- nla_len(nla) -> ^
76 * nla_data(nla)----^ |
77 * nla_next(nla)-----------------------------'
78 *
79 * Data Structures:
80 * struct nlattr netlink attribtue header
81 *
82 * Attribute Construction:
83 * nla_reserve(skb, type, len) reserve skb tailroom for an attribute
84 * nla_put(skb, type, len, data) add attribute to skb
85 *
86 * Attribute Construction for Basic Types:
87 * nla_put_u8(skb, type, value) add u8 attribute to skb
88 * nla_put_u16(skb, type, value) add u16 attribute to skb
89 * nla_put_u32(skb, type, value) add u32 attribute to skb
90 * nla_put_u64(skb, type, value) add u64 attribute to skb
91 * nla_put_string(skb, type, str) add string attribute to skb
92 * nla_put_flag(skb, type) add flag attribute to skb
93 * nla_put_msecs(skb, type, jiffies) add msecs attribute to skb
94 *
95 * Exceptions Based Attribute Construction:
96 * NLA_PUT(skb, type, len, data) add attribute to skb
97 * NLA_PUT_U8(skb, type, value) add u8 attribute to skb
98 * NLA_PUT_U16(skb, type, value) add u16 attribute to skb
99 * NLA_PUT_U32(skb, type, value) add u32 attribute to skb
100 * NLA_PUT_U64(skb, type, value) add u64 attribute to skb
101 * NLA_PUT_STRING(skb, type, str) add string attribute to skb
102 * NLA_PUT_FLAG(skb, type) add flag attribute to skb
103 * NLA_PUT_MSECS(skb, type, jiffies) add msecs attribute to skb
104 *
105 * The meaning of these functions is equal to their lower case
106 * variants but they jump to the label nla_put_failure in case
107 * of a failure.
108 *
109 * Nested Attributes Construction:
110 * nla_nest_start(skb, type) start a nested attribute
111 * nla_nest_end(skb, nla) finalize a nested attribute
112 * nla_nest_cancel(skb, nla) cancel nested attribute construction
113 *
114 * Attribute Length Calculations:
115 * nla_attr_size(payload) length of attribute w/o padding
116 * nla_total_size(payload) length of attribute w/ padding
117 * nla_padlen(payload) length of padding
118 *
119 * Attribute Payload Access:
120 * nla_data(nla) head of attribute payload
121 * nla_len(nla) length of attribute payload
122 *
123 * Attribute Payload Access for Basic Types:
124 * nla_get_u8(nla) get payload for a u8 attribute
125 * nla_get_u16(nla) get payload for a u16 attribute
126 * nla_get_u32(nla) get payload for a u32 attribute
127 * nla_get_u64(nla) get payload for a u64 attribute
128 * nla_get_flag(nla) return 1 if flag is true
129 * nla_get_msecs(nla) get payload for a msecs attribute
130 *
131 * Attribute Misc:
132 * nla_memcpy(dest, nla, count) copy attribute into memory
133 * nla_memcmp(nla, data, size) compare attribute with memory area
134 * nla_strlcpy(dst, nla, size) copy attribute to a sized string
135 * nla_strcmp(nla, str) compare attribute with string
136 *
137 * Attribute Parsing:
138 * nla_ok(nla, remaining) does nla fit into remaining bytes?
139 * nla_next(nla, remaining) get next netlink attribute
140 * nla_validate() validate a stream of attributes
141 * nla_find() find attribute in stream of attributes
142 * nla_parse() parse and validate stream of attrs
143 * nla_parse_nested() parse nested attribuets
144 * nla_for_each_attr() loop over all attributes
145 *=========================================================================
146 */
147
148 /**
149 * Standard attribute types to specify validation policy
150 */
151enum {
152 NLA_UNSPEC,
153 NLA_U8,
154 NLA_U16,
155 NLA_U32,
156 NLA_U64,
157 NLA_STRING,
158 NLA_FLAG,
159 NLA_MSECS,
160 NLA_NESTED,
161 __NLA_TYPE_MAX,
162};
163
164#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
165
166/**
167 * struct nla_policy - attribute validation policy
168 * @type: Type of attribute or NLA_UNSPEC
169 * @minlen: Minimal length of payload required to be available
170 *
171 * Policies are defined as arrays of this struct, the array must be
172 * accessible by attribute type up to the highest identifier to be expected.
173 *
174 * Example:
175 * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = {
176 * [ATTR_FOO] = { .type = NLA_U16 },
177 * [ATTR_BAR] = { .type = NLA_STRING },
178 * [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) },
179 * };
180 */
181struct nla_policy {
182 u16 type;
183 u16 minlen;
184};
185
186extern int nla_validate(struct nlattr *head, int len, int maxtype,
187 struct nla_policy *policy);
188extern int nla_parse(struct nlattr *tb[], int maxtype,
189 struct nlattr *head, int len,
190 struct nla_policy *policy);
191extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
192extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
193 size_t dstsize);
194extern int nla_memcpy(void *dest, struct nlattr *src, int count);
195extern int nla_memcmp(const struct nlattr *nla, const void *data,
196 size_t size);
197extern int nla_strcmp(const struct nlattr *nla, const char *str);
198extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype,
199 int attrlen);
200extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype,
201 int attrlen);
202extern void __nla_put(struct sk_buff *skb, int attrtype,
203 int attrlen, const void *data);
204extern int nla_put(struct sk_buff *skb, int attrtype,
205 int attrlen, const void *data);
206
207/**************************************************************************
208 * Netlink Messages
209 **************************************************************************/
210
211/**
212 * nlmsg_msg_size - length of netlink message not including padding
213 * @payload: length of message payload
214 */
215static inline int nlmsg_msg_size(int payload)
216{
217 return NLMSG_HDRLEN + payload;
218}
219
220/**
221 * nlmsg_total_size - length of netlink message including padding
222 * @payload: length of message payload
223 */
224static inline int nlmsg_total_size(int payload)
225{
226 return NLMSG_ALIGN(nlmsg_msg_size(payload));
227}
228
229/**
230 * nlmsg_padlen - length of padding at the message's tail
231 * @payload: length of message payload
232 */
233static inline int nlmsg_padlen(int payload)
234{
235 return nlmsg_total_size(payload) - nlmsg_msg_size(payload);
236}
237
238/**
239 * nlmsg_data - head of message payload
240 * @nlh: netlink messsage header
241 */
242static inline void *nlmsg_data(const struct nlmsghdr *nlh)
243{
244 return (unsigned char *) nlh + NLMSG_HDRLEN;
245}
246
247/**
248 * nlmsg_len - length of message payload
249 * @nlh: netlink message header
250 */
251static inline int nlmsg_len(const struct nlmsghdr *nlh)
252{
253 return nlh->nlmsg_len - NLMSG_HDRLEN;
254}
255
256/**
257 * nlmsg_attrdata - head of attributes data
258 * @nlh: netlink message header
259 * @hdrlen: length of family specific header
260 */
261static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
262 int hdrlen)
263{
264 unsigned char *data = nlmsg_data(nlh);
265 return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
266}
267
268/**
269 * nlmsg_attrlen - length of attributes data
270 * @nlh: netlink message header
271 * @hdrlen: length of family specific header
272 */
273static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
274{
275 return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
276}
277
278/**
279 * nlmsg_ok - check if the netlink message fits into the remaining bytes
280 * @nlh: netlink message header
281 * @remaining: number of bytes remaining in message stream
282 */
283static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
284{
285 return (remaining >= sizeof(struct nlmsghdr) &&
286 nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
287 nlh->nlmsg_len <= remaining);
288}
289
290/**
291 * nlmsg_next - next netlink message in message stream
292 * @nlh: netlink message header
293 * @remaining: number of bytes remaining in message stream
294 *
295 * Returns the next netlink message in the message stream and
296 * decrements remaining by the size of the current message.
297 */
298static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
299{
300 int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
301
302 *remaining -= totlen;
303
304 return (struct nlmsghdr *) ((unsigned char *) nlh + totlen);
305}
306
307/**
308 * nlmsg_parse - parse attributes of a netlink message
309 * @nlh: netlink message header
310 * @hdrlen: length of family specific header
311 * @tb: destination array with maxtype+1 elements
312 * @maxtype: maximum attribute type to be expected
313 * @policy: validation policy
314 *
315 * See nla_parse()
316 */
317static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
318 struct nlattr *tb[], int maxtype,
319 struct nla_policy *policy)
320{
321 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
322 return -EINVAL;
323
324 return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
325 nlmsg_attrlen(nlh, hdrlen), policy);
326}
327
328/**
329 * nlmsg_find_attr - find a specific attribute in a netlink message
330 * @nlh: netlink message header
331 * @hdrlen: length of familiy specific header
332 * @attrtype: type of attribute to look for
333 *
334 * Returns the first attribute which matches the specified type.
335 */
336static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
337 int hdrlen, int attrtype)
338{
339 return nla_find(nlmsg_attrdata(nlh, hdrlen),
340 nlmsg_attrlen(nlh, hdrlen), attrtype);
341}
342
343/**
344 * nlmsg_validate - validate a netlink message including attributes
345 * @nlh: netlinket message header
346 * @hdrlen: length of familiy specific header
347 * @maxtype: maximum attribute type to be expected
348 * @policy: validation policy
349 */
350static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
351 struct nla_policy *policy)
352{
353 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
354 return -EINVAL;
355
356 return nla_validate(nlmsg_attrdata(nlh, hdrlen),
357 nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
358}
359
360/**
361 * nlmsg_for_each_attr - iterate over a stream of attributes
362 * @pos: loop counter, set to current attribute
363 * @nlh: netlink message header
364 * @hdrlen: length of familiy specific header
365 * @rem: initialized to len, holds bytes currently remaining in stream
366 */
367#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
368 nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
369 nlmsg_attrlen(nlh, hdrlen), rem)
370
371#if 0
372/* FIXME: Enable once all users have been converted */
373
374/**
375 * __nlmsg_put - Add a new netlink message to an skb
376 * @skb: socket buffer to store message in
377 * @pid: netlink process id
378 * @seq: sequence number of message
379 * @type: message type
380 * @payload: length of message payload
381 * @flags: message flags
382 *
383 * The caller is responsible to ensure that the skb provides enough
384 * tailroom for both the netlink header and payload.
385 */
386static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid,
387 u32 seq, int type, int payload,
388 int flags)
389{
390 struct nlmsghdr *nlh;
391
392 nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload));
393 nlh->nlmsg_type = type;
394 nlh->nlmsg_len = nlmsg_msg_size(payload);
395 nlh->nlmsg_flags = flags;
396 nlh->nlmsg_pid = pid;
397 nlh->nlmsg_seq = seq;
398
399 memset((unsigned char *) nlmsg_data(nlh) + payload, 0,
400 nlmsg_padlen(payload));
401
402 return nlh;
403}
404#endif
405
406/**
407 * nlmsg_put - Add a new netlink message to an skb
408 * @skb: socket buffer to store message in
409 * @pid: netlink process id
410 * @seq: sequence number of message
411 * @type: message type
412 * @payload: length of message payload
413 * @flags: message flags
414 *
415 * Returns NULL if the tailroom of the skb is insufficient to store
416 * the message header and payload.
417 */
418static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
419 int type, int payload, int flags)
420{
421 if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
422 return NULL;
423
424 return __nlmsg_put(skb, pid, seq, type, payload, flags);
425}
426
427/**
428 * nlmsg_put_answer - Add a new callback based netlink message to an skb
429 * @skb: socket buffer to store message in
430 * @cb: netlink callback
431 * @type: message type
432 * @payload: length of message payload
433 * @flags: message flags
434 *
435 * Returns NULL if the tailroom of the skb is insufficient to store
436 * the message header and payload.
437 */
438static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
439 struct netlink_callback *cb,
440 int type, int payload,
441 int flags)
442{
443 return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
444 type, payload, flags);
445}
446
447/**
448 * nlmsg_new - Allocate a new netlink message
449 * @size: maximum size of message
450 *
451 * Use NLMSG_GOODSIZE if size isn't know and you need a good default size.
452 */
453static inline struct sk_buff *nlmsg_new(int size)
454{
455 return alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
456}
457
458/**
459 * nlmsg_end - Finalize a netlink message
460 * @skb: socket buffer the message is stored in
461 * @nlh: netlink message header
462 *
463 * Corrects the netlink message header to include the appeneded
464 * attributes. Only necessary if attributes have been added to
465 * the message.
466 *
467 * Returns the total data length of the skb.
468 */
469static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
470{
471 nlh->nlmsg_len = skb->tail - (unsigned char *) nlh;
472
473 return skb->len;
474}
475
476/**
477 * nlmsg_cancel - Cancel construction of a netlink message
478 * @skb: socket buffer the message is stored in
479 * @nlh: netlink message header
480 *
481 * Removes the complete netlink message including all
482 * attributes from the socket buffer again. Returns -1.
483 */
484static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
485{
486 skb_trim(skb, (unsigned char *) nlh - skb->data);
487
488 return -1;
489}
490
491/**
492 * nlmsg_free - free a netlink message
493 * @skb: socket buffer of netlink message
494 */
495static inline void nlmsg_free(struct sk_buff *skb)
496{
497 kfree_skb(skb);
498}
499
500/**
501 * nlmsg_multicast - multicast a netlink message
502 * @sk: netlink socket to spread messages to
503 * @skb: netlink message as socket buffer
504 * @pid: own netlink pid to avoid sending to yourself
505 * @group: multicast group id
506 */
507static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
508 u32 pid, unsigned int group)
509{
510 int err;
511
512 NETLINK_CB(skb).dst_group = group;
513
514 err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL);
515 if (err > 0)
516 err = 0;
517
518 return err;
519}
520
521/**
522 * nlmsg_unicast - unicast a netlink message
523 * @sk: netlink socket to spread message to
524 * @skb: netlink message as socket buffer
525 * @pid: netlink pid of the destination socket
526 */
527static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid)
528{
529 int err;
530
531 err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
532 if (err > 0)
533 err = 0;
534
535 return err;
536}
537
538/**
539 * nlmsg_for_each_msg - iterate over a stream of messages
540 * @pos: loop counter, set to current message
541 * @head: head of message stream
542 * @len: length of message stream
543 * @rem: initialized to len, holds bytes currently remaining in stream
544 */
545#define nlmsg_for_each_msg(pos, head, len, rem) \
546 for (pos = head, rem = len; \
547 nlmsg_ok(pos, rem); \
548 pos = nlmsg_next(pos, &(rem)))
549
550/**************************************************************************
551 * Netlink Attributes
552 **************************************************************************/
553
554/**
555 * nla_attr_size - length of attribute not including padding
556 * @payload: length of payload
557 */
558static inline int nla_attr_size(int payload)
559{
560 return NLA_HDRLEN + payload;
561}
562
563/**
564 * nla_total_size - total length of attribute including padding
565 * @payload: length of payload
566 */
567static inline int nla_total_size(int payload)
568{
569 return NLA_ALIGN(nla_attr_size(payload));
570}
571
572/**
573 * nla_padlen - length of padding at the tail of attribute
574 * @payload: length of payload
575 */
576static inline int nla_padlen(int payload)
577{
578 return nla_total_size(payload) - nla_attr_size(payload);
579}
580
581/**
582 * nla_data - head of payload
583 * @nla: netlink attribute
584 */
585static inline void *nla_data(const struct nlattr *nla)
586{
587 return (char *) nla + NLA_HDRLEN;
588}
589
590/**
591 * nla_len - length of payload
592 * @nla: netlink attribute
593 */
594static inline int nla_len(const struct nlattr *nla)
595{
596 return nla->nla_len - NLA_HDRLEN;
597}
598
599/**
600 * nla_ok - check if the netlink attribute fits into the remaining bytes
601 * @nla: netlink attribute
602 * @remaining: number of bytes remaining in attribute stream
603 */
604static inline int nla_ok(const struct nlattr *nla, int remaining)
605{
606 return remaining >= sizeof(*nla) &&
607 nla->nla_len >= sizeof(*nla) &&
608 nla->nla_len <= remaining;
609}
610
611/**
612 * nla_next - next netlink attribte in attribute stream
613 * @nla: netlink attribute
614 * @remaining: number of bytes remaining in attribute stream
615 *
616 * Returns the next netlink attribute in the attribute stream and
617 * decrements remaining by the size of the current attribute.
618 */
619static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
620{
621 int totlen = NLA_ALIGN(nla->nla_len);
622
623 *remaining -= totlen;
624 return (struct nlattr *) ((char *) nla + totlen);
625}
626
627/**
628 * nla_parse_nested - parse nested attributes
629 * @tb: destination array with maxtype+1 elements
630 * @maxtype: maximum attribute type to be expected
631 * @nla: attribute containing the nested attributes
632 * @policy: validation policy
633 *
634 * See nla_parse()
635 */
636static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
637 struct nlattr *nla,
638 struct nla_policy *policy)
639{
640 return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
641}
642/**
643 * nla_put_u8 - Add a u16 netlink attribute to a socket buffer
644 * @skb: socket buffer to add attribute to
645 * @attrtype: attribute type
646 * @value: numeric value
647 */
648static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
649{
650 return nla_put(skb, attrtype, sizeof(u8), &value);
651}
652
653/**
654 * nla_put_u16 - Add a u16 netlink attribute to a socket buffer
655 * @skb: socket buffer to add attribute to
656 * @attrtype: attribute type
657 * @value: numeric value
658 */
659static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
660{
661 return nla_put(skb, attrtype, sizeof(u16), &value);
662}
663
664/**
665 * nla_put_u32 - Add a u32 netlink attribute to a socket buffer
666 * @skb: socket buffer to add attribute to
667 * @attrtype: attribute type
668 * @value: numeric value
669 */
670static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
671{
672 return nla_put(skb, attrtype, sizeof(u32), &value);
673}
674
675/**
676 * nla_put_64 - Add a u64 netlink attribute to a socket buffer
677 * @skb: socket buffer to add attribute to
678 * @attrtype: attribute type
679 * @value: numeric value
680 */
681static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)
682{
683 return nla_put(skb, attrtype, sizeof(u64), &value);
684}
685
686/**
687 * nla_put_string - Add a string netlink attribute to a socket buffer
688 * @skb: socket buffer to add attribute to
689 * @attrtype: attribute type
690 * @str: NUL terminated string
691 */
692static inline int nla_put_string(struct sk_buff *skb, int attrtype,
693 const char *str)
694{
695 return nla_put(skb, attrtype, strlen(str) + 1, str);
696}
697
698/**
699 * nla_put_flag - Add a flag netlink attribute to a socket buffer
700 * @skb: socket buffer to add attribute to
701 * @attrtype: attribute type
702 */
703static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
704{
705 return nla_put(skb, attrtype, 0, NULL);
706}
707
708/**
709 * nla_put_msecs - Add a msecs netlink attribute to a socket buffer
710 * @skb: socket buffer to add attribute to
711 * @attrtype: attribute type
712 * @jiffies: number of msecs in jiffies
713 */
714static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
715 unsigned long jiffies)
716{
717 u64 tmp = jiffies_to_msecs(jiffies);
718 return nla_put(skb, attrtype, sizeof(u64), &tmp);
719}
720
721#define NLA_PUT(skb, attrtype, attrlen, data) \
722 do { \
723 if (nla_put(skb, attrtype, attrlen, data) < 0) \
724 goto nla_put_failure; \
725 } while(0)
726
727#define NLA_PUT_TYPE(skb, type, attrtype, value) \
728 do { \
729 type __tmp = value; \
730 NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
731 } while(0)
732
733#define NLA_PUT_U8(skb, attrtype, value) \
734 NLA_PUT_TYPE(skb, u8, attrtype, value)
735
736#define NLA_PUT_U16(skb, attrtype, value) \
737 NLA_PUT_TYPE(skb, u16, attrtype, value)
738
739#define NLA_PUT_U32(skb, attrtype, value) \
740 NLA_PUT_TYPE(skb, u32, attrtype, value)
741
742#define NLA_PUT_U64(skb, attrtype, value) \
743 NLA_PUT_TYPE(skb, u64, attrtype, value)
744
745#define NLA_PUT_STRING(skb, attrtype, value) \
746 NLA_PUT(skb, attrtype, strlen(value) + 1, value)
747
748#define NLA_PUT_FLAG(skb, attrtype, value) \
749 NLA_PUT(skb, attrtype, 0, NULL)
750
751#define NLA_PUT_MSECS(skb, attrtype, jiffies) \
752 NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies))
753
754/**
755 * nla_get_u32 - return payload of u32 attribute
756 * @nla: u32 netlink attribute
757 */
758static inline u32 nla_get_u32(struct nlattr *nla)
759{
760 return *(u32 *) nla_data(nla);
761}
762
763/**
764 * nla_get_u16 - return payload of u16 attribute
765 * @nla: u16 netlink attribute
766 */
767static inline u16 nla_get_u16(struct nlattr *nla)
768{
769 return *(u16 *) nla_data(nla);
770}
771
772/**
773 * nla_get_u8 - return payload of u8 attribute
774 * @nla: u8 netlink attribute
775 */
776static inline u8 nla_get_u8(struct nlattr *nla)
777{
778 return *(u8 *) nla_data(nla);
779}
780
781/**
782 * nla_get_u64 - return payload of u64 attribute
783 * @nla: u64 netlink attribute
784 */
785static inline u64 nla_get_u64(struct nlattr *nla)
786{
787 u64 tmp;
788
789 nla_memcpy(&tmp, nla, sizeof(tmp));
790
791 return tmp;
792}
793
794/**
795 * nla_get_flag - return payload of flag attribute
796 * @nla: flag netlink attribute
797 */
798static inline int nla_get_flag(struct nlattr *nla)
799{
800 return !!nla;
801}
802
803/**
804 * nla_get_msecs - return payload of msecs attribute
805 * @nla: msecs netlink attribute
806 *
807 * Returns the number of milliseconds in jiffies.
808 */
809static inline unsigned long nla_get_msecs(struct nlattr *nla)
810{
811 u64 msecs = nla_get_u64(nla);
812
813 return msecs_to_jiffies((unsigned long) msecs);
814}
815
816/**
817 * nla_nest_start - Start a new level of nested attributes
818 * @skb: socket buffer to add attributes to
819 * @attrtype: attribute type of container
820 *
821 * Returns the container attribute
822 */
823static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
824{
825 struct nlattr *start = (struct nlattr *) skb->tail;
826
827 if (nla_put(skb, attrtype, 0, NULL) < 0)
828 return NULL;
829
830 return start;
831}
832
833/**
834 * nla_nest_end - Finalize nesting of attributes
835 * @skb: socket buffer the attribtues are stored in
836 * @start: container attribute
837 *
838 * Corrects the container attribute header to include the all
839 * appeneded attributes.
840 *
841 * Returns the total data length of the skb.
842 */
843static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
844{
845 start->nla_len = skb->tail - (unsigned char *) start;
846 return skb->len;
847}
848
849/**
850 * nla_nest_cancel - Cancel nesting of attributes
851 * @skb: socket buffer the message is stored in
852 * @start: container attribute
853 *
854 * Removes the container attribute and including all nested
855 * attributes. Returns -1.
856 */
857static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
858{
859 if (start)
860 skb_trim(skb, (unsigned char *) start - skb->data);
861
862 return -1;
863}
864
865/**
866 * nla_for_each_attr - iterate over a stream of attributes
867 * @pos: loop counter, set to current attribute
868 * @head: head of attribute stream
869 * @len: length of attribute stream
870 * @rem: initialized to len, holds bytes currently remaining in stream
871 */
872#define nla_for_each_attr(pos, head, len, rem) \
873 for (pos = head, rem = len; \
874 nla_ok(pos, rem); \
875 pos = nla_next(pos, &(rem)))
876
877#endif