Commit | Line | Data |
---|---|---|
1b402f7e | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
ceb98d03 PNA |
2 | /* |
3 | * (C) 2011 Pablo Neira Ayuso <pablo@netfilter.org> | |
4 | * (C) 2011 Intra2net AG <http://www.intra2net.com> | |
ceb98d03 | 5 | */ |
b2606644 FW |
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
7 | ||
ceb98d03 PNA |
8 | #include <linux/module.h> |
9 | #include <linux/skbuff.h> | |
10 | ||
11 | #include <linux/netfilter/x_tables.h> | |
12 | #include <linux/netfilter/nfnetlink_acct.h> | |
13 | #include <linux/netfilter/xt_nfacct.h> | |
14 | ||
15 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); | |
16 | MODULE_DESCRIPTION("Xtables: match for the extended accounting infrastructure"); | |
17 | MODULE_LICENSE("GPL"); | |
18 | MODULE_ALIAS("ipt_nfacct"); | |
19 | MODULE_ALIAS("ip6t_nfacct"); | |
20 | ||
21 | static bool nfacct_mt(const struct sk_buff *skb, struct xt_action_param *par) | |
22 | { | |
683399ed | 23 | int overquota; |
ceb98d03 PNA |
24 | const struct xt_nfacct_match_info *info = par->targinfo; |
25 | ||
26 | nfnl_acct_update(skb, info->nfacct); | |
27 | ||
cceae76e | 28 | overquota = nfnl_acct_overquota(xt_net(par), info->nfacct); |
683399ed MP |
29 | |
30 | return overquota == NFACCT_UNDERQUOTA ? false : true; | |
ceb98d03 PNA |
31 | } |
32 | ||
33 | static int | |
34 | nfacct_mt_checkentry(const struct xt_mtchk_param *par) | |
35 | { | |
36 | struct xt_nfacct_match_info *info = par->matchinfo; | |
37 | struct nf_acct *nfacct; | |
38 | ||
3499abb2 | 39 | nfacct = nfnl_acct_find_get(par->net, info->name); |
ceb98d03 | 40 | if (nfacct == NULL) { |
b2606644 FW |
41 | pr_info_ratelimited("accounting object `%s' does not exists\n", |
42 | info->name); | |
ceb98d03 PNA |
43 | return -ENOENT; |
44 | } | |
45 | info->nfacct = nfacct; | |
46 | return 0; | |
47 | } | |
48 | ||
49 | static void | |
50 | nfacct_mt_destroy(const struct xt_mtdtor_param *par) | |
51 | { | |
52 | const struct xt_nfacct_match_info *info = par->matchinfo; | |
53 | ||
54 | nfnl_acct_put(info->nfacct); | |
55 | } | |
56 | ||
89a26cd4 JR |
57 | static struct xt_match nfacct_mt_reg[] __read_mostly = { |
58 | { | |
59 | .name = "nfacct", | |
60 | .revision = 0, | |
61 | .family = NFPROTO_UNSPEC, | |
62 | .checkentry = nfacct_mt_checkentry, | |
63 | .match = nfacct_mt, | |
64 | .destroy = nfacct_mt_destroy, | |
65 | .matchsize = sizeof(struct xt_nfacct_match_info), | |
66 | .usersize = offsetof(struct xt_nfacct_match_info, nfacct), | |
67 | .me = THIS_MODULE, | |
68 | }, | |
69 | { | |
70 | .name = "nfacct", | |
71 | .revision = 1, | |
72 | .family = NFPROTO_UNSPEC, | |
73 | .checkentry = nfacct_mt_checkentry, | |
74 | .match = nfacct_mt, | |
75 | .destroy = nfacct_mt_destroy, | |
76 | .matchsize = sizeof(struct xt_nfacct_match_info_v1), | |
77 | .usersize = offsetof(struct xt_nfacct_match_info_v1, nfacct), | |
78 | .me = THIS_MODULE, | |
79 | }, | |
ceb98d03 PNA |
80 | }; |
81 | ||
82 | static int __init nfacct_mt_init(void) | |
83 | { | |
89a26cd4 | 84 | return xt_register_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg)); |
ceb98d03 PNA |
85 | } |
86 | ||
87 | static void __exit nfacct_mt_exit(void) | |
88 | { | |
89a26cd4 | 89 | xt_unregister_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg)); |
ceb98d03 PNA |
90 | } |
91 | ||
92 | module_init(nfacct_mt_init); | |
93 | module_exit(nfacct_mt_exit); |