mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 18:54:09 +08:00
netfilter: nft_ct: add byte/packet counter support
If the accounting extension isn't present, we'll return a counter value of 0. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
ce1e7989d9
commit
48f66c905a
@ -757,6 +757,8 @@ enum nft_ct_keys {
|
|||||||
NFT_CT_PROTO_SRC,
|
NFT_CT_PROTO_SRC,
|
||||||
NFT_CT_PROTO_DST,
|
NFT_CT_PROTO_DST,
|
||||||
NFT_CT_LABELS,
|
NFT_CT_LABELS,
|
||||||
|
NFT_CT_PKTS,
|
||||||
|
NFT_CT_BYTES,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <linux/netfilter/nf_tables.h>
|
#include <linux/netfilter/nf_tables.h>
|
||||||
#include <net/netfilter/nf_tables.h>
|
#include <net/netfilter/nf_tables.h>
|
||||||
#include <net/netfilter/nf_conntrack.h>
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_acct.h>
|
||||||
#include <net/netfilter/nf_conntrack_tuple.h>
|
#include <net/netfilter/nf_conntrack_tuple.h>
|
||||||
#include <net/netfilter/nf_conntrack_helper.h>
|
#include <net/netfilter/nf_conntrack_helper.h>
|
||||||
#include <net/netfilter/nf_conntrack_ecache.h>
|
#include <net/netfilter/nf_conntrack_ecache.h>
|
||||||
@ -30,6 +31,18 @@ struct nft_ct {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c,
|
||||||
|
enum nft_ct_keys k,
|
||||||
|
enum ip_conntrack_dir d)
|
||||||
|
{
|
||||||
|
if (d < IP_CT_DIR_MAX)
|
||||||
|
return k == NFT_CT_BYTES ? atomic64_read(&c[d].bytes) :
|
||||||
|
atomic64_read(&c[d].packets);
|
||||||
|
|
||||||
|
return nft_ct_get_eval_counter(c, k, IP_CT_DIR_ORIGINAL) +
|
||||||
|
nft_ct_get_eval_counter(c, k, IP_CT_DIR_REPLY);
|
||||||
|
}
|
||||||
|
|
||||||
static void nft_ct_get_eval(const struct nft_expr *expr,
|
static void nft_ct_get_eval(const struct nft_expr *expr,
|
||||||
struct nft_regs *regs,
|
struct nft_regs *regs,
|
||||||
const struct nft_pktinfo *pkt)
|
const struct nft_pktinfo *pkt)
|
||||||
@ -114,6 +127,17 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
|
|||||||
NF_CT_LABELS_MAX_SIZE - size);
|
NF_CT_LABELS_MAX_SIZE - size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case NFT_CT_BYTES: /* fallthrough */
|
||||||
|
case NFT_CT_PKTS: {
|
||||||
|
const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
|
||||||
|
u64 count = 0;
|
||||||
|
|
||||||
|
if (acct)
|
||||||
|
count = nft_ct_get_eval_counter(acct->counter,
|
||||||
|
priv->key, priv->dir);
|
||||||
|
memcpy(dest, &count, sizeof(count));
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -291,6 +315,13 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
|
len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
|
||||||
break;
|
break;
|
||||||
|
case NFT_CT_BYTES:
|
||||||
|
case NFT_CT_PKTS:
|
||||||
|
/* no direction? return sum of original + reply */
|
||||||
|
if (tb[NFTA_CT_DIRECTION] == NULL)
|
||||||
|
priv->dir = IP_CT_DIR_MAX;
|
||||||
|
len = sizeof(u64);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
@ -373,6 +404,13 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
|||||||
case NFT_CT_PROTO_DST:
|
case NFT_CT_PROTO_DST:
|
||||||
if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
|
if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
break;
|
||||||
|
case NFT_CT_BYTES:
|
||||||
|
case NFT_CT_PKTS:
|
||||||
|
if (priv->dir < IP_CT_DIR_MAX &&
|
||||||
|
nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
|
||||||
|
goto nla_put_failure;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user