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