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