0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007
0008 #include <linux/module.h>
0009 #include <linux/skbuff.h>
0010
0011 #include <linux/netfilter/x_tables.h>
0012 #include <linux/netfilter/nfnetlink_acct.h>
0013 #include <linux/netfilter/xt_nfacct.h>
0014
0015 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
0016 MODULE_DESCRIPTION("Xtables: match for the extended accounting infrastructure");
0017 MODULE_LICENSE("GPL");
0018 MODULE_ALIAS("ipt_nfacct");
0019 MODULE_ALIAS("ip6t_nfacct");
0020
0021 static bool nfacct_mt(const struct sk_buff *skb, struct xt_action_param *par)
0022 {
0023 int overquota;
0024 const struct xt_nfacct_match_info *info = par->targinfo;
0025
0026 nfnl_acct_update(skb, info->nfacct);
0027
0028 overquota = nfnl_acct_overquota(xt_net(par), info->nfacct);
0029
0030 return overquota != NFACCT_UNDERQUOTA;
0031 }
0032
0033 static int
0034 nfacct_mt_checkentry(const struct xt_mtchk_param *par)
0035 {
0036 struct xt_nfacct_match_info *info = par->matchinfo;
0037 struct nf_acct *nfacct;
0038
0039 nfacct = nfnl_acct_find_get(par->net, info->name);
0040 if (nfacct == NULL) {
0041 pr_info_ratelimited("accounting object `%s' does not exists\n",
0042 info->name);
0043 return -ENOENT;
0044 }
0045 info->nfacct = nfacct;
0046 return 0;
0047 }
0048
0049 static void
0050 nfacct_mt_destroy(const struct xt_mtdtor_param *par)
0051 {
0052 const struct xt_nfacct_match_info *info = par->matchinfo;
0053
0054 nfnl_acct_put(info->nfacct);
0055 }
0056
0057 static struct xt_match nfacct_mt_reg[] __read_mostly = {
0058 {
0059 .name = "nfacct",
0060 .revision = 0,
0061 .family = NFPROTO_UNSPEC,
0062 .checkentry = nfacct_mt_checkentry,
0063 .match = nfacct_mt,
0064 .destroy = nfacct_mt_destroy,
0065 .matchsize = sizeof(struct xt_nfacct_match_info),
0066 .usersize = offsetof(struct xt_nfacct_match_info, nfacct),
0067 .me = THIS_MODULE,
0068 },
0069 {
0070 .name = "nfacct",
0071 .revision = 1,
0072 .family = NFPROTO_UNSPEC,
0073 .checkentry = nfacct_mt_checkentry,
0074 .match = nfacct_mt,
0075 .destroy = nfacct_mt_destroy,
0076 .matchsize = sizeof(struct xt_nfacct_match_info_v1),
0077 .usersize = offsetof(struct xt_nfacct_match_info_v1, nfacct),
0078 .me = THIS_MODULE,
0079 },
0080 };
0081
0082 static int __init nfacct_mt_init(void)
0083 {
0084 return xt_register_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg));
0085 }
0086
0087 static void __exit nfacct_mt_exit(void)
0088 {
0089 xt_unregister_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg));
0090 }
0091
0092 module_init(nfacct_mt_init);
0093 module_exit(nfacct_mt_exit);