Commit | Line | Data |
---|---|---|
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 | |
616b14b4 FW |
15 | enum nf_ct_ecache_state { |
16 | NFCT_ECACHE_UNKNOWN, /* destroy event not sent */ | |
17 | NFCT_ECACHE_DESTROY_FAIL, /* tried but failed to send destroy event */ | |
18 | NFCT_ECACHE_DESTROY_SENT, /* sent destroy event after failure */ | |
19 | }; | |
20 | ||
a0891aa6 | 21 | struct nf_conntrack_ecache { |
616b14b4 FW |
22 | unsigned long cache; /* bitops want long */ |
23 | unsigned long missed; /* missed events */ | |
24 | u16 ctmask; /* bitmask of ct events to be delivered */ | |
25 | u16 expmask; /* bitmask of expect events to be delivered */ | |
26 | u32 portid; /* netlink portid of destroyer */ | |
27 | enum nf_ct_ecache_state state; /* ecache state */ | |
a0891aa6 | 28 | }; |
6bfea198 | 29 | |
a0891aa6 PNA |
30 | static inline struct nf_conntrack_ecache * |
31 | nf_ct_ecache_find(const struct nf_conn *ct) | |
32 | { | |
e0e76c83 | 33 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
a0891aa6 | 34 | return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE); |
e0e76c83 CG |
35 | #else |
36 | return NULL; | |
37 | #endif | |
a0891aa6 | 38 | } |
6bfea198 | 39 | |
a0891aa6 | 40 | static inline struct nf_conntrack_ecache * |
0cebe4b4 | 41 | nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp) |
a0891aa6 | 42 | { |
e0e76c83 | 43 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
a0891aa6 | 44 | struct net *net = nf_ct_net(ct); |
0cebe4b4 | 45 | struct nf_conntrack_ecache *e; |
6bfea198 | 46 | |
0cebe4b4 PM |
47 | if (!ctmask && !expmask && net->ct.sysctl_events) { |
48 | ctmask = ~0; | |
49 | expmask = ~0; | |
50 | } | |
51 | if (!ctmask && !expmask) | |
a0891aa6 | 52 | return NULL; |
6bfea198 | 53 | |
0cebe4b4 PM |
54 | e = nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp); |
55 | if (e) { | |
56 | e->ctmask = ctmask; | |
57 | e->expmask = expmask; | |
58 | } | |
59 | return e; | |
e0e76c83 CG |
60 | #else |
61 | return NULL; | |
62 | #endif | |
6bfea198 PNA |
63 | }; |
64 | ||
f6180121 | 65 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
19abb7b0 PNA |
66 | /* This structure is passed to event handler */ |
67 | struct nf_ct_event { | |
68 | struct nf_conn *ct; | |
15e47304 | 69 | u32 portid; |
19abb7b0 PNA |
70 | int report; |
71 | }; | |
72 | ||
e34d5c1a PNA |
73 | struct nf_ct_event_notifier { |
74 | int (*fcn)(unsigned int events, struct nf_ct_event *item); | |
75 | }; | |
76 | ||
4e77be46 JP |
77 | int nf_conntrack_register_notifier(struct net *net, |
78 | struct nf_ct_event_notifier *nb); | |
79 | void nf_conntrack_unregister_notifier(struct net *net, | |
80 | struct nf_ct_event_notifier *nb); | |
f6180121 | 81 | |
4e77be46 | 82 | void nf_ct_deliver_cached_events(struct nf_conn *ct); |
3c435e2e FW |
83 | int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, |
84 | u32 portid, int report); | |
f6180121 MJ |
85 | |
86 | static inline void | |
a71996fc | 87 | nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) |
f6180121 | 88 | { |
70e9942f | 89 | struct net *net = nf_ct_net(ct); |
a0891aa6 PNA |
90 | struct nf_conntrack_ecache *e; |
91 | ||
6bd0405b | 92 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) |
a0891aa6 PNA |
93 | return; |
94 | ||
95 | e = nf_ct_ecache_find(ct); | |
96 | if (e == NULL) | |
97 | return; | |
98 | ||
99 | set_bit(event, &e->cache); | |
f6180121 MJ |
100 | } |
101 | ||
dd7669a9 | 102 | static inline int |
a0891aa6 | 103 | nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, |
15e47304 | 104 | u32 portid, int report) |
a0891aa6 | 105 | { |
3c435e2e FW |
106 | const struct net *net = nf_ct_net(ct); |
107 | ||
108 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) | |
109 | return 0; | |
110 | ||
15e47304 | 111 | return nf_conntrack_eventmask_report(1 << event, ct, portid, report); |
a0891aa6 PNA |
112 | } |
113 | ||
dd7669a9 | 114 | static inline int |
19abb7b0 PNA |
115 | nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) |
116 | { | |
3c435e2e FW |
117 | const struct net *net = nf_ct_net(ct); |
118 | ||
119 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) | |
120 | return 0; | |
121 | ||
dd7669a9 | 122 | return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); |
19abb7b0 PNA |
123 | } |
124 | ||
125 | struct nf_exp_event { | |
126 | struct nf_conntrack_expect *exp; | |
15e47304 | 127 | u32 portid; |
19abb7b0 PNA |
128 | int report; |
129 | }; | |
130 | ||
e34d5c1a PNA |
131 | struct nf_exp_event_notifier { |
132 | int (*fcn)(unsigned int events, struct nf_exp_event *item); | |
133 | }; | |
134 | ||
4e77be46 JP |
135 | int nf_ct_expect_register_notifier(struct net *net, |
136 | struct nf_exp_event_notifier *nb); | |
137 | void nf_ct_expect_unregister_notifier(struct net *net, | |
138 | struct nf_exp_event_notifier *nb); | |
010c7d6f | 139 | |
ecdfb48c FW |
140 | void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, |
141 | struct nf_conntrack_expect *exp, | |
142 | u32 portid, int report); | |
f6180121 | 143 | |
4e77be46 JP |
144 | int nf_conntrack_ecache_pernet_init(struct net *net); |
145 | void nf_conntrack_ecache_pernet_fini(struct net *net); | |
6058fa6b | 146 | |
4e77be46 JP |
147 | int nf_conntrack_ecache_init(void); |
148 | void nf_conntrack_ecache_fini(void); | |
f6180121 | 149 | |
9500507c FW |
150 | static inline void nf_conntrack_ecache_delayed_work(struct net *net) |
151 | { | |
152 | if (!delayed_work_pending(&net->ct.ecache_dwork)) { | |
153 | schedule_delayed_work(&net->ct.ecache_dwork, HZ); | |
154 | net->ct.ecache_dwork_pending = true; | |
155 | } | |
156 | } | |
157 | ||
158 | static inline void nf_conntrack_ecache_work(struct net *net) | |
159 | { | |
160 | if (net->ct.ecache_dwork_pending) { | |
161 | net->ct.ecache_dwork_pending = false; | |
162 | mod_delayed_work(system_wq, &net->ct.ecache_dwork, 0); | |
163 | } | |
164 | } | |
165 | #else /* CONFIG_NF_CONNTRACK_EVENTS */ | |
f6180121 | 166 | static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, |
64f1b653 | 167 | struct nf_conn *ct) {} |
dd7669a9 PNA |
168 | static inline int nf_conntrack_eventmask_report(unsigned int eventmask, |
169 | struct nf_conn *ct, | |
15e47304 | 170 | u32 portid, |
dd7669a9 PNA |
171 | int report) { return 0; } |
172 | static inline int nf_conntrack_event(enum ip_conntrack_events event, | |
173 | struct nf_conn *ct) { return 0; } | |
174 | static inline int nf_conntrack_event_report(enum ip_conntrack_events event, | |
175 | struct nf_conn *ct, | |
15e47304 | 176 | u32 portid, |
dd7669a9 | 177 | int report) { return 0; } |
f6180121 | 178 | static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {} |
19abb7b0 PNA |
179 | static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e, |
180 | struct nf_conntrack_expect *exp, | |
15e47304 | 181 | u32 portid, |
19abb7b0 | 182 | int report) {} |
6058fa6b | 183 | |
3fe0f943 | 184 | static inline int nf_conntrack_ecache_pernet_init(struct net *net) |
6058fa6b AD |
185 | { |
186 | return 0; | |
bb21c95e | 187 | } |
6058fa6b | 188 | |
3fe0f943 G |
189 | static inline void nf_conntrack_ecache_pernet_fini(struct net *net) |
190 | { | |
191 | } | |
192 | ||
193 | static inline int nf_conntrack_ecache_init(void) | |
194 | { | |
195 | return 0; | |
196 | } | |
197 | ||
198 | static inline void nf_conntrack_ecache_fini(void) | |
6058fa6b AD |
199 | { |
200 | } | |
9500507c FW |
201 | |
202 | static inline void nf_conntrack_ecache_delayed_work(struct net *net) | |
203 | { | |
204 | } | |
205 | ||
206 | static inline void nf_conntrack_ecache_work(struct net *net) | |
207 | { | |
208 | } | |
f6180121 MJ |
209 | #endif /* CONFIG_NF_CONNTRACK_EVENTS */ |
210 | ||
211 | #endif /*_NF_CONNTRACK_ECACHE_H*/ | |
212 |