Blame view
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
10.6 KB
e4bd8bce3 [NETFILTER]: nf_c... |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* ip_conntrack proc compat - based on ip_conntrack_standalone.c * * (C) 1999-2001 Paul `Rusty' Russell * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/types.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/percpu.h> |
1ae4de0cd secmark: export s... |
14 |
#include <linux/security.h> |
457c4cbc5 [NET]: Make /proc... |
15 |
#include <net/net_namespace.h> |
e4bd8bce3 [NETFILTER]: nf_c... |
16 17 18 19 20 21 |
#include <linux/netfilter.h> #include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_l3proto.h> #include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack_expect.h> |
584015727 netfilter: accoun... |
22 |
#include <net/netfilter/nf_conntrack_acct.h> |
eb733162a netfilter: add __... |
23 |
#include <linux/rculist_nulls.h> |
bc3b2d7fb net: Add export.h... |
24 |
#include <linux/export.h> |
e4bd8bce3 [NETFILTER]: nf_c... |
25 26 |
struct ct_iter_state { |
5e6b29972 netfilter: netns ... |
27 |
struct seq_net_private p; |
e4bd8bce3 [NETFILTER]: nf_c... |
28 29 |
unsigned int bucket; }; |
ea781f197 netfilter: nf_con... |
30 |
static struct hlist_nulls_node *ct_get_first(struct seq_file *seq) |
e4bd8bce3 [NETFILTER]: nf_c... |
31 |
{ |
5e6b29972 netfilter: netns ... |
32 |
struct net *net = seq_file_net(seq); |
e4bd8bce3 [NETFILTER]: nf_c... |
33 |
struct ct_iter_state *st = seq->private; |
ea781f197 netfilter: nf_con... |
34 |
struct hlist_nulls_node *n; |
e4bd8bce3 [NETFILTER]: nf_c... |
35 36 |
for (st->bucket = 0; |
d696c7bda netfilter: nf_con... |
37 |
st->bucket < net->ct.htable_size; |
e4bd8bce3 [NETFILTER]: nf_c... |
38 |
st->bucket++) { |
eb733162a netfilter: add __... |
39 40 |
n = rcu_dereference( hlist_nulls_first_rcu(&net->ct.hash[st->bucket])); |
ea781f197 netfilter: nf_con... |
41 |
if (!is_a_nulls(n)) |
76507f69c [NETFILTER]: nf_c... |
42 |
return n; |
e4bd8bce3 [NETFILTER]: nf_c... |
43 44 45 |
} return NULL; } |
ea781f197 netfilter: nf_con... |
46 47 |
static struct hlist_nulls_node *ct_get_next(struct seq_file *seq, struct hlist_nulls_node *head) |
e4bd8bce3 [NETFILTER]: nf_c... |
48 |
{ |
5e6b29972 netfilter: netns ... |
49 |
struct net *net = seq_file_net(seq); |
e4bd8bce3 [NETFILTER]: nf_c... |
50 |
struct ct_iter_state *st = seq->private; |
eb733162a netfilter: add __... |
51 |
head = rcu_dereference(hlist_nulls_next_rcu(head)); |
ea781f197 netfilter: nf_con... |
52 53 |
while (is_a_nulls(head)) { if (likely(get_nulls_value(head) == st->bucket)) { |
d696c7bda netfilter: nf_con... |
54 |
if (++st->bucket >= net->ct.htable_size) |
ea781f197 netfilter: nf_con... |
55 56 |
return NULL; } |
eb733162a netfilter: add __... |
57 58 |
head = rcu_dereference( hlist_nulls_first_rcu(&net->ct.hash[st->bucket])); |
e4bd8bce3 [NETFILTER]: nf_c... |
59 60 61 |
} return head; } |
ea781f197 netfilter: nf_con... |
62 |
static struct hlist_nulls_node *ct_get_idx(struct seq_file *seq, loff_t pos) |
e4bd8bce3 [NETFILTER]: nf_c... |
63 |
{ |
ea781f197 netfilter: nf_con... |
64 |
struct hlist_nulls_node *head = ct_get_first(seq); |
e4bd8bce3 [NETFILTER]: nf_c... |
65 66 67 68 69 70 71 72 |
if (head) while (pos && (head = ct_get_next(seq, head))) pos--; return pos ? NULL : head; } static void *ct_seq_start(struct seq_file *seq, loff_t *pos) |
76507f69c [NETFILTER]: nf_c... |
73 |
__acquires(RCU) |
e4bd8bce3 [NETFILTER]: nf_c... |
74 |
{ |
76507f69c [NETFILTER]: nf_c... |
75 |
rcu_read_lock(); |
e4bd8bce3 [NETFILTER]: nf_c... |
76 77 78 79 80 81 82 83 84 85 |
return ct_get_idx(seq, *pos); } static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos) { (*pos)++; return ct_get_next(s, v); } static void ct_seq_stop(struct seq_file *s, void *v) |
76507f69c [NETFILTER]: nf_c... |
86 |
__releases(RCU) |
e4bd8bce3 [NETFILTER]: nf_c... |
87 |
{ |
76507f69c [NETFILTER]: nf_c... |
88 |
rcu_read_unlock(); |
e4bd8bce3 [NETFILTER]: nf_c... |
89 |
} |
1ae4de0cd secmark: export s... |
90 91 92 93 94 95 96 97 98 |
#ifdef CONFIG_NF_CONNTRACK_SECMARK static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) { int ret; u32 len; char *secctx; ret = security_secid_to_secctx(ct->secmark, &secctx, &len); if (ret) |
cba85b532 netfilter: fix ex... |
99 |
return 0; |
1ae4de0cd secmark: export s... |
100 101 102 103 104 105 106 107 108 109 110 111 |
ret = seq_printf(s, "secctx=%s ", secctx); security_release_secctx(secctx, len); return ret; } #else static inline int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) { return 0; } #endif |
e4bd8bce3 [NETFILTER]: nf_c... |
112 113 |
static int ct_seq_show(struct seq_file *s, void *v) { |
ea781f197 netfilter: nf_con... |
114 115 |
struct nf_conntrack_tuple_hash *hash = v; struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash); |
32948588a [NETFILTER]: nf_c... |
116 117 |
const struct nf_conntrack_l3proto *l3proto; const struct nf_conntrack_l4proto *l4proto; |
ea781f197 netfilter: nf_con... |
118 |
int ret = 0; |
e4bd8bce3 [NETFILTER]: nf_c... |
119 120 |
NF_CT_ASSERT(ct); |
ea781f197 netfilter: nf_con... |
121 122 |
if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) return 0; |
e4bd8bce3 [NETFILTER]: nf_c... |
123 124 125 |
/* we only want to print DIR_ORIGINAL */ if (NF_CT_DIRECTION(hash)) |
ea781f197 netfilter: nf_con... |
126 |
goto release; |
5e8fbe2ac [NETFILTER]: nf_c... |
127 |
if (nf_ct_l3num(ct) != AF_INET) |
ea781f197 netfilter: nf_con... |
128 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
129 |
|
5e8fbe2ac [NETFILTER]: nf_c... |
130 |
l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); |
e4bd8bce3 [NETFILTER]: nf_c... |
131 |
NF_CT_ASSERT(l3proto); |
5e8fbe2ac [NETFILTER]: nf_c... |
132 |
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); |
e4bd8bce3 [NETFILTER]: nf_c... |
133 |
NF_CT_ASSERT(l4proto); |
ea781f197 netfilter: nf_con... |
134 |
ret = -ENOSPC; |
e4bd8bce3 [NETFILTER]: nf_c... |
135 |
if (seq_printf(s, "%-8s %u %ld ", |
5e8fbe2ac [NETFILTER]: nf_c... |
136 |
l4proto->name, nf_ct_protonum(ct), |
e4bd8bce3 [NETFILTER]: nf_c... |
137 138 |
timer_pending(&ct->timeout) ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0) |
ea781f197 netfilter: nf_con... |
139 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
140 |
|
c71e91670 [NETFILTER]: nf_c... |
141 |
if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct)) |
ea781f197 netfilter: nf_con... |
142 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
143 144 145 |
if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, l3proto, l4proto)) |
ea781f197 netfilter: nf_con... |
146 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
147 |
|
584015727 netfilter: accoun... |
148 |
if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) |
ea781f197 netfilter: nf_con... |
149 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
150 151 152 |
if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) if (seq_printf(s, "[UNREPLIED] ")) |
ea781f197 netfilter: nf_con... |
153 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
154 155 156 |
if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, l3proto, l4proto)) |
ea781f197 netfilter: nf_con... |
157 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
158 |
|
584015727 netfilter: accoun... |
159 |
if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) |
ea781f197 netfilter: nf_con... |
160 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
161 162 163 |
if (test_bit(IPS_ASSURED_BIT, &ct->status)) if (seq_printf(s, "[ASSURED] ")) |
ea781f197 netfilter: nf_con... |
164 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
165 166 167 |
#ifdef CONFIG_NF_CONNTRACK_MARK if (seq_printf(s, "mark=%u ", ct->mark)) |
ea781f197 netfilter: nf_con... |
168 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
169 |
#endif |
1ae4de0cd secmark: export s... |
170 |
if (ct_show_secctx(s, ct)) |
ea781f197 netfilter: nf_con... |
171 |
goto release; |
e4bd8bce3 [NETFILTER]: nf_c... |
172 173 174 |
if (seq_printf(s, "use=%u ", atomic_read(&ct->ct_general.use))) |
ea781f197 netfilter: nf_con... |
175 176 177 178 179 |
goto release; ret = 0; release: nf_ct_put(ct); return ret; |
e4bd8bce3 [NETFILTER]: nf_c... |
180 |
} |
56b3d975b [NET]: Make all i... |
181 |
static const struct seq_operations ct_seq_ops = { |
e4bd8bce3 [NETFILTER]: nf_c... |
182 183 184 185 186 187 188 189 |
.start = ct_seq_start, .next = ct_seq_next, .stop = ct_seq_stop, .show = ct_seq_show }; static int ct_open(struct inode *inode, struct file *file) { |
5e6b29972 netfilter: netns ... |
190 191 |
return seq_open_net(inode, file, &ct_seq_ops, sizeof(struct ct_iter_state)); |
e4bd8bce3 [NETFILTER]: nf_c... |
192 |
} |
9a32144e9 [PATCH] mark stru... |
193 |
static const struct file_operations ct_file_ops = { |
e4bd8bce3 [NETFILTER]: nf_c... |
194 195 196 197 |
.owner = THIS_MODULE, .open = ct_open, .read = seq_read, .llseek = seq_lseek, |
5e6b29972 netfilter: netns ... |
198 |
.release = seq_release_net, |
e4bd8bce3 [NETFILTER]: nf_c... |
199 200 201 |
}; /* expects */ |
5d08ad440 [NETFILTER]: nf_c... |
202 |
struct ct_expect_iter_state { |
5e6b29972 netfilter: netns ... |
203 |
struct seq_net_private p; |
5d08ad440 [NETFILTER]: nf_c... |
204 205 206 207 |
unsigned int bucket; }; static struct hlist_node *ct_expect_get_first(struct seq_file *seq) |
e4bd8bce3 [NETFILTER]: nf_c... |
208 |
{ |
5e6b29972 netfilter: netns ... |
209 |
struct net *net = seq_file_net(seq); |
5d08ad440 [NETFILTER]: nf_c... |
210 |
struct ct_expect_iter_state *st = seq->private; |
7d0742da1 [NETFILTER]: nf_c... |
211 |
struct hlist_node *n; |
e4bd8bce3 [NETFILTER]: nf_c... |
212 |
|
5d08ad440 [NETFILTER]: nf_c... |
213 |
for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { |
eb733162a netfilter: add __... |
214 215 |
n = rcu_dereference( hlist_first_rcu(&net->ct.expect_hash[st->bucket])); |
7d0742da1 [NETFILTER]: nf_c... |
216 217 |
if (n) return n; |
5d08ad440 [NETFILTER]: nf_c... |
218 219 220 |
} return NULL; } |
e4bd8bce3 [NETFILTER]: nf_c... |
221 |
|
5d08ad440 [NETFILTER]: nf_c... |
222 223 224 |
static struct hlist_node *ct_expect_get_next(struct seq_file *seq, struct hlist_node *head) { |
5e6b29972 netfilter: netns ... |
225 |
struct net *net = seq_file_net(seq); |
5d08ad440 [NETFILTER]: nf_c... |
226 |
struct ct_expect_iter_state *st = seq->private; |
e4bd8bce3 [NETFILTER]: nf_c... |
227 |
|
eb733162a netfilter: add __... |
228 |
head = rcu_dereference(hlist_next_rcu(head)); |
5d08ad440 [NETFILTER]: nf_c... |
229 230 |
while (head == NULL) { if (++st->bucket >= nf_ct_expect_hsize) |
e4bd8bce3 [NETFILTER]: nf_c... |
231 |
return NULL; |
eb733162a netfilter: add __... |
232 233 |
head = rcu_dereference( hlist_first_rcu(&net->ct.expect_hash[st->bucket])); |
e4bd8bce3 [NETFILTER]: nf_c... |
234 |
} |
5d08ad440 [NETFILTER]: nf_c... |
235 |
return head; |
e4bd8bce3 [NETFILTER]: nf_c... |
236 |
} |
5d08ad440 [NETFILTER]: nf_c... |
237 |
static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos) |
e4bd8bce3 [NETFILTER]: nf_c... |
238 |
{ |
5d08ad440 [NETFILTER]: nf_c... |
239 |
struct hlist_node *head = ct_expect_get_first(seq); |
e4bd8bce3 [NETFILTER]: nf_c... |
240 |
|
5d08ad440 [NETFILTER]: nf_c... |
241 242 243 244 245 |
if (head) while (pos && (head = ct_expect_get_next(seq, head))) pos--; return pos ? NULL : head; } |
e4bd8bce3 [NETFILTER]: nf_c... |
246 |
|
5d08ad440 [NETFILTER]: nf_c... |
247 |
static void *exp_seq_start(struct seq_file *seq, loff_t *pos) |
76507f69c [NETFILTER]: nf_c... |
248 |
__acquires(RCU) |
5d08ad440 [NETFILTER]: nf_c... |
249 |
{ |
7d0742da1 [NETFILTER]: nf_c... |
250 |
rcu_read_lock(); |
5d08ad440 [NETFILTER]: nf_c... |
251 252 |
return ct_expect_get_idx(seq, *pos); } |
e4bd8bce3 [NETFILTER]: nf_c... |
253 |
|
5d08ad440 [NETFILTER]: nf_c... |
254 255 256 257 |
static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos) { (*pos)++; return ct_expect_get_next(seq, v); |
e4bd8bce3 [NETFILTER]: nf_c... |
258 |
} |
5d08ad440 [NETFILTER]: nf_c... |
259 |
static void exp_seq_stop(struct seq_file *seq, void *v) |
76507f69c [NETFILTER]: nf_c... |
260 |
__releases(RCU) |
e4bd8bce3 [NETFILTER]: nf_c... |
261 |
{ |
7d0742da1 [NETFILTER]: nf_c... |
262 |
rcu_read_unlock(); |
e4bd8bce3 [NETFILTER]: nf_c... |
263 264 265 266 |
} static int exp_seq_show(struct seq_file *s, void *v) { |
5d08ad440 [NETFILTER]: nf_c... |
267 |
struct nf_conntrack_expect *exp; |
32948588a [NETFILTER]: nf_c... |
268 |
const struct hlist_node *n = v; |
5d08ad440 [NETFILTER]: nf_c... |
269 270 |
exp = hlist_entry(n, struct nf_conntrack_expect, hnode); |
e4bd8bce3 [NETFILTER]: nf_c... |
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
if (exp->tuple.src.l3num != AF_INET) return 0; if (exp->timeout.function) seq_printf(s, "%ld ", timer_pending(&exp->timeout) ? (long)(exp->timeout.expires - jiffies)/HZ : 0); else seq_printf(s, "- "); seq_printf(s, "proto=%u ", exp->tuple.dst.protonum); print_tuple(s, &exp->tuple, __nf_ct_l3proto_find(exp->tuple.src.l3num), __nf_ct_l4proto_find(exp->tuple.src.l3num, |
e905a9eda [NET] IPV4: Fix w... |
286 |
exp->tuple.dst.protonum)); |
e4bd8bce3 [NETFILTER]: nf_c... |
287 288 289 |
return seq_putc(s, ' '); } |
56b3d975b [NET]: Make all i... |
290 |
static const struct seq_operations exp_seq_ops = { |
e4bd8bce3 [NETFILTER]: nf_c... |
291 292 293 294 295 296 297 298 |
.start = exp_seq_start, .next = exp_seq_next, .stop = exp_seq_stop, .show = exp_seq_show }; static int exp_open(struct inode *inode, struct file *file) { |
5e6b29972 netfilter: netns ... |
299 300 |
return seq_open_net(inode, file, &exp_seq_ops, sizeof(struct ct_expect_iter_state)); |
e4bd8bce3 [NETFILTER]: nf_c... |
301 |
} |
9a32144e9 [PATCH] mark stru... |
302 |
static const struct file_operations ip_exp_file_ops = { |
e4bd8bce3 [NETFILTER]: nf_c... |
303 304 305 306 |
.owner = THIS_MODULE, .open = exp_open, .read = seq_read, .llseek = seq_lseek, |
5e6b29972 netfilter: netns ... |
307 |
.release = seq_release_net, |
e4bd8bce3 [NETFILTER]: nf_c... |
308 309 310 311 |
}; static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) { |
8e9df8018 netfilter: netns ... |
312 |
struct net *net = seq_file_net(seq); |
e4bd8bce3 [NETFILTER]: nf_c... |
313 314 315 316 |
int cpu; if (*pos == 0) return SEQ_START_TOKEN; |
0f23174aa cpumask: prepare ... |
317 |
for (cpu = *pos-1; cpu < nr_cpu_ids; ++cpu) { |
e4bd8bce3 [NETFILTER]: nf_c... |
318 319 320 |
if (!cpu_possible(cpu)) continue; *pos = cpu+1; |
8e9df8018 netfilter: netns ... |
321 |
return per_cpu_ptr(net->ct.stat, cpu); |
e4bd8bce3 [NETFILTER]: nf_c... |
322 323 324 325 326 327 328 |
} return NULL; } static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) { |
8e9df8018 netfilter: netns ... |
329 |
struct net *net = seq_file_net(seq); |
e4bd8bce3 [NETFILTER]: nf_c... |
330 |
int cpu; |
0f23174aa cpumask: prepare ... |
331 |
for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) { |
e4bd8bce3 [NETFILTER]: nf_c... |
332 333 334 |
if (!cpu_possible(cpu)) continue; *pos = cpu+1; |
8e9df8018 netfilter: netns ... |
335 |
return per_cpu_ptr(net->ct.stat, cpu); |
e4bd8bce3 [NETFILTER]: nf_c... |
336 337 338 339 340 341 342 343 344 345 346 |
} return NULL; } static void ct_cpu_seq_stop(struct seq_file *seq, void *v) { } static int ct_cpu_seq_show(struct seq_file *seq, void *v) { |
8e9df8018 netfilter: netns ... |
347 348 |
struct net *net = seq_file_net(seq); unsigned int nr_conntracks = atomic_read(&net->ct.count); |
32948588a [NETFILTER]: nf_c... |
349 |
const struct ip_conntrack_stat *st = v; |
e4bd8bce3 [NETFILTER]: nf_c... |
350 351 |
if (v == SEQ_START_TOKEN) { |
af740b2c8 netfilter: nf_con... |
352 353 |
seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete search_restart "); |
e4bd8bce3 [NETFILTER]: nf_c... |
354 355 356 357 |
return 0; } seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x " |
af740b2c8 netfilter: nf_con... |
358 359 |
"%08x %08x %08x %08x %08x %08x %08x %08x %08x ", |
e4bd8bce3 [NETFILTER]: nf_c... |
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
nr_conntracks, st->searched, st->found, st->new, st->invalid, st->ignore, st->delete, st->delete_list, st->insert, st->insert_failed, st->drop, st->early_drop, st->error, st->expect_new, st->expect_create, |
af740b2c8 netfilter: nf_con... |
376 377 |
st->expect_delete, st->search_restart |
e4bd8bce3 [NETFILTER]: nf_c... |
378 379 380 |
); return 0; } |
56b3d975b [NET]: Make all i... |
381 |
static const struct seq_operations ct_cpu_seq_ops = { |
e4bd8bce3 [NETFILTER]: nf_c... |
382 383 384 385 386 387 388 389 |
.start = ct_cpu_seq_start, .next = ct_cpu_seq_next, .stop = ct_cpu_seq_stop, .show = ct_cpu_seq_show, }; static int ct_cpu_seq_open(struct inode *inode, struct file *file) { |
8e9df8018 netfilter: netns ... |
390 391 |
return seq_open_net(inode, file, &ct_cpu_seq_ops, sizeof(struct seq_net_private)); |
e4bd8bce3 [NETFILTER]: nf_c... |
392 |
} |
9a32144e9 [PATCH] mark stru... |
393 |
static const struct file_operations ct_cpu_seq_fops = { |
e4bd8bce3 [NETFILTER]: nf_c... |
394 395 396 397 |
.owner = THIS_MODULE, .open = ct_cpu_seq_open, .read = seq_read, .llseek = seq_lseek, |
8e9df8018 netfilter: netns ... |
398 |
.release = seq_release_net, |
e4bd8bce3 [NETFILTER]: nf_c... |
399 |
}; |
5e6b29972 netfilter: netns ... |
400 |
static int __net_init ip_conntrack_net_init(struct net *net) |
e4bd8bce3 [NETFILTER]: nf_c... |
401 402 |
{ struct proc_dir_entry *proc, *proc_exp, *proc_stat; |
5e6b29972 netfilter: netns ... |
403 |
proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops); |
e4bd8bce3 [NETFILTER]: nf_c... |
404 405 |
if (!proc) goto err1; |
5e6b29972 netfilter: netns ... |
406 |
proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440, |
e4bd8bce3 [NETFILTER]: nf_c... |
407 408 409 |
&ip_exp_file_ops); if (!proc_exp) goto err2; |
8eeee8b15 [NETFILTER]: Repl... |
410 |
proc_stat = proc_create("ip_conntrack", S_IRUGO, |
5e6b29972 netfilter: netns ... |
411 |
net->proc_net_stat, &ct_cpu_seq_fops); |
e4bd8bce3 [NETFILTER]: nf_c... |
412 413 |
if (!proc_stat) goto err3; |
e4bd8bce3 [NETFILTER]: nf_c... |
414 415 416 |
return 0; err3: |
5e6b29972 netfilter: netns ... |
417 |
proc_net_remove(net, "ip_conntrack_expect"); |
e4bd8bce3 [NETFILTER]: nf_c... |
418 |
err2: |
5e6b29972 netfilter: netns ... |
419 |
proc_net_remove(net, "ip_conntrack"); |
e4bd8bce3 [NETFILTER]: nf_c... |
420 421 422 |
err1: return -ENOMEM; } |
5e6b29972 netfilter: netns ... |
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
static void __net_exit ip_conntrack_net_exit(struct net *net) { remove_proc_entry("ip_conntrack", net->proc_net_stat); proc_net_remove(net, "ip_conntrack_expect"); proc_net_remove(net, "ip_conntrack"); } static struct pernet_operations ip_conntrack_net_ops = { .init = ip_conntrack_net_init, .exit = ip_conntrack_net_exit, }; int __init nf_conntrack_ipv4_compat_init(void) { return register_pernet_subsys(&ip_conntrack_net_ops); } |
e4bd8bce3 [NETFILTER]: nf_c... |
439 440 |
void __exit nf_conntrack_ipv4_compat_fini(void) { |
5e6b29972 netfilter: netns ... |
441 |
unregister_pernet_subsys(&ip_conntrack_net_ops); |
e4bd8bce3 [NETFILTER]: nf_c... |
442 |
} |