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 | 16 | enum nf_ct_ecache_state { |
616b14b4 FW |
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 | 22 | unsigned long cache; /* bitops want long */ |
616b14b4 FW |
23 | u16 ctmask; /* bitmask of ct events to be delivered */ |
24 | u16 expmask; /* bitmask of expect events to be delivered */ | |
8dd8678e | 25 | u32 missed; /* missed events */ |
616b14b4 | 26 | u32 portid; /* netlink portid of destroyer */ |
a0891aa6 | 27 | }; |
6bfea198 | 28 | |
a0891aa6 PNA |
29 | static inline struct nf_conntrack_ecache * |
30 | nf_ct_ecache_find(const struct nf_conn *ct) | |
31 | { | |
e0e76c83 | 32 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
a0891aa6 | 33 | return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE); |
e0e76c83 CG |
34 | #else |
35 | return NULL; | |
36 | #endif | |
a0891aa6 | 37 | } |
6bfea198 | 38 | |
8edc8131 FW |
39 | static inline bool nf_ct_ecache_exist(const struct nf_conn *ct) |
40 | { | |
41 | #ifdef CONFIG_NF_CONNTRACK_EVENTS | |
42 | return nf_ct_ext_exist(ct, NF_CT_EXT_ECACHE); | |
43 | #else | |
44 | return false; | |
45 | #endif | |
46 | } | |
47 | ||
f6180121 | 48 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
16b26cde | 49 | |
19abb7b0 PNA |
50 | /* This structure is passed to event handler */ |
51 | struct nf_ct_event { | |
52 | struct nf_conn *ct; | |
15e47304 | 53 | u32 portid; |
19abb7b0 PNA |
54 | int report; |
55 | }; | |
56 | ||
bd1431db FW |
57 | struct nf_exp_event { |
58 | struct nf_conntrack_expect *exp; | |
59 | u32 portid; | |
60 | int report; | |
61 | }; | |
62 | ||
e34d5c1a | 63 | struct nf_ct_event_notifier { |
b86c0e64 | 64 | int (*ct_event)(unsigned int events, const struct nf_ct_event *item); |
bd1431db | 65 | int (*exp_event)(unsigned int events, const struct nf_exp_event *item); |
e34d5c1a PNA |
66 | }; |
67 | ||
b86c0e64 FW |
68 | void nf_conntrack_register_notifier(struct net *net, |
69 | const struct nf_ct_event_notifier *nb); | |
70 | void nf_conntrack_unregister_notifier(struct net *net); | |
f6180121 | 71 | |
4e77be46 | 72 | void nf_ct_deliver_cached_events(struct nf_conn *ct); |
3c435e2e FW |
73 | int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, |
74 | u32 portid, int report); | |
f6180121 | 75 | |
b0a7ab4a | 76 | bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp); |
16b26cde JS |
77 | #else |
78 | ||
79 | static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) | |
80 | { | |
81 | } | |
82 | ||
83 | static inline int nf_conntrack_eventmask_report(unsigned int eventmask, | |
84 | struct nf_conn *ct, | |
85 | u32 portid, | |
86 | int report) | |
87 | { | |
88 | return 0; | |
89 | } | |
90 | ||
b0a7ab4a FW |
91 | static inline bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp) |
92 | { | |
93 | return false; | |
94 | } | |
16b26cde JS |
95 | #endif |
96 | ||
f6180121 | 97 | static inline void |
a71996fc | 98 | nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) |
f6180121 | 99 | { |
16b26cde | 100 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
70e9942f | 101 | struct net *net = nf_ct_net(ct); |
a0891aa6 PNA |
102 | struct nf_conntrack_ecache *e; |
103 | ||
6bd0405b | 104 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) |
a0891aa6 PNA |
105 | return; |
106 | ||
107 | e = nf_ct_ecache_find(ct); | |
108 | if (e == NULL) | |
109 | return; | |
110 | ||
111 | set_bit(event, &e->cache); | |
16b26cde | 112 | #endif |
f6180121 MJ |
113 | } |
114 | ||
dd7669a9 | 115 | static inline int |
a0891aa6 | 116 | nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, |
15e47304 | 117 | u32 portid, int report) |
a0891aa6 | 118 | { |
16b26cde | 119 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
8edc8131 FW |
120 | if (nf_ct_ecache_exist(ct)) |
121 | return nf_conntrack_eventmask_report(1 << event, ct, portid, report); | |
16b26cde | 122 | #endif |
8edc8131 | 123 | return 0; |
a0891aa6 PNA |
124 | } |
125 | ||
dd7669a9 | 126 | static inline int |
19abb7b0 PNA |
127 | nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) |
128 | { | |
16b26cde | 129 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
8edc8131 FW |
130 | if (nf_ct_ecache_exist(ct)) |
131 | return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); | |
16b26cde | 132 | #endif |
8edc8131 | 133 | return 0; |
19abb7b0 PNA |
134 | } |
135 | ||
16b26cde | 136 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
ecdfb48c FW |
137 | void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, |
138 | struct nf_conntrack_expect *exp, | |
139 | u32 portid, int report); | |
f6180121 | 140 | |
1379940b FW |
141 | void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state); |
142 | ||
fc3893fd | 143 | void nf_conntrack_ecache_pernet_init(struct net *net); |
4e77be46 | 144 | void nf_conntrack_ecache_pernet_fini(struct net *net); |
6058fa6b | 145 | |
0d3cc504 FW |
146 | struct nf_conntrack_net_ecache *nf_conn_pernet_ecache(const struct net *net); |
147 | ||
1379940b FW |
148 | static inline bool nf_conntrack_ecache_dwork_pending(const struct net *net) |
149 | { | |
150 | return net->ct.ecache_dwork_pending; | |
151 | } | |
16b26cde JS |
152 | #else /* CONFIG_NF_CONNTRACK_EVENTS */ |
153 | ||
154 | static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e, | |
155 | struct nf_conntrack_expect *exp, | |
156 | u32 portid, | |
157 | int report) | |
9500507c | 158 | { |
9500507c FW |
159 | } |
160 | ||
1379940b FW |
161 | static inline void nf_conntrack_ecache_work(struct net *net, |
162 | enum nf_ct_ecache_state s) | |
163 | { | |
164 | } | |
165 | ||
16b26cde | 166 | static inline void nf_conntrack_ecache_pernet_init(struct net *net) |
9500507c | 167 | { |
9500507c | 168 | } |
6058fa6b | 169 | |
3fe0f943 G |
170 | static inline void nf_conntrack_ecache_pernet_fini(struct net *net) |
171 | { | |
172 | } | |
1379940b | 173 | static inline bool nf_conntrack_ecache_dwork_pending(const struct net *net) { return false; } |
16b26cde | 174 | #endif /* CONFIG_NF_CONNTRACK_EVENTS */ |
f6180121 | 175 | #endif /*_NF_CONNTRACK_ECACHE_H*/ |