]> bbs.cooldavid.org Git - net-next-2.6.git/blame - include/net/netfilter/nf_conntrack_ecache.h
net: cleanup include/net
[net-next-2.6.git] / include / net / netfilter / nf_conntrack_ecache.h
CommitLineData
f6180121
MJ
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
6058fa6b 9#include <net/net_namespace.h>
f6180121 10#include <net/netfilter/nf_conntrack_expect.h>
a0891aa6
PNA
11#include <linux/netfilter/nf_conntrack_common.h>
12#include <linux/netfilter/nf_conntrack_tuple_common.h>
13#include <net/netfilter/nf_conntrack_extend.h>
f6180121 14
a0891aa6 15/* Connection tracking event types */
fd2c3ef7 16enum ip_conntrack_events {
a0891aa6
PNA
17 IPCT_NEW = 0, /* new conntrack */
18 IPCT_RELATED = 1, /* related conntrack */
19 IPCT_DESTROY = 2, /* destroyed conntrack */
20 IPCT_STATUS = 3, /* status has changed */
21 IPCT_PROTOINFO = 4, /* protocol information has changed */
22 IPCT_HELPER = 5, /* new helper has been set */
23 IPCT_MARK = 6, /* new mark has been set */
24 IPCT_NATSEQADJ = 7, /* NAT is doing sequence adjustment */
25 IPCT_SECMARK = 8, /* new security mark has been set */
26};
6bfea198 27
a0891aa6
PNA
28enum ip_conntrack_expect_events {
29 IPEXP_NEW = 0, /* new expectation */
30};
6bfea198 31
a0891aa6
PNA
32struct nf_conntrack_ecache {
33 unsigned long cache; /* bitops want long */
dd7669a9
PNA
34 unsigned long missed; /* missed events */
35 u32 pid; /* netlink pid of destroyer */
a0891aa6 36};
6bfea198 37
a0891aa6
PNA
38static inline struct nf_conntrack_ecache *
39nf_ct_ecache_find(const struct nf_conn *ct)
40{
41 return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE);
42}
6bfea198 43
a0891aa6
PNA
44static inline struct nf_conntrack_ecache *
45nf_ct_ecache_ext_add(struct nf_conn *ct, gfp_t gfp)
46{
47 struct net *net = nf_ct_net(ct);
6bfea198 48
a0891aa6
PNA
49 if (!net->ct.sysctl_events)
50 return NULL;
6bfea198 51
a0891aa6 52 return nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
6bfea198
PNA
53};
54
f6180121 55#ifdef CONFIG_NF_CONNTRACK_EVENTS
19abb7b0
PNA
56/* This structure is passed to event handler */
57struct nf_ct_event {
58 struct nf_conn *ct;
59 u32 pid;
60 int report;
61};
62
e34d5c1a
PNA
63struct nf_ct_event_notifier {
64 int (*fcn)(unsigned int events, struct nf_ct_event *item);
65};
66
67extern struct nf_ct_event_notifier *nf_conntrack_event_cb;
68extern int nf_conntrack_register_notifier(struct nf_ct_event_notifier *nb);
69extern void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *nb);
f6180121 70
a0891aa6 71extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
f6180121
MJ
72
73static inline void
a71996fc 74nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
f6180121 75{
a0891aa6
PNA
76 struct nf_conntrack_ecache *e;
77
78 if (nf_conntrack_event_cb == NULL)
79 return;
80
81 e = nf_ct_ecache_find(ct);
82 if (e == NULL)
83 return;
84
85 set_bit(event, &e->cache);
f6180121
MJ
86}
87
dd7669a9 88static inline int
a0891aa6
PNA
89nf_conntrack_eventmask_report(unsigned int eventmask,
90 struct nf_conn *ct,
91 u32 pid,
92 int report)
f6180121 93{
dd7669a9 94 int ret = 0;
a0891aa6 95 struct net *net = nf_ct_net(ct);
e34d5c1a 96 struct nf_ct_event_notifier *notify;
dd7669a9 97 struct nf_conntrack_ecache *e;
e34d5c1a
PNA
98
99 rcu_read_lock();
100 notify = rcu_dereference(nf_conntrack_event_cb);
101 if (notify == NULL)
102 goto out_unlock;
103
a0891aa6
PNA
104 if (!net->ct.sysctl_events)
105 goto out_unlock;
106
dd7669a9
PNA
107 e = nf_ct_ecache_find(ct);
108 if (e == NULL)
109 goto out_unlock;
110
e34d5c1a
PNA
111 if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
112 struct nf_ct_event item = {
113 .ct = ct,
dd7669a9 114 .pid = e->pid ? e->pid : pid,
e34d5c1a
PNA
115 .report = report
116 };
dd7669a9
PNA
117 /* This is a resent of a destroy event? If so, skip missed */
118 unsigned long missed = e->pid ? 0 : e->missed;
119
120 ret = notify->fcn(eventmask | missed, &item);
121 if (unlikely(ret < 0 || missed)) {
122 spin_lock_bh(&ct->lock);
123 if (ret < 0) {
124 /* This is a destroy event that has been
125 * triggered by a process, we store the PID
126 * to include it in the retransmission. */
127 if (eventmask & (1 << IPCT_DESTROY) &&
128 e->pid == 0 && pid != 0)
129 e->pid = pid;
130 else
131 e->missed |= eventmask;
132 } else
133 e->missed &= ~missed;
134 spin_unlock_bh(&ct->lock);
135 }
e34d5c1a
PNA
136 }
137out_unlock:
138 rcu_read_unlock();
dd7669a9 139 return ret;
f6180121
MJ
140}
141
dd7669a9 142static inline int
a0891aa6
PNA
143nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
144 u32 pid, int report)
145{
dd7669a9 146 return nf_conntrack_eventmask_report(1 << event, ct, pid, report);
a0891aa6
PNA
147}
148
dd7669a9 149static inline int
19abb7b0
PNA
150nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
151{
dd7669a9 152 return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
19abb7b0
PNA
153}
154
155struct nf_exp_event {
156 struct nf_conntrack_expect *exp;
157 u32 pid;
158 int report;
159};
160
e34d5c1a
PNA
161struct nf_exp_event_notifier {
162 int (*fcn)(unsigned int events, struct nf_exp_event *item);
163};
164
165extern struct nf_exp_event_notifier *nf_expect_event_cb;
166extern int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *nb);
167extern void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *nb);
010c7d6f 168
19abb7b0
PNA
169static inline void
170nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
171 struct nf_conntrack_expect *exp,
172 u32 pid,
173 int report)
174{
a0891aa6 175 struct net *net = nf_ct_exp_net(exp);
e34d5c1a
PNA
176 struct nf_exp_event_notifier *notify;
177
178 rcu_read_lock();
179 notify = rcu_dereference(nf_expect_event_cb);
180 if (notify == NULL)
181 goto out_unlock;
182
a0891aa6
PNA
183 if (!net->ct.sysctl_events)
184 goto out_unlock;
185
e34d5c1a
PNA
186 {
187 struct nf_exp_event item = {
188 .exp = exp,
189 .pid = pid,
190 .report = report
191 };
a0891aa6 192 notify->fcn(1 << event, &item);
e34d5c1a
PNA
193 }
194out_unlock:
195 rcu_read_unlock();
19abb7b0
PNA
196}
197
f6180121 198static inline void
6823645d
PM
199nf_ct_expect_event(enum ip_conntrack_expect_events event,
200 struct nf_conntrack_expect *exp)
f6180121 201{
19abb7b0 202 nf_ct_expect_event_report(event, exp, 0, 0);
f6180121
MJ
203}
204
6058fa6b
AD
205extern int nf_conntrack_ecache_init(struct net *net);
206extern void nf_conntrack_ecache_fini(struct net *net);
207
f6180121
MJ
208#else /* CONFIG_NF_CONNTRACK_EVENTS */
209
210static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
64f1b653 211 struct nf_conn *ct) {}
dd7669a9
PNA
212static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
213 struct nf_conn *ct,
214 u32 pid,
215 int report) { return 0; }
216static inline int nf_conntrack_event(enum ip_conntrack_events event,
217 struct nf_conn *ct) { return 0; }
218static inline int nf_conntrack_event_report(enum ip_conntrack_events event,
219 struct nf_conn *ct,
220 u32 pid,
221 int report) { return 0; }
f6180121 222static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
6823645d
PM
223static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
224 struct nf_conntrack_expect *exp) {}
19abb7b0
PNA
225static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
226 struct nf_conntrack_expect *exp,
227 u32 pid,
228 int report) {}
6058fa6b
AD
229
230static inline int nf_conntrack_ecache_init(struct net *net)
231{
232 return 0;
bb21c95e 233}
6058fa6b
AD
234
235static inline void nf_conntrack_ecache_fini(struct net *net)
236{
237}
f6180121
MJ
238#endif /* CONFIG_NF_CONNTRACK_EVENTS */
239
240#endif /*_NF_CONNTRACK_ECACHE_H*/
241