1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * (C) 2011 Pablo Neira Ayuso <pablo@netfilter.org> |
4 | * (C) 2011 Intra2net AG <https://www.intra2net.com> |
5 | */ |
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
7 | |
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 | { |
23 | int overquota; |
24 | const struct xt_nfacct_match_info *info = par->targinfo; |
25 | |
26 | nfnl_acct_update(skb, nfacct: info->nfacct); |
27 | |
28 | overquota = nfnl_acct_overquota(net: xt_net(par), nfacct: info->nfacct); |
29 | |
30 | return overquota != NFACCT_UNDERQUOTA; |
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 | |
39 | nfacct = nfnl_acct_find_get(net: par->net, filter_name: info->name); |
40 | if (nfacct == NULL) { |
41 | pr_info_ratelimited("accounting object `%s' does not exists\n" , |
42 | info->name); |
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(acct: info->nfacct); |
55 | } |
56 | |
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 | }, |
80 | }; |
81 | |
82 | static int __init nfacct_mt_init(void) |
83 | { |
84 | return xt_register_matches(match: nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg)); |
85 | } |
86 | |
87 | static void __exit nfacct_mt_exit(void) |
88 | { |
89 | xt_unregister_matches(match: nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg)); |
90 | } |
91 | |
92 | module_init(nfacct_mt_init); |
93 | module_exit(nfacct_mt_exit); |
94 | |