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