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