mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-18 10:07:39 +07:00
netfilter: nft_limit: add stateful object type
Register a new limit stateful object type into the stateful object infrastructure. Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
6e32388756
commit
a691205571
@ -1282,7 +1282,8 @@ enum nft_ct_helper_attributes {
|
||||
#define NFT_OBJECT_COUNTER 1
|
||||
#define NFT_OBJECT_QUOTA 2
|
||||
#define NFT_OBJECT_CT_HELPER 3
|
||||
#define __NFT_OBJECT_MAX 4
|
||||
#define NFT_OBJECT_LIMIT 4
|
||||
#define __NFT_OBJECT_MAX 5
|
||||
#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
|
||||
|
||||
/**
|
||||
|
@ -229,14 +229,133 @@ static struct nft_expr_type nft_limit_type __read_mostly = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static void nft_limit_obj_pkts_eval(struct nft_object *obj,
|
||||
struct nft_regs *regs,
|
||||
const struct nft_pktinfo *pkt)
|
||||
{
|
||||
struct nft_limit_pkts *priv = nft_obj_data(obj);
|
||||
|
||||
if (nft_limit_eval(&priv->limit, priv->cost))
|
||||
regs->verdict.code = NFT_BREAK;
|
||||
}
|
||||
|
||||
static int nft_limit_obj_pkts_init(const struct nft_ctx *ctx,
|
||||
const struct nlattr * const tb[],
|
||||
struct nft_object *obj)
|
||||
{
|
||||
struct nft_limit_pkts *priv = nft_obj_data(obj);
|
||||
int err;
|
||||
|
||||
err = nft_limit_init(&priv->limit, tb);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->cost = div64_u64(priv->limit.nsecs, priv->limit.rate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nft_limit_obj_pkts_dump(struct sk_buff *skb,
|
||||
struct nft_object *obj,
|
||||
bool reset)
|
||||
{
|
||||
const struct nft_limit_pkts *priv = nft_obj_data(obj);
|
||||
|
||||
return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS);
|
||||
}
|
||||
|
||||
static struct nft_object_type nft_limit_obj_type;
|
||||
static const struct nft_object_ops nft_limit_obj_pkts_ops = {
|
||||
.type = &nft_limit_obj_type,
|
||||
.size = NFT_EXPR_SIZE(sizeof(struct nft_limit_pkts)),
|
||||
.init = nft_limit_obj_pkts_init,
|
||||
.eval = nft_limit_obj_pkts_eval,
|
||||
.dump = nft_limit_obj_pkts_dump,
|
||||
};
|
||||
|
||||
static void nft_limit_obj_bytes_eval(struct nft_object *obj,
|
||||
struct nft_regs *regs,
|
||||
const struct nft_pktinfo *pkt)
|
||||
{
|
||||
struct nft_limit *priv = nft_obj_data(obj);
|
||||
u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate);
|
||||
|
||||
if (nft_limit_eval(priv, cost))
|
||||
regs->verdict.code = NFT_BREAK;
|
||||
}
|
||||
|
||||
static int nft_limit_obj_bytes_init(const struct nft_ctx *ctx,
|
||||
const struct nlattr * const tb[],
|
||||
struct nft_object *obj)
|
||||
{
|
||||
struct nft_limit *priv = nft_obj_data(obj);
|
||||
|
||||
return nft_limit_init(priv, tb);
|
||||
}
|
||||
|
||||
static int nft_limit_obj_bytes_dump(struct sk_buff *skb,
|
||||
struct nft_object *obj,
|
||||
bool reset)
|
||||
{
|
||||
const struct nft_limit *priv = nft_obj_data(obj);
|
||||
|
||||
return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES);
|
||||
}
|
||||
|
||||
static struct nft_object_type nft_limit_obj_type;
|
||||
static const struct nft_object_ops nft_limit_obj_bytes_ops = {
|
||||
.type = &nft_limit_obj_type,
|
||||
.size = sizeof(struct nft_limit),
|
||||
.init = nft_limit_obj_bytes_init,
|
||||
.eval = nft_limit_obj_bytes_eval,
|
||||
.dump = nft_limit_obj_bytes_dump,
|
||||
};
|
||||
|
||||
static const struct nft_object_ops *
|
||||
nft_limit_obj_select_ops(const struct nft_ctx *ctx,
|
||||
const struct nlattr * const tb[])
|
||||
{
|
||||
if (!tb[NFTA_LIMIT_TYPE])
|
||||
return &nft_limit_obj_pkts_ops;
|
||||
|
||||
switch (ntohl(nla_get_be32(tb[NFTA_LIMIT_TYPE]))) {
|
||||
case NFT_LIMIT_PKTS:
|
||||
return &nft_limit_obj_pkts_ops;
|
||||
case NFT_LIMIT_PKT_BYTES:
|
||||
return &nft_limit_obj_bytes_ops;
|
||||
}
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static struct nft_object_type nft_limit_obj_type __read_mostly = {
|
||||
.select_ops = nft_limit_obj_select_ops,
|
||||
.type = NFT_OBJECT_LIMIT,
|
||||
.maxattr = NFTA_LIMIT_MAX,
|
||||
.policy = nft_limit_policy,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init nft_limit_module_init(void)
|
||||
{
|
||||
return nft_register_expr(&nft_limit_type);
|
||||
int err;
|
||||
|
||||
err = nft_register_obj(&nft_limit_obj_type);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = nft_register_expr(&nft_limit_type);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
return 0;
|
||||
err1:
|
||||
nft_unregister_obj(&nft_limit_obj_type);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit nft_limit_module_exit(void)
|
||||
{
|
||||
nft_unregister_expr(&nft_limit_type);
|
||||
nft_unregister_obj(&nft_limit_obj_type);
|
||||
}
|
||||
|
||||
module_init(nft_limit_module_init);
|
||||
@ -245,3 +364,4 @@ module_exit(nft_limit_module_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
|
||||
MODULE_ALIAS_NFT_EXPR("limit");
|
||||
MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_LIMIT);
|
||||
|
Loading…
Reference in New Issue
Block a user