netfilter: conntrack: simplify event caching system
[linux-2.6.git] / include / net / netfilter / nf_conntrack_ecache.h
1 /*
2  * connection tracking event cache.
3  */
4
5 #ifndef _NF_CONNTRACK_ECACHE_H
6 #define _NF_CONNTRACK_ECACHE_H
7 #include <net/netfilter/nf_conntrack.h>
8
9 #include <linux/notifier.h>
10 #include <linux/interrupt.h>
11 #include <net/net_namespace.h>
12 #include <net/netfilter/nf_conntrack_expect.h>
13
14 /* Connection tracking event bits */
15 enum ip_conntrack_events
16 {
17         /* New conntrack */
18         IPCT_NEW_BIT = 0,
19         IPCT_NEW = (1 << IPCT_NEW_BIT),
20
21         /* Expected connection */
22         IPCT_RELATED_BIT = 1,
23         IPCT_RELATED = (1 << IPCT_RELATED_BIT),
24
25         /* Destroyed conntrack */
26         IPCT_DESTROY_BIT = 2,
27         IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
28
29         /* Status has changed */
30         IPCT_STATUS_BIT = 3,
31         IPCT_STATUS = (1 << IPCT_STATUS_BIT),
32
33         /* Update of protocol info */
34         IPCT_PROTOINFO_BIT = 4,
35         IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
36
37         /* New helper for conntrack */
38         IPCT_HELPER_BIT = 5,
39         IPCT_HELPER = (1 << IPCT_HELPER_BIT),
40
41         /* Mark is set */
42         IPCT_MARK_BIT = 6,
43         IPCT_MARK = (1 << IPCT_MARK_BIT),
44
45         /* NAT sequence adjustment */
46         IPCT_NATSEQADJ_BIT = 7,
47         IPCT_NATSEQADJ = (1 << IPCT_NATSEQADJ_BIT),
48
49         /* Secmark is set */
50         IPCT_SECMARK_BIT = 8,
51         IPCT_SECMARK = (1 << IPCT_SECMARK_BIT),
52 };
53
54 enum ip_conntrack_expect_events {
55         IPEXP_NEW_BIT = 0,
56         IPEXP_NEW = (1 << IPEXP_NEW_BIT),
57 };
58
59 #ifdef CONFIG_NF_CONNTRACK_EVENTS
60 struct nf_conntrack_ecache {
61         struct nf_conn *ct;
62         unsigned int events;
63 };
64
65 /* This structure is passed to event handler */
66 struct nf_ct_event {
67         struct nf_conn *ct;
68         u32 pid;
69         int report;
70 };
71
72 extern struct atomic_notifier_head nf_conntrack_chain;
73 extern int nf_conntrack_register_notifier(struct notifier_block *nb);
74 extern int nf_conntrack_unregister_notifier(struct notifier_block *nb);
75
76 extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
77 extern void __nf_ct_event_cache_init(struct nf_conn *ct);
78 extern void nf_ct_event_cache_flush(struct net *net);
79
80 static inline void
81 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
82 {
83         struct net *net = nf_ct_net(ct);
84         struct nf_conntrack_ecache *ecache;
85
86         local_bh_disable();
87         ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
88         if (ct != ecache->ct)
89                 __nf_ct_event_cache_init(ct);
90         ecache->events |= event;
91         local_bh_enable();
92 }
93
94 static inline void
95 nf_conntrack_event_report(enum ip_conntrack_events event,
96                           struct nf_conn *ct,
97                           u32 pid,
98                           int report)
99 {
100         struct nf_ct_event item = {
101                 .ct     = ct,
102                 .pid    = pid,
103                 .report = report
104         };
105         if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
106                 atomic_notifier_call_chain(&nf_conntrack_chain, event, &item);
107 }
108
109 static inline void
110 nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
111 {
112         nf_conntrack_event_report(event, ct, 0, 0);
113 }
114
115 struct nf_exp_event {
116         struct nf_conntrack_expect *exp;
117         u32 pid;
118         int report;
119 };
120
121 extern struct atomic_notifier_head nf_ct_expect_chain;
122 extern int nf_ct_expect_register_notifier(struct notifier_block *nb);
123 extern int nf_ct_expect_unregister_notifier(struct notifier_block *nb);
124
125 static inline void
126 nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
127                           struct nf_conntrack_expect *exp,
128                           u32 pid,
129                           int report)
130 {
131         struct nf_exp_event item = {
132                 .exp    = exp,
133                 .pid    = pid,
134                 .report = report
135         };
136         atomic_notifier_call_chain(&nf_ct_expect_chain, event, &item);
137 }
138
139 static inline void
140 nf_ct_expect_event(enum ip_conntrack_expect_events event,
141                    struct nf_conntrack_expect *exp)
142 {
143         nf_ct_expect_event_report(event, exp, 0, 0);
144 }
145
146 extern int nf_conntrack_ecache_init(struct net *net);
147 extern void nf_conntrack_ecache_fini(struct net *net);
148
149 #else /* CONFIG_NF_CONNTRACK_EVENTS */
150
151 static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
152                                             struct nf_conn *ct) {}
153 static inline void nf_conntrack_event(enum ip_conntrack_events event,
154                                       struct nf_conn *ct) {}
155 static inline void nf_conntrack_event_report(enum ip_conntrack_events event,
156                                              struct nf_conn *ct,
157                                              u32 pid,
158                                              int report) {}
159 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
160 static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
161                                       struct nf_conntrack_expect *exp) {}
162 static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
163                                              struct nf_conntrack_expect *exp,
164                                              u32 pid,
165                                              int report) {}
166 static inline void nf_ct_event_cache_flush(struct net *net) {}
167
168 static inline int nf_conntrack_ecache_init(struct net *net)
169 {
170         return 0;
171 }
172
173 static inline void nf_conntrack_ecache_fini(struct net *net)
174 {
175 }
176 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
177
178 #endif /*_NF_CONNTRACK_ECACHE_H*/
179