Commit f703651ef870bd6b94ddc98ae07488b7d3fd9335
Committed by
Patrick McHardy
1 parent
6a4ddef2a3
Exists in
master
and in
7 other branches
netfilter: NFNL_SUBSYS_IPSET id and NLA_PUT_NET* macros
The patch adds the NFNL_SUBSYS_IPSET id and NLA_PUT_NET* macros to the vanilla kernel. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Patrick McHardy <kaber@trash.net>
Showing 2 changed files with 11 additions and 1 deletions Inline Diff
include/linux/netfilter/nfnetlink.h
1 | #ifndef _NFNETLINK_H | 1 | #ifndef _NFNETLINK_H |
2 | #define _NFNETLINK_H | 2 | #define _NFNETLINK_H |
3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
4 | #include <linux/netfilter/nfnetlink_compat.h> | 4 | #include <linux/netfilter/nfnetlink_compat.h> |
5 | 5 | ||
6 | enum nfnetlink_groups { | 6 | enum nfnetlink_groups { |
7 | NFNLGRP_NONE, | 7 | NFNLGRP_NONE, |
8 | #define NFNLGRP_NONE NFNLGRP_NONE | 8 | #define NFNLGRP_NONE NFNLGRP_NONE |
9 | NFNLGRP_CONNTRACK_NEW, | 9 | NFNLGRP_CONNTRACK_NEW, |
10 | #define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW | 10 | #define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW |
11 | NFNLGRP_CONNTRACK_UPDATE, | 11 | NFNLGRP_CONNTRACK_UPDATE, |
12 | #define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE | 12 | #define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE |
13 | NFNLGRP_CONNTRACK_DESTROY, | 13 | NFNLGRP_CONNTRACK_DESTROY, |
14 | #define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY | 14 | #define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY |
15 | NFNLGRP_CONNTRACK_EXP_NEW, | 15 | NFNLGRP_CONNTRACK_EXP_NEW, |
16 | #define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW | 16 | #define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW |
17 | NFNLGRP_CONNTRACK_EXP_UPDATE, | 17 | NFNLGRP_CONNTRACK_EXP_UPDATE, |
18 | #define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE | 18 | #define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE |
19 | NFNLGRP_CONNTRACK_EXP_DESTROY, | 19 | NFNLGRP_CONNTRACK_EXP_DESTROY, |
20 | #define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY | 20 | #define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY |
21 | __NFNLGRP_MAX, | 21 | __NFNLGRP_MAX, |
22 | }; | 22 | }; |
23 | #define NFNLGRP_MAX (__NFNLGRP_MAX - 1) | 23 | #define NFNLGRP_MAX (__NFNLGRP_MAX - 1) |
24 | 24 | ||
25 | /* General form of address family dependent message. | 25 | /* General form of address family dependent message. |
26 | */ | 26 | */ |
27 | struct nfgenmsg { | 27 | struct nfgenmsg { |
28 | __u8 nfgen_family; /* AF_xxx */ | 28 | __u8 nfgen_family; /* AF_xxx */ |
29 | __u8 version; /* nfnetlink version */ | 29 | __u8 version; /* nfnetlink version */ |
30 | __be16 res_id; /* resource id */ | 30 | __be16 res_id; /* resource id */ |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #define NFNETLINK_V0 0 | 33 | #define NFNETLINK_V0 0 |
34 | 34 | ||
35 | /* netfilter netlink message types are split in two pieces: | 35 | /* netfilter netlink message types are split in two pieces: |
36 | * 8 bit subsystem, 8bit operation. | 36 | * 8 bit subsystem, 8bit operation. |
37 | */ | 37 | */ |
38 | 38 | ||
39 | #define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8) | 39 | #define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8) |
40 | #define NFNL_MSG_TYPE(x) (x & 0x00ff) | 40 | #define NFNL_MSG_TYPE(x) (x & 0x00ff) |
41 | 41 | ||
42 | /* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS() | 42 | /* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS() |
43 | * won't work anymore */ | 43 | * won't work anymore */ |
44 | #define NFNL_SUBSYS_NONE 0 | 44 | #define NFNL_SUBSYS_NONE 0 |
45 | #define NFNL_SUBSYS_CTNETLINK 1 | 45 | #define NFNL_SUBSYS_CTNETLINK 1 |
46 | #define NFNL_SUBSYS_CTNETLINK_EXP 2 | 46 | #define NFNL_SUBSYS_CTNETLINK_EXP 2 |
47 | #define NFNL_SUBSYS_QUEUE 3 | 47 | #define NFNL_SUBSYS_QUEUE 3 |
48 | #define NFNL_SUBSYS_ULOG 4 | 48 | #define NFNL_SUBSYS_ULOG 4 |
49 | #define NFNL_SUBSYS_OSF 5 | 49 | #define NFNL_SUBSYS_OSF 5 |
50 | #define NFNL_SUBSYS_COUNT 6 | 50 | #define NFNL_SUBSYS_IPSET 6 |
51 | #define NFNL_SUBSYS_COUNT 7 | ||
51 | 52 | ||
52 | #ifdef __KERNEL__ | 53 | #ifdef __KERNEL__ |
53 | 54 | ||
54 | #include <linux/netlink.h> | 55 | #include <linux/netlink.h> |
55 | #include <linux/capability.h> | 56 | #include <linux/capability.h> |
56 | #include <net/netlink.h> | 57 | #include <net/netlink.h> |
57 | 58 | ||
58 | struct nfnl_callback { | 59 | struct nfnl_callback { |
59 | int (*call)(struct sock *nl, struct sk_buff *skb, | 60 | int (*call)(struct sock *nl, struct sk_buff *skb, |
60 | const struct nlmsghdr *nlh, | 61 | const struct nlmsghdr *nlh, |
61 | const struct nlattr * const cda[]); | 62 | const struct nlattr * const cda[]); |
62 | const struct nla_policy *policy; /* netlink attribute policy */ | 63 | const struct nla_policy *policy; /* netlink attribute policy */ |
63 | const u_int16_t attr_count; /* number of nlattr's */ | 64 | const u_int16_t attr_count; /* number of nlattr's */ |
64 | }; | 65 | }; |
65 | 66 | ||
66 | struct nfnetlink_subsystem { | 67 | struct nfnetlink_subsystem { |
67 | const char *name; | 68 | const char *name; |
68 | __u8 subsys_id; /* nfnetlink subsystem ID */ | 69 | __u8 subsys_id; /* nfnetlink subsystem ID */ |
69 | __u8 cb_count; /* number of callbacks */ | 70 | __u8 cb_count; /* number of callbacks */ |
70 | const struct nfnl_callback *cb; /* callback for individual types */ | 71 | const struct nfnl_callback *cb; /* callback for individual types */ |
71 | }; | 72 | }; |
72 | 73 | ||
73 | extern int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n); | 74 | extern int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n); |
74 | extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); | 75 | extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); |
75 | 76 | ||
76 | extern int nfnetlink_has_listeners(struct net *net, unsigned int group); | 77 | extern int nfnetlink_has_listeners(struct net *net, unsigned int group); |
77 | extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, | 78 | extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, |
78 | int echo, gfp_t flags); | 79 | int echo, gfp_t flags); |
79 | extern int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error); | 80 | extern int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error); |
80 | extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags); | 81 | extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags); |
81 | 82 | ||
82 | extern void nfnl_lock(void); | 83 | extern void nfnl_lock(void); |
83 | extern void nfnl_unlock(void); | 84 | extern void nfnl_unlock(void); |
84 | 85 | ||
85 | #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \ | 86 | #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \ |
86 | MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys)) | 87 | MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys)) |
87 | 88 | ||
88 | #endif /* __KERNEL__ */ | 89 | #endif /* __KERNEL__ */ |
89 | #endif /* _NFNETLINK_H */ | 90 | #endif /* _NFNETLINK_H */ |
90 | 91 |
include/net/netlink.h
1 | #ifndef __NET_NETLINK_H | 1 | #ifndef __NET_NETLINK_H |
2 | #define __NET_NETLINK_H | 2 | #define __NET_NETLINK_H |
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/netlink.h> | 5 | #include <linux/netlink.h> |
6 | #include <linux/jiffies.h> | 6 | #include <linux/jiffies.h> |
7 | 7 | ||
8 | /* ======================================================================== | 8 | /* ======================================================================== |
9 | * Netlink Messages and Attributes Interface (As Seen On TV) | 9 | * Netlink Messages and Attributes Interface (As Seen On TV) |
10 | * ------------------------------------------------------------------------ | 10 | * ------------------------------------------------------------------------ |
11 | * Messages Interface | 11 | * Messages Interface |
12 | * ------------------------------------------------------------------------ | 12 | * ------------------------------------------------------------------------ |
13 | * | 13 | * |
14 | * Message Format: | 14 | * Message Format: |
15 | * <--- nlmsg_total_size(payload) ---> | 15 | * <--- nlmsg_total_size(payload) ---> |
16 | * <-- nlmsg_msg_size(payload) -> | 16 | * <-- nlmsg_msg_size(payload) -> |
17 | * +----------+- - -+-------------+- - -+-------- - - | 17 | * +----------+- - -+-------------+- - -+-------- - - |
18 | * | nlmsghdr | Pad | Payload | Pad | nlmsghdr | 18 | * | nlmsghdr | Pad | Payload | Pad | nlmsghdr |
19 | * +----------+- - -+-------------+- - -+-------- - - | 19 | * +----------+- - -+-------------+- - -+-------- - - |
20 | * nlmsg_data(nlh)---^ ^ | 20 | * nlmsg_data(nlh)---^ ^ |
21 | * nlmsg_next(nlh)-----------------------+ | 21 | * nlmsg_next(nlh)-----------------------+ |
22 | * | 22 | * |
23 | * Payload Format: | 23 | * Payload Format: |
24 | * <---------------------- nlmsg_len(nlh) ---------------------> | 24 | * <---------------------- nlmsg_len(nlh) ---------------------> |
25 | * <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) -> | 25 | * <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) -> |
26 | * +----------------------+- - -+--------------------------------+ | 26 | * +----------------------+- - -+--------------------------------+ |
27 | * | Family Header | Pad | Attributes | | 27 | * | Family Header | Pad | Attributes | |
28 | * +----------------------+- - -+--------------------------------+ | 28 | * +----------------------+- - -+--------------------------------+ |
29 | * nlmsg_attrdata(nlh, hdrlen)---^ | 29 | * nlmsg_attrdata(nlh, hdrlen)---^ |
30 | * | 30 | * |
31 | * Data Structures: | 31 | * Data Structures: |
32 | * struct nlmsghdr netlink message header | 32 | * struct nlmsghdr netlink message header |
33 | * | 33 | * |
34 | * Message Construction: | 34 | * Message Construction: |
35 | * nlmsg_new() create a new netlink message | 35 | * nlmsg_new() create a new netlink message |
36 | * nlmsg_put() add a netlink message to an skb | 36 | * nlmsg_put() add a netlink message to an skb |
37 | * nlmsg_put_answer() callback based nlmsg_put() | 37 | * nlmsg_put_answer() callback based nlmsg_put() |
38 | * nlmsg_end() finalize netlink message | 38 | * nlmsg_end() finalize netlink message |
39 | * nlmsg_get_pos() return current position in message | 39 | * nlmsg_get_pos() return current position in message |
40 | * nlmsg_trim() trim part of message | 40 | * nlmsg_trim() trim part of message |
41 | * nlmsg_cancel() cancel message construction | 41 | * nlmsg_cancel() cancel message construction |
42 | * nlmsg_free() free a netlink message | 42 | * nlmsg_free() free a netlink message |
43 | * | 43 | * |
44 | * Message Sending: | 44 | * Message Sending: |
45 | * nlmsg_multicast() multicast message to several groups | 45 | * nlmsg_multicast() multicast message to several groups |
46 | * nlmsg_unicast() unicast a message to a single socket | 46 | * nlmsg_unicast() unicast a message to a single socket |
47 | * nlmsg_notify() send notification message | 47 | * nlmsg_notify() send notification message |
48 | * | 48 | * |
49 | * Message Length Calculations: | 49 | * Message Length Calculations: |
50 | * nlmsg_msg_size(payload) length of message w/o padding | 50 | * nlmsg_msg_size(payload) length of message w/o padding |
51 | * nlmsg_total_size(payload) length of message w/ padding | 51 | * nlmsg_total_size(payload) length of message w/ padding |
52 | * nlmsg_padlen(payload) length of padding at tail | 52 | * nlmsg_padlen(payload) length of padding at tail |
53 | * | 53 | * |
54 | * Message Payload Access: | 54 | * Message Payload Access: |
55 | * nlmsg_data(nlh) head of message payload | 55 | * nlmsg_data(nlh) head of message payload |
56 | * nlmsg_len(nlh) length of message payload | 56 | * nlmsg_len(nlh) length of message payload |
57 | * nlmsg_attrdata(nlh, hdrlen) head of attributes data | 57 | * nlmsg_attrdata(nlh, hdrlen) head of attributes data |
58 | * nlmsg_attrlen(nlh, hdrlen) length of attributes data | 58 | * nlmsg_attrlen(nlh, hdrlen) length of attributes data |
59 | * | 59 | * |
60 | * Message Parsing: | 60 | * Message Parsing: |
61 | * nlmsg_ok(nlh, remaining) does nlh fit into remaining bytes? | 61 | * nlmsg_ok(nlh, remaining) does nlh fit into remaining bytes? |
62 | * nlmsg_next(nlh, remaining) get next netlink message | 62 | * nlmsg_next(nlh, remaining) get next netlink message |
63 | * nlmsg_parse() parse attributes of a message | 63 | * nlmsg_parse() parse attributes of a message |
64 | * nlmsg_find_attr() find an attribute in a message | 64 | * nlmsg_find_attr() find an attribute in a message |
65 | * nlmsg_for_each_msg() loop over all messages | 65 | * nlmsg_for_each_msg() loop over all messages |
66 | * nlmsg_validate() validate netlink message incl. attrs | 66 | * nlmsg_validate() validate netlink message incl. attrs |
67 | * nlmsg_for_each_attr() loop over all attributes | 67 | * nlmsg_for_each_attr() loop over all attributes |
68 | * | 68 | * |
69 | * Misc: | 69 | * Misc: |
70 | * nlmsg_report() report back to application? | 70 | * nlmsg_report() report back to application? |
71 | * | 71 | * |
72 | * ------------------------------------------------------------------------ | 72 | * ------------------------------------------------------------------------ |
73 | * Attributes Interface | 73 | * Attributes Interface |
74 | * ------------------------------------------------------------------------ | 74 | * ------------------------------------------------------------------------ |
75 | * | 75 | * |
76 | * Attribute Format: | 76 | * Attribute Format: |
77 | * <------- nla_total_size(payload) -------> | 77 | * <------- nla_total_size(payload) -------> |
78 | * <---- nla_attr_size(payload) -----> | 78 | * <---- nla_attr_size(payload) -----> |
79 | * +----------+- - -+- - - - - - - - - +- - -+-------- - - | 79 | * +----------+- - -+- - - - - - - - - +- - -+-------- - - |
80 | * | Header | Pad | Payload | Pad | Header | 80 | * | Header | Pad | Payload | Pad | Header |
81 | * +----------+- - -+- - - - - - - - - +- - -+-------- - - | 81 | * +----------+- - -+- - - - - - - - - +- - -+-------- - - |
82 | * <- nla_len(nla) -> ^ | 82 | * <- nla_len(nla) -> ^ |
83 | * nla_data(nla)----^ | | 83 | * nla_data(nla)----^ | |
84 | * nla_next(nla)-----------------------------' | 84 | * nla_next(nla)-----------------------------' |
85 | * | 85 | * |
86 | * Data Structures: | 86 | * Data Structures: |
87 | * struct nlattr netlink attribute header | 87 | * struct nlattr netlink attribute header |
88 | * | 88 | * |
89 | * Attribute Construction: | 89 | * Attribute Construction: |
90 | * nla_reserve(skb, type, len) reserve room for an attribute | 90 | * nla_reserve(skb, type, len) reserve room for an attribute |
91 | * nla_reserve_nohdr(skb, len) reserve room for an attribute w/o hdr | 91 | * nla_reserve_nohdr(skb, len) reserve room for an attribute w/o hdr |
92 | * nla_put(skb, type, len, data) add attribute to skb | 92 | * nla_put(skb, type, len, data) add attribute to skb |
93 | * nla_put_nohdr(skb, len, data) add attribute w/o hdr | 93 | * nla_put_nohdr(skb, len, data) add attribute w/o hdr |
94 | * nla_append(skb, len, data) append data to skb | 94 | * nla_append(skb, len, data) append data to skb |
95 | * | 95 | * |
96 | * Attribute Construction for Basic Types: | 96 | * Attribute Construction for Basic Types: |
97 | * nla_put_u8(skb, type, value) add u8 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 | 98 | * nla_put_u16(skb, type, value) add u16 attribute to skb |
99 | * nla_put_u32(skb, type, value) add u32 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 | 100 | * nla_put_u64(skb, type, value) add u64 attribute to skb |
101 | * nla_put_string(skb, type, str) add string 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 | 102 | * nla_put_flag(skb, type) add flag attribute to skb |
103 | * nla_put_msecs(skb, type, jiffies) add msecs attribute to skb | 103 | * nla_put_msecs(skb, type, jiffies) add msecs attribute to skb |
104 | * | 104 | * |
105 | * Exceptions Based Attribute Construction: | 105 | * Exceptions Based Attribute Construction: |
106 | * NLA_PUT(skb, type, len, data) add attribute to skb | 106 | * NLA_PUT(skb, type, len, data) add attribute to skb |
107 | * NLA_PUT_U8(skb, type, value) add u8 attribute to skb | 107 | * NLA_PUT_U8(skb, type, value) add u8 attribute to skb |
108 | * NLA_PUT_U16(skb, type, value) add u16 attribute to skb | 108 | * NLA_PUT_U16(skb, type, value) add u16 attribute to skb |
109 | * NLA_PUT_U32(skb, type, value) add u32 attribute to skb | 109 | * NLA_PUT_U32(skb, type, value) add u32 attribute to skb |
110 | * NLA_PUT_U64(skb, type, value) add u64 attribute to skb | 110 | * NLA_PUT_U64(skb, type, value) add u64 attribute to skb |
111 | * NLA_PUT_STRING(skb, type, str) add string attribute to skb | 111 | * NLA_PUT_STRING(skb, type, str) add string attribute to skb |
112 | * NLA_PUT_FLAG(skb, type) add flag attribute to skb | 112 | * NLA_PUT_FLAG(skb, type) add flag attribute to skb |
113 | * NLA_PUT_MSECS(skb, type, jiffies) add msecs attribute to skb | 113 | * NLA_PUT_MSECS(skb, type, jiffies) add msecs attribute to skb |
114 | * | 114 | * |
115 | * The meaning of these functions is equal to their lower case | 115 | * The meaning of these functions is equal to their lower case |
116 | * variants but they jump to the label nla_put_failure in case | 116 | * variants but they jump to the label nla_put_failure in case |
117 | * of a failure. | 117 | * of a failure. |
118 | * | 118 | * |
119 | * Nested Attributes Construction: | 119 | * Nested Attributes Construction: |
120 | * nla_nest_start(skb, type) start a nested attribute | 120 | * nla_nest_start(skb, type) start a nested attribute |
121 | * nla_nest_end(skb, nla) finalize a nested attribute | 121 | * nla_nest_end(skb, nla) finalize a nested attribute |
122 | * nla_nest_cancel(skb, nla) cancel nested attribute construction | 122 | * nla_nest_cancel(skb, nla) cancel nested attribute construction |
123 | * | 123 | * |
124 | * Attribute Length Calculations: | 124 | * Attribute Length Calculations: |
125 | * nla_attr_size(payload) length of attribute w/o padding | 125 | * nla_attr_size(payload) length of attribute w/o padding |
126 | * nla_total_size(payload) length of attribute w/ padding | 126 | * nla_total_size(payload) length of attribute w/ padding |
127 | * nla_padlen(payload) length of padding | 127 | * nla_padlen(payload) length of padding |
128 | * | 128 | * |
129 | * Attribute Payload Access: | 129 | * Attribute Payload Access: |
130 | * nla_data(nla) head of attribute payload | 130 | * nla_data(nla) head of attribute payload |
131 | * nla_len(nla) length of attribute payload | 131 | * nla_len(nla) length of attribute payload |
132 | * | 132 | * |
133 | * Attribute Payload Access for Basic Types: | 133 | * Attribute Payload Access for Basic Types: |
134 | * nla_get_u8(nla) get payload for a u8 attribute | 134 | * nla_get_u8(nla) get payload for a u8 attribute |
135 | * nla_get_u16(nla) get payload for a u16 attribute | 135 | * nla_get_u16(nla) get payload for a u16 attribute |
136 | * nla_get_u32(nla) get payload for a u32 attribute | 136 | * nla_get_u32(nla) get payload for a u32 attribute |
137 | * nla_get_u64(nla) get payload for a u64 attribute | 137 | * nla_get_u64(nla) get payload for a u64 attribute |
138 | * nla_get_flag(nla) return 1 if flag is true | 138 | * nla_get_flag(nla) return 1 if flag is true |
139 | * nla_get_msecs(nla) get payload for a msecs attribute | 139 | * nla_get_msecs(nla) get payload for a msecs attribute |
140 | * | 140 | * |
141 | * Attribute Misc: | 141 | * Attribute Misc: |
142 | * nla_memcpy(dest, nla, count) copy attribute into memory | 142 | * nla_memcpy(dest, nla, count) copy attribute into memory |
143 | * nla_memcmp(nla, data, size) compare attribute with memory area | 143 | * nla_memcmp(nla, data, size) compare attribute with memory area |
144 | * nla_strlcpy(dst, nla, size) copy attribute to a sized string | 144 | * nla_strlcpy(dst, nla, size) copy attribute to a sized string |
145 | * nla_strcmp(nla, str) compare attribute with string | 145 | * nla_strcmp(nla, str) compare attribute with string |
146 | * | 146 | * |
147 | * Attribute Parsing: | 147 | * Attribute Parsing: |
148 | * nla_ok(nla, remaining) does nla fit into remaining bytes? | 148 | * nla_ok(nla, remaining) does nla fit into remaining bytes? |
149 | * nla_next(nla, remaining) get next netlink attribute | 149 | * nla_next(nla, remaining) get next netlink attribute |
150 | * nla_validate() validate a stream of attributes | 150 | * nla_validate() validate a stream of attributes |
151 | * nla_validate_nested() validate a stream of nested attributes | 151 | * nla_validate_nested() validate a stream of nested attributes |
152 | * nla_find() find attribute in stream of attributes | 152 | * nla_find() find attribute in stream of attributes |
153 | * nla_find_nested() find attribute in nested attributes | 153 | * nla_find_nested() find attribute in nested attributes |
154 | * nla_parse() parse and validate stream of attrs | 154 | * nla_parse() parse and validate stream of attrs |
155 | * nla_parse_nested() parse nested attribuets | 155 | * nla_parse_nested() parse nested attribuets |
156 | * nla_for_each_attr() loop over all attributes | 156 | * nla_for_each_attr() loop over all attributes |
157 | * nla_for_each_nested() loop over the nested attributes | 157 | * nla_for_each_nested() loop over the nested attributes |
158 | *========================================================================= | 158 | *========================================================================= |
159 | */ | 159 | */ |
160 | 160 | ||
161 | /** | 161 | /** |
162 | * Standard attribute types to specify validation policy | 162 | * Standard attribute types to specify validation policy |
163 | */ | 163 | */ |
164 | enum { | 164 | enum { |
165 | NLA_UNSPEC, | 165 | NLA_UNSPEC, |
166 | NLA_U8, | 166 | NLA_U8, |
167 | NLA_U16, | 167 | NLA_U16, |
168 | NLA_U32, | 168 | NLA_U32, |
169 | NLA_U64, | 169 | NLA_U64, |
170 | NLA_STRING, | 170 | NLA_STRING, |
171 | NLA_FLAG, | 171 | NLA_FLAG, |
172 | NLA_MSECS, | 172 | NLA_MSECS, |
173 | NLA_NESTED, | 173 | NLA_NESTED, |
174 | NLA_NESTED_COMPAT, | 174 | NLA_NESTED_COMPAT, |
175 | NLA_NUL_STRING, | 175 | NLA_NUL_STRING, |
176 | NLA_BINARY, | 176 | NLA_BINARY, |
177 | __NLA_TYPE_MAX, | 177 | __NLA_TYPE_MAX, |
178 | }; | 178 | }; |
179 | 179 | ||
180 | #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) | 180 | #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) |
181 | 181 | ||
182 | /** | 182 | /** |
183 | * struct nla_policy - attribute validation policy | 183 | * struct nla_policy - attribute validation policy |
184 | * @type: Type of attribute or NLA_UNSPEC | 184 | * @type: Type of attribute or NLA_UNSPEC |
185 | * @len: Type specific length of payload | 185 | * @len: Type specific length of payload |
186 | * | 186 | * |
187 | * Policies are defined as arrays of this struct, the array must be | 187 | * Policies are defined as arrays of this struct, the array must be |
188 | * accessible by attribute type up to the highest identifier to be expected. | 188 | * accessible by attribute type up to the highest identifier to be expected. |
189 | * | 189 | * |
190 | * Meaning of `len' field: | 190 | * Meaning of `len' field: |
191 | * NLA_STRING Maximum length of string | 191 | * NLA_STRING Maximum length of string |
192 | * NLA_NUL_STRING Maximum length of string (excluding NUL) | 192 | * NLA_NUL_STRING Maximum length of string (excluding NUL) |
193 | * NLA_FLAG Unused | 193 | * NLA_FLAG Unused |
194 | * NLA_BINARY Maximum length of attribute payload | 194 | * NLA_BINARY Maximum length of attribute payload |
195 | * NLA_NESTED_COMPAT Exact length of structure payload | 195 | * NLA_NESTED_COMPAT Exact length of structure payload |
196 | * All other Exact length of attribute payload | 196 | * All other Exact length of attribute payload |
197 | * | 197 | * |
198 | * Example: | 198 | * Example: |
199 | * static const struct nla_policy my_policy[ATTR_MAX+1] = { | 199 | * static const struct nla_policy my_policy[ATTR_MAX+1] = { |
200 | * [ATTR_FOO] = { .type = NLA_U16 }, | 200 | * [ATTR_FOO] = { .type = NLA_U16 }, |
201 | * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, | 201 | * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, |
202 | * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, | 202 | * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, |
203 | * }; | 203 | * }; |
204 | */ | 204 | */ |
205 | struct nla_policy { | 205 | struct nla_policy { |
206 | u16 type; | 206 | u16 type; |
207 | u16 len; | 207 | u16 len; |
208 | }; | 208 | }; |
209 | 209 | ||
210 | /** | 210 | /** |
211 | * struct nl_info - netlink source information | 211 | * struct nl_info - netlink source information |
212 | * @nlh: Netlink message header of original request | 212 | * @nlh: Netlink message header of original request |
213 | * @pid: Netlink PID of requesting application | 213 | * @pid: Netlink PID of requesting application |
214 | */ | 214 | */ |
215 | struct nl_info { | 215 | struct nl_info { |
216 | struct nlmsghdr *nlh; | 216 | struct nlmsghdr *nlh; |
217 | struct net *nl_net; | 217 | struct net *nl_net; |
218 | u32 pid; | 218 | u32 pid; |
219 | }; | 219 | }; |
220 | 220 | ||
221 | extern int netlink_rcv_skb(struct sk_buff *skb, | 221 | extern int netlink_rcv_skb(struct sk_buff *skb, |
222 | int (*cb)(struct sk_buff *, | 222 | int (*cb)(struct sk_buff *, |
223 | struct nlmsghdr *)); | 223 | struct nlmsghdr *)); |
224 | extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, | 224 | extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, |
225 | u32 pid, unsigned int group, int report, | 225 | u32 pid, unsigned int group, int report, |
226 | gfp_t flags); | 226 | gfp_t flags); |
227 | 227 | ||
228 | extern int nla_validate(const struct nlattr *head, | 228 | extern int nla_validate(const struct nlattr *head, |
229 | int len, int maxtype, | 229 | int len, int maxtype, |
230 | const struct nla_policy *policy); | 230 | const struct nla_policy *policy); |
231 | extern int nla_parse(struct nlattr **tb, int maxtype, | 231 | extern int nla_parse(struct nlattr **tb, int maxtype, |
232 | const struct nlattr *head, int len, | 232 | const struct nlattr *head, int len, |
233 | const struct nla_policy *policy); | 233 | const struct nla_policy *policy); |
234 | extern int nla_policy_len(const struct nla_policy *, int); | 234 | extern int nla_policy_len(const struct nla_policy *, int); |
235 | extern struct nlattr * nla_find(const struct nlattr *head, | 235 | extern struct nlattr * nla_find(const struct nlattr *head, |
236 | int len, int attrtype); | 236 | int len, int attrtype); |
237 | extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, | 237 | extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, |
238 | size_t dstsize); | 238 | size_t dstsize); |
239 | extern int nla_memcpy(void *dest, const struct nlattr *src, int count); | 239 | extern int nla_memcpy(void *dest, const struct nlattr *src, int count); |
240 | extern int nla_memcmp(const struct nlattr *nla, const void *data, | 240 | extern int nla_memcmp(const struct nlattr *nla, const void *data, |
241 | size_t size); | 241 | size_t size); |
242 | extern int nla_strcmp(const struct nlattr *nla, const char *str); | 242 | extern int nla_strcmp(const struct nlattr *nla, const char *str); |
243 | extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype, | 243 | extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype, |
244 | int attrlen); | 244 | int attrlen); |
245 | extern void * __nla_reserve_nohdr(struct sk_buff *skb, int attrlen); | 245 | extern void * __nla_reserve_nohdr(struct sk_buff *skb, int attrlen); |
246 | extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype, | 246 | extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype, |
247 | int attrlen); | 247 | int attrlen); |
248 | extern void * nla_reserve_nohdr(struct sk_buff *skb, int attrlen); | 248 | extern void * nla_reserve_nohdr(struct sk_buff *skb, int attrlen); |
249 | extern void __nla_put(struct sk_buff *skb, int attrtype, | 249 | extern void __nla_put(struct sk_buff *skb, int attrtype, |
250 | int attrlen, const void *data); | 250 | int attrlen, const void *data); |
251 | extern void __nla_put_nohdr(struct sk_buff *skb, int attrlen, | 251 | extern void __nla_put_nohdr(struct sk_buff *skb, int attrlen, |
252 | const void *data); | 252 | const void *data); |
253 | extern int nla_put(struct sk_buff *skb, int attrtype, | 253 | extern int nla_put(struct sk_buff *skb, int attrtype, |
254 | int attrlen, const void *data); | 254 | int attrlen, const void *data); |
255 | extern int nla_put_nohdr(struct sk_buff *skb, int attrlen, | 255 | extern int nla_put_nohdr(struct sk_buff *skb, int attrlen, |
256 | const void *data); | 256 | const void *data); |
257 | extern int nla_append(struct sk_buff *skb, int attrlen, | 257 | extern int nla_append(struct sk_buff *skb, int attrlen, |
258 | const void *data); | 258 | const void *data); |
259 | 259 | ||
260 | /************************************************************************** | 260 | /************************************************************************** |
261 | * Netlink Messages | 261 | * Netlink Messages |
262 | **************************************************************************/ | 262 | **************************************************************************/ |
263 | 263 | ||
264 | /** | 264 | /** |
265 | * nlmsg_msg_size - length of netlink message not including padding | 265 | * nlmsg_msg_size - length of netlink message not including padding |
266 | * @payload: length of message payload | 266 | * @payload: length of message payload |
267 | */ | 267 | */ |
268 | static inline int nlmsg_msg_size(int payload) | 268 | static inline int nlmsg_msg_size(int payload) |
269 | { | 269 | { |
270 | return NLMSG_HDRLEN + payload; | 270 | return NLMSG_HDRLEN + payload; |
271 | } | 271 | } |
272 | 272 | ||
273 | /** | 273 | /** |
274 | * nlmsg_total_size - length of netlink message including padding | 274 | * nlmsg_total_size - length of netlink message including padding |
275 | * @payload: length of message payload | 275 | * @payload: length of message payload |
276 | */ | 276 | */ |
277 | static inline int nlmsg_total_size(int payload) | 277 | static inline int nlmsg_total_size(int payload) |
278 | { | 278 | { |
279 | return NLMSG_ALIGN(nlmsg_msg_size(payload)); | 279 | return NLMSG_ALIGN(nlmsg_msg_size(payload)); |
280 | } | 280 | } |
281 | 281 | ||
282 | /** | 282 | /** |
283 | * nlmsg_padlen - length of padding at the message's tail | 283 | * nlmsg_padlen - length of padding at the message's tail |
284 | * @payload: length of message payload | 284 | * @payload: length of message payload |
285 | */ | 285 | */ |
286 | static inline int nlmsg_padlen(int payload) | 286 | static inline int nlmsg_padlen(int payload) |
287 | { | 287 | { |
288 | return nlmsg_total_size(payload) - nlmsg_msg_size(payload); | 288 | return nlmsg_total_size(payload) - nlmsg_msg_size(payload); |
289 | } | 289 | } |
290 | 290 | ||
291 | /** | 291 | /** |
292 | * nlmsg_data - head of message payload | 292 | * nlmsg_data - head of message payload |
293 | * @nlh: netlink messsage header | 293 | * @nlh: netlink messsage header |
294 | */ | 294 | */ |
295 | static inline void *nlmsg_data(const struct nlmsghdr *nlh) | 295 | static inline void *nlmsg_data(const struct nlmsghdr *nlh) |
296 | { | 296 | { |
297 | return (unsigned char *) nlh + NLMSG_HDRLEN; | 297 | return (unsigned char *) nlh + NLMSG_HDRLEN; |
298 | } | 298 | } |
299 | 299 | ||
300 | /** | 300 | /** |
301 | * nlmsg_len - length of message payload | 301 | * nlmsg_len - length of message payload |
302 | * @nlh: netlink message header | 302 | * @nlh: netlink message header |
303 | */ | 303 | */ |
304 | static inline int nlmsg_len(const struct nlmsghdr *nlh) | 304 | static inline int nlmsg_len(const struct nlmsghdr *nlh) |
305 | { | 305 | { |
306 | return nlh->nlmsg_len - NLMSG_HDRLEN; | 306 | return nlh->nlmsg_len - NLMSG_HDRLEN; |
307 | } | 307 | } |
308 | 308 | ||
309 | /** | 309 | /** |
310 | * nlmsg_attrdata - head of attributes data | 310 | * nlmsg_attrdata - head of attributes data |
311 | * @nlh: netlink message header | 311 | * @nlh: netlink message header |
312 | * @hdrlen: length of family specific header | 312 | * @hdrlen: length of family specific header |
313 | */ | 313 | */ |
314 | static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, | 314 | static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, |
315 | int hdrlen) | 315 | int hdrlen) |
316 | { | 316 | { |
317 | unsigned char *data = nlmsg_data(nlh); | 317 | unsigned char *data = nlmsg_data(nlh); |
318 | return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen)); | 318 | return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen)); |
319 | } | 319 | } |
320 | 320 | ||
321 | /** | 321 | /** |
322 | * nlmsg_attrlen - length of attributes data | 322 | * nlmsg_attrlen - length of attributes data |
323 | * @nlh: netlink message header | 323 | * @nlh: netlink message header |
324 | * @hdrlen: length of family specific header | 324 | * @hdrlen: length of family specific header |
325 | */ | 325 | */ |
326 | static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen) | 326 | static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen) |
327 | { | 327 | { |
328 | return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen); | 328 | return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen); |
329 | } | 329 | } |
330 | 330 | ||
331 | /** | 331 | /** |
332 | * nlmsg_ok - check if the netlink message fits into the remaining bytes | 332 | * nlmsg_ok - check if the netlink message fits into the remaining bytes |
333 | * @nlh: netlink message header | 333 | * @nlh: netlink message header |
334 | * @remaining: number of bytes remaining in message stream | 334 | * @remaining: number of bytes remaining in message stream |
335 | */ | 335 | */ |
336 | static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining) | 336 | static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining) |
337 | { | 337 | { |
338 | return (remaining >= (int) sizeof(struct nlmsghdr) && | 338 | return (remaining >= (int) sizeof(struct nlmsghdr) && |
339 | nlh->nlmsg_len >= sizeof(struct nlmsghdr) && | 339 | nlh->nlmsg_len >= sizeof(struct nlmsghdr) && |
340 | nlh->nlmsg_len <= remaining); | 340 | nlh->nlmsg_len <= remaining); |
341 | } | 341 | } |
342 | 342 | ||
343 | /** | 343 | /** |
344 | * nlmsg_next - next netlink message in message stream | 344 | * nlmsg_next - next netlink message in message stream |
345 | * @nlh: netlink message header | 345 | * @nlh: netlink message header |
346 | * @remaining: number of bytes remaining in message stream | 346 | * @remaining: number of bytes remaining in message stream |
347 | * | 347 | * |
348 | * Returns the next netlink message in the message stream and | 348 | * Returns the next netlink message in the message stream and |
349 | * decrements remaining by the size of the current message. | 349 | * decrements remaining by the size of the current message. |
350 | */ | 350 | */ |
351 | static inline struct nlmsghdr * | 351 | static inline struct nlmsghdr * |
352 | nlmsg_next(const struct nlmsghdr *nlh, int *remaining) | 352 | nlmsg_next(const struct nlmsghdr *nlh, int *remaining) |
353 | { | 353 | { |
354 | int totlen = NLMSG_ALIGN(nlh->nlmsg_len); | 354 | int totlen = NLMSG_ALIGN(nlh->nlmsg_len); |
355 | 355 | ||
356 | *remaining -= totlen; | 356 | *remaining -= totlen; |
357 | 357 | ||
358 | return (struct nlmsghdr *) ((unsigned char *) nlh + totlen); | 358 | return (struct nlmsghdr *) ((unsigned char *) nlh + totlen); |
359 | } | 359 | } |
360 | 360 | ||
361 | /** | 361 | /** |
362 | * nlmsg_parse - parse attributes of a netlink message | 362 | * nlmsg_parse - parse attributes of a netlink message |
363 | * @nlh: netlink message header | 363 | * @nlh: netlink message header |
364 | * @hdrlen: length of family specific header | 364 | * @hdrlen: length of family specific header |
365 | * @tb: destination array with maxtype+1 elements | 365 | * @tb: destination array with maxtype+1 elements |
366 | * @maxtype: maximum attribute type to be expected | 366 | * @maxtype: maximum attribute type to be expected |
367 | * @policy: validation policy | 367 | * @policy: validation policy |
368 | * | 368 | * |
369 | * See nla_parse() | 369 | * See nla_parse() |
370 | */ | 370 | */ |
371 | static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, | 371 | static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, |
372 | struct nlattr *tb[], int maxtype, | 372 | struct nlattr *tb[], int maxtype, |
373 | const struct nla_policy *policy) | 373 | const struct nla_policy *policy) |
374 | { | 374 | { |
375 | if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) | 375 | if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) |
376 | return -EINVAL; | 376 | return -EINVAL; |
377 | 377 | ||
378 | return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen), | 378 | return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen), |
379 | nlmsg_attrlen(nlh, hdrlen), policy); | 379 | nlmsg_attrlen(nlh, hdrlen), policy); |
380 | } | 380 | } |
381 | 381 | ||
382 | /** | 382 | /** |
383 | * nlmsg_find_attr - find a specific attribute in a netlink message | 383 | * nlmsg_find_attr - find a specific attribute in a netlink message |
384 | * @nlh: netlink message header | 384 | * @nlh: netlink message header |
385 | * @hdrlen: length of familiy specific header | 385 | * @hdrlen: length of familiy specific header |
386 | * @attrtype: type of attribute to look for | 386 | * @attrtype: type of attribute to look for |
387 | * | 387 | * |
388 | * Returns the first attribute which matches the specified type. | 388 | * Returns the first attribute which matches the specified type. |
389 | */ | 389 | */ |
390 | static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, | 390 | static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, |
391 | int hdrlen, int attrtype) | 391 | int hdrlen, int attrtype) |
392 | { | 392 | { |
393 | return nla_find(nlmsg_attrdata(nlh, hdrlen), | 393 | return nla_find(nlmsg_attrdata(nlh, hdrlen), |
394 | nlmsg_attrlen(nlh, hdrlen), attrtype); | 394 | nlmsg_attrlen(nlh, hdrlen), attrtype); |
395 | } | 395 | } |
396 | 396 | ||
397 | /** | 397 | /** |
398 | * nlmsg_validate - validate a netlink message including attributes | 398 | * nlmsg_validate - validate a netlink message including attributes |
399 | * @nlh: netlinket message header | 399 | * @nlh: netlinket message header |
400 | * @hdrlen: length of familiy specific header | 400 | * @hdrlen: length of familiy specific header |
401 | * @maxtype: maximum attribute type to be expected | 401 | * @maxtype: maximum attribute type to be expected |
402 | * @policy: validation policy | 402 | * @policy: validation policy |
403 | */ | 403 | */ |
404 | static inline int nlmsg_validate(const struct nlmsghdr *nlh, | 404 | static inline int nlmsg_validate(const struct nlmsghdr *nlh, |
405 | int hdrlen, int maxtype, | 405 | int hdrlen, int maxtype, |
406 | const struct nla_policy *policy) | 406 | const struct nla_policy *policy) |
407 | { | 407 | { |
408 | if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) | 408 | if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) |
409 | return -EINVAL; | 409 | return -EINVAL; |
410 | 410 | ||
411 | return nla_validate(nlmsg_attrdata(nlh, hdrlen), | 411 | return nla_validate(nlmsg_attrdata(nlh, hdrlen), |
412 | nlmsg_attrlen(nlh, hdrlen), maxtype, policy); | 412 | nlmsg_attrlen(nlh, hdrlen), maxtype, policy); |
413 | } | 413 | } |
414 | 414 | ||
415 | /** | 415 | /** |
416 | * nlmsg_report - need to report back to application? | 416 | * nlmsg_report - need to report back to application? |
417 | * @nlh: netlink message header | 417 | * @nlh: netlink message header |
418 | * | 418 | * |
419 | * Returns 1 if a report back to the application is requested. | 419 | * Returns 1 if a report back to the application is requested. |
420 | */ | 420 | */ |
421 | static inline int nlmsg_report(const struct nlmsghdr *nlh) | 421 | static inline int nlmsg_report(const struct nlmsghdr *nlh) |
422 | { | 422 | { |
423 | return !!(nlh->nlmsg_flags & NLM_F_ECHO); | 423 | return !!(nlh->nlmsg_flags & NLM_F_ECHO); |
424 | } | 424 | } |
425 | 425 | ||
426 | /** | 426 | /** |
427 | * nlmsg_for_each_attr - iterate over a stream of attributes | 427 | * nlmsg_for_each_attr - iterate over a stream of attributes |
428 | * @pos: loop counter, set to current attribute | 428 | * @pos: loop counter, set to current attribute |
429 | * @nlh: netlink message header | 429 | * @nlh: netlink message header |
430 | * @hdrlen: length of familiy specific header | 430 | * @hdrlen: length of familiy specific header |
431 | * @rem: initialized to len, holds bytes currently remaining in stream | 431 | * @rem: initialized to len, holds bytes currently remaining in stream |
432 | */ | 432 | */ |
433 | #define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ | 433 | #define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ |
434 | nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \ | 434 | nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \ |
435 | nlmsg_attrlen(nlh, hdrlen), rem) | 435 | nlmsg_attrlen(nlh, hdrlen), rem) |
436 | 436 | ||
437 | #if 0 | 437 | #if 0 |
438 | /* FIXME: Enable once all users have been converted */ | 438 | /* FIXME: Enable once all users have been converted */ |
439 | 439 | ||
440 | /** | 440 | /** |
441 | * __nlmsg_put - Add a new netlink message to an skb | 441 | * __nlmsg_put - Add a new netlink message to an skb |
442 | * @skb: socket buffer to store message in | 442 | * @skb: socket buffer to store message in |
443 | * @pid: netlink process id | 443 | * @pid: netlink process id |
444 | * @seq: sequence number of message | 444 | * @seq: sequence number of message |
445 | * @type: message type | 445 | * @type: message type |
446 | * @payload: length of message payload | 446 | * @payload: length of message payload |
447 | * @flags: message flags | 447 | * @flags: message flags |
448 | * | 448 | * |
449 | * The caller is responsible to ensure that the skb provides enough | 449 | * The caller is responsible to ensure that the skb provides enough |
450 | * tailroom for both the netlink header and payload. | 450 | * tailroom for both the netlink header and payload. |
451 | */ | 451 | */ |
452 | static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid, | 452 | static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid, |
453 | u32 seq, int type, int payload, | 453 | u32 seq, int type, int payload, |
454 | int flags) | 454 | int flags) |
455 | { | 455 | { |
456 | struct nlmsghdr *nlh; | 456 | struct nlmsghdr *nlh; |
457 | 457 | ||
458 | nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload)); | 458 | nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload)); |
459 | nlh->nlmsg_type = type; | 459 | nlh->nlmsg_type = type; |
460 | nlh->nlmsg_len = nlmsg_msg_size(payload); | 460 | nlh->nlmsg_len = nlmsg_msg_size(payload); |
461 | nlh->nlmsg_flags = flags; | 461 | nlh->nlmsg_flags = flags; |
462 | nlh->nlmsg_pid = pid; | 462 | nlh->nlmsg_pid = pid; |
463 | nlh->nlmsg_seq = seq; | 463 | nlh->nlmsg_seq = seq; |
464 | 464 | ||
465 | memset((unsigned char *) nlmsg_data(nlh) + payload, 0, | 465 | memset((unsigned char *) nlmsg_data(nlh) + payload, 0, |
466 | nlmsg_padlen(payload)); | 466 | nlmsg_padlen(payload)); |
467 | 467 | ||
468 | return nlh; | 468 | return nlh; |
469 | } | 469 | } |
470 | #endif | 470 | #endif |
471 | 471 | ||
472 | /** | 472 | /** |
473 | * nlmsg_put - Add a new netlink message to an skb | 473 | * nlmsg_put - Add a new netlink message to an skb |
474 | * @skb: socket buffer to store message in | 474 | * @skb: socket buffer to store message in |
475 | * @pid: netlink process id | 475 | * @pid: netlink process id |
476 | * @seq: sequence number of message | 476 | * @seq: sequence number of message |
477 | * @type: message type | 477 | * @type: message type |
478 | * @payload: length of message payload | 478 | * @payload: length of message payload |
479 | * @flags: message flags | 479 | * @flags: message flags |
480 | * | 480 | * |
481 | * Returns NULL if the tailroom of the skb is insufficient to store | 481 | * Returns NULL if the tailroom of the skb is insufficient to store |
482 | * the message header and payload. | 482 | * the message header and payload. |
483 | */ | 483 | */ |
484 | static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, | 484 | static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, |
485 | int type, int payload, int flags) | 485 | int type, int payload, int flags) |
486 | { | 486 | { |
487 | if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload))) | 487 | if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload))) |
488 | return NULL; | 488 | return NULL; |
489 | 489 | ||
490 | return __nlmsg_put(skb, pid, seq, type, payload, flags); | 490 | return __nlmsg_put(skb, pid, seq, type, payload, flags); |
491 | } | 491 | } |
492 | 492 | ||
493 | /** | 493 | /** |
494 | * nlmsg_put_answer - Add a new callback based netlink message to an skb | 494 | * nlmsg_put_answer - Add a new callback based netlink message to an skb |
495 | * @skb: socket buffer to store message in | 495 | * @skb: socket buffer to store message in |
496 | * @cb: netlink callback | 496 | * @cb: netlink callback |
497 | * @type: message type | 497 | * @type: message type |
498 | * @payload: length of message payload | 498 | * @payload: length of message payload |
499 | * @flags: message flags | 499 | * @flags: message flags |
500 | * | 500 | * |
501 | * Returns NULL if the tailroom of the skb is insufficient to store | 501 | * Returns NULL if the tailroom of the skb is insufficient to store |
502 | * the message header and payload. | 502 | * the message header and payload. |
503 | */ | 503 | */ |
504 | static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, | 504 | static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, |
505 | struct netlink_callback *cb, | 505 | struct netlink_callback *cb, |
506 | int type, int payload, | 506 | int type, int payload, |
507 | int flags) | 507 | int flags) |
508 | { | 508 | { |
509 | return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, | 509 | return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, |
510 | type, payload, flags); | 510 | type, payload, flags); |
511 | } | 511 | } |
512 | 512 | ||
513 | /** | 513 | /** |
514 | * nlmsg_new - Allocate a new netlink message | 514 | * nlmsg_new - Allocate a new netlink message |
515 | * @payload: size of the message payload | 515 | * @payload: size of the message payload |
516 | * @flags: the type of memory to allocate. | 516 | * @flags: the type of memory to allocate. |
517 | * | 517 | * |
518 | * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known | 518 | * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known |
519 | * and a good default is needed. | 519 | * and a good default is needed. |
520 | */ | 520 | */ |
521 | static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags) | 521 | static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags) |
522 | { | 522 | { |
523 | return alloc_skb(nlmsg_total_size(payload), flags); | 523 | return alloc_skb(nlmsg_total_size(payload), flags); |
524 | } | 524 | } |
525 | 525 | ||
526 | /** | 526 | /** |
527 | * nlmsg_end - Finalize a netlink message | 527 | * nlmsg_end - Finalize a netlink message |
528 | * @skb: socket buffer the message is stored in | 528 | * @skb: socket buffer the message is stored in |
529 | * @nlh: netlink message header | 529 | * @nlh: netlink message header |
530 | * | 530 | * |
531 | * Corrects the netlink message header to include the appeneded | 531 | * Corrects the netlink message header to include the appeneded |
532 | * attributes. Only necessary if attributes have been added to | 532 | * attributes. Only necessary if attributes have been added to |
533 | * the message. | 533 | * the message. |
534 | * | 534 | * |
535 | * Returns the total data length of the skb. | 535 | * Returns the total data length of the skb. |
536 | */ | 536 | */ |
537 | static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh) | 537 | static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh) |
538 | { | 538 | { |
539 | nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh; | 539 | nlh->nlmsg_len = skb_tail_pointer(skb) - (unsigned char *)nlh; |
540 | 540 | ||
541 | return skb->len; | 541 | return skb->len; |
542 | } | 542 | } |
543 | 543 | ||
544 | /** | 544 | /** |
545 | * nlmsg_get_pos - return current position in netlink message | 545 | * nlmsg_get_pos - return current position in netlink message |
546 | * @skb: socket buffer the message is stored in | 546 | * @skb: socket buffer the message is stored in |
547 | * | 547 | * |
548 | * Returns a pointer to the current tail of the message. | 548 | * Returns a pointer to the current tail of the message. |
549 | */ | 549 | */ |
550 | static inline void *nlmsg_get_pos(struct sk_buff *skb) | 550 | static inline void *nlmsg_get_pos(struct sk_buff *skb) |
551 | { | 551 | { |
552 | return skb_tail_pointer(skb); | 552 | return skb_tail_pointer(skb); |
553 | } | 553 | } |
554 | 554 | ||
555 | /** | 555 | /** |
556 | * nlmsg_trim - Trim message to a mark | 556 | * nlmsg_trim - Trim message to a mark |
557 | * @skb: socket buffer the message is stored in | 557 | * @skb: socket buffer the message is stored in |
558 | * @mark: mark to trim to | 558 | * @mark: mark to trim to |
559 | * | 559 | * |
560 | * Trims the message to the provided mark. | 560 | * Trims the message to the provided mark. |
561 | */ | 561 | */ |
562 | static inline void nlmsg_trim(struct sk_buff *skb, const void *mark) | 562 | static inline void nlmsg_trim(struct sk_buff *skb, const void *mark) |
563 | { | 563 | { |
564 | if (mark) | 564 | if (mark) |
565 | skb_trim(skb, (unsigned char *) mark - skb->data); | 565 | skb_trim(skb, (unsigned char *) mark - skb->data); |
566 | } | 566 | } |
567 | 567 | ||
568 | /** | 568 | /** |
569 | * nlmsg_cancel - Cancel construction of a netlink message | 569 | * nlmsg_cancel - Cancel construction of a netlink message |
570 | * @skb: socket buffer the message is stored in | 570 | * @skb: socket buffer the message is stored in |
571 | * @nlh: netlink message header | 571 | * @nlh: netlink message header |
572 | * | 572 | * |
573 | * Removes the complete netlink message including all | 573 | * Removes the complete netlink message including all |
574 | * attributes from the socket buffer again. | 574 | * attributes from the socket buffer again. |
575 | */ | 575 | */ |
576 | static inline void nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh) | 576 | static inline void nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh) |
577 | { | 577 | { |
578 | nlmsg_trim(skb, nlh); | 578 | nlmsg_trim(skb, nlh); |
579 | } | 579 | } |
580 | 580 | ||
581 | /** | 581 | /** |
582 | * nlmsg_free - free a netlink message | 582 | * nlmsg_free - free a netlink message |
583 | * @skb: socket buffer of netlink message | 583 | * @skb: socket buffer of netlink message |
584 | */ | 584 | */ |
585 | static inline void nlmsg_free(struct sk_buff *skb) | 585 | static inline void nlmsg_free(struct sk_buff *skb) |
586 | { | 586 | { |
587 | kfree_skb(skb); | 587 | kfree_skb(skb); |
588 | } | 588 | } |
589 | 589 | ||
590 | /** | 590 | /** |
591 | * nlmsg_multicast - multicast a netlink message | 591 | * nlmsg_multicast - multicast a netlink message |
592 | * @sk: netlink socket to spread messages to | 592 | * @sk: netlink socket to spread messages to |
593 | * @skb: netlink message as socket buffer | 593 | * @skb: netlink message as socket buffer |
594 | * @pid: own netlink pid to avoid sending to yourself | 594 | * @pid: own netlink pid to avoid sending to yourself |
595 | * @group: multicast group id | 595 | * @group: multicast group id |
596 | * @flags: allocation flags | 596 | * @flags: allocation flags |
597 | */ | 597 | */ |
598 | static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb, | 598 | static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb, |
599 | u32 pid, unsigned int group, gfp_t flags) | 599 | u32 pid, unsigned int group, gfp_t flags) |
600 | { | 600 | { |
601 | int err; | 601 | int err; |
602 | 602 | ||
603 | NETLINK_CB(skb).dst_group = group; | 603 | NETLINK_CB(skb).dst_group = group; |
604 | 604 | ||
605 | err = netlink_broadcast(sk, skb, pid, group, flags); | 605 | err = netlink_broadcast(sk, skb, pid, group, flags); |
606 | if (err > 0) | 606 | if (err > 0) |
607 | err = 0; | 607 | err = 0; |
608 | 608 | ||
609 | return err; | 609 | return err; |
610 | } | 610 | } |
611 | 611 | ||
612 | /** | 612 | /** |
613 | * nlmsg_unicast - unicast a netlink message | 613 | * nlmsg_unicast - unicast a netlink message |
614 | * @sk: netlink socket to spread message to | 614 | * @sk: netlink socket to spread message to |
615 | * @skb: netlink message as socket buffer | 615 | * @skb: netlink message as socket buffer |
616 | * @pid: netlink pid of the destination socket | 616 | * @pid: netlink pid of the destination socket |
617 | */ | 617 | */ |
618 | static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid) | 618 | static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid) |
619 | { | 619 | { |
620 | int err; | 620 | int err; |
621 | 621 | ||
622 | err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT); | 622 | err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT); |
623 | if (err > 0) | 623 | if (err > 0) |
624 | err = 0; | 624 | err = 0; |
625 | 625 | ||
626 | return err; | 626 | return err; |
627 | } | 627 | } |
628 | 628 | ||
629 | /** | 629 | /** |
630 | * nlmsg_for_each_msg - iterate over a stream of messages | 630 | * nlmsg_for_each_msg - iterate over a stream of messages |
631 | * @pos: loop counter, set to current message | 631 | * @pos: loop counter, set to current message |
632 | * @head: head of message stream | 632 | * @head: head of message stream |
633 | * @len: length of message stream | 633 | * @len: length of message stream |
634 | * @rem: initialized to len, holds bytes currently remaining in stream | 634 | * @rem: initialized to len, holds bytes currently remaining in stream |
635 | */ | 635 | */ |
636 | #define nlmsg_for_each_msg(pos, head, len, rem) \ | 636 | #define nlmsg_for_each_msg(pos, head, len, rem) \ |
637 | for (pos = head, rem = len; \ | 637 | for (pos = head, rem = len; \ |
638 | nlmsg_ok(pos, rem); \ | 638 | nlmsg_ok(pos, rem); \ |
639 | pos = nlmsg_next(pos, &(rem))) | 639 | pos = nlmsg_next(pos, &(rem))) |
640 | 640 | ||
641 | /************************************************************************** | 641 | /************************************************************************** |
642 | * Netlink Attributes | 642 | * Netlink Attributes |
643 | **************************************************************************/ | 643 | **************************************************************************/ |
644 | 644 | ||
645 | /** | 645 | /** |
646 | * nla_attr_size - length of attribute not including padding | 646 | * nla_attr_size - length of attribute not including padding |
647 | * @payload: length of payload | 647 | * @payload: length of payload |
648 | */ | 648 | */ |
649 | static inline int nla_attr_size(int payload) | 649 | static inline int nla_attr_size(int payload) |
650 | { | 650 | { |
651 | return NLA_HDRLEN + payload; | 651 | return NLA_HDRLEN + payload; |
652 | } | 652 | } |
653 | 653 | ||
654 | /** | 654 | /** |
655 | * nla_total_size - total length of attribute including padding | 655 | * nla_total_size - total length of attribute including padding |
656 | * @payload: length of payload | 656 | * @payload: length of payload |
657 | */ | 657 | */ |
658 | static inline int nla_total_size(int payload) | 658 | static inline int nla_total_size(int payload) |
659 | { | 659 | { |
660 | return NLA_ALIGN(nla_attr_size(payload)); | 660 | return NLA_ALIGN(nla_attr_size(payload)); |
661 | } | 661 | } |
662 | 662 | ||
663 | /** | 663 | /** |
664 | * nla_padlen - length of padding at the tail of attribute | 664 | * nla_padlen - length of padding at the tail of attribute |
665 | * @payload: length of payload | 665 | * @payload: length of payload |
666 | */ | 666 | */ |
667 | static inline int nla_padlen(int payload) | 667 | static inline int nla_padlen(int payload) |
668 | { | 668 | { |
669 | return nla_total_size(payload) - nla_attr_size(payload); | 669 | return nla_total_size(payload) - nla_attr_size(payload); |
670 | } | 670 | } |
671 | 671 | ||
672 | /** | 672 | /** |
673 | * nla_type - attribute type | 673 | * nla_type - attribute type |
674 | * @nla: netlink attribute | 674 | * @nla: netlink attribute |
675 | */ | 675 | */ |
676 | static inline int nla_type(const struct nlattr *nla) | 676 | static inline int nla_type(const struct nlattr *nla) |
677 | { | 677 | { |
678 | return nla->nla_type & NLA_TYPE_MASK; | 678 | return nla->nla_type & NLA_TYPE_MASK; |
679 | } | 679 | } |
680 | 680 | ||
681 | /** | 681 | /** |
682 | * nla_data - head of payload | 682 | * nla_data - head of payload |
683 | * @nla: netlink attribute | 683 | * @nla: netlink attribute |
684 | */ | 684 | */ |
685 | static inline void *nla_data(const struct nlattr *nla) | 685 | static inline void *nla_data(const struct nlattr *nla) |
686 | { | 686 | { |
687 | return (char *) nla + NLA_HDRLEN; | 687 | return (char *) nla + NLA_HDRLEN; |
688 | } | 688 | } |
689 | 689 | ||
690 | /** | 690 | /** |
691 | * nla_len - length of payload | 691 | * nla_len - length of payload |
692 | * @nla: netlink attribute | 692 | * @nla: netlink attribute |
693 | */ | 693 | */ |
694 | static inline int nla_len(const struct nlattr *nla) | 694 | static inline int nla_len(const struct nlattr *nla) |
695 | { | 695 | { |
696 | return nla->nla_len - NLA_HDRLEN; | 696 | return nla->nla_len - NLA_HDRLEN; |
697 | } | 697 | } |
698 | 698 | ||
699 | /** | 699 | /** |
700 | * nla_ok - check if the netlink attribute fits into the remaining bytes | 700 | * nla_ok - check if the netlink attribute fits into the remaining bytes |
701 | * @nla: netlink attribute | 701 | * @nla: netlink attribute |
702 | * @remaining: number of bytes remaining in attribute stream | 702 | * @remaining: number of bytes remaining in attribute stream |
703 | */ | 703 | */ |
704 | static inline int nla_ok(const struct nlattr *nla, int remaining) | 704 | static inline int nla_ok(const struct nlattr *nla, int remaining) |
705 | { | 705 | { |
706 | return remaining >= (int) sizeof(*nla) && | 706 | return remaining >= (int) sizeof(*nla) && |
707 | nla->nla_len >= sizeof(*nla) && | 707 | nla->nla_len >= sizeof(*nla) && |
708 | nla->nla_len <= remaining; | 708 | nla->nla_len <= remaining; |
709 | } | 709 | } |
710 | 710 | ||
711 | /** | 711 | /** |
712 | * nla_next - next netlink attribute in attribute stream | 712 | * nla_next - next netlink attribute in attribute stream |
713 | * @nla: netlink attribute | 713 | * @nla: netlink attribute |
714 | * @remaining: number of bytes remaining in attribute stream | 714 | * @remaining: number of bytes remaining in attribute stream |
715 | * | 715 | * |
716 | * Returns the next netlink attribute in the attribute stream and | 716 | * Returns the next netlink attribute in the attribute stream and |
717 | * decrements remaining by the size of the current attribute. | 717 | * decrements remaining by the size of the current attribute. |
718 | */ | 718 | */ |
719 | static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining) | 719 | static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining) |
720 | { | 720 | { |
721 | int totlen = NLA_ALIGN(nla->nla_len); | 721 | int totlen = NLA_ALIGN(nla->nla_len); |
722 | 722 | ||
723 | *remaining -= totlen; | 723 | *remaining -= totlen; |
724 | return (struct nlattr *) ((char *) nla + totlen); | 724 | return (struct nlattr *) ((char *) nla + totlen); |
725 | } | 725 | } |
726 | 726 | ||
727 | /** | 727 | /** |
728 | * nla_find_nested - find attribute in a set of nested attributes | 728 | * nla_find_nested - find attribute in a set of nested attributes |
729 | * @nla: attribute containing the nested attributes | 729 | * @nla: attribute containing the nested attributes |
730 | * @attrtype: type of attribute to look for | 730 | * @attrtype: type of attribute to look for |
731 | * | 731 | * |
732 | * Returns the first attribute which matches the specified type. | 732 | * Returns the first attribute which matches the specified type. |
733 | */ | 733 | */ |
734 | static inline struct nlattr * | 734 | static inline struct nlattr * |
735 | nla_find_nested(const struct nlattr *nla, int attrtype) | 735 | nla_find_nested(const struct nlattr *nla, int attrtype) |
736 | { | 736 | { |
737 | return nla_find(nla_data(nla), nla_len(nla), attrtype); | 737 | return nla_find(nla_data(nla), nla_len(nla), attrtype); |
738 | } | 738 | } |
739 | 739 | ||
740 | /** | 740 | /** |
741 | * nla_parse_nested - parse nested attributes | 741 | * nla_parse_nested - parse nested attributes |
742 | * @tb: destination array with maxtype+1 elements | 742 | * @tb: destination array with maxtype+1 elements |
743 | * @maxtype: maximum attribute type to be expected | 743 | * @maxtype: maximum attribute type to be expected |
744 | * @nla: attribute containing the nested attributes | 744 | * @nla: attribute containing the nested attributes |
745 | * @policy: validation policy | 745 | * @policy: validation policy |
746 | * | 746 | * |
747 | * See nla_parse() | 747 | * See nla_parse() |
748 | */ | 748 | */ |
749 | static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, | 749 | static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, |
750 | const struct nlattr *nla, | 750 | const struct nlattr *nla, |
751 | const struct nla_policy *policy) | 751 | const struct nla_policy *policy) |
752 | { | 752 | { |
753 | return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); | 753 | return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); |
754 | } | 754 | } |
755 | 755 | ||
756 | /** | 756 | /** |
757 | * nla_put_u8 - Add a u8 netlink attribute to a socket buffer | 757 | * nla_put_u8 - Add a u8 netlink attribute to a socket buffer |
758 | * @skb: socket buffer to add attribute to | 758 | * @skb: socket buffer to add attribute to |
759 | * @attrtype: attribute type | 759 | * @attrtype: attribute type |
760 | * @value: numeric value | 760 | * @value: numeric value |
761 | */ | 761 | */ |
762 | static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value) | 762 | static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value) |
763 | { | 763 | { |
764 | return nla_put(skb, attrtype, sizeof(u8), &value); | 764 | return nla_put(skb, attrtype, sizeof(u8), &value); |
765 | } | 765 | } |
766 | 766 | ||
767 | /** | 767 | /** |
768 | * nla_put_u16 - Add a u16 netlink attribute to a socket buffer | 768 | * nla_put_u16 - Add a u16 netlink attribute to a socket buffer |
769 | * @skb: socket buffer to add attribute to | 769 | * @skb: socket buffer to add attribute to |
770 | * @attrtype: attribute type | 770 | * @attrtype: attribute type |
771 | * @value: numeric value | 771 | * @value: numeric value |
772 | */ | 772 | */ |
773 | static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value) | 773 | static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value) |
774 | { | 774 | { |
775 | return nla_put(skb, attrtype, sizeof(u16), &value); | 775 | return nla_put(skb, attrtype, sizeof(u16), &value); |
776 | } | 776 | } |
777 | 777 | ||
778 | /** | 778 | /** |
779 | * nla_put_u32 - Add a u32 netlink attribute to a socket buffer | 779 | * nla_put_u32 - Add a u32 netlink attribute to a socket buffer |
780 | * @skb: socket buffer to add attribute to | 780 | * @skb: socket buffer to add attribute to |
781 | * @attrtype: attribute type | 781 | * @attrtype: attribute type |
782 | * @value: numeric value | 782 | * @value: numeric value |
783 | */ | 783 | */ |
784 | static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value) | 784 | static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value) |
785 | { | 785 | { |
786 | return nla_put(skb, attrtype, sizeof(u32), &value); | 786 | return nla_put(skb, attrtype, sizeof(u32), &value); |
787 | } | 787 | } |
788 | 788 | ||
789 | /** | 789 | /** |
790 | * nla_put_64 - Add a u64 netlink attribute to a socket buffer | 790 | * nla_put_64 - Add a u64 netlink attribute to a socket buffer |
791 | * @skb: socket buffer to add attribute to | 791 | * @skb: socket buffer to add attribute to |
792 | * @attrtype: attribute type | 792 | * @attrtype: attribute type |
793 | * @value: numeric value | 793 | * @value: numeric value |
794 | */ | 794 | */ |
795 | static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value) | 795 | static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value) |
796 | { | 796 | { |
797 | return nla_put(skb, attrtype, sizeof(u64), &value); | 797 | return nla_put(skb, attrtype, sizeof(u64), &value); |
798 | } | 798 | } |
799 | 799 | ||
800 | /** | 800 | /** |
801 | * nla_put_string - Add a string netlink attribute to a socket buffer | 801 | * nla_put_string - Add a string netlink attribute to a socket buffer |
802 | * @skb: socket buffer to add attribute to | 802 | * @skb: socket buffer to add attribute to |
803 | * @attrtype: attribute type | 803 | * @attrtype: attribute type |
804 | * @str: NUL terminated string | 804 | * @str: NUL terminated string |
805 | */ | 805 | */ |
806 | static inline int nla_put_string(struct sk_buff *skb, int attrtype, | 806 | static inline int nla_put_string(struct sk_buff *skb, int attrtype, |
807 | const char *str) | 807 | const char *str) |
808 | { | 808 | { |
809 | return nla_put(skb, attrtype, strlen(str) + 1, str); | 809 | return nla_put(skb, attrtype, strlen(str) + 1, str); |
810 | } | 810 | } |
811 | 811 | ||
812 | /** | 812 | /** |
813 | * nla_put_flag - Add a flag netlink attribute to a socket buffer | 813 | * nla_put_flag - Add a flag netlink attribute to a socket buffer |
814 | * @skb: socket buffer to add attribute to | 814 | * @skb: socket buffer to add attribute to |
815 | * @attrtype: attribute type | 815 | * @attrtype: attribute type |
816 | */ | 816 | */ |
817 | static inline int nla_put_flag(struct sk_buff *skb, int attrtype) | 817 | static inline int nla_put_flag(struct sk_buff *skb, int attrtype) |
818 | { | 818 | { |
819 | return nla_put(skb, attrtype, 0, NULL); | 819 | return nla_put(skb, attrtype, 0, NULL); |
820 | } | 820 | } |
821 | 821 | ||
822 | /** | 822 | /** |
823 | * nla_put_msecs - Add a msecs netlink attribute to a socket buffer | 823 | * nla_put_msecs - Add a msecs netlink attribute to a socket buffer |
824 | * @skb: socket buffer to add attribute to | 824 | * @skb: socket buffer to add attribute to |
825 | * @attrtype: attribute type | 825 | * @attrtype: attribute type |
826 | * @jiffies: number of msecs in jiffies | 826 | * @jiffies: number of msecs in jiffies |
827 | */ | 827 | */ |
828 | static inline int nla_put_msecs(struct sk_buff *skb, int attrtype, | 828 | static inline int nla_put_msecs(struct sk_buff *skb, int attrtype, |
829 | unsigned long jiffies) | 829 | unsigned long jiffies) |
830 | { | 830 | { |
831 | u64 tmp = jiffies_to_msecs(jiffies); | 831 | u64 tmp = jiffies_to_msecs(jiffies); |
832 | return nla_put(skb, attrtype, sizeof(u64), &tmp); | 832 | return nla_put(skb, attrtype, sizeof(u64), &tmp); |
833 | } | 833 | } |
834 | 834 | ||
835 | #define NLA_PUT(skb, attrtype, attrlen, data) \ | 835 | #define NLA_PUT(skb, attrtype, attrlen, data) \ |
836 | do { \ | 836 | do { \ |
837 | if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ | 837 | if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ |
838 | goto nla_put_failure; \ | 838 | goto nla_put_failure; \ |
839 | } while(0) | 839 | } while(0) |
840 | 840 | ||
841 | #define NLA_PUT_TYPE(skb, type, attrtype, value) \ | 841 | #define NLA_PUT_TYPE(skb, type, attrtype, value) \ |
842 | do { \ | 842 | do { \ |
843 | type __tmp = value; \ | 843 | type __tmp = value; \ |
844 | NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ | 844 | NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ |
845 | } while(0) | 845 | } while(0) |
846 | 846 | ||
847 | #define NLA_PUT_U8(skb, attrtype, value) \ | 847 | #define NLA_PUT_U8(skb, attrtype, value) \ |
848 | NLA_PUT_TYPE(skb, u8, attrtype, value) | 848 | NLA_PUT_TYPE(skb, u8, attrtype, value) |
849 | 849 | ||
850 | #define NLA_PUT_U16(skb, attrtype, value) \ | 850 | #define NLA_PUT_U16(skb, attrtype, value) \ |
851 | NLA_PUT_TYPE(skb, u16, attrtype, value) | 851 | NLA_PUT_TYPE(skb, u16, attrtype, value) |
852 | 852 | ||
853 | #define NLA_PUT_LE16(skb, attrtype, value) \ | 853 | #define NLA_PUT_LE16(skb, attrtype, value) \ |
854 | NLA_PUT_TYPE(skb, __le16, attrtype, value) | 854 | NLA_PUT_TYPE(skb, __le16, attrtype, value) |
855 | 855 | ||
856 | #define NLA_PUT_BE16(skb, attrtype, value) \ | 856 | #define NLA_PUT_BE16(skb, attrtype, value) \ |
857 | NLA_PUT_TYPE(skb, __be16, attrtype, value) | 857 | NLA_PUT_TYPE(skb, __be16, attrtype, value) |
858 | 858 | ||
859 | #define NLA_PUT_NET16(skb, attrtype, value) \ | ||
860 | NLA_PUT_BE16(skb, attrtype | NLA_F_NET_BYTEORDER, value) | ||
861 | |||
859 | #define NLA_PUT_U32(skb, attrtype, value) \ | 862 | #define NLA_PUT_U32(skb, attrtype, value) \ |
860 | NLA_PUT_TYPE(skb, u32, attrtype, value) | 863 | NLA_PUT_TYPE(skb, u32, attrtype, value) |
861 | 864 | ||
862 | #define NLA_PUT_BE32(skb, attrtype, value) \ | 865 | #define NLA_PUT_BE32(skb, attrtype, value) \ |
863 | NLA_PUT_TYPE(skb, __be32, attrtype, value) | 866 | NLA_PUT_TYPE(skb, __be32, attrtype, value) |
864 | 867 | ||
868 | #define NLA_PUT_NET32(skb, attrtype, value) \ | ||
869 | NLA_PUT_BE32(skb, attrtype | NLA_F_NET_BYTEORDER, value) | ||
870 | |||
865 | #define NLA_PUT_U64(skb, attrtype, value) \ | 871 | #define NLA_PUT_U64(skb, attrtype, value) \ |
866 | NLA_PUT_TYPE(skb, u64, attrtype, value) | 872 | NLA_PUT_TYPE(skb, u64, attrtype, value) |
867 | 873 | ||
868 | #define NLA_PUT_BE64(skb, attrtype, value) \ | 874 | #define NLA_PUT_BE64(skb, attrtype, value) \ |
869 | NLA_PUT_TYPE(skb, __be64, attrtype, value) | 875 | NLA_PUT_TYPE(skb, __be64, attrtype, value) |
876 | |||
877 | #define NLA_PUT_NET64(skb, attrtype, value) \ | ||
878 | NLA_PUT_BE64(skb, attrtype | NLA_F_NET_BYTEORDER, value) | ||
870 | 879 | ||
871 | #define NLA_PUT_STRING(skb, attrtype, value) \ | 880 | #define NLA_PUT_STRING(skb, attrtype, value) \ |
872 | NLA_PUT(skb, attrtype, strlen(value) + 1, value) | 881 | NLA_PUT(skb, attrtype, strlen(value) + 1, value) |
873 | 882 | ||
874 | #define NLA_PUT_FLAG(skb, attrtype) \ | 883 | #define NLA_PUT_FLAG(skb, attrtype) \ |
875 | NLA_PUT(skb, attrtype, 0, NULL) | 884 | NLA_PUT(skb, attrtype, 0, NULL) |
876 | 885 | ||
877 | #define NLA_PUT_MSECS(skb, attrtype, jiffies) \ | 886 | #define NLA_PUT_MSECS(skb, attrtype, jiffies) \ |
878 | NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies)) | 887 | NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies)) |
879 | 888 | ||
880 | /** | 889 | /** |
881 | * nla_get_u32 - return payload of u32 attribute | 890 | * nla_get_u32 - return payload of u32 attribute |
882 | * @nla: u32 netlink attribute | 891 | * @nla: u32 netlink attribute |
883 | */ | 892 | */ |
884 | static inline u32 nla_get_u32(const struct nlattr *nla) | 893 | static inline u32 nla_get_u32(const struct nlattr *nla) |
885 | { | 894 | { |
886 | return *(u32 *) nla_data(nla); | 895 | return *(u32 *) nla_data(nla); |
887 | } | 896 | } |
888 | 897 | ||
889 | /** | 898 | /** |
890 | * nla_get_be32 - return payload of __be32 attribute | 899 | * nla_get_be32 - return payload of __be32 attribute |
891 | * @nla: __be32 netlink attribute | 900 | * @nla: __be32 netlink attribute |
892 | */ | 901 | */ |
893 | static inline __be32 nla_get_be32(const struct nlattr *nla) | 902 | static inline __be32 nla_get_be32(const struct nlattr *nla) |
894 | { | 903 | { |
895 | return *(__be32 *) nla_data(nla); | 904 | return *(__be32 *) nla_data(nla); |
896 | } | 905 | } |
897 | 906 | ||
898 | /** | 907 | /** |
899 | * nla_get_u16 - return payload of u16 attribute | 908 | * nla_get_u16 - return payload of u16 attribute |
900 | * @nla: u16 netlink attribute | 909 | * @nla: u16 netlink attribute |
901 | */ | 910 | */ |
902 | static inline u16 nla_get_u16(const struct nlattr *nla) | 911 | static inline u16 nla_get_u16(const struct nlattr *nla) |
903 | { | 912 | { |
904 | return *(u16 *) nla_data(nla); | 913 | return *(u16 *) nla_data(nla); |
905 | } | 914 | } |
906 | 915 | ||
907 | /** | 916 | /** |
908 | * nla_get_be16 - return payload of __be16 attribute | 917 | * nla_get_be16 - return payload of __be16 attribute |
909 | * @nla: __be16 netlink attribute | 918 | * @nla: __be16 netlink attribute |
910 | */ | 919 | */ |
911 | static inline __be16 nla_get_be16(const struct nlattr *nla) | 920 | static inline __be16 nla_get_be16(const struct nlattr *nla) |
912 | { | 921 | { |
913 | return *(__be16 *) nla_data(nla); | 922 | return *(__be16 *) nla_data(nla); |
914 | } | 923 | } |
915 | 924 | ||
916 | /** | 925 | /** |
917 | * nla_get_le16 - return payload of __le16 attribute | 926 | * nla_get_le16 - return payload of __le16 attribute |
918 | * @nla: __le16 netlink attribute | 927 | * @nla: __le16 netlink attribute |
919 | */ | 928 | */ |
920 | static inline __le16 nla_get_le16(const struct nlattr *nla) | 929 | static inline __le16 nla_get_le16(const struct nlattr *nla) |
921 | { | 930 | { |
922 | return *(__le16 *) nla_data(nla); | 931 | return *(__le16 *) nla_data(nla); |
923 | } | 932 | } |
924 | 933 | ||
925 | /** | 934 | /** |
926 | * nla_get_u8 - return payload of u8 attribute | 935 | * nla_get_u8 - return payload of u8 attribute |
927 | * @nla: u8 netlink attribute | 936 | * @nla: u8 netlink attribute |
928 | */ | 937 | */ |
929 | static inline u8 nla_get_u8(const struct nlattr *nla) | 938 | static inline u8 nla_get_u8(const struct nlattr *nla) |
930 | { | 939 | { |
931 | return *(u8 *) nla_data(nla); | 940 | return *(u8 *) nla_data(nla); |
932 | } | 941 | } |
933 | 942 | ||
934 | /** | 943 | /** |
935 | * nla_get_u64 - return payload of u64 attribute | 944 | * nla_get_u64 - return payload of u64 attribute |
936 | * @nla: u64 netlink attribute | 945 | * @nla: u64 netlink attribute |
937 | */ | 946 | */ |
938 | static inline u64 nla_get_u64(const struct nlattr *nla) | 947 | static inline u64 nla_get_u64(const struct nlattr *nla) |
939 | { | 948 | { |
940 | u64 tmp; | 949 | u64 tmp; |
941 | 950 | ||
942 | nla_memcpy(&tmp, nla, sizeof(tmp)); | 951 | nla_memcpy(&tmp, nla, sizeof(tmp)); |
943 | 952 | ||
944 | return tmp; | 953 | return tmp; |
945 | } | 954 | } |
946 | 955 | ||
947 | /** | 956 | /** |
948 | * nla_get_be64 - return payload of __be64 attribute | 957 | * nla_get_be64 - return payload of __be64 attribute |
949 | * @nla: __be64 netlink attribute | 958 | * @nla: __be64 netlink attribute |
950 | */ | 959 | */ |
951 | static inline __be64 nla_get_be64(const struct nlattr *nla) | 960 | static inline __be64 nla_get_be64(const struct nlattr *nla) |
952 | { | 961 | { |
953 | __be64 tmp; | 962 | __be64 tmp; |
954 | 963 | ||
955 | nla_memcpy(&tmp, nla, sizeof(tmp)); | 964 | nla_memcpy(&tmp, nla, sizeof(tmp)); |
956 | 965 | ||
957 | return tmp; | 966 | return tmp; |
958 | } | 967 | } |
959 | 968 | ||
960 | /** | 969 | /** |
961 | * nla_get_flag - return payload of flag attribute | 970 | * nla_get_flag - return payload of flag attribute |
962 | * @nla: flag netlink attribute | 971 | * @nla: flag netlink attribute |
963 | */ | 972 | */ |
964 | static inline int nla_get_flag(const struct nlattr *nla) | 973 | static inline int nla_get_flag(const struct nlattr *nla) |
965 | { | 974 | { |
966 | return !!nla; | 975 | return !!nla; |
967 | } | 976 | } |
968 | 977 | ||
969 | /** | 978 | /** |
970 | * nla_get_msecs - return payload of msecs attribute | 979 | * nla_get_msecs - return payload of msecs attribute |
971 | * @nla: msecs netlink attribute | 980 | * @nla: msecs netlink attribute |
972 | * | 981 | * |
973 | * Returns the number of milliseconds in jiffies. | 982 | * Returns the number of milliseconds in jiffies. |
974 | */ | 983 | */ |
975 | static inline unsigned long nla_get_msecs(const struct nlattr *nla) | 984 | static inline unsigned long nla_get_msecs(const struct nlattr *nla) |
976 | { | 985 | { |
977 | u64 msecs = nla_get_u64(nla); | 986 | u64 msecs = nla_get_u64(nla); |
978 | 987 | ||
979 | return msecs_to_jiffies((unsigned long) msecs); | 988 | return msecs_to_jiffies((unsigned long) msecs); |
980 | } | 989 | } |
981 | 990 | ||
982 | /** | 991 | /** |
983 | * nla_nest_start - Start a new level of nested attributes | 992 | * nla_nest_start - Start a new level of nested attributes |
984 | * @skb: socket buffer to add attributes to | 993 | * @skb: socket buffer to add attributes to |
985 | * @attrtype: attribute type of container | 994 | * @attrtype: attribute type of container |
986 | * | 995 | * |
987 | * Returns the container attribute | 996 | * Returns the container attribute |
988 | */ | 997 | */ |
989 | static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype) | 998 | static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype) |
990 | { | 999 | { |
991 | struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb); | 1000 | struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb); |
992 | 1001 | ||
993 | if (nla_put(skb, attrtype, 0, NULL) < 0) | 1002 | if (nla_put(skb, attrtype, 0, NULL) < 0) |
994 | return NULL; | 1003 | return NULL; |
995 | 1004 | ||
996 | return start; | 1005 | return start; |
997 | } | 1006 | } |
998 | 1007 | ||
999 | /** | 1008 | /** |
1000 | * nla_nest_end - Finalize nesting of attributes | 1009 | * nla_nest_end - Finalize nesting of attributes |
1001 | * @skb: socket buffer the attributes are stored in | 1010 | * @skb: socket buffer the attributes are stored in |
1002 | * @start: container attribute | 1011 | * @start: container attribute |
1003 | * | 1012 | * |
1004 | * Corrects the container attribute header to include the all | 1013 | * Corrects the container attribute header to include the all |
1005 | * appeneded attributes. | 1014 | * appeneded attributes. |
1006 | * | 1015 | * |
1007 | * Returns the total data length of the skb. | 1016 | * Returns the total data length of the skb. |
1008 | */ | 1017 | */ |
1009 | static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start) | 1018 | static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start) |
1010 | { | 1019 | { |
1011 | start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start; | 1020 | start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start; |
1012 | return skb->len; | 1021 | return skb->len; |
1013 | } | 1022 | } |
1014 | 1023 | ||
1015 | /** | 1024 | /** |
1016 | * nla_nest_cancel - Cancel nesting of attributes | 1025 | * nla_nest_cancel - Cancel nesting of attributes |
1017 | * @skb: socket buffer the message is stored in | 1026 | * @skb: socket buffer the message is stored in |
1018 | * @start: container attribute | 1027 | * @start: container attribute |
1019 | * | 1028 | * |
1020 | * Removes the container attribute and including all nested | 1029 | * Removes the container attribute and including all nested |
1021 | * attributes. Returns -EMSGSIZE | 1030 | * attributes. Returns -EMSGSIZE |
1022 | */ | 1031 | */ |
1023 | static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) | 1032 | static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) |
1024 | { | 1033 | { |
1025 | nlmsg_trim(skb, start); | 1034 | nlmsg_trim(skb, start); |
1026 | } | 1035 | } |
1027 | 1036 | ||
1028 | /** | 1037 | /** |
1029 | * nla_validate_nested - Validate a stream of nested attributes | 1038 | * nla_validate_nested - Validate a stream of nested attributes |
1030 | * @start: container attribute | 1039 | * @start: container attribute |
1031 | * @maxtype: maximum attribute type to be expected | 1040 | * @maxtype: maximum attribute type to be expected |
1032 | * @policy: validation policy | 1041 | * @policy: validation policy |
1033 | * | 1042 | * |
1034 | * Validates all attributes in the nested attribute stream against the | 1043 | * Validates all attributes in the nested attribute stream against the |
1035 | * specified policy. Attributes with a type exceeding maxtype will be | 1044 | * specified policy. Attributes with a type exceeding maxtype will be |
1036 | * ignored. See documenation of struct nla_policy for more details. | 1045 | * ignored. See documenation of struct nla_policy for more details. |
1037 | * | 1046 | * |
1038 | * Returns 0 on success or a negative error code. | 1047 | * Returns 0 on success or a negative error code. |
1039 | */ | 1048 | */ |
1040 | static inline int nla_validate_nested(const struct nlattr *start, int maxtype, | 1049 | static inline int nla_validate_nested(const struct nlattr *start, int maxtype, |
1041 | const struct nla_policy *policy) | 1050 | const struct nla_policy *policy) |
1042 | { | 1051 | { |
1043 | return nla_validate(nla_data(start), nla_len(start), maxtype, policy); | 1052 | return nla_validate(nla_data(start), nla_len(start), maxtype, policy); |
1044 | } | 1053 | } |
1045 | 1054 | ||
1046 | /** | 1055 | /** |
1047 | * nla_for_each_attr - iterate over a stream of attributes | 1056 | * nla_for_each_attr - iterate over a stream of attributes |
1048 | * @pos: loop counter, set to current attribute | 1057 | * @pos: loop counter, set to current attribute |
1049 | * @head: head of attribute stream | 1058 | * @head: head of attribute stream |
1050 | * @len: length of attribute stream | 1059 | * @len: length of attribute stream |
1051 | * @rem: initialized to len, holds bytes currently remaining in stream | 1060 | * @rem: initialized to len, holds bytes currently remaining in stream |
1052 | */ | 1061 | */ |
1053 | #define nla_for_each_attr(pos, head, len, rem) \ | 1062 | #define nla_for_each_attr(pos, head, len, rem) \ |
1054 | for (pos = head, rem = len; \ | 1063 | for (pos = head, rem = len; \ |
1055 | nla_ok(pos, rem); \ | 1064 | nla_ok(pos, rem); \ |
1056 | pos = nla_next(pos, &(rem))) | 1065 | pos = nla_next(pos, &(rem))) |
1057 | 1066 | ||
1058 | /** | 1067 | /** |
1059 | * nla_for_each_nested - iterate over nested attributes | 1068 | * nla_for_each_nested - iterate over nested attributes |
1060 | * @pos: loop counter, set to current attribute | 1069 | * @pos: loop counter, set to current attribute |
1061 | * @nla: attribute containing the nested attributes | 1070 | * @nla: attribute containing the nested attributes |
1062 | * @rem: initialized to len, holds bytes currently remaining in stream | 1071 | * @rem: initialized to len, holds bytes currently remaining in stream |
1063 | */ | 1072 | */ |
1064 | #define nla_for_each_nested(pos, nla, rem) \ | 1073 | #define nla_for_each_nested(pos, nla, rem) \ |
1065 | nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem) | 1074 | nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem) |
1066 | 1075 | ||
1067 | #endif | 1076 | #endif |
1068 | 1077 |