Blame view
include/net/netfilter/nf_conntrack_ecache.h
6.11 KB
f61801218 [NETFILTER]: nf_c... |
1 2 3 4 5 6 7 |
/* * connection tracking event cache. */ #ifndef _NF_CONNTRACK_ECACHE_H #define _NF_CONNTRACK_ECACHE_H #include <net/netfilter/nf_conntrack.h> |
6058fa6bb netfilter: netns ... |
8 |
#include <net/net_namespace.h> |
f61801218 [NETFILTER]: nf_c... |
9 |
#include <net/netfilter/nf_conntrack_expect.h> |
a0891aa6a netfilter: conntr... |
10 11 12 |
#include <linux/netfilter/nf_conntrack_common.h> #include <linux/netfilter/nf_conntrack_tuple_common.h> #include <net/netfilter/nf_conntrack_extend.h> |
f61801218 [NETFILTER]: nf_c... |
13 |
|
a0891aa6a netfilter: conntr... |
14 |
struct nf_conntrack_ecache { |
0cebe4b41 netfilter: ctnetl... |
15 16 17 18 19 |
unsigned long cache; /* bitops want long */ unsigned long missed; /* missed events */ u16 ctmask; /* bitmask of ct events to be delivered */ u16 expmask; /* bitmask of expect events to be delivered */ u32 pid; /* netlink pid of destroyer */ |
a0891aa6a netfilter: conntr... |
20 |
}; |
6bfea1984 netfilter: conntr... |
21 |
|
a0891aa6a netfilter: conntr... |
22 23 24 |
static inline struct nf_conntrack_ecache * nf_ct_ecache_find(const struct nf_conn *ct) { |
e0e76c83b netfilter: ct_ext... |
25 |
#ifdef CONFIG_NF_CONNTRACK_EVENTS |
a0891aa6a netfilter: conntr... |
26 |
return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE); |
e0e76c83b netfilter: ct_ext... |
27 28 29 |
#else return NULL; #endif |
a0891aa6a netfilter: conntr... |
30 |
} |
6bfea1984 netfilter: conntr... |
31 |
|
a0891aa6a netfilter: conntr... |
32 |
static inline struct nf_conntrack_ecache * |
0cebe4b41 netfilter: ctnetl... |
33 |
nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp) |
a0891aa6a netfilter: conntr... |
34 |
{ |
e0e76c83b netfilter: ct_ext... |
35 |
#ifdef CONFIG_NF_CONNTRACK_EVENTS |
a0891aa6a netfilter: conntr... |
36 |
struct net *net = nf_ct_net(ct); |
0cebe4b41 netfilter: ctnetl... |
37 |
struct nf_conntrack_ecache *e; |
6bfea1984 netfilter: conntr... |
38 |
|
0cebe4b41 netfilter: ctnetl... |
39 40 41 42 43 |
if (!ctmask && !expmask && net->ct.sysctl_events) { ctmask = ~0; expmask = ~0; } if (!ctmask && !expmask) |
a0891aa6a netfilter: conntr... |
44 |
return NULL; |
6bfea1984 netfilter: conntr... |
45 |
|
0cebe4b41 netfilter: ctnetl... |
46 47 48 49 50 51 |
e = nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp); if (e) { e->ctmask = ctmask; e->expmask = expmask; } return e; |
e0e76c83b netfilter: ct_ext... |
52 53 54 |
#else return NULL; #endif |
6bfea1984 netfilter: conntr... |
55 |
}; |
f61801218 [NETFILTER]: nf_c... |
56 |
#ifdef CONFIG_NF_CONNTRACK_EVENTS |
19abb7b09 netfilter: ctnetl... |
57 58 59 60 61 62 |
/* This structure is passed to event handler */ struct nf_ct_event { struct nf_conn *ct; u32 pid; int report; }; |
e34d5c1a4 netfilter: conntr... |
63 64 65 |
struct nf_ct_event_notifier { int (*fcn)(unsigned int events, struct nf_ct_event *item); }; |
70e9942f1 netfilter: nf_con... |
66 67 |
extern int nf_conntrack_register_notifier(struct net *net, struct nf_ct_event_notifier *nb); extern void nf_conntrack_unregister_notifier(struct net *net, struct nf_ct_event_notifier *nb); |
f61801218 [NETFILTER]: nf_c... |
68 |
|
a0891aa6a netfilter: conntr... |
69 |
extern void nf_ct_deliver_cached_events(struct nf_conn *ct); |
f61801218 [NETFILTER]: nf_c... |
70 71 |
static inline void |
a71996fcc netfilter: netns ... |
72 |
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) |
f61801218 [NETFILTER]: nf_c... |
73 |
{ |
70e9942f1 netfilter: nf_con... |
74 |
struct net *net = nf_ct_net(ct); |
a0891aa6a netfilter: conntr... |
75 |
struct nf_conntrack_ecache *e; |
70e9942f1 netfilter: nf_con... |
76 |
if (net->ct.nf_conntrack_event_cb == NULL) |
a0891aa6a netfilter: conntr... |
77 78 79 80 81 82 83 |
return; e = nf_ct_ecache_find(ct); if (e == NULL) return; set_bit(event, &e->cache); |
f61801218 [NETFILTER]: nf_c... |
84 |
} |
dd7669a92 netfilter: conntr... |
85 |
static inline int |
a0891aa6a netfilter: conntr... |
86 87 88 89 |
nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, u32 pid, int report) |
f61801218 [NETFILTER]: nf_c... |
90 |
{ |
dd7669a92 netfilter: conntr... |
91 |
int ret = 0; |
70e9942f1 netfilter: nf_con... |
92 |
struct net *net = nf_ct_net(ct); |
e34d5c1a4 netfilter: conntr... |
93 |
struct nf_ct_event_notifier *notify; |
dd7669a92 netfilter: conntr... |
94 |
struct nf_conntrack_ecache *e; |
e34d5c1a4 netfilter: conntr... |
95 96 |
rcu_read_lock(); |
70e9942f1 netfilter: nf_con... |
97 |
notify = rcu_dereference(net->ct.nf_conntrack_event_cb); |
e34d5c1a4 netfilter: conntr... |
98 99 |
if (notify == NULL) goto out_unlock; |
dd7669a92 netfilter: conntr... |
100 101 102 |
e = nf_ct_ecache_find(ct); if (e == NULL) goto out_unlock; |
e34d5c1a4 netfilter: conntr... |
103 104 105 |
if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) { struct nf_ct_event item = { .ct = ct, |
dd7669a92 netfilter: conntr... |
106 |
.pid = e->pid ? e->pid : pid, |
e34d5c1a4 netfilter: conntr... |
107 108 |
.report = report }; |
dd7669a92 netfilter: conntr... |
109 110 |
/* This is a resent of a destroy event? If so, skip missed */ unsigned long missed = e->pid ? 0 : e->missed; |
0cebe4b41 netfilter: ctnetl... |
111 112 |
if (!((eventmask | missed) & e->ctmask)) goto out_unlock; |
dd7669a92 netfilter: conntr... |
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
ret = notify->fcn(eventmask | missed, &item); if (unlikely(ret < 0 || missed)) { spin_lock_bh(&ct->lock); if (ret < 0) { /* This is a destroy event that has been * triggered by a process, we store the PID * to include it in the retransmission. */ if (eventmask & (1 << IPCT_DESTROY) && e->pid == 0 && pid != 0) e->pid = pid; else e->missed |= eventmask; } else e->missed &= ~missed; spin_unlock_bh(&ct->lock); } |
e34d5c1a4 netfilter: conntr... |
129 130 131 |
} out_unlock: rcu_read_unlock(); |
dd7669a92 netfilter: conntr... |
132 |
return ret; |
f61801218 [NETFILTER]: nf_c... |
133 |
} |
dd7669a92 netfilter: conntr... |
134 |
static inline int |
a0891aa6a netfilter: conntr... |
135 136 137 |
nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, u32 pid, int report) { |
dd7669a92 netfilter: conntr... |
138 |
return nf_conntrack_eventmask_report(1 << event, ct, pid, report); |
a0891aa6a netfilter: conntr... |
139 |
} |
dd7669a92 netfilter: conntr... |
140 |
static inline int |
19abb7b09 netfilter: ctnetl... |
141 142 |
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) { |
dd7669a92 netfilter: conntr... |
143 |
return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); |
19abb7b09 netfilter: ctnetl... |
144 145 146 147 148 149 150 |
} struct nf_exp_event { struct nf_conntrack_expect *exp; u32 pid; int report; }; |
e34d5c1a4 netfilter: conntr... |
151 152 153 |
struct nf_exp_event_notifier { int (*fcn)(unsigned int events, struct nf_exp_event *item); }; |
70e9942f1 netfilter: nf_con... |
154 155 |
extern int nf_ct_expect_register_notifier(struct net *net, struct nf_exp_event_notifier *nb); extern void nf_ct_expect_unregister_notifier(struct net *net, struct nf_exp_event_notifier *nb); |
010c7d6f8 [NETFILTER]: nf_c... |
156 |
|
f61801218 [NETFILTER]: nf_c... |
157 |
static inline void |
19abb7b09 netfilter: ctnetl... |
158 159 160 161 162 |
nf_ct_expect_event_report(enum ip_conntrack_expect_events event, struct nf_conntrack_expect *exp, u32 pid, int report) { |
70e9942f1 netfilter: nf_con... |
163 |
struct net *net = nf_ct_exp_net(exp); |
e34d5c1a4 netfilter: conntr... |
164 |
struct nf_exp_event_notifier *notify; |
0cebe4b41 netfilter: ctnetl... |
165 |
struct nf_conntrack_ecache *e; |
e34d5c1a4 netfilter: conntr... |
166 167 |
rcu_read_lock(); |
70e9942f1 netfilter: nf_con... |
168 |
notify = rcu_dereference(net->ct.nf_expect_event_cb); |
e34d5c1a4 netfilter: conntr... |
169 170 |
if (notify == NULL) goto out_unlock; |
0cebe4b41 netfilter: ctnetl... |
171 172 |
e = nf_ct_ecache_find(exp->master); if (e == NULL) |
a0891aa6a netfilter: conntr... |
173 |
goto out_unlock; |
0cebe4b41 netfilter: ctnetl... |
174 |
if (e->expmask & (1 << event)) { |
e34d5c1a4 netfilter: conntr... |
175 176 177 178 179 |
struct nf_exp_event item = { .exp = exp, .pid = pid, .report = report }; |
a0891aa6a netfilter: conntr... |
180 |
notify->fcn(1 << event, &item); |
e34d5c1a4 netfilter: conntr... |
181 182 183 |
} out_unlock: rcu_read_unlock(); |
19abb7b09 netfilter: ctnetl... |
184 185 186 |
} static inline void |
6823645d6 [NETFILTER]: nf_c... |
187 188 |
nf_ct_expect_event(enum ip_conntrack_expect_events event, struct nf_conntrack_expect *exp) |
f61801218 [NETFILTER]: nf_c... |
189 |
{ |
19abb7b09 netfilter: ctnetl... |
190 |
nf_ct_expect_event_report(event, exp, 0, 0); |
f61801218 [NETFILTER]: nf_c... |
191 |
} |
6058fa6bb netfilter: netns ... |
192 193 |
extern int nf_conntrack_ecache_init(struct net *net); extern void nf_conntrack_ecache_fini(struct net *net); |
f61801218 [NETFILTER]: nf_c... |
194 195 196 |
#else /* CONFIG_NF_CONNTRACK_EVENTS */ static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, |
64f1b6538 net: fix dummy 'n... |
197 |
struct nf_conn *ct) {} |
dd7669a92 netfilter: conntr... |
198 199 200 201 202 203 204 205 206 207 |
static inline int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, u32 pid, int report) { return 0; } static inline int nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) { return 0; } static inline int nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, u32 pid, int report) { return 0; } |
f61801218 [NETFILTER]: nf_c... |
208 |
static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {} |
6823645d6 [NETFILTER]: nf_c... |
209 210 |
static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event, struct nf_conntrack_expect *exp) {} |
19abb7b09 netfilter: ctnetl... |
211 212 213 214 |
static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e, struct nf_conntrack_expect *exp, u32 pid, int report) {} |
6058fa6bb netfilter: netns ... |
215 216 217 218 |
static inline int nf_conntrack_ecache_init(struct net *net) { return 0; |
bb21c95e2 nf_conntrack_ecac... |
219 |
} |
6058fa6bb netfilter: netns ... |
220 221 222 223 |
static inline void nf_conntrack_ecache_fini(struct net *net) { } |
f61801218 [NETFILTER]: nf_c... |
224 225 226 |
#endif /* CONFIG_NF_CONNTRACK_EVENTS */ #endif /*_NF_CONNTRACK_ECACHE_H*/ |