Merge to Fedora kernel-2.6.18-1.2224_FC5-vs2.0.2.2-rc4 patched with stable patch...
[linux-2.6.git] / include / linux / netfilter_ipv4 / ip_conntrack.h
1 #ifndef _IP_CONNTRACK_H
2 #define _IP_CONNTRACK_H
3
4 #include <linux/netfilter/nf_conntrack_common.h>
5
6 #ifdef __KERNEL__
7 #include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
8 #include <linux/bitops.h>
9 #include <linux/compiler.h>
10 #include <asm/atomic.h>
11
12 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
13 #include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
14 #include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
15 #include <linux/netfilter_ipv4/ip_conntrack_sctp.h>
16
17 /* per conntrack: protocol private data */
18 union ip_conntrack_proto {
19         /* insert conntrack proto private data here */
20         struct ip_ct_gre gre;
21         struct ip_ct_sctp sctp;
22         struct ip_ct_tcp tcp;
23         struct ip_ct_icmp icmp;
24 };
25
26 union ip_conntrack_expect_proto {
27         /* insert expect proto private data here */
28 };
29
30 /* Add protocol helper include file here */
31 #include <linux/netfilter_ipv4/ip_conntrack_h323.h>
32 #include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
33 #include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
34 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
35 #include <linux/netfilter_ipv4/ip_conntrack_irc.h>
36
37 /* per conntrack: application helper private data */
38 union ip_conntrack_help {
39         /* insert conntrack helper private data (master) here */
40         struct ip_ct_h323_master ct_h323_info;
41         struct ip_ct_pptp_master ct_pptp_info;
42         struct ip_ct_ftp_master ct_ftp_info;
43         struct ip_ct_irc_master ct_irc_info;
44 };
45
46 #ifdef CONFIG_IP_NF_NAT_NEEDED
47 #include <linux/netfilter_ipv4/ip_nat.h>
48 #include <linux/netfilter_ipv4/ip_nat_pptp.h>
49
50 /* per conntrack: nat application helper private data */
51 union ip_conntrack_nat_help {
52         /* insert nat helper private data here */
53         struct ip_nat_pptp nat_pptp_info;
54 };
55 #endif
56
57 #include <linux/types.h>
58 #include <linux/skbuff.h>
59
60 #ifdef CONFIG_NETFILTER_DEBUG
61 #define IP_NF_ASSERT(x)                                                 \
62 do {                                                                    \
63         if (!(x))                                                       \
64                 /* Wooah!  I'm tripping my conntrack in a frenzy of     \
65                    netplay... */                                        \
66                 printk("NF_IP_ASSERT: %s:%i(%s)\n",                     \
67                        __FILE__, __LINE__, __FUNCTION__);               \
68 } while(0)
69 #else
70 #define IP_NF_ASSERT(x)
71 #endif
72
73 struct ip_conntrack_helper;
74
75 struct ip_conntrack
76 {
77         /* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
78            plus 1 for any connection(s) we are `master' for */
79         struct nf_conntrack ct_general;
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_IP_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 ip_conntrack *master;
93
94         /* Current number of expected connections */
95         unsigned int expecting;
96
97         /* Unique ID that identifies this conntrack*/
98         unsigned int id;
99
100         /* Helper, if any. */
101         struct ip_conntrack_helper *helper;
102
103         /* Storage reserved for other modules: */
104         union ip_conntrack_proto proto;
105
106         union ip_conntrack_help help;
107
108 #ifdef CONFIG_IP_NF_NAT_NEEDED
109         struct {
110                 struct ip_nat_info info;
111                 union ip_conntrack_nat_help help;
112 #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
113         defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
114                 int masq_index;
115 #endif
116         } nat;
117 #endif /* CONFIG_IP_NF_NAT_NEEDED */
118
119 #if defined(CONFIG_IP_NF_CONNTRACK_MARK)
120         u_int32_t mark;
121 #endif
122
123 #if defined(CONFIG_VNET) || defined(CONFIG_VNET_MODULE)
124         /* VServer context id */
125         xid_t xid[IP_CT_DIR_MAX];
126
127         /* Connection priority (pushed to skb->priority) */
128         /* Can be used directly by some classful qdiscs such as HTB */
129         u_int32_t priority;
130 #endif
131
132 #ifdef CONFIG_IP_NF_CONNTRACK_SECMARK
133         u_int32_t secmark;
134 #endif
135
136         /* Traversed often, so hopefully in different cacheline to top */
137         /* These are my tuples; original and reply */
138         struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
139 };
140
141 struct ip_conntrack_expect
142 {
143         /* Internal linked list (global expectation list) */
144         struct list_head list;
145
146         /* We expect this tuple, with the following mask */
147         struct ip_conntrack_tuple tuple, mask;
148  
149         /* Function to call after setup and insertion */
150         void (*expectfn)(struct ip_conntrack *new,
151                          struct ip_conntrack_expect *this);
152
153         /* The conntrack of the master connection */
154         struct ip_conntrack *master;
155
156         /* Timer function; deletes the expectation. */
157         struct timer_list timeout;
158
159         /* Usage count. */
160         atomic_t use;
161
162         /* Unique ID */
163         unsigned int id;
164
165         /* Flags */
166         unsigned int flags;
167
168 #ifdef CONFIG_IP_NF_NAT_NEEDED
169         u_int32_t saved_ip;
170         /* This is the original per-proto part, used to map the
171          * expected connection the way the recipient expects. */
172         union ip_conntrack_manip_proto saved_proto;
173         /* Direction relative to the master connection. */
174         enum ip_conntrack_dir dir;
175 #endif
176 };
177
178 #define IP_CT_EXPECT_PERMANENT  0x1
179
180 static inline struct ip_conntrack *
181 tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash)
182 {
183         return container_of(hash, struct ip_conntrack,
184                             tuplehash[hash->tuple.dst.dir]);
185 }
186
187 /* get master conntrack via master expectation */
188 #define master_ct(conntr) (conntr->master)
189
190 /* Alter reply tuple (maybe alter helper). */
191 extern void
192 ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
193                          const struct ip_conntrack_tuple *newreply);
194
195 /* Is this tuple taken? (ignoring any belonging to the given
196    conntrack). */
197 extern int
198 ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple,
199                          const struct ip_conntrack *ignored_conntrack);
200
201 /* Return conntrack_info and tuple hash for given skb. */
202 static inline struct ip_conntrack *
203 ip_conntrack_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
204 {
205         *ctinfo = skb->nfctinfo;
206         return (struct ip_conntrack *)skb->nfct;
207 }
208
209 /* decrement reference count on a conntrack */
210 static inline void
211 ip_conntrack_put(struct ip_conntrack *ct)
212 {
213         IP_NF_ASSERT(ct);
214         nf_conntrack_put(&ct->ct_general);
215 }
216
217 extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
218                           const struct ip_conntrack_tuple *orig);
219
220 extern void __ip_ct_refresh_acct(struct ip_conntrack *ct,
221                                  enum ip_conntrack_info ctinfo,
222                                  const struct sk_buff *skb,
223                                  unsigned long extra_jiffies,
224                                  int do_acct);
225
226 /* Refresh conntrack for this many jiffies and do accounting */
227 static inline void ip_ct_refresh_acct(struct ip_conntrack *ct, 
228                                       enum ip_conntrack_info ctinfo,
229                                       const struct sk_buff *skb,
230                                       unsigned long extra_jiffies)
231 {
232         __ip_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1);
233 }
234
235 /* Refresh conntrack for this many jiffies */
236 static inline void ip_ct_refresh(struct ip_conntrack *ct,
237                                  const struct sk_buff *skb,
238                                  unsigned long extra_jiffies)
239 {
240         __ip_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
241 }
242
243 /* These are for NAT.  Icky. */
244 /* Update TCP window tracking data when NAT mangles the packet */
245 extern void ip_conntrack_tcp_update(struct sk_buff *skb,
246                                     struct ip_conntrack *conntrack,
247                                     enum ip_conntrack_dir dir);
248
249 /* Call me when a conntrack is destroyed. */
250 extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
251
252 /* Fake conntrack entry for untracked connections */
253 extern struct ip_conntrack ip_conntrack_untracked;
254
255 /* Returns new sk_buff, or NULL */
256 struct sk_buff *
257 ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user);
258
259 /* Iterate over all conntracks: if iter returns true, it's deleted. */
260 extern void
261 ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *data),
262                       void *data);
263
264 extern struct ip_conntrack_helper *
265 __ip_conntrack_helper_find_byname(const char *);
266 extern struct ip_conntrack_helper *
267 ip_conntrack_helper_find_get(const struct ip_conntrack_tuple *tuple);
268 extern void ip_conntrack_helper_put(struct ip_conntrack_helper *helper);
269
270 extern struct ip_conntrack_protocol *
271 __ip_conntrack_proto_find(u_int8_t protocol);
272 extern struct ip_conntrack_protocol *
273 ip_conntrack_proto_find_get(u_int8_t protocol);
274 extern void ip_conntrack_proto_put(struct ip_conntrack_protocol *proto);
275
276 extern void ip_ct_remove_expectations(struct ip_conntrack *ct);
277
278 extern struct ip_conntrack *ip_conntrack_alloc(struct ip_conntrack_tuple *,
279                                                struct ip_conntrack_tuple *);
280
281 extern void ip_conntrack_free(struct ip_conntrack *ct);
282
283 extern void ip_conntrack_hash_insert(struct ip_conntrack *ct);
284
285 extern struct ip_conntrack_expect *
286 __ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple);
287
288 extern struct ip_conntrack_expect *
289 ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple);
290
291 extern struct ip_conntrack_tuple_hash *
292 __ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
293                     const struct ip_conntrack *ignored_conntrack);
294
295 extern void ip_conntrack_flush(void);
296
297 /* It's confirmed if it is, or has been in the hash table. */
298 static inline int is_confirmed(struct ip_conntrack *ct)
299 {
300         return test_bit(IPS_CONFIRMED_BIT, &ct->status);
301 }
302
303 static inline int is_dying(struct ip_conntrack *ct)
304 {
305         return test_bit(IPS_DYING_BIT, &ct->status);
306 }
307
308 extern unsigned int ip_conntrack_htable_size;
309 extern int ip_conntrack_checksum;
310  
311 #define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
312
313 #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
314 #include <linux/notifier.h>
315 #include <linux/interrupt.h>
316
317 struct ip_conntrack_ecache {
318         struct ip_conntrack *ct;
319         unsigned int events;
320 };
321 DECLARE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache);
322
323 #define CONNTRACK_ECACHE(x)     (__get_cpu_var(ip_conntrack_ecache).x)
324  
325 extern struct atomic_notifier_head ip_conntrack_chain;
326 extern struct atomic_notifier_head ip_conntrack_expect_chain;
327
328 static inline int ip_conntrack_register_notifier(struct notifier_block *nb)
329 {
330         return atomic_notifier_chain_register(&ip_conntrack_chain, nb);
331 }
332
333 static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb)
334 {
335         return atomic_notifier_chain_unregister(&ip_conntrack_chain, nb);
336 }
337
338 static inline int 
339 ip_conntrack_expect_register_notifier(struct notifier_block *nb)
340 {
341         return atomic_notifier_chain_register(&ip_conntrack_expect_chain, nb);
342 }
343
344 static inline int
345 ip_conntrack_expect_unregister_notifier(struct notifier_block *nb)
346 {
347         return atomic_notifier_chain_unregister(&ip_conntrack_expect_chain,
348                         nb);
349 }
350
351 extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct);
352 extern void __ip_ct_event_cache_init(struct ip_conntrack *ct);
353
354 static inline void 
355 ip_conntrack_event_cache(enum ip_conntrack_events event,
356                          const struct sk_buff *skb)
357 {
358         struct ip_conntrack *ct = (struct ip_conntrack *)skb->nfct;
359         struct ip_conntrack_ecache *ecache;
360         
361         local_bh_disable();
362         ecache = &__get_cpu_var(ip_conntrack_ecache);
363         if (ct != ecache->ct)
364                 __ip_ct_event_cache_init(ct);
365         ecache->events |= event;
366         local_bh_enable();
367 }
368
369 static inline void ip_conntrack_event(enum ip_conntrack_events event,
370                                       struct ip_conntrack *ct)
371 {
372         if (is_confirmed(ct) && !is_dying(ct))
373                 atomic_notifier_call_chain(&ip_conntrack_chain, event, ct);
374 }
375
376 static inline void 
377 ip_conntrack_expect_event(enum ip_conntrack_expect_events event,
378                           struct ip_conntrack_expect *exp)
379 {
380         atomic_notifier_call_chain(&ip_conntrack_expect_chain, event, exp);
381 }
382 #else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
383 static inline void ip_conntrack_event_cache(enum ip_conntrack_events event, 
384                                             const struct sk_buff *skb) {}
385 static inline void ip_conntrack_event(enum ip_conntrack_events event, 
386                                       struct ip_conntrack *ct) {}
387 static inline void ip_ct_deliver_cached_events(const struct ip_conntrack *ct) {}
388 static inline void 
389 ip_conntrack_expect_event(enum ip_conntrack_expect_events event, 
390                           struct ip_conntrack_expect *exp) {}
391 #endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
392
393 #ifdef CONFIG_IP_NF_NAT_NEEDED
394 static inline int ip_nat_initialized(struct ip_conntrack *conntrack,
395                                      enum ip_nat_manip_type manip)
396 {
397         if (manip == IP_NAT_MANIP_SRC)
398                 return test_bit(IPS_SRC_NAT_DONE_BIT, &conntrack->status);
399         return test_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status);
400 }
401 #endif /* CONFIG_IP_NF_NAT_NEEDED */
402
403 #endif /* __KERNEL__ */
404 #endif /* _IP_CONNTRACK_H */