aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
Diffstat (limited to 'include/net')
-rw-r--r--include/net/genetlink.h154
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_icmp.h11
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_ipv4.h43
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_icmpv6.h27
-rw-r--r--include/net/netfilter/nf_conntrack.h354
-rw-r--r--include/net/netfilter/nf_conntrack_compat.h108
-rw-r--r--include/net/netfilter/nf_conntrack_core.h76
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h51
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h93
-rw-r--r--include/net/netfilter/nf_conntrack_protocol.h105
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h190
-rw-r--r--include/net/netlink.h883
12 files changed, 2095 insertions, 0 deletions
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
new file mode 100644
index 000000000000..52d8b1a73d52
--- /dev/null
+++ b/include/net/genetlink.h
@@ -0,0 +1,154 @@
1#ifndef __NET_GENERIC_NETLINK_H
2#define __NET_GENERIC_NETLINK_H
3
4#include <linux/genetlink.h>
5#include <net/netlink.h>
6
7/**
8 * struct genl_family - generic netlink family
9 * @id: protocol family idenfitier
10 * @hdrsize: length of user specific header in bytes
11 * @name: name of family
12 * @version: protocol version
13 * @maxattr: maximum number of attributes supported
14 * @attrbuf: buffer to store parsed attributes
15 * @ops_list: list of all assigned operations
16 * @family_list: family list
17 */
18struct genl_family
19{
20 unsigned int id;
21 unsigned int hdrsize;
22 char name[GENL_NAMSIZ];
23 unsigned int version;
24 unsigned int maxattr;
25 struct module * owner;
26 struct nlattr ** attrbuf; /* private */
27 struct list_head ops_list; /* private */
28 struct list_head family_list; /* private */
29};
30
31#define GENL_ADMIN_PERM 0x01
32
33/**
34 * struct genl_info - receiving information
35 * @snd_seq: sending sequence number
36 * @snd_pid: netlink pid of sender
37 * @nlhdr: netlink message header
38 * @genlhdr: generic netlink message header
39 * @userhdr: user specific header
40 * @attrs: netlink attributes
41 */
42struct genl_info
43{
44 u32 snd_seq;
45 u32 snd_pid;
46 struct nlmsghdr * nlhdr;
47 struct genlmsghdr * genlhdr;
48 void * userhdr;
49 struct nlattr ** attrs;
50};
51
52/**
53 * struct genl_ops - generic netlink operations
54 * @cmd: command identifier
55 * @flags: flags
56 * @policy: attribute validation policy
57 * @doit: standard command callback
58 * @dumpit: callback for dumpers
59 * @ops_list: operations list
60 */
61struct genl_ops
62{
63 unsigned int cmd;
64 unsigned int flags;
65 struct nla_policy *policy;
66 int (*doit)(struct sk_buff *skb,
67 struct genl_info *info);
68 int (*dumpit)(struct sk_buff *skb,
69 struct netlink_callback *cb);
70 struct list_head ops_list;
71};
72
73extern int genl_register_family(struct genl_family *family);
74extern int genl_unregister_family(struct genl_family *family);
75extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
76extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
77
78extern struct sock *genl_sock;
79
80/**
81 * genlmsg_put - Add generic netlink header to netlink message
82 * @skb: socket buffer holding the message
83 * @pid: netlink pid the message is addressed to
84 * @seq: sequence number (usually the one of the sender)
85 * @type: netlink message type
86 * @hdrlen: length of the user specific header
87 * @flags netlink message flags
88 * @cmd: generic netlink command
89 * @version: version
90 *
91 * Returns pointer to user specific header
92 */
93static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
94 int type, int hdrlen, int flags,
95 u8 cmd, u8 version)
96{
97 struct nlmsghdr *nlh;
98 struct genlmsghdr *hdr;
99
100 nlh = nlmsg_put(skb, pid, seq, type, GENL_HDRLEN + hdrlen, flags);
101 if (nlh == NULL)
102 return NULL;
103
104 hdr = nlmsg_data(nlh);
105 hdr->cmd = cmd;
106 hdr->version = version;
107 hdr->reserved = 0;
108
109 return (char *) hdr + GENL_HDRLEN;
110}
111
112/**
113 * genlmsg_end - Finalize a generic netlink message
114 * @skb: socket buffer the message is stored in
115 * @hdr: user specific header
116 */
117static inline int genlmsg_end(struct sk_buff *skb, void *hdr)
118{
119 return nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
120}
121
122/**
123 * genlmsg_cancel - Cancel construction of a generic netlink message
124 * @skb: socket buffer the message is stored in
125 * @hdr: generic netlink message header
126 */
127static inline int genlmsg_cancel(struct sk_buff *skb, void *hdr)
128{
129 return nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
130}
131
132/**
133 * genlmsg_multicast - multicast a netlink message
134 * @skb: netlink message as socket buffer
135 * @pid: own netlink pid to avoid sending to yourself
136 * @group: multicast group id
137 */
138static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
139 unsigned int group)
140{
141 return nlmsg_multicast(genl_sock, skb, pid, group);
142}
143
144/**
145 * genlmsg_unicast - unicast a netlink message
146 * @skb: netlink message as socket buffer
147 * @pid: netlink pid of the destination socket
148 */
149static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
150{
151 return nlmsg_unicast(genl_sock, skb, pid);
152}
153
154#endif /* __NET_GENERIC_NETLINK_H */
diff --git a/include/net/netfilter/ipv4/nf_conntrack_icmp.h b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
new file mode 100644
index 000000000000..3dd22cff23ec
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
@@ -0,0 +1,11 @@
1#ifndef _NF_CONNTRACK_ICMP_H
2#define _NF_CONNTRACK_ICMP_H
3/* ICMP tracking. */
4#include <asm/atomic.h>
5
6struct ip_ct_icmp
7{
8 /* Optimization: when number in == number out, forget immediately. */
9 atomic_t count;
10};
11#endif /* _NF_CONNTRACK_ICMP_H */
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
new file mode 100644
index 000000000000..25b081a730e6
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -0,0 +1,43 @@
1/*
2 * IPv4 support for nf_conntrack.
3 *
4 * 23 Mar 2004: Yasuyuki Kozakai @ USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - move L3 protocol dependent part from include/linux/netfilter_ipv4/
6 * ip_conntarck.h
7 */
8
9#ifndef _NF_CONNTRACK_IPV4_H
10#define _NF_CONNTRACK_IPV4_H
11
12#ifdef CONFIG_IP_NF_NAT_NEEDED
13#include <linux/netfilter_ipv4/ip_nat.h>
14
15/* per conntrack: nat application helper private data */
16union ip_conntrack_nat_help {
17 /* insert nat helper private data here */
18};
19
20struct nf_conntrack_ipv4_nat {
21 struct ip_nat_info info;
22 union ip_conntrack_nat_help help;
23#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
24 defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
25 int masq_index;
26#endif
27};
28#endif /* CONFIG_IP_NF_NAT_NEEDED */
29
30struct nf_conntrack_ipv4 {
31#ifdef CONFIG_IP_NF_NAT_NEEDED
32 struct nf_conntrack_ipv4_nat *nat;
33#endif
34};
35
36/* Returns new sk_buff, or NULL */
37struct sk_buff *
38nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
39
40/* call to create an explicit dependency on nf_conntrack_l3proto_ipv4. */
41extern void need_ip_conntrack(void);
42
43#endif /*_NF_CONNTRACK_IPV4_H*/
diff --git a/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
new file mode 100644
index 000000000000..86591afda29c
--- /dev/null
+++ b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
@@ -0,0 +1,27 @@
1/*
2 * ICMPv6 tracking.
3 *
4 * 21 Apl 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - separated from nf_conntrack_icmp.h
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_icmp.h
8 */
9
10#ifndef _NF_CONNTRACK_ICMPV6_H
11#define _NF_CONNTRACK_ICMPV6_H
12#include <asm/atomic.h>
13
14#ifndef ICMPV6_NI_QUERY
15#define ICMPV6_NI_QUERY 139
16#endif
17#ifndef ICMPV6_NI_REPLY
18#define ICMPV6_NI_REPLY 140
19#endif
20
21struct nf_ct_icmpv6
22{
23 /* Optimization: when number in == number out, forget immediately. */
24 atomic_t count;
25};
26
27#endif /* _NF_CONNTRACK_ICMPV6_H */
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
new file mode 100644
index 000000000000..cc4825610795
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack.h
@@ -0,0 +1,354 @@
1/*
2 * Connection state tracking for netfilter. This is separated from,
3 * but required by, the (future) NAT layer; it can also be used by an iptables
4 * extension.
5 *
6 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
7 * - generalize L3 protocol dependent part.
8 *
9 * Derived from include/linux/netfiter_ipv4/ip_conntrack.h
10 */
11
12#ifndef _NF_CONNTRACK_H
13#define _NF_CONNTRACK_H
14
15#include <linux/netfilter/nf_conntrack_common.h>
16
17#ifdef __KERNEL__
18#include <linux/config.h>
19#include <linux/bitops.h>
20#include <linux/compiler.h>
21#include <asm/atomic.h>
22
23#include <linux/netfilter/nf_conntrack_tcp.h>
24#include <linux/netfilter/nf_conntrack_sctp.h>
25#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
26#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
27
28#include <net/netfilter/nf_conntrack_tuple.h>
29
30/* per conntrack: protocol private data */
31union nf_conntrack_proto {
32 /* insert conntrack proto private data here */
33 struct ip_ct_sctp sctp;
34 struct ip_ct_tcp tcp;
35 struct ip_ct_icmp icmp;
36 struct nf_ct_icmpv6 icmpv6;
37};
38
39union nf_conntrack_expect_proto {
40 /* insert expect proto private data here */
41};
42
43/* Add protocol helper include file here */
44#include <linux/netfilter/nf_conntrack_ftp.h>
45
46/* per conntrack: application helper private data */
47union nf_conntrack_help {
48 /* insert conntrack helper private data (master) here */
49 struct ip_ct_ftp_master ct_ftp_info;
50};
51
52#include <linux/types.h>
53#include <linux/skbuff.h>
54
55#ifdef CONFIG_NETFILTER_DEBUG
56#define NF_CT_ASSERT(x) \
57do { \
58 if (!(x)) \
59 /* Wooah! I'm tripping my conntrack in a frenzy of \
60 netplay... */ \
61 printk("NF_CT_ASSERT: %s:%i(%s)\n", \
62 __FILE__, __LINE__, __FUNCTION__); \
63} while(0)
64#else
65#define NF_CT_ASSERT(x)
66#endif
67
68struct nf_conntrack_helper;
69
70#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
71struct nf_conn
72{
73 /* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
74 plus 1 for any connection(s) we are `master' for */
75 struct nf_conntrack ct_general;
76
77 /* XXX should I move this to the tail ? - Y.K */
78 /* These are my tuples; original and reply */
79 struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
80
81 /* Have we seen traffic both ways yet? (bitset) */
82 unsigned long status;
83
84 /* Timer function; drops refcnt when it goes off. */
85 struct timer_list timeout;
86
87#ifdef CONFIG_NF_CT_ACCT
88 /* Accounting Information (same cache line as other written members) */
89 struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
90#endif
91 /* If we were expected by an expectation, this will be it */
92 struct nf_conn *master;
93
94 /* Current number of expected connections */
95 unsigned int expecting;
96
97 /* Helper. if any */
98 struct nf_conntrack_helper *helper;
99
100 /* features - nat, helper, ... used by allocating system */
101 u_int32_t features;
102
103 /* Storage reserved for other modules: */
104
105 union nf_conntrack_proto proto;
106
107#if defined(CONFIG_NF_CONNTRACK_MARK)
108 u_int32_t mark;
109#endif
110
111 /* These members are dynamically allocated. */
112
113 union nf_conntrack_help *help;
114
115 /* Layer 3 dependent members. (ex: NAT) */
116 union {
117 struct nf_conntrack_ipv4 *ipv4;
118 } l3proto;
119 void *data[0];
120};
121
122struct nf_conntrack_expect
123{
124 /* Internal linked list (global expectation list) */
125 struct list_head list;
126
127 /* We expect this tuple, with the following mask */
128 struct nf_conntrack_tuple tuple, mask;
129
130 /* Function to call after setup and insertion */
131 void (*expectfn)(struct nf_conn *new,
132 struct nf_conntrack_expect *this);
133
134 /* The conntrack of the master connection */
135 struct nf_conn *master;
136
137 /* Timer function; deletes the expectation. */
138 struct timer_list timeout;
139
140 /* Usage count. */
141 atomic_t use;
142
143 /* Flags */
144 unsigned int flags;
145
146#ifdef CONFIG_NF_NAT_NEEDED
147 /* This is the original per-proto part, used to map the
148 * expected connection the way the recipient expects. */
149 union nf_conntrack_manip_proto saved_proto;
150 /* Direction relative to the master connection. */
151 enum ip_conntrack_dir dir;
152#endif
153};
154
155#define NF_CT_EXPECT_PERMANENT 0x1
156
157static inline struct nf_conn *
158nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
159{
160 return container_of(hash, struct nf_conn,
161 tuplehash[hash->tuple.dst.dir]);
162}
163
164/* get master conntrack via master expectation */
165#define master_ct(conntr) (conntr->master)
166
167/* Alter reply tuple (maybe alter helper). */
168extern void
169nf_conntrack_alter_reply(struct nf_conn *conntrack,
170 const struct nf_conntrack_tuple *newreply);
171
172/* Is this tuple taken? (ignoring any belonging to the given
173 conntrack). */
174extern int
175nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
176 const struct nf_conn *ignored_conntrack);
177
178/* Return conntrack_info and tuple hash for given skb. */
179static inline struct nf_conn *
180nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
181{
182 *ctinfo = skb->nfctinfo;
183 return (struct nf_conn *)skb->nfct;
184}
185
186/* decrement reference count on a conntrack */
187static inline void nf_ct_put(struct nf_conn *ct)
188{
189 NF_CT_ASSERT(ct);
190 nf_conntrack_put(&ct->ct_general);
191}
192
193/* call to create an explicit dependency on nf_conntrack. */
194extern void need_nf_conntrack(void);
195
196extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
197 const struct nf_conntrack_tuple *orig);
198
199extern void __nf_ct_refresh_acct(struct nf_conn *ct,
200 enum ip_conntrack_info ctinfo,
201 const struct sk_buff *skb,
202 unsigned long extra_jiffies,
203 int do_acct);
204
205/* Refresh conntrack for this many jiffies and do accounting */
206static inline void nf_ct_refresh_acct(struct nf_conn *ct,
207 enum ip_conntrack_info ctinfo,
208 const struct sk_buff *skb,
209 unsigned long extra_jiffies)
210{
211 __nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1);
212}
213
214/* Refresh conntrack for this many jiffies */
215static inline void nf_ct_refresh(struct nf_conn *ct,
216 const struct sk_buff *skb,
217 unsigned long extra_jiffies)
218{
219 __nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
220}
221
222/* These are for NAT. Icky. */
223/* Update TCP window tracking data when NAT mangles the packet */
224extern void nf_conntrack_tcp_update(struct sk_buff *skb,
225 unsigned int dataoff,
226 struct nf_conn *conntrack,
227 int dir);
228
229/* Call me when a conntrack is destroyed. */
230extern void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
231
232/* Fake conntrack entry for untracked connections */
233extern struct nf_conn nf_conntrack_untracked;
234
235extern int nf_ct_no_defrag;
236
237/* Iterate over all conntracks: if iter returns true, it's deleted. */
238extern void
239nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
240extern void nf_conntrack_free(struct nf_conn *ct);
241extern struct nf_conn *
242nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
243 const struct nf_conntrack_tuple *repl);
244
245/* It's confirmed if it is, or has been in the hash table. */
246static inline int nf_ct_is_confirmed(struct nf_conn *ct)
247{
248 return test_bit(IPS_CONFIRMED_BIT, &ct->status);
249}
250
251static inline int nf_ct_is_dying(struct nf_conn *ct)
252{
253 return test_bit(IPS_DYING_BIT, &ct->status);
254}
255
256extern unsigned int nf_conntrack_htable_size;
257
258#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++)
259
260#ifdef CONFIG_NF_CONNTRACK_EVENTS
261#include <linux/notifier.h>
262#include <linux/interrupt.h>
263
264struct nf_conntrack_ecache {
265 struct nf_conn *ct;
266 unsigned int events;
267};
268DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
269
270#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x)
271
272extern struct notifier_block *nf_conntrack_chain;
273extern struct notifier_block *nf_conntrack_expect_chain;
274
275static inline int nf_conntrack_register_notifier(struct notifier_block *nb)
276{
277 return notifier_chain_register(&nf_conntrack_chain, nb);
278}
279
280static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb)
281{
282 return notifier_chain_unregister(&nf_conntrack_chain, nb);
283}
284
285static inline int
286nf_conntrack_expect_register_notifier(struct notifier_block *nb)
287{
288 return notifier_chain_register(&nf_conntrack_expect_chain, nb);
289}
290
291static inline int
292nf_conntrack_expect_unregister_notifier(struct notifier_block *nb)
293{
294 return notifier_chain_unregister(&nf_conntrack_expect_chain, nb);
295}
296
297extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
298extern void __nf_ct_event_cache_init(struct nf_conn *ct);
299
300static inline void
301nf_conntrack_event_cache(enum ip_conntrack_events event,
302 const struct sk_buff *skb)
303{
304 struct nf_conn *ct = (struct nf_conn *)skb->nfct;
305 struct nf_conntrack_ecache *ecache;
306
307 local_bh_disable();
308 ecache = &__get_cpu_var(nf_conntrack_ecache);
309 if (ct != ecache->ct)
310 __nf_ct_event_cache_init(ct);
311 ecache->events |= event;
312 local_bh_enable();
313}
314
315static inline void nf_conntrack_event(enum ip_conntrack_events event,
316 struct nf_conn *ct)
317{
318 if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
319 notifier_call_chain(&nf_conntrack_chain, event, ct);
320}
321
322static inline void
323nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
324 struct nf_conntrack_expect *exp)
325{
326 notifier_call_chain(&nf_conntrack_expect_chain, event, exp);
327}
328#else /* CONFIG_NF_CONNTRACK_EVENTS */
329static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
330 const struct sk_buff *skb) {}
331static inline void nf_conntrack_event(enum ip_conntrack_events event,
332 struct nf_conn *ct) {}
333static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
334static inline void
335nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
336 struct nf_conntrack_expect *exp) {}
337#endif /* CONFIG_NF_CONNTRACK_EVENTS */
338
339/* no helper, no nat */
340#define NF_CT_F_BASIC 0
341/* for helper */
342#define NF_CT_F_HELP 1
343/* for nat. */
344#define NF_CT_F_NAT 2
345#define NF_CT_F_NUM 4
346
347extern int
348nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size,
349 int (*init_conntrack)(struct nf_conn *, u_int32_t));
350extern void
351nf_conntrack_unregister_cache(u_int32_t features);
352
353#endif /* __KERNEL__ */
354#endif /* _NF_CONNTRACK_H */
diff --git a/include/net/netfilter/nf_conntrack_compat.h b/include/net/netfilter/nf_conntrack_compat.h
new file mode 100644
index 000000000000..3cac19fb3648
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_compat.h
@@ -0,0 +1,108 @@
1#ifndef _NF_CONNTRACK_COMPAT_H
2#define _NF_CONNTRACK_COMPAT_H
3
4#ifdef __KERNEL__
5
6#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
7
8#include <linux/netfilter_ipv4/ip_conntrack.h>
9
10#ifdef CONFIG_IP_NF_CONNTRACK_MARK
11static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
12 u_int32_t *ctinfo)
13{
14 struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
15
16 if (ct)
17 return &ct->mark;
18 else
19 return NULL;
20}
21#endif /* CONFIG_IP_NF_CONNTRACK_MARK */
22
23#ifdef CONFIG_IP_NF_CT_ACCT
24static inline struct ip_conntrack_counter *
25nf_ct_get_counters(const struct sk_buff *skb)
26{
27 enum ip_conntrack_info ctinfo;
28 struct ip_conntrack *ct = ip_conntrack_get(skb, &ctinfo);
29
30 if (ct)
31 return ct->counters;
32 else
33 return NULL;
34}
35#endif /* CONFIG_IP_NF_CT_ACCT */
36
37static inline int nf_ct_is_untracked(const struct sk_buff *skb)
38{
39 return (skb->nfct == &ip_conntrack_untracked.ct_general);
40}
41
42static inline void nf_ct_untrack(struct sk_buff *skb)
43{
44 skb->nfct = &ip_conntrack_untracked.ct_general;
45}
46
47static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
48 enum ip_conntrack_info *ctinfo)
49{
50 struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
51 return (ct != NULL);
52}
53
54#else /* CONFIG_IP_NF_CONNTRACK */
55
56#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
57#include <net/netfilter/nf_conntrack.h>
58
59#ifdef CONFIG_NF_CONNTRACK_MARK
60
61static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
62 u_int32_t *ctinfo)
63{
64 struct nf_conn *ct = nf_ct_get(skb, ctinfo);
65
66 if (ct)
67 return &ct->mark;
68 else
69 return NULL;
70}
71#endif /* CONFIG_NF_CONNTRACK_MARK */
72
73#ifdef CONFIG_NF_CT_ACCT
74static inline struct ip_conntrack_counter *
75nf_ct_get_counters(const struct sk_buff *skb)
76{
77 enum ip_conntrack_info ctinfo;
78 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
79
80 if (ct)
81 return ct->counters;
82 else
83 return NULL;
84}
85#endif /* CONFIG_NF_CT_ACCT */
86
87static inline int nf_ct_is_untracked(const struct sk_buff *skb)
88{
89 return (skb->nfct == &nf_conntrack_untracked.ct_general);
90}
91
92static inline void nf_ct_untrack(struct sk_buff *skb)
93{
94 skb->nfct = &nf_conntrack_untracked.ct_general;
95}
96
97static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
98 enum ip_conntrack_info *ctinfo)
99{
100 struct nf_conn *ct = nf_ct_get(skb, ctinfo);
101 return (ct != NULL);
102}
103
104#endif /* CONFIG_IP_NF_CONNTRACK */
105
106#endif /* __KERNEL__ */
107
108#endif /* _NF_CONNTRACK_COMPAT_H */
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
new file mode 100644
index 000000000000..da254525a4ce
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -0,0 +1,76 @@
1/*
2 * This header is used to share core functionality between the
3 * standalone connection tracking module, and the compatibility layer's use
4 * of connection tracking.
5 *
6 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
7 * - generalize L3 protocol dependent part.
8 *
9 * Derived from include/linux/netfiter_ipv4/ip_conntrack_core.h
10 */
11
12#ifndef _NF_CONNTRACK_CORE_H
13#define _NF_CONNTRACK_CORE_H
14
15#include <linux/netfilter.h>
16
17/* This header is used to share core functionality between the
18 standalone connection tracking module, and the compatibility layer's use
19 of connection tracking. */
20extern unsigned int nf_conntrack_in(int pf,
21 unsigned int hooknum,
22 struct sk_buff **pskb);
23
24extern int nf_conntrack_init(void);
25extern void nf_conntrack_cleanup(void);
26
27struct nf_conntrack_l3proto;
28extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf);
29/* Like above, but you already have conntrack read lock. */
30extern struct nf_conntrack_l3proto *__nf_ct_find_l3proto(u_int16_t l3proto);
31
32struct nf_conntrack_protocol;
33
34extern int
35nf_ct_get_tuple(const struct sk_buff *skb,
36 unsigned int nhoff,
37 unsigned int dataoff,
38 u_int16_t l3num,
39 u_int8_t protonum,
40 struct nf_conntrack_tuple *tuple,
41 const struct nf_conntrack_l3proto *l3proto,
42 const struct nf_conntrack_protocol *protocol);
43
44extern int
45nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
46 const struct nf_conntrack_tuple *orig,
47 const struct nf_conntrack_l3proto *l3proto,
48 const struct nf_conntrack_protocol *protocol);
49
50/* Find a connection corresponding to a tuple. */
51extern struct nf_conntrack_tuple_hash *
52nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
53 const struct nf_conn *ignored_conntrack);
54
55extern int __nf_conntrack_confirm(struct sk_buff **pskb);
56
57/* Confirm a connection: returns NF_DROP if packet must be dropped. */
58static inline int nf_conntrack_confirm(struct sk_buff **pskb)
59{
60 struct nf_conn *ct = (struct nf_conn *)(*pskb)->nfct;
61 int ret = NF_ACCEPT;
62
63 if (ct) {
64 if (!nf_ct_is_confirmed(ct))
65 ret = __nf_conntrack_confirm(pskb);
66 nf_ct_deliver_cached_events(ct);
67 }
68 return ret;
69}
70
71extern void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb);
72
73extern struct list_head *nf_conntrack_hash;
74extern struct list_head nf_conntrack_expect_list;
75extern rwlock_t nf_conntrack_lock ;
76#endif /* _NF_CONNTRACK_CORE_H */
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
new file mode 100644
index 000000000000..5a66b2a3a623
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -0,0 +1,51 @@
1/*
2 * connection tracking helpers.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalize L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_helper.h
8 */
9
10#ifndef _NF_CONNTRACK_HELPER_H
11#define _NF_CONNTRACK_HELPER_H
12#include <net/netfilter/nf_conntrack.h>
13
14struct module;
15
16struct nf_conntrack_helper
17{
18 struct list_head list; /* Internal use. */
19
20 const char *name; /* name of the module */
21 struct module *me; /* pointer to self */
22 unsigned int max_expected; /* Maximum number of concurrent
23 * expected connections */
24 unsigned int timeout; /* timeout for expecteds */
25
26 /* Mask of things we will help (compared against server response) */
27 struct nf_conntrack_tuple tuple;
28 struct nf_conntrack_tuple mask;
29
30 /* Function to call when data passes; return verdict, or -1 to
31 invalidate. */
32 int (*help)(struct sk_buff **pskb,
33 unsigned int protoff,
34 struct nf_conn *ct,
35 enum ip_conntrack_info conntrackinfo);
36};
37
38extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
39extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
40
41/* Allocate space for an expectation: this is mandatory before calling
42 nf_conntrack_expect_related. You will have to call put afterwards. */
43extern struct nf_conntrack_expect *
44nf_conntrack_expect_alloc(struct nf_conn *master);
45extern void nf_conntrack_expect_put(struct nf_conntrack_expect *exp);
46
47/* Add an expected connection: can have more than one per connection */
48extern int nf_conntrack_expect_related(struct nf_conntrack_expect *exp);
49extern void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp);
50
51#endif /*_NF_CONNTRACK_HELPER_H*/
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
new file mode 100644
index 000000000000..01663e5b33df
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -0,0 +1,93 @@
1/*
2 * Copyright (C)2003,2004 USAGI/WIDE Project
3 *
4 * Header for use in defining a given L3 protocol for connection tracking.
5 *
6 * Author:
7 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
8 *
9 * Derived from include/netfilter_ipv4/ip_conntrack_protocol.h
10 */
11
12#ifndef _NF_CONNTRACK_L3PROTO_H
13#define _NF_CONNTRACK_L3PROTO_H
14#include <linux/seq_file.h>
15#include <net/netfilter/nf_conntrack.h>
16
17struct nf_conntrack_l3proto
18{
19 /* Next pointer. */
20 struct list_head list;
21
22 /* L3 Protocol Family number. ex) PF_INET */
23 u_int16_t l3proto;
24
25 /* Protocol name */
26 const char *name;
27
28 /*
29 * Try to fill in the third arg: nhoff is offset of l3 proto
30 * hdr. Return true if possible.
31 */
32 int (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int nhoff,
33 struct nf_conntrack_tuple *tuple);
34
35 /*
36 * Invert the per-proto part of the tuple: ie. turn xmit into reply.
37 * Some packets can't be inverted: return 0 in that case.
38 */
39 int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
40 const struct nf_conntrack_tuple *orig);
41
42 /* Print out the per-protocol part of the tuple. */
43 int (*print_tuple)(struct seq_file *s,
44 const struct nf_conntrack_tuple *);
45
46 /* Print out the private part of the conntrack. */
47 int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
48
49 /* Returns verdict for packet, or -1 for invalid. */
50 int (*packet)(struct nf_conn *conntrack,
51 const struct sk_buff *skb,
52 enum ip_conntrack_info ctinfo);
53
54 /*
55 * Called when a new connection for this protocol found;
56 * returns TRUE if it's OK. If so, packet() called next.
57 */
58 int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb);
59
60 /* Called when a conntrack entry is destroyed */
61 void (*destroy)(struct nf_conn *conntrack);
62
63 /*
64 * Called before tracking.
65 * *dataoff: offset of protocol header (TCP, UDP,...) in *pskb
66 * *protonum: protocol number
67 */
68 int (*prepare)(struct sk_buff **pskb, unsigned int hooknum,
69 unsigned int *dataoff, u_int8_t *protonum);
70
71 u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple);
72
73 /* Module (if any) which this is connected to. */
74 struct module *me;
75};
76
77extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX];
78
79/* Protocol registration. */
80extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
81extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
82
83static inline struct nf_conntrack_l3proto *
84nf_ct_find_l3proto(u_int16_t l3proto)
85{
86 return nf_ct_l3protos[l3proto];
87}
88
89/* Existing built-in protocols */
90extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
91extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
92extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto;
93#endif /*_NF_CONNTRACK_L3PROTO_H*/
diff --git a/include/net/netfilter/nf_conntrack_protocol.h b/include/net/netfilter/nf_conntrack_protocol.h
new file mode 100644
index 000000000000..b3afda35397a
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_protocol.h
@@ -0,0 +1,105 @@
1/*
2 * Header for use in defining a given protocol for connection tracking.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalized L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h
8 */
9
10#ifndef _NF_CONNTRACK_PROTOCOL_H
11#define _NF_CONNTRACK_PROTOCOL_H
12#include <net/netfilter/nf_conntrack.h>
13
14struct seq_file;
15
16struct nf_conntrack_protocol
17{
18 /* Next pointer. */
19 struct list_head list;
20
21 /* L3 Protocol number. */
22 u_int16_t l3proto;
23
24 /* Protocol number. */
25 u_int8_t proto;
26
27 /* Protocol name */
28 const char *name;
29
30 /* Try to fill in the third arg: dataoff is offset past network protocol
31 hdr. Return true if possible. */
32 int (*pkt_to_tuple)(const struct sk_buff *skb,
33 unsigned int dataoff,
34 struct nf_conntrack_tuple *tuple);
35
36 /* Invert the per-proto part of the tuple: ie. turn xmit into reply.
37 * Some packets can't be inverted: return 0 in that case.
38 */
39 int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
40 const struct nf_conntrack_tuple *orig);
41
42 /* Print out the per-protocol part of the tuple. Return like seq_* */
43 int (*print_tuple)(struct seq_file *s,
44 const struct nf_conntrack_tuple *);
45
46 /* Print out the private part of the conntrack. */
47 int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
48
49 /* Returns verdict for packet, or -1 for invalid. */
50 int (*packet)(struct nf_conn *conntrack,
51 const struct sk_buff *skb,
52 unsigned int dataoff,
53 enum ip_conntrack_info ctinfo,
54 int pf,
55 unsigned int hooknum);
56
57 /* Called when a new connection for this protocol found;
58 * returns TRUE if it's OK. If so, packet() called next. */
59 int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb,
60 unsigned int dataoff);
61
62 /* Called when a conntrack entry is destroyed */
63 void (*destroy)(struct nf_conn *conntrack);
64
65 int (*error)(struct sk_buff *skb, unsigned int dataoff,
66 enum ip_conntrack_info *ctinfo,
67 int pf, unsigned int hooknum);
68
69 /* Module (if any) which this is connected to. */
70 struct module *me;
71};
72
73/* Existing built-in protocols */
74extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
75extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
76extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
77extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
78
79#define MAX_NF_CT_PROTO 256
80extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
81
82extern struct nf_conntrack_protocol *
83nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol);
84
85/* Protocol registration. */
86extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto);
87extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto);
88
89/* Log invalid packets */
90extern unsigned int nf_ct_log_invalid;
91
92#ifdef CONFIG_SYSCTL
93#ifdef DEBUG_INVALID_PACKETS
94#define LOG_INVALID(proto) \
95 (nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW)
96#else
97#define LOG_INVALID(proto) \
98 ((nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) \
99 && net_ratelimit())
100#endif
101#else
102#define LOG_INVALID(proto) 0
103#endif /* CONFIG_SYSCTL */
104
105#endif /*_NF_CONNTRACK_PROTOCOL_H*/
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
new file mode 100644
index 000000000000..14ce790e5c65
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -0,0 +1,190 @@
1/*
2 * Definitions and Declarations for tuple.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalize L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h
8 */
9
10#ifndef _NF_CONNTRACK_TUPLE_H
11#define _NF_CONNTRACK_TUPLE_H
12
13#include <linux/netfilter/nf_conntrack_tuple_common.h>
14
15/* A `tuple' is a structure containing the information to uniquely
16 identify a connection. ie. if two packets have the same tuple, they
17 are in the same connection; if not, they are not.
18
19 We divide the structure along "manipulatable" and
20 "non-manipulatable" lines, for the benefit of the NAT code.
21*/
22
23#define NF_CT_TUPLE_L3SIZE 4
24
25/* The l3 protocol-specific manipulable parts of the tuple: always in
26 network order! */
27union nf_conntrack_man_l3proto {
28 u_int32_t all[NF_CT_TUPLE_L3SIZE];
29 u_int32_t ip;
30 u_int32_t ip6[4];
31};
32
33/* The protocol-specific manipulable parts of the tuple: always in
34 network order! */
35union nf_conntrack_man_proto
36{
37 /* Add other protocols here. */
38 u_int16_t all;
39
40 struct {
41 u_int16_t port;
42 } tcp;
43 struct {
44 u_int16_t port;
45 } udp;
46 struct {
47 u_int16_t id;
48 } icmp;
49 struct {
50 u_int16_t port;
51 } sctp;
52};
53
54/* The manipulable part of the tuple. */
55struct nf_conntrack_man
56{
57 union nf_conntrack_man_l3proto u3;
58 union nf_conntrack_man_proto u;
59 /* Layer 3 protocol */
60 u_int16_t l3num;
61};
62
63/* This contains the information to distinguish a connection. */
64struct nf_conntrack_tuple
65{
66 struct nf_conntrack_man src;
67
68 /* These are the parts of the tuple which are fixed. */
69 struct {
70 union {
71 u_int32_t all[NF_CT_TUPLE_L3SIZE];
72 u_int32_t ip;
73 u_int32_t ip6[4];
74 } u3;
75 union {
76 /* Add other protocols here. */
77 u_int16_t all;
78
79 struct {
80 u_int16_t port;
81 } tcp;
82 struct {
83 u_int16_t port;
84 } udp;
85 struct {
86 u_int8_t type, code;
87 } icmp;
88 struct {
89 u_int16_t port;
90 } sctp;
91 } u;
92
93 /* The protocol. */
94 u_int8_t protonum;
95
96 /* The direction (for tuplehash) */
97 u_int8_t dir;
98 } dst;
99};
100
101/* This is optimized opposed to a memset of the whole structure. Everything we
102 * really care about is the source/destination unions */
103#define NF_CT_TUPLE_U_BLANK(tuple) \
104 do { \
105 (tuple)->src.u.all = 0; \
106 (tuple)->dst.u.all = 0; \
107 memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3)); \
108 memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3)); \
109 } while (0)
110
111#ifdef __KERNEL__
112
113#define NF_CT_DUMP_TUPLE(tp) \
114DEBUGP("tuple %p: %u %u %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu -> %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu\n", \
115 (tp), (tp)->src.l3num, (tp)->dst.protonum, \
116 NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
117 NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
118
119/* If we're the first tuple, it's the original dir. */
120#define NF_CT_DIRECTION(h) \
121 ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
122
123/* Connections have two entries in the hash table: one for each way */
124struct nf_conntrack_tuple_hash
125{
126 struct list_head list;
127
128 struct nf_conntrack_tuple tuple;
129};
130
131#endif /* __KERNEL__ */
132
133static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
134 const struct nf_conntrack_tuple *t2)
135{
136 return (t1->src.u3.all[0] == t2->src.u3.all[0] &&
137 t1->src.u3.all[1] == t2->src.u3.all[1] &&
138 t1->src.u3.all[2] == t2->src.u3.all[2] &&
139 t1->src.u3.all[3] == t2->src.u3.all[3] &&
140 t1->src.u.all == t2->src.u.all &&
141 t1->src.l3num == t2->src.l3num &&
142 t1->dst.protonum == t2->dst.protonum);
143}
144
145static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
146 const struct nf_conntrack_tuple *t2)
147{
148 return (t1->dst.u3.all[0] == t2->dst.u3.all[0] &&
149 t1->dst.u3.all[1] == t2->dst.u3.all[1] &&
150 t1->dst.u3.all[2] == t2->dst.u3.all[2] &&
151 t1->dst.u3.all[3] == t2->dst.u3.all[3] &&
152 t1->dst.u.all == t2->dst.u.all &&
153 t1->src.l3num == t2->src.l3num &&
154 t1->dst.protonum == t2->dst.protonum);
155}
156
157static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
158 const struct nf_conntrack_tuple *t2)
159{
160 return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
161}
162
163static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
164 const struct nf_conntrack_tuple *tuple,
165 const struct nf_conntrack_tuple *mask)
166{
167 int count = 0;
168
169 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
170 if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) &
171 mask->src.u3.all[count])
172 return 0;
173 }
174
175 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
176 if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) &
177 mask->dst.u3.all[count])
178 return 0;
179 }
180
181 if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all ||
182 (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all ||
183 (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num ||
184 (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum)
185 return 0;
186
187 return 1;
188}
189
190#endif /* _NF_CONNTRACK_TUPLE_H */
diff --git a/include/net/netlink.h b/include/net/netlink.h
new file mode 100644
index 000000000000..640c26a90cf1
--- /dev/null
+++ b/include/net/netlink.h
@@ -0,0 +1,883 @@
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 void netlink_run_queue(struct sock *sk, unsigned int *qlen,
187 int (*cb)(struct sk_buff *,
188 struct nlmsghdr *, int *));
189extern void netlink_queue_skip(struct nlmsghdr *nlh,
190 struct sk_buff *skb);
191
192extern int nla_validate(struct nlattr *head, int len, int maxtype,
193 struct nla_policy *policy);
194extern int nla_parse(struct nlattr *tb[], int maxtype,
195 struct nlattr *head, int len,
196 struct nla_policy *policy);
197extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
198extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
199 size_t dstsize);
200extern int nla_memcpy(void *dest, struct nlattr *src, int count);
201extern int nla_memcmp(const struct nlattr *nla, const void *data,
202 size_t size);
203extern int nla_strcmp(const struct nlattr *nla, const char *str);
204extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype,
205 int attrlen);
206extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype,
207 int attrlen);
208extern void __nla_put(struct sk_buff *skb, int attrtype,
209 int attrlen, const void *data);
210extern int nla_put(struct sk_buff *skb, int attrtype,
211 int attrlen, const void *data);
212
213/**************************************************************************
214 * Netlink Messages
215 **************************************************************************/
216
217/**
218 * nlmsg_msg_size - length of netlink message not including padding
219 * @payload: length of message payload
220 */
221static inline int nlmsg_msg_size(int payload)
222{
223 return NLMSG_HDRLEN + payload;
224}
225
226/**
227 * nlmsg_total_size - length of netlink message including padding
228 * @payload: length of message payload
229 */
230static inline int nlmsg_total_size(int payload)
231{
232 return NLMSG_ALIGN(nlmsg_msg_size(payload));
233}
234
235/**
236 * nlmsg_padlen - length of padding at the message's tail
237 * @payload: length of message payload
238 */
239static inline int nlmsg_padlen(int payload)
240{
241 return nlmsg_total_size(payload) - nlmsg_msg_size(payload);
242}
243
244/**
245 * nlmsg_data - head of message payload
246 * @nlh: netlink messsage header
247 */
248static inline void *nlmsg_data(const struct nlmsghdr *nlh)
249{
250 return (unsigned char *) nlh + NLMSG_HDRLEN;
251}
252
253/**
254 * nlmsg_len - length of message payload
255 * @nlh: netlink message header
256 */
257static inline int nlmsg_len(const struct nlmsghdr *nlh)
258{
259 return nlh->nlmsg_len - NLMSG_HDRLEN;
260}
261
262/**
263 * nlmsg_attrdata - head of attributes data
264 * @nlh: netlink message header
265 * @hdrlen: length of family specific header
266 */
267static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
268 int hdrlen)
269{
270 unsigned char *data = nlmsg_data(nlh);
271 return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
272}
273
274/**
275 * nlmsg_attrlen - length of attributes data
276 * @nlh: netlink message header
277 * @hdrlen: length of family specific header
278 */
279static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
280{
281 return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
282}
283
284/**
285 * nlmsg_ok - check if the netlink message fits into the remaining bytes
286 * @nlh: netlink message header
287 * @remaining: number of bytes remaining in message stream
288 */
289static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
290{
291 return (remaining >= sizeof(struct nlmsghdr) &&
292 nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
293 nlh->nlmsg_len <= remaining);
294}
295
296/**
297 * nlmsg_next - next netlink message in message stream
298 * @nlh: netlink message header
299 * @remaining: number of bytes remaining in message stream
300 *
301 * Returns the next netlink message in the message stream and
302 * decrements remaining by the size of the current message.
303 */
304static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
305{
306 int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
307
308 *remaining -= totlen;
309
310 return (struct nlmsghdr *) ((unsigned char *) nlh + totlen);
311}
312
313/**
314 * nlmsg_parse - parse attributes of a netlink message
315 * @nlh: netlink message header
316 * @hdrlen: length of family specific header
317 * @tb: destination array with maxtype+1 elements
318 * @maxtype: maximum attribute type to be expected
319 * @policy: validation policy
320 *
321 * See nla_parse()
322 */
323static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
324 struct nlattr *tb[], int maxtype,
325 struct nla_policy *policy)
326{
327 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
328 return -EINVAL;
329
330 return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
331 nlmsg_attrlen(nlh, hdrlen), policy);
332}
333
334/**
335 * nlmsg_find_attr - find a specific attribute in a netlink message
336 * @nlh: netlink message header
337 * @hdrlen: length of familiy specific header
338 * @attrtype: type of attribute to look for
339 *
340 * Returns the first attribute which matches the specified type.
341 */
342static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
343 int hdrlen, int attrtype)
344{
345 return nla_find(nlmsg_attrdata(nlh, hdrlen),
346 nlmsg_attrlen(nlh, hdrlen), attrtype);
347}
348
349/**
350 * nlmsg_validate - validate a netlink message including attributes
351 * @nlh: netlinket message header
352 * @hdrlen: length of familiy specific header
353 * @maxtype: maximum attribute type to be expected
354 * @policy: validation policy
355 */
356static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
357 struct nla_policy *policy)
358{
359 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
360 return -EINVAL;
361
362 return nla_validate(nlmsg_attrdata(nlh, hdrlen),
363 nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
364}
365
366/**
367 * nlmsg_for_each_attr - iterate over a stream of attributes
368 * @pos: loop counter, set to current attribute
369 * @nlh: netlink message header
370 * @hdrlen: length of familiy specific header
371 * @rem: initialized to len, holds bytes currently remaining in stream
372 */
373#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
374 nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
375 nlmsg_attrlen(nlh, hdrlen), rem)
376
377#if 0
378/* FIXME: Enable once all users have been converted */
379
380/**
381 * __nlmsg_put - Add a new netlink message to an skb
382 * @skb: socket buffer to store message in
383 * @pid: netlink process id
384 * @seq: sequence number of message
385 * @type: message type
386 * @payload: length of message payload
387 * @flags: message flags
388 *
389 * The caller is responsible to ensure that the skb provides enough
390 * tailroom for both the netlink header and payload.
391 */
392static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid,
393 u32 seq, int type, int payload,
394 int flags)
395{
396 struct nlmsghdr *nlh;
397
398 nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload));
399 nlh->nlmsg_type = type;
400 nlh->nlmsg_len = nlmsg_msg_size(payload);
401 nlh->nlmsg_flags = flags;
402 nlh->nlmsg_pid = pid;
403 nlh->nlmsg_seq = seq;
404
405 memset((unsigned char *) nlmsg_data(nlh) + payload, 0,
406 nlmsg_padlen(payload));
407
408 return nlh;
409}
410#endif
411
412/**
413 * nlmsg_put - Add a new netlink message to an skb
414 * @skb: socket buffer to store message in
415 * @pid: netlink process id
416 * @seq: sequence number of message
417 * @type: message type
418 * @payload: length of message payload
419 * @flags: message flags
420 *
421 * Returns NULL if the tailroom of the skb is insufficient to store
422 * the message header and payload.
423 */
424static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
425 int type, int payload, int flags)
426{
427 if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
428 return NULL;
429
430 return __nlmsg_put(skb, pid, seq, type, payload, flags);
431}
432
433/**
434 * nlmsg_put_answer - Add a new callback based netlink message to an skb
435 * @skb: socket buffer to store message in
436 * @cb: netlink callback
437 * @type: message type
438 * @payload: length of message payload
439 * @flags: message flags
440 *
441 * Returns NULL if the tailroom of the skb is insufficient to store
442 * the message header and payload.
443 */
444static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
445 struct netlink_callback *cb,
446 int type, int payload,
447 int flags)
448{
449 return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
450 type, payload, flags);
451}
452
453/**
454 * nlmsg_new - Allocate a new netlink message
455 * @size: maximum size of message
456 *
457 * Use NLMSG_GOODSIZE if size isn't know and you need a good default size.
458 */
459static inline struct sk_buff *nlmsg_new(int size)
460{
461 return alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
462}
463
464/**
465 * nlmsg_end - Finalize a netlink message
466 * @skb: socket buffer the message is stored in
467 * @nlh: netlink message header
468 *
469 * Corrects the netlink message header to include the appeneded
470 * attributes. Only necessary if attributes have been added to
471 * the message.
472 *
473 * Returns the total data length of the skb.
474 */
475static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
476{
477 nlh->nlmsg_len = skb->tail - (unsigned char *) nlh;
478
479 return skb->len;
480}
481
482/**
483 * nlmsg_cancel - Cancel construction of a netlink message
484 * @skb: socket buffer the message is stored in
485 * @nlh: netlink message header
486 *
487 * Removes the complete netlink message including all
488 * attributes from the socket buffer again. Returns -1.
489 */
490static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
491{
492 skb_trim(skb, (unsigned char *) nlh - skb->data);
493
494 return -1;
495}
496
497/**
498 * nlmsg_free - free a netlink message
499 * @skb: socket buffer of netlink message
500 */
501static inline void nlmsg_free(struct sk_buff *skb)
502{
503 kfree_skb(skb);
504}
505
506/**
507 * nlmsg_multicast - multicast a netlink message
508 * @sk: netlink socket to spread messages to
509 * @skb: netlink message as socket buffer
510 * @pid: own netlink pid to avoid sending to yourself
511 * @group: multicast group id
512 */
513static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
514 u32 pid, unsigned int group)
515{
516 int err;
517
518 NETLINK_CB(skb).dst_group = group;
519
520 err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL);
521 if (err > 0)
522 err = 0;
523
524 return err;
525}
526
527/**
528 * nlmsg_unicast - unicast a netlink message
529 * @sk: netlink socket to spread message to
530 * @skb: netlink message as socket buffer
531 * @pid: netlink pid of the destination socket
532 */
533static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid)
534{
535 int err;
536
537 err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
538 if (err > 0)
539 err = 0;
540
541 return err;
542}
543
544/**
545 * nlmsg_for_each_msg - iterate over a stream of messages
546 * @pos: loop counter, set to current message
547 * @head: head of message stream
548 * @len: length of message stream
549 * @rem: initialized to len, holds bytes currently remaining in stream
550 */
551#define nlmsg_for_each_msg(pos, head, len, rem) \
552 for (pos = head, rem = len; \
553 nlmsg_ok(pos, rem); \
554 pos = nlmsg_next(pos, &(rem)))
555
556/**************************************************************************
557 * Netlink Attributes
558 **************************************************************************/
559
560/**
561 * nla_attr_size - length of attribute not including padding
562 * @payload: length of payload
563 */
564static inline int nla_attr_size(int payload)
565{
566 return NLA_HDRLEN + payload;
567}
568
569/**
570 * nla_total_size - total length of attribute including padding
571 * @payload: length of payload
572 */
573static inline int nla_total_size(int payload)
574{
575 return NLA_ALIGN(nla_attr_size(payload));
576}
577
578/**
579 * nla_padlen - length of padding at the tail of attribute
580 * @payload: length of payload
581 */
582static inline int nla_padlen(int payload)
583{
584 return nla_total_size(payload) - nla_attr_size(payload);
585}
586
587/**
588 * nla_data - head of payload
589 * @nla: netlink attribute
590 */
591static inline void *nla_data(const struct nlattr *nla)
592{
593 return (char *) nla + NLA_HDRLEN;
594}
595
596/**
597 * nla_len - length of payload
598 * @nla: netlink attribute
599 */
600static inline int nla_len(const struct nlattr *nla)
601{
602 return nla->nla_len - NLA_HDRLEN;
603}
604
605/**
606 * nla_ok - check if the netlink attribute fits into the remaining bytes
607 * @nla: netlink attribute
608 * @remaining: number of bytes remaining in attribute stream
609 */
610static inline int nla_ok(const struct nlattr *nla, int remaining)
611{
612 return remaining >= sizeof(*nla) &&
613 nla->nla_len >= sizeof(*nla) &&
614 nla->nla_len <= remaining;
615}
616
617/**
618 * nla_next - next netlink attribte in attribute stream
619 * @nla: netlink attribute
620 * @remaining: number of bytes remaining in attribute stream
621 *
622 * Returns the next netlink attribute in the attribute stream and
623 * decrements remaining by the size of the current attribute.
624 */
625static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
626{
627 int totlen = NLA_ALIGN(nla->nla_len);
628
629 *remaining -= totlen;
630 return (struct nlattr *) ((char *) nla + totlen);
631}
632
633/**
634 * nla_parse_nested - parse nested attributes
635 * @tb: destination array with maxtype+1 elements
636 * @maxtype: maximum attribute type to be expected
637 * @nla: attribute containing the nested attributes
638 * @policy: validation policy
639 *
640 * See nla_parse()
641 */
642static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
643 struct nlattr *nla,
644 struct nla_policy *policy)
645{
646 return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
647}
648/**
649 * nla_put_u8 - Add a u16 netlink attribute to a socket buffer
650 * @skb: socket buffer to add attribute to
651 * @attrtype: attribute type
652 * @value: numeric value
653 */
654static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
655{
656 return nla_put(skb, attrtype, sizeof(u8), &value);
657}
658
659/**
660 * nla_put_u16 - Add a u16 netlink attribute to a socket buffer
661 * @skb: socket buffer to add attribute to
662 * @attrtype: attribute type
663 * @value: numeric value
664 */
665static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
666{
667 return nla_put(skb, attrtype, sizeof(u16), &value);
668}
669
670/**
671 * nla_put_u32 - Add a u32 netlink attribute to a socket buffer
672 * @skb: socket buffer to add attribute to
673 * @attrtype: attribute type
674 * @value: numeric value
675 */
676static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
677{
678 return nla_put(skb, attrtype, sizeof(u32), &value);
679}
680
681/**
682 * nla_put_64 - Add a u64 netlink attribute to a socket buffer
683 * @skb: socket buffer to add attribute to
684 * @attrtype: attribute type
685 * @value: numeric value
686 */
687static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)
688{
689 return nla_put(skb, attrtype, sizeof(u64), &value);
690}
691
692/**
693 * nla_put_string - Add a string netlink attribute to a socket buffer
694 * @skb: socket buffer to add attribute to
695 * @attrtype: attribute type
696 * @str: NUL terminated string
697 */
698static inline int nla_put_string(struct sk_buff *skb, int attrtype,
699 const char *str)
700{
701 return nla_put(skb, attrtype, strlen(str) + 1, str);
702}
703
704/**
705 * nla_put_flag - Add a flag netlink attribute to a socket buffer
706 * @skb: socket buffer to add attribute to
707 * @attrtype: attribute type
708 */
709static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
710{
711 return nla_put(skb, attrtype, 0, NULL);
712}
713
714/**
715 * nla_put_msecs - Add a msecs netlink attribute to a socket buffer
716 * @skb: socket buffer to add attribute to
717 * @attrtype: attribute type
718 * @jiffies: number of msecs in jiffies
719 */
720static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
721 unsigned long jiffies)
722{
723 u64 tmp = jiffies_to_msecs(jiffies);
724 return nla_put(skb, attrtype, sizeof(u64), &tmp);
725}
726
727#define NLA_PUT(skb, attrtype, attrlen, data) \
728 do { \
729 if (nla_put(skb, attrtype, attrlen, data) < 0) \
730 goto nla_put_failure; \
731 } while(0)
732
733#define NLA_PUT_TYPE(skb, type, attrtype, value) \
734 do { \
735 type __tmp = value; \
736 NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
737 } while(0)
738
739#define NLA_PUT_U8(skb, attrtype, value) \
740 NLA_PUT_TYPE(skb, u8, attrtype, value)
741
742#define NLA_PUT_U16(skb, attrtype, value) \
743 NLA_PUT_TYPE(skb, u16, attrtype, value)
744
745#define NLA_PUT_U32(skb, attrtype, value) \
746 NLA_PUT_TYPE(skb, u32, attrtype, value)
747
748#define NLA_PUT_U64(skb, attrtype, value) \
749 NLA_PUT_TYPE(skb, u64, attrtype, value)
750
751#define NLA_PUT_STRING(skb, attrtype, value) \
752 NLA_PUT(skb, attrtype, strlen(value) + 1, value)
753
754#define NLA_PUT_FLAG(skb, attrtype, value) \
755 NLA_PUT(skb, attrtype, 0, NULL)
756
757#define NLA_PUT_MSECS(skb, attrtype, jiffies) \
758 NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies))
759
760/**
761 * nla_get_u32 - return payload of u32 attribute
762 * @nla: u32 netlink attribute
763 */
764static inline u32 nla_get_u32(struct nlattr *nla)
765{
766 return *(u32 *) nla_data(nla);
767}
768
769/**
770 * nla_get_u16 - return payload of u16 attribute
771 * @nla: u16 netlink attribute
772 */
773static inline u16 nla_get_u16(struct nlattr *nla)
774{
775 return *(u16 *) nla_data(nla);
776}
777
778/**
779 * nla_get_u8 - return payload of u8 attribute
780 * @nla: u8 netlink attribute
781 */
782static inline u8 nla_get_u8(struct nlattr *nla)
783{
784 return *(u8 *) nla_data(nla);
785}
786
787/**
788 * nla_get_u64 - return payload of u64 attribute
789 * @nla: u64 netlink attribute
790 */
791static inline u64 nla_get_u64(struct nlattr *nla)
792{
793 u64 tmp;
794
795 nla_memcpy(&tmp, nla, sizeof(tmp));
796
797 return tmp;
798}
799
800/**
801 * nla_get_flag - return payload of flag attribute
802 * @nla: flag netlink attribute
803 */
804static inline int nla_get_flag(struct nlattr *nla)
805{
806 return !!nla;
807}
808
809/**
810 * nla_get_msecs - return payload of msecs attribute
811 * @nla: msecs netlink attribute
812 *
813 * Returns the number of milliseconds in jiffies.
814 */
815static inline unsigned long nla_get_msecs(struct nlattr *nla)
816{
817 u64 msecs = nla_get_u64(nla);
818
819 return msecs_to_jiffies((unsigned long) msecs);
820}
821
822/**
823 * nla_nest_start - Start a new level of nested attributes
824 * @skb: socket buffer to add attributes to
825 * @attrtype: attribute type of container
826 *
827 * Returns the container attribute
828 */
829static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
830{
831 struct nlattr *start = (struct nlattr *) skb->tail;
832
833 if (nla_put(skb, attrtype, 0, NULL) < 0)
834 return NULL;
835
836 return start;
837}
838
839/**
840 * nla_nest_end - Finalize nesting of attributes
841 * @skb: socket buffer the attribtues are stored in
842 * @start: container attribute
843 *
844 * Corrects the container attribute header to include the all
845 * appeneded attributes.
846 *
847 * Returns the total data length of the skb.
848 */
849static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
850{
851 start->nla_len = skb->tail - (unsigned char *) start;
852 return skb->len;
853}
854
855/**
856 * nla_nest_cancel - Cancel nesting of attributes
857 * @skb: socket buffer the message is stored in
858 * @start: container attribute
859 *
860 * Removes the container attribute and including all nested
861 * attributes. Returns -1.
862 */
863static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
864{
865 if (start)
866 skb_trim(skb, (unsigned char *) start - skb->data);
867
868 return -1;
869}
870
871/**
872 * nla_for_each_attr - iterate over a stream of attributes
873 * @pos: loop counter, set to current attribute
874 * @head: head of attribute stream
875 * @len: length of attribute stream
876 * @rem: initialized to len, holds bytes currently remaining in stream
877 */
878#define nla_for_each_attr(pos, head, len, rem) \
879 for (pos = head, rem = len; \
880 nla_ok(pos, rem); \
881 pos = nla_next(pos, &(rem)))
882
883#endif