Commit | Line | Data |
---|---|---|
c539f017 FW |
1 | /* |
2 | * test/set flag bits stored in conntrack extension area. | |
3 | * | |
4 | * (C) 2013 Astaro GmbH & Co KG | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | */ | |
10 | ||
11 | #include <linux/ctype.h> | |
12 | #include <linux/export.h> | |
13 | #include <linux/jhash.h> | |
14 | #include <linux/spinlock.h> | |
15 | #include <linux/types.h> | |
16 | #include <linux/slab.h> | |
17 | ||
18 | #include <net/netfilter/nf_conntrack_ecache.h> | |
19 | #include <net/netfilter/nf_conntrack_labels.h> | |
20 | ||
21 | static unsigned int label_bits(const struct nf_conn_labels *l) | |
22 | { | |
23 | unsigned int longs = l->words; | |
24 | return longs * BITS_PER_LONG; | |
25 | } | |
26 | ||
27 | bool nf_connlabel_match(const struct nf_conn *ct, u16 bit) | |
28 | { | |
29 | struct nf_conn_labels *labels = nf_ct_labels_find(ct); | |
30 | ||
31 | if (!labels) | |
32 | return false; | |
33 | ||
34 | return bit < label_bits(labels) && test_bit(bit, labels->bits); | |
35 | } | |
36 | EXPORT_SYMBOL_GPL(nf_connlabel_match); | |
37 | ||
38 | int nf_connlabel_set(struct nf_conn *ct, u16 bit) | |
39 | { | |
40 | struct nf_conn_labels *labels = nf_ct_labels_find(ct); | |
41 | ||
42 | if (!labels || bit >= label_bits(labels)) | |
43 | return -ENOSPC; | |
44 | ||
45 | if (test_bit(bit, labels->bits)) | |
46 | return 0; | |
47 | ||
48 | if (test_and_set_bit(bit, labels->bits)) | |
0ceabd83 | 49 | nf_conntrack_event_cache(IPCT_LABEL, ct); |
c539f017 FW |
50 | |
51 | return 0; | |
52 | } | |
53 | EXPORT_SYMBOL_GPL(nf_connlabel_set); | |
54 | ||
55 | static struct nf_ct_ext_type labels_extend __read_mostly = { | |
56 | .len = sizeof(struct nf_conn_labels), | |
57 | .align = __alignof__(struct nf_conn_labels), | |
58 | .id = NF_CT_EXT_LABELS, | |
59 | }; | |
60 | ||
61 | int nf_conntrack_labels_init(struct net *net) | |
62 | { | |
63 | if (net_eq(net, &init_net)) | |
64 | return nf_ct_extend_register(&labels_extend); | |
65 | return 0; | |
66 | } | |
67 | ||
68 | void nf_conntrack_labels_fini(struct net *net) | |
69 | { | |
70 | if (net_eq(net, &init_net)) | |
71 | nf_ct_extend_unregister(&labels_extend); | |
72 | } |