• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Expectation handling for nf_conntrack. */
2 
3 /* (C) 1999-2001 Paul `Rusty' Russell
4  * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5  * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
6  * (c) 2005-2012 Patrick McHardy <kaber@trash.net>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/types.h>
14 #include <linux/netfilter.h>
15 #include <linux/skbuff.h>
16 #include <linux/proc_fs.h>
17 #include <linux/seq_file.h>
18 #include <linux/stddef.h>
19 #include <linux/slab.h>
20 #include <linux/err.h>
21 #include <linux/percpu.h>
22 #include <linux/kernel.h>
23 #include <linux/jhash.h>
24 #include <linux/moduleparam.h>
25 #include <linux/export.h>
26 #include <net/net_namespace.h>
27 
28 #include <net/netfilter/nf_conntrack.h>
29 #include <net/netfilter/nf_conntrack_core.h>
30 #include <net/netfilter/nf_conntrack_expect.h>
31 #include <net/netfilter/nf_conntrack_helper.h>
32 #include <net/netfilter/nf_conntrack_tuple.h>
33 #include <net/netfilter/nf_conntrack_zones.h>
34 
35 unsigned int nf_ct_expect_hsize __read_mostly;
36 EXPORT_SYMBOL_GPL(nf_ct_expect_hsize);
37 
38 unsigned int nf_ct_expect_max __read_mostly;
39 
40 static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
41 
42 /* nf_conntrack_expect helper functions */
nf_ct_unlink_expect_report(struct nf_conntrack_expect * exp,u32 portid,int report)43 void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
44 				u32 portid, int report)
45 {
46 	struct nf_conn_help *master_help = nfct_help(exp->master);
47 	struct net *net = nf_ct_exp_net(exp);
48 
49 	NF_CT_ASSERT(master_help);
50 	NF_CT_ASSERT(!timer_pending(&exp->timeout));
51 
52 	hlist_del_rcu(&exp->hnode);
53 	net->ct.expect_count--;
54 
55 	hlist_del(&exp->lnode);
56 	master_help->expecting[exp->class]--;
57 
58 	nf_ct_expect_event_report(IPEXP_DESTROY, exp, portid, report);
59 	nf_ct_expect_put(exp);
60 
61 	NF_CT_STAT_INC(net, expect_delete);
62 }
63 EXPORT_SYMBOL_GPL(nf_ct_unlink_expect_report);
64 
nf_ct_expectation_timed_out(unsigned long ul_expect)65 static void nf_ct_expectation_timed_out(unsigned long ul_expect)
66 {
67 	struct nf_conntrack_expect *exp = (void *)ul_expect;
68 
69 	spin_lock_bh(&nf_conntrack_expect_lock);
70 	nf_ct_unlink_expect(exp);
71 	spin_unlock_bh(&nf_conntrack_expect_lock);
72 	nf_ct_expect_put(exp);
73 }
74 
nf_ct_expect_dst_hash(const struct nf_conntrack_tuple * tuple)75 static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple)
76 {
77 	unsigned int hash;
78 
79 	if (unlikely(!nf_conntrack_hash_rnd)) {
80 		init_nf_conntrack_hash_rnd();
81 	}
82 
83 	hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
84 		      (((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
85 		       (__force __u16)tuple->dst.u.all) ^ nf_conntrack_hash_rnd);
86 
87 	return reciprocal_scale(hash, nf_ct_expect_hsize);
88 }
89 
90 struct nf_conntrack_expect *
__nf_ct_expect_find(struct net * net,const struct nf_conntrack_zone * zone,const struct nf_conntrack_tuple * tuple)91 __nf_ct_expect_find(struct net *net,
92 		    const struct nf_conntrack_zone *zone,
93 		    const struct nf_conntrack_tuple *tuple)
94 {
95 	struct nf_conntrack_expect *i;
96 	unsigned int h;
97 
98 	if (!net->ct.expect_count)
99 		return NULL;
100 
101 	h = nf_ct_expect_dst_hash(tuple);
102 	hlist_for_each_entry_rcu(i, &net->ct.expect_hash[h], hnode) {
103 		if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) &&
104 		    nf_ct_zone_equal_any(i->master, zone))
105 			return i;
106 	}
107 	return NULL;
108 }
109 EXPORT_SYMBOL_GPL(__nf_ct_expect_find);
110 
111 /* Just find a expectation corresponding to a tuple. */
112 struct nf_conntrack_expect *
nf_ct_expect_find_get(struct net * net,const struct nf_conntrack_zone * zone,const struct nf_conntrack_tuple * tuple)113 nf_ct_expect_find_get(struct net *net,
114 		      const struct nf_conntrack_zone *zone,
115 		      const struct nf_conntrack_tuple *tuple)
116 {
117 	struct nf_conntrack_expect *i;
118 
119 	rcu_read_lock();
120 	i = __nf_ct_expect_find(net, zone, tuple);
121 	if (i && !atomic_inc_not_zero(&i->use))
122 		i = NULL;
123 	rcu_read_unlock();
124 
125 	return i;
126 }
127 EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);
128 
129 /* If an expectation for this connection is found, it gets delete from
130  * global list then returned. */
131 struct nf_conntrack_expect *
nf_ct_find_expectation(struct net * net,const struct nf_conntrack_zone * zone,const struct nf_conntrack_tuple * tuple)132 nf_ct_find_expectation(struct net *net,
133 		       const struct nf_conntrack_zone *zone,
134 		       const struct nf_conntrack_tuple *tuple)
135 {
136 	struct nf_conntrack_expect *i, *exp = NULL;
137 	unsigned int h;
138 
139 	if (!net->ct.expect_count)
140 		return NULL;
141 
142 	h = nf_ct_expect_dst_hash(tuple);
143 	hlist_for_each_entry(i, &net->ct.expect_hash[h], hnode) {
144 		if (!(i->flags & NF_CT_EXPECT_INACTIVE) &&
145 		    nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) &&
146 		    nf_ct_zone_equal_any(i->master, zone)) {
147 			exp = i;
148 			break;
149 		}
150 	}
151 	if (!exp)
152 		return NULL;
153 
154 	/* If master is not in hash table yet (ie. packet hasn't left
155 	   this machine yet), how can other end know about expected?
156 	   Hence these are not the droids you are looking for (if
157 	   master ct never got confirmed, we'd hold a reference to it
158 	   and weird things would happen to future packets). */
159 	if (!nf_ct_is_confirmed(exp->master))
160 		return NULL;
161 
162 	/* Avoid race with other CPUs, that for exp->master ct, is
163 	 * about to invoke ->destroy(), or nf_ct_delete() via timeout
164 	 * or early_drop().
165 	 *
166 	 * The atomic_inc_not_zero() check tells:  If that fails, we
167 	 * know that the ct is being destroyed.  If it succeeds, we
168 	 * can be sure the ct cannot disappear underneath.
169 	 */
170 	if (unlikely(nf_ct_is_dying(exp->master) ||
171 		     !atomic_inc_not_zero(&exp->master->ct_general.use)))
172 		return NULL;
173 
174 	if (exp->flags & NF_CT_EXPECT_PERMANENT) {
175 		atomic_inc(&exp->use);
176 		return exp;
177 	} else if (del_timer(&exp->timeout)) {
178 		nf_ct_unlink_expect(exp);
179 		return exp;
180 	}
181 	/* Undo exp->master refcnt increase, if del_timer() failed */
182 	nf_ct_put(exp->master);
183 
184 	return NULL;
185 }
186 
187 /* delete all expectations for this conntrack */
nf_ct_remove_expectations(struct nf_conn * ct)188 void nf_ct_remove_expectations(struct nf_conn *ct)
189 {
190 	struct nf_conn_help *help = nfct_help(ct);
191 	struct nf_conntrack_expect *exp;
192 	struct hlist_node *next;
193 
194 	/* Optimization: most connection never expect any others. */
195 	if (!help)
196 		return;
197 
198 	spin_lock_bh(&nf_conntrack_expect_lock);
199 	hlist_for_each_entry_safe(exp, next, &help->expectations, lnode) {
200 		if (del_timer(&exp->timeout)) {
201 			nf_ct_unlink_expect(exp);
202 			nf_ct_expect_put(exp);
203 		}
204 	}
205 	spin_unlock_bh(&nf_conntrack_expect_lock);
206 }
207 EXPORT_SYMBOL_GPL(nf_ct_remove_expectations);
208 
209 /* Would two expected things clash? */
expect_clash(const struct nf_conntrack_expect * a,const struct nf_conntrack_expect * b)210 static inline int expect_clash(const struct nf_conntrack_expect *a,
211 			       const struct nf_conntrack_expect *b)
212 {
213 	/* Part covered by intersection of masks must be unequal,
214 	   otherwise they clash */
215 	struct nf_conntrack_tuple_mask intersect_mask;
216 	int count;
217 
218 	intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
219 
220 	for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
221 		intersect_mask.src.u3.all[count] =
222 			a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
223 	}
224 
225 	return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask) &&
226 	       nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master));
227 }
228 
expect_matches(const struct nf_conntrack_expect * a,const struct nf_conntrack_expect * b)229 static inline int expect_matches(const struct nf_conntrack_expect *a,
230 				 const struct nf_conntrack_expect *b)
231 {
232 	return a->master == b->master && a->class == b->class &&
233 	       nf_ct_tuple_equal(&a->tuple, &b->tuple) &&
234 	       nf_ct_tuple_mask_equal(&a->mask, &b->mask) &&
235 	       nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master));
236 }
237 
238 /* Generally a bad idea to call this: could have matched already. */
nf_ct_unexpect_related(struct nf_conntrack_expect * exp)239 void nf_ct_unexpect_related(struct nf_conntrack_expect *exp)
240 {
241 	spin_lock_bh(&nf_conntrack_expect_lock);
242 	if (del_timer(&exp->timeout)) {
243 		nf_ct_unlink_expect(exp);
244 		nf_ct_expect_put(exp);
245 	}
246 	spin_unlock_bh(&nf_conntrack_expect_lock);
247 }
248 EXPORT_SYMBOL_GPL(nf_ct_unexpect_related);
249 
250 /* We don't increase the master conntrack refcount for non-fulfilled
251  * conntracks. During the conntrack destruction, the expectations are
252  * always killed before the conntrack itself */
nf_ct_expect_alloc(struct nf_conn * me)253 struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
254 {
255 	struct nf_conntrack_expect *new;
256 
257 	new = kmem_cache_alloc(nf_ct_expect_cachep, GFP_ATOMIC);
258 	if (!new)
259 		return NULL;
260 
261 	new->master = me;
262 	atomic_set(&new->use, 1);
263 	return new;
264 }
265 EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
266 
nf_ct_expect_init(struct nf_conntrack_expect * exp,unsigned int class,u_int8_t family,const union nf_inet_addr * saddr,const union nf_inet_addr * daddr,u_int8_t proto,const __be16 * src,const __be16 * dst)267 void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class,
268 		       u_int8_t family,
269 		       const union nf_inet_addr *saddr,
270 		       const union nf_inet_addr *daddr,
271 		       u_int8_t proto, const __be16 *src, const __be16 *dst)
272 {
273 	int len;
274 
275 	if (family == AF_INET)
276 		len = 4;
277 	else
278 		len = 16;
279 
280 	exp->flags = 0;
281 	exp->class = class;
282 	exp->expectfn = NULL;
283 	exp->helper = NULL;
284 	exp->tuple.src.l3num = family;
285 	exp->tuple.dst.protonum = proto;
286 
287 	if (saddr) {
288 		memcpy(&exp->tuple.src.u3, saddr, len);
289 		if (sizeof(exp->tuple.src.u3) > len)
290 			/* address needs to be cleared for nf_ct_tuple_equal */
291 			memset((void *)&exp->tuple.src.u3 + len, 0x00,
292 			       sizeof(exp->tuple.src.u3) - len);
293 		memset(&exp->mask.src.u3, 0xFF, len);
294 		if (sizeof(exp->mask.src.u3) > len)
295 			memset((void *)&exp->mask.src.u3 + len, 0x00,
296 			       sizeof(exp->mask.src.u3) - len);
297 	} else {
298 		memset(&exp->tuple.src.u3, 0x00, sizeof(exp->tuple.src.u3));
299 		memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3));
300 	}
301 
302 	if (src) {
303 		exp->tuple.src.u.all = *src;
304 		exp->mask.src.u.all = htons(0xFFFF);
305 	} else {
306 		exp->tuple.src.u.all = 0;
307 		exp->mask.src.u.all = 0;
308 	}
309 
310 	memcpy(&exp->tuple.dst.u3, daddr, len);
311 	if (sizeof(exp->tuple.dst.u3) > len)
312 		/* address needs to be cleared for nf_ct_tuple_equal */
313 		memset((void *)&exp->tuple.dst.u3 + len, 0x00,
314 		       sizeof(exp->tuple.dst.u3) - len);
315 
316 	exp->tuple.dst.u.all = *dst;
317 
318 #ifdef CONFIG_NF_NAT_NEEDED
319 	memset(&exp->saved_addr, 0, sizeof(exp->saved_addr));
320 	memset(&exp->saved_proto, 0, sizeof(exp->saved_proto));
321 #endif
322 }
323 EXPORT_SYMBOL_GPL(nf_ct_expect_init);
324 
nf_ct_expect_free_rcu(struct rcu_head * head)325 static void nf_ct_expect_free_rcu(struct rcu_head *head)
326 {
327 	struct nf_conntrack_expect *exp;
328 
329 	exp = container_of(head, struct nf_conntrack_expect, rcu);
330 	kmem_cache_free(nf_ct_expect_cachep, exp);
331 }
332 
nf_ct_expect_put(struct nf_conntrack_expect * exp)333 void nf_ct_expect_put(struct nf_conntrack_expect *exp)
334 {
335 	if (atomic_dec_and_test(&exp->use))
336 		call_rcu(&exp->rcu, nf_ct_expect_free_rcu);
337 }
338 EXPORT_SYMBOL_GPL(nf_ct_expect_put);
339 
nf_ct_expect_insert(struct nf_conntrack_expect * exp)340 static int nf_ct_expect_insert(struct nf_conntrack_expect *exp)
341 {
342 	struct nf_conn_help *master_help = nfct_help(exp->master);
343 	struct nf_conntrack_helper *helper;
344 	struct net *net = nf_ct_exp_net(exp);
345 	unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);
346 
347 	/* two references : one for hash insert, one for the timer */
348 	atomic_add(2, &exp->use);
349 
350 	hlist_add_head(&exp->lnode, &master_help->expectations);
351 	master_help->expecting[exp->class]++;
352 
353 	hlist_add_head_rcu(&exp->hnode, &net->ct.expect_hash[h]);
354 	net->ct.expect_count++;
355 
356 	setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
357 		    (unsigned long)exp);
358 	helper = rcu_dereference_protected(master_help->helper,
359 					   lockdep_is_held(&nf_conntrack_expect_lock));
360 	if (helper) {
361 		exp->timeout.expires = jiffies +
362 			helper->expect_policy[exp->class].timeout * HZ;
363 	}
364 	add_timer(&exp->timeout);
365 
366 	NF_CT_STAT_INC(net, expect_create);
367 	return 0;
368 }
369 
370 /* Race with expectations being used means we could have none to find; OK. */
evict_oldest_expect(struct nf_conn * master,struct nf_conntrack_expect * new)371 static void evict_oldest_expect(struct nf_conn *master,
372 				struct nf_conntrack_expect *new)
373 {
374 	struct nf_conn_help *master_help = nfct_help(master);
375 	struct nf_conntrack_expect *exp, *last = NULL;
376 
377 	hlist_for_each_entry(exp, &master_help->expectations, lnode) {
378 		if (exp->class == new->class)
379 			last = exp;
380 	}
381 
382 	if (last && del_timer(&last->timeout)) {
383 		nf_ct_unlink_expect(last);
384 		nf_ct_expect_put(last);
385 	}
386 }
387 
__nf_ct_expect_check(struct nf_conntrack_expect * expect)388 static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
389 {
390 	const struct nf_conntrack_expect_policy *p;
391 	struct nf_conntrack_expect *i;
392 	struct nf_conn *master = expect->master;
393 	struct nf_conn_help *master_help = nfct_help(master);
394 	struct nf_conntrack_helper *helper;
395 	struct net *net = nf_ct_exp_net(expect);
396 	struct hlist_node *next;
397 	unsigned int h;
398 	int ret = 0;
399 
400 	if (!master_help) {
401 		ret = -ESHUTDOWN;
402 		goto out;
403 	}
404 	h = nf_ct_expect_dst_hash(&expect->tuple);
405 	hlist_for_each_entry_safe(i, next, &net->ct.expect_hash[h], hnode) {
406 		if (expect_matches(i, expect)) {
407 			if (del_timer(&i->timeout)) {
408 				nf_ct_unlink_expect(i);
409 				nf_ct_expect_put(i);
410 				break;
411 			}
412 		} else if (expect_clash(i, expect)) {
413 			ret = -EBUSY;
414 			goto out;
415 		}
416 	}
417 	/* Will be over limit? */
418 	helper = rcu_dereference_protected(master_help->helper,
419 					   lockdep_is_held(&nf_conntrack_expect_lock));
420 	if (helper) {
421 		p = &helper->expect_policy[expect->class];
422 		if (p->max_expected &&
423 		    master_help->expecting[expect->class] >= p->max_expected) {
424 			evict_oldest_expect(master, expect);
425 			if (master_help->expecting[expect->class]
426 						>= p->max_expected) {
427 				ret = -EMFILE;
428 				goto out;
429 			}
430 		}
431 	}
432 
433 	if (net->ct.expect_count >= nf_ct_expect_max) {
434 		net_warn_ratelimited("nf_conntrack: expectation table full\n");
435 		ret = -EMFILE;
436 	}
437 out:
438 	return ret;
439 }
440 
nf_ct_expect_related_report(struct nf_conntrack_expect * expect,u32 portid,int report)441 int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
442 				u32 portid, int report)
443 {
444 	int ret;
445 
446 	spin_lock_bh(&nf_conntrack_expect_lock);
447 	ret = __nf_ct_expect_check(expect);
448 	if (ret < 0)
449 		goto out;
450 
451 	ret = nf_ct_expect_insert(expect);
452 	if (ret < 0)
453 		goto out;
454 	spin_unlock_bh(&nf_conntrack_expect_lock);
455 	nf_ct_expect_event_report(IPEXP_NEW, expect, portid, report);
456 	return ret;
457 out:
458 	spin_unlock_bh(&nf_conntrack_expect_lock);
459 	return ret;
460 }
461 EXPORT_SYMBOL_GPL(nf_ct_expect_related_report);
462 
463 #ifdef CONFIG_NF_CONNTRACK_PROCFS
464 struct ct_expect_iter_state {
465 	struct seq_net_private p;
466 	unsigned int bucket;
467 };
468 
ct_expect_get_first(struct seq_file * seq)469 static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
470 {
471 	struct net *net = seq_file_net(seq);
472 	struct ct_expect_iter_state *st = seq->private;
473 	struct hlist_node *n;
474 
475 	for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
476 		n = rcu_dereference(hlist_first_rcu(&net->ct.expect_hash[st->bucket]));
477 		if (n)
478 			return n;
479 	}
480 	return NULL;
481 }
482 
ct_expect_get_next(struct seq_file * seq,struct hlist_node * head)483 static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
484 					     struct hlist_node *head)
485 {
486 	struct net *net = seq_file_net(seq);
487 	struct ct_expect_iter_state *st = seq->private;
488 
489 	head = rcu_dereference(hlist_next_rcu(head));
490 	while (head == NULL) {
491 		if (++st->bucket >= nf_ct_expect_hsize)
492 			return NULL;
493 		head = rcu_dereference(hlist_first_rcu(&net->ct.expect_hash[st->bucket]));
494 	}
495 	return head;
496 }
497 
ct_expect_get_idx(struct seq_file * seq,loff_t pos)498 static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
499 {
500 	struct hlist_node *head = ct_expect_get_first(seq);
501 
502 	if (head)
503 		while (pos && (head = ct_expect_get_next(seq, head)))
504 			pos--;
505 	return pos ? NULL : head;
506 }
507 
exp_seq_start(struct seq_file * seq,loff_t * pos)508 static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
509 	__acquires(RCU)
510 {
511 	rcu_read_lock();
512 	return ct_expect_get_idx(seq, *pos);
513 }
514 
exp_seq_next(struct seq_file * seq,void * v,loff_t * pos)515 static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
516 {
517 	(*pos)++;
518 	return ct_expect_get_next(seq, v);
519 }
520 
exp_seq_stop(struct seq_file * seq,void * v)521 static void exp_seq_stop(struct seq_file *seq, void *v)
522 	__releases(RCU)
523 {
524 	rcu_read_unlock();
525 }
526 
exp_seq_show(struct seq_file * s,void * v)527 static int exp_seq_show(struct seq_file *s, void *v)
528 {
529 	struct nf_conntrack_expect *expect;
530 	struct nf_conntrack_helper *helper;
531 	struct hlist_node *n = v;
532 	char *delim = "";
533 
534 	expect = hlist_entry(n, struct nf_conntrack_expect, hnode);
535 
536 	if (expect->timeout.function)
537 		seq_printf(s, "%ld ", timer_pending(&expect->timeout)
538 			   ? (long)(expect->timeout.expires - jiffies)/HZ : 0);
539 	else
540 		seq_printf(s, "- ");
541 	seq_printf(s, "l3proto = %u proto=%u ",
542 		   expect->tuple.src.l3num,
543 		   expect->tuple.dst.protonum);
544 	print_tuple(s, &expect->tuple,
545 		    __nf_ct_l3proto_find(expect->tuple.src.l3num),
546 		    __nf_ct_l4proto_find(expect->tuple.src.l3num,
547 				       expect->tuple.dst.protonum));
548 
549 	if (expect->flags & NF_CT_EXPECT_PERMANENT) {
550 		seq_printf(s, "PERMANENT");
551 		delim = ",";
552 	}
553 	if (expect->flags & NF_CT_EXPECT_INACTIVE) {
554 		seq_printf(s, "%sINACTIVE", delim);
555 		delim = ",";
556 	}
557 	if (expect->flags & NF_CT_EXPECT_USERSPACE)
558 		seq_printf(s, "%sUSERSPACE", delim);
559 
560 	helper = rcu_dereference(nfct_help(expect->master)->helper);
561 	if (helper) {
562 		seq_printf(s, "%s%s", expect->flags ? " " : "", helper->name);
563 		if (helper->expect_policy[expect->class].name[0])
564 			seq_printf(s, "/%s",
565 				   helper->expect_policy[expect->class].name);
566 	}
567 
568 	seq_putc(s, '\n');
569 
570 	return 0;
571 }
572 
573 static const struct seq_operations exp_seq_ops = {
574 	.start = exp_seq_start,
575 	.next = exp_seq_next,
576 	.stop = exp_seq_stop,
577 	.show = exp_seq_show
578 };
579 
exp_open(struct inode * inode,struct file * file)580 static int exp_open(struct inode *inode, struct file *file)
581 {
582 	return seq_open_net(inode, file, &exp_seq_ops,
583 			sizeof(struct ct_expect_iter_state));
584 }
585 
586 static const struct file_operations exp_file_ops = {
587 	.owner   = THIS_MODULE,
588 	.open    = exp_open,
589 	.read    = seq_read,
590 	.llseek  = seq_lseek,
591 	.release = seq_release_net,
592 };
593 #endif /* CONFIG_NF_CONNTRACK_PROCFS */
594 
exp_proc_init(struct net * net)595 static int exp_proc_init(struct net *net)
596 {
597 #ifdef CONFIG_NF_CONNTRACK_PROCFS
598 	struct proc_dir_entry *proc;
599 
600 	proc = proc_create("nf_conntrack_expect", 0440, net->proc_net,
601 			   &exp_file_ops);
602 	if (!proc)
603 		return -ENOMEM;
604 #endif /* CONFIG_NF_CONNTRACK_PROCFS */
605 	return 0;
606 }
607 
exp_proc_remove(struct net * net)608 static void exp_proc_remove(struct net *net)
609 {
610 #ifdef CONFIG_NF_CONNTRACK_PROCFS
611 	remove_proc_entry("nf_conntrack_expect", net->proc_net);
612 #endif /* CONFIG_NF_CONNTRACK_PROCFS */
613 }
614 
615 module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0400);
616 
nf_conntrack_expect_pernet_init(struct net * net)617 int nf_conntrack_expect_pernet_init(struct net *net)
618 {
619 	int err = -ENOMEM;
620 
621 	net->ct.expect_count = 0;
622 	net->ct.expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize, 0);
623 	if (net->ct.expect_hash == NULL)
624 		goto err1;
625 
626 	err = exp_proc_init(net);
627 	if (err < 0)
628 		goto err2;
629 
630 	return 0;
631 err2:
632 	nf_ct_free_hashtable(net->ct.expect_hash, nf_ct_expect_hsize);
633 err1:
634 	return err;
635 }
636 
nf_conntrack_expect_pernet_fini(struct net * net)637 void nf_conntrack_expect_pernet_fini(struct net *net)
638 {
639 	exp_proc_remove(net);
640 	nf_ct_free_hashtable(net->ct.expect_hash, nf_ct_expect_hsize);
641 }
642 
nf_conntrack_expect_init(void)643 int nf_conntrack_expect_init(void)
644 {
645 	if (!nf_ct_expect_hsize) {
646 		nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
647 		if (!nf_ct_expect_hsize)
648 			nf_ct_expect_hsize = 1;
649 	}
650 	nf_ct_expect_max = nf_ct_expect_hsize * 4;
651 	nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
652 				sizeof(struct nf_conntrack_expect),
653 				0, 0, NULL);
654 	if (!nf_ct_expect_cachep)
655 		return -ENOMEM;
656 	return 0;
657 }
658 
nf_conntrack_expect_fini(void)659 void nf_conntrack_expect_fini(void)
660 {
661 	rcu_barrier(); /* Wait for call_rcu() before destroy */
662 	kmem_cache_destroy(nf_ct_expect_cachep);
663 }
664