Accounting objects support in nft
Subsystems (2)
v2 cover Accounting objects support in nft
Hi,
With this patchset, we add accounting objects support to let us manipulate extended accounting objects.
Example of use in nft:
# nft add counter ip filter http-traffic # nft add counter ip filter https-traffic
# nft add rule ip filter output tcp dport 80 counter name http-traffic # nft add rule ip filter output tcp dport 443 counter name https-traffic
# nft delete counter ip filter https-traffic
# nft list table ip test
table ip filter {
counter http-traffic { pkts 779 bytes 99495}
counter https-traffic { pkts 189 bytes 37824}
chain output {
type filter hook output priority 0;
tcp dport http counter http-traffic
tcp dport https counter https-traffic
}
}It is difficult to reuse the existing code of nfacct because:
* nfacct does not have transation support transactions.
* We need something that integrated well to nf_tables.
There is a reset accounter support in the kernel-space and libnftnl. But not in nft-tool yet.
No quota support yet.
[Changes in v2]
* This deletes the acct module and uses the counter module.
* This renames from nft_counter to nft_counter_priv struct
* This uses _COUNTER_ names instead of _ACCT_ names in variables and functions
* Rename acct netlink attributes to named counter netlink attributes. The new names are NFTA_NAMED_CTR_XXX
* This limits NFT_CTR_MAXNAMELEN to 16
* This fixes some memory problems
These changes were sugguested by Pablo Neira and Patrick McHardy.
[kernel-nf]
Ana Rey (1):
netfilter: named counter: add support to counters in nftables
Ana Rey Botello (1):
netfilter: Rename from nft_counter to nft_counter_priv
include/net/netfilter/nf_tables.h | 49 +++ include/uapi/linux/netfilter/nf_tables.h | 34 +++ net/netfilter/nf_tables_api.c | 486 +++++++++++++++++++++++++++++- net/netfilter/nft_counter.c | 130 ++++++-- 4 files changed, 677 insertions(+), 22 deletions(-)
[libnftnl]
Ana Rey (1):
src: Add counters support
Ana Rey Botello (1):
tests: add unit tests for counters
examples/Makefile.am | 27 +- examples/nft-counter-add.c | 140 ++++++++ examples/nft-counter-del.c | 135 +++++++ examples/nft-counter-get.c | 137 +++++++ examples/nft-counter-reset.c | 123 +++++++ examples/nft-counters-get.c | 136 +++++++ examples/nft-rule-add.c | 2 +- examples/nft-rule-counter-add.c | 221 ++++++++++++ examples/nft-rule-get.c | 1 + include/buffer.h | 1 + include/libnftnl/Makefile.am | 3 +- include/libnftnl/counter.h | 97 +++++ include/libnftnl/expr.h | 1 + include/linux/netfilter/nf_tables.h | 33 ++ src/Makefile.am | 1 + src/counter.c | 671 +++++++++++++++++++++++++++++++++++ src/expr/counter.c | 48 ++- src/internal.h | 6 + src/libnftnl.map | 30 ++ tests/Makefile.am | 4 + tests/nft-counter-test.c | 86 +++++ tests/nft-expr_counter-test.c | 4 + 22 files changed, 1902 insertions(+), 5 deletions(-) create mode 100644 examples/nft-counter-add.c create mode 100644 examples/nft-counter-del.c create mode 100644 examples/nft-counter-get.c create mode 100644 examples/nft-counter-reset.c create mode 100644 examples/nft-counters-get.c create mode 100644 examples/nft-rule-counter-add.c create mode 100644 include/libnftnl/counter.h create mode 100644 src/counter.c create mode 100644 tests/nft-counter-test.c
[nft]
Ana Rey (2):
src: Add the accounter support
tests: regression: Add counters support
include/linux/netfilter/nf_tables.h | 32 +++++ include/mnl.h | 8 ++ include/netlink.h | 22 ++++ include/rule.h | 47 +++++++ include/statement.h | 1 + src/evaluate.c | 13 +- src/mnl.c | 119 ++++++++++++++++++ src/netlink.c | 235 +++++++++++++++++++++++++++++++++++ src/netlink_delinearize.c | 3 + src/netlink_linearize.c | 4 + src/parser_bison.y | 60 ++++++++- src/rule.c | 139 +++++++++++++++++++++ src/scanner.l | 1 + src/statement.c | 8 +- tests/regression/ip/counter.t | 15 +++ tests/regression/nft-test.py | 110 ++++++++++++++++ 16 files changed, 810 insertions(+), 7 deletions(-) create mode 100644 tests/regression/ip/counter.t
Signature · 1 line
1.7.10.4
PATCH v2 1/2 netfilter: Rename from nft_counter to nft_counter_priv
We need this change for the patch:
"netfilter: named counter: add support to accounters in nftables"
--- net/netfilter/nft_counter.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/netfilter/nft_counter.c +5 -5
@@ -17,7 +17,7 @@#include <linux/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h> -struct nft_counter { +struct nft_counter_priv {seqlock_t lock;u64 bytes;u64 packets;
@@ -27,7 +27,7 @@ static void nft_counter_eval(const struct nft_expr *expr,struct nft_data data[NFT_REG_MAX +1 ], const struct nft_pktinfo *pkt) { - struct nft_counter *priv = nft_expr_priv(expr); + struct nft_counter_priv *priv = nft_expr_priv(expr);write_seqlock_bh (&priv->lock); priv->bytes += pkt->skb->len;
@@ -37,7 +37,7 @@ static void nft_counter_eval(const struct nft_expr *expr,static int nft_counter_dump (struct sk_buff *skb,const struct nft_expr *expr) { -struct nft_counter *priv =nft_expr_priv (expr); +struct nft_counter_priv *priv =nft_expr_priv (expr);unsigned int seq;u64 bytes;u64 packets;
@@ -67,7 +67,7 @@ static int nft_counter_init(const struct nft_ctx *ctx,const struct nft_expr *expr, const struct nlattr * const tb[]) { - struct nft_counter *priv = nft_expr_priv(expr); + struct nft_counter_priv *priv = nft_expr_priv(expr);if (tb[NFTA_COUNTER_PACKETS ]) priv->packets =be64_to_cpu (nla_get_be64 (tb[NFTA_COUNTER_PACKETS ]));
@@ -81,7 +81,7 @@ static int nft_counter_init(const struct nft_ctx *ctx,static struct nft_expr_type nft_counter_type;static const struct nft_expr_ops nft_counter_ops = { .type = &nft_counter_type, - .size =NFT_EXPR_SIZE (sizeof (struct nft_counter )), + .size =NFT_EXPR_SIZE (sizeof (struct nft_counter_priv )), .eval = nft_counter_eval, .init = nft_counter_init, .dump = nft_counter_dump,
Signature · 1 line
1.7.10.4
PATCH v2 1/2 src: Add counters support
In reply to Ana Rey BotelloFrom: Ana Rey <[email protected]>
This adds userspace support to counters: support to counter objects and counter expression.
Moreover, this adds some examples to add/delete/get/reset the counter object and add rules using an existing counter.
Example of how to use those examples:
* Add a new counter:
# ./examples/nft-counter-add ip test counter1
# ./examples/nft-counter-get ip test counter1 default table test family ip counter counter1 packet 0 bytes 0
* Delete a counter:
# ./examples/nft-counter-del ip test counter1
* Add a rule using the counter expression.
# ./examples/nft-rule-add ip test output
* Reset the counter:
# ./examples/nft-counter-reset ip test counter1
The kernel support is added in the commit:
netfilter: named counter: add support to counters in nftables
--- examples/Makefile.am | 27 +- examples/nft-counter-add.c | 140 ++++++++ examples/nft-counter-del.c | 135 +++++++ examples/nft-counter-get.c | 137 +++++++ examples/nft-counter-reset.c | 123 +++++++ examples/nft-counters-get.c | 136 +++++++ examples/nft-rule-add.c | 2 +- examples/nft-rule-counter-add.c | 221 ++++++++++++ examples/nft-rule-get.c | 1 + include/buffer.h | 1 + include/libnftnl/Makefile.am | 3 +- include/libnftnl/counter.h | 97 +++++ include/libnftnl/expr.h | 1 + include/linux/netfilter/nf_tables.h | 33 ++ src/Makefile.am | 1 + src/counter.c | 671 +++++++++++++++++++++++++++++++++++ src/expr/counter.c | 48 ++- src/internal.h | 6 + src/libnftnl.map | 30 ++ 19 files changed, 1808 insertions(+), 5 deletions(-) create mode 100644 examples/nft-counter-add.c create mode 100644 examples/nft-counter-del.c create mode 100644 examples/nft-counter-get.c create mode 100644 examples/nft-counter-reset.c create mode 100644 examples/nft-counters-get.c create mode 100644 examples/nft-rule-counter-add.c create mode 100644 include/libnftnl/counter.h create mode 100644 src/counter.c
examples/Makefile.am +26 -1
@@ -22,7 +22,14 @@ check_PROGRAMS = nft-table-add \ nft-set-elem-get \ nft-set-elem-del \ nft-ruleset-get \ - nft-compat-get + nft-compat-get \ + nft-counter-add \ + nft-counter-get \ + nft-counters-get \ + nft-counter-reset \ + nft-rule-counter-add \ + nft-counter-del + nft_table_add_SOURCES = nft-table-add.c nft_table_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
@@ -92,3 +99,21 @@ nft_ruleset_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} nft_compat_get_SOURCES = nft-compat-get.c nft_compat_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} + +nft_counter_add_SOURCES = nft-counter-add.c +nft_counter_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} + +nft_counter_get_SOURCES = nft-counter-get.c +nft_counter_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} + +nft_counters_get_SOURCES = nft-counters-get.c +nft_counters_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} + +nft_counter_reset_SOURCES = nft-counter-reset.c +nft_counter_reset_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} + +nft_counter_del_SOURCES = nft-counter-del.c +nft_counter_del_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} + +nft_rule_counter_add_SOURCES = nft-rule-counter-add.c +nft_rule_counter_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
examples/nft-counter-add.c new file +140 -0
140 lines not on this page · raw message
examples/nft-counter-del.c new file +135 -0
135 lines not on this page · raw message
examples/nft-counter-get.c new file +137 -0
137 lines not on this page · raw message
examples/nft-counter-reset.c new file +123 -0
123 lines not on this page · raw message
examples/nft-counters-get.c new file +136 -0
136 lines not on this page · raw message
examples/nft-rule-add.c +1 -1
@@ -107,7 +107,7 @@ static struct nft_rule *setup_rule(uint8_t family, const char *table, offsetof(struct iphdr, protocol), sizeof(uint8_t));add_cmp (r,NFT_REG_1 ,NFT_CMP_EQ , &proto,sizeof (uint8_t )); - dport =htons (22 ); + dport =htons (80 );add_payload (r,NFT_PAYLOAD_TRANSPORT_HEADER ,NFT_REG_1 , offsetof(struct tcphdr , dest),sizeof (uint16_t ));add_cmp (r,NFT_REG_1 ,NFT_CMP_EQ , &dport,sizeof (uint16_t ));
examples/nft-rule-counter-add.c new file +221 -0
221 lines not on this page · raw message
examples/nft-rule-get.c +1 -0
@@ -19,6 +19,7 @@#include <libmnl/libmnl.h> #include <libnftnl/rule.h> +#include <libnftnl/expr.h> static int table_cb (const struct nlmsghdr *nlh,void *data) {
include/buffer.h +1 -0
@@ -37,6 +37,7 @@ int nft_buf_reg(struct nft_buf *b, int type, union nft_data_reg *reg,#define BYTES "bytes"#define CHAIN "chain"#define CODE "code" +#define COUNTER "counter"#define DATA "data"#define DIR "dir"#define DREG "dreg"
include/libnftnl/Makefile.am +2 -1
@@ -5,4 +5,5 @@ pkginclude_HEADERS = table.h \ set.h \ ruleset.h \ common.h \ - gen.h + gen.h \ + counter.h
include/libnftnl/counter.h new file +97 -0
97 lines not on this page · raw message
include/libnftnl/expr.h +1 -0
@@ -71,6 +71,7 @@ enum {enum {NFT_EXPR_CTR_PACKETS =NFT_RULE_EXPR_ATTR_BASE ,NFT_EXPR_CTR_BYTES , +NFT_EXPR_CTR_NAME , };enum {
include/linux/netfilter/nf_tables.h +33 -0
@@ -2,6 +2,7 @@#define _LINUX_NF_TABLES_H#define NFT_CHAIN_MAXNAMELEN 32 +#define NFT_CTR_MAXNAMELEN 16#define NFT_USERDATA_MAXLEN 256enum nft_registers {
@@ -53,6 +54,10 @@ enum nft_verdicts {* @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes) * @NFT_MSG_NEWGEN: announce a new generation, only for events (enum nft_gen_attributes) * @NFT_MSG_GETGEN: get the rule-set generation (enum nft_gen_attributes) +* @NFT_MSG_NEWCOUNTER: create a new counter (enum nft_counter_attributes) +* @NFT_MSG_GETCOUNTER: get a counter (enum nft_counter_attributes) +* @NFT_MSG_GETCOUNTER_ZERO: get a reset counter (enum nft_counter_attributes) +* @NFT_MSG_DELCOUNTER: delete a counter (enum nft_counter_attributes) */ enum nf_tables_msg_types {NFT_MSG_NEWTABLE ,
@@ -72,6 +77,10 @@ enum nf_tables_msg_types {NFT_MSG_DELSETELEM ,NFT_MSG_NEWGEN ,NFT_MSG_GETGEN , +NFT_MSG_NEWCOUNTER , +NFT_MSG_GETCOUNTER , +NFT_MSG_GETCOUNTER_ZERO , +NFT_MSG_DELCOUNTER , NFT_MSG_MAX, };
@@ -695,16 +704,40 @@ enum nft_limit_attributes {* * @NFTA_COUNTER_BYTES: number of bytes (NLA_U64) * @NFTA_COUNTER_PACKETS: number of packets (NLA_U64) +* @NFTA_COUNTER_NAME: name of the counter (NLA_STRING) */ enum nft_counter_attributes {NFTA_COUNTER_UNSPEC ,NFTA_COUNTER_BYTES ,NFTA_COUNTER_PACKETS , +NFTA_COUNTER_NAME , __NFTA_COUNTER_MAX };#define NFTA_COUNTER_MAX (__NFTA_COUNTER_MAX - 1)/** +* enum nft_named_counter_attributes - nf_tables named counter netlink attributes +* +* @NFTA_NAMED_CTR_NAME: named counter name (NLA_STRING) +* @NFTA_NAMED_CTR_TABLE: table name (NLA_STRING) +* @NFTA_NAMED_CTR_USE: number of references to this named counter (NLA_U32) +* @NFTA_NAMED_CTR_ID: uniquely identifies a named counter in a transaction (NLA_U32) +* @NFTA_NAMED_CTR_BYTES: number of bytes (NLA_U64) +* @NFTA_NAMED_CTR_PACKETS: number of packets (NLA_U64) +*/ +enum nft_named_counter_attributes { +NFTA_NAMED_CTR_UNSPEC , +NFTA_NAMED_CTR_NAME , +NFTA_NAMED_CTR_TABLE , +NFTA_NAMED_CTR_USE , +NFTA_NAMED_CTR_ID , +NFTA_NAMED_CTR_BYTES , +NFTA_NAMED_CTR_PACKETS , + __NFTA_NAMED_CTR_MAX +}; +#define NFTA_NAMED_CTR_MAX (__NFTA_NAMED_CTR_MAX - 1) + +/** * enum nft_log_attributes - nf_tables log expression netlink attributes * * @NFTA_LOG_GROUP: netlink group to send messages to (NLA_U32)
src/Makefile.am +1 -0
@@ -8,6 +8,7 @@ libnftnl_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnftnl.map \ libnftnl_la_SOURCES = utils.c \ buffer.c \ common.c \ + counter.c \ gen.c \ table.c \ chain.c \
src/counter.c new file +671 -0
671 lines not on this page · raw message
src/expr/counter.c +46 -2
127 lines not on this page · raw message
src/internal.h +6 -0
@@ -90,6 +90,9 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r,struct nft_set ;int nft_mxml_set_parse (mxml_node_t *tree,struct nft_set *s,struct nft_parse_err *err); +struct nft_counter ; +int nft_mxml_counter_parse (mxml_node_t *tree,struct nft_counter *counter, +struct nft_parse_err *err);#endif struct nft_set_list ;
@@ -139,6 +142,9 @@ int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree,struct nft_set ;int nft_jansson_parse_set (struct nft_set *s,json_t *tree,struct nft_parse_err *err); +struct nft_counter ; +int nft_jansson_parse_counter (struct nft_counter *counter,json_t *tree, +struct nft_parse_err *err);#endif const char *nft_family2str (uint32_t family);
src/libnftnl.map +30 -0
@@ -226,4 +226,34 @@ LIBNFTNL_1.2 { nft_gen_nlmsg_parse; nft_gen_snprintf; nft_gen_fprintf; + + nft_counter_alloc; + nft_counter_free; + nft_counter_attr_is_set; + nft_counter_attr_unset; + nft_counter_attr_set; + nft_counter_attr_get; + nft_counter_attr_set_u64; + nft_counter_attr_set_u32; + nft_counter_attr_set_str; + nft_counter_attr_get_u64; + nft_counter_attr_get_u32; + nft_counter_attr_get_str; + nft_counter_parse; + nft_counter_parse_file; + nft_counter_snprintf; + nft_counter_fprintf; + nft_counter_nlmsg_build_payload; + nft_counter_nlmsg_parse; + nft_counter_list_alloc; + nft_counter_list_free; + nft_counter_list_is_empty; + nft_counter_list_foreach; + nft_counter_list_add; + nft_counter_list_add_tail; + nft_counter_list_del; + nft_counter_list_iter_create; + nft_counter_list_iter_next; + nft_counter_list_iter_destroy; + } LIBNFTNL_1.1;
Signature · 1 line
1.7.10.4
PATCH v2 1/2 src: Add the accounter support
In reply to Ana Rey BotelloFrom: Ana Rey <[email protected]>
This adds userspace support to accounting objects and expression.
Example of use in nft:
# nft add counter ip filter http-traffic # nft add counter ip filter https-traffic # nft add rule ip filter output tcp dport 80 counter name http-traffic # nft add rule ip filter output tcp dport 443 counter name https-traffic # nft delete counter ip filter https-traffic
Generate Some traffic:
# nft list table ip test
table ip filter {
counter http-traffic { pkts 779 bytes 99495}
counter https-traffic { pkts 189 bytes 37824}
chain output {
type filter hook output priority 0;
tcp dport http counter http-traffic
tcp dport https counter https-traffic
}
}The kernel support is added in the commit:
"netfilter: named counter: add support to counters in nftables"
The libnftnl support is added in the commit:
"src: Add accounters support"
--- include/linux/netfilter/nf_tables.h | 32 +++++ include/mnl.h | 8 ++ include/netlink.h | 22 ++++ include/rule.h | 47 +++++++ include/statement.h | 1 + src/evaluate.c | 13 +- src/mnl.c | 119 ++++++++++++++++++ src/netlink.c | 235 +++++++++++++++++++++++++++++++++++ src/netlink_delinearize.c | 3 + src/netlink_linearize.c | 4 + src/parser_bison.y | 60 ++++++++- src/rule.c | 139 +++++++++++++++++++++ src/scanner.l | 1 + src/statement.c | 8 +- 14 files changed, 685 insertions(+), 7 deletions(-)
include/linux/netfilter/nf_tables.h +32 -0
@@ -53,6 +53,10 @@ enum nft_verdicts {* @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes) * @NFT_MSG_NEWGEN: announce a new generation, only for events (enum nft_gen_attributes) * @NFT_MSG_GETGEN: get the rule-set generation (enum nft_gen_attributes) +* @NFT_MSG_NEWCOUNTER: create a new counter (enum nft_counter_attributes) +* @NFT_MSG_GETCOUNTER: get a counter (enum nft_counter_attributes) +* @NFT_MSG_GETCOUNTER_ZERO: get a reset counter (enum nft_counter_attributes) +* @NFT_MSG_DELCOUNTER: delete a counter (enum nft_counter_attributes) */ enum nf_tables_msg_types {NFT_MSG_NEWTABLE ,
@@ -72,6 +76,10 @@ enum nf_tables_msg_types {NFT_MSG_DELSETELEM ,NFT_MSG_NEWGEN ,NFT_MSG_GETGEN , +NFT_MSG_NEWCOUNTER , +NFT_MSG_GETCOUNTER , +NFT_MSG_GETCOUNTER_ZERO , +NFT_MSG_DELCOUNTER , NFT_MSG_MAX, };
@@ -695,16 +703,40 @@ enum nft_limit_attributes {* * @NFTA_COUNTER_BYTES: number of bytes (NLA_U64) * @NFTA_COUNTER_PACKETS: number of packets (NLA_U64) +* @NFTA_COUNTER_NAME: name of the counter (NLA_STRING) */ enum nft_counter_attributes {NFTA_COUNTER_UNSPEC ,NFTA_COUNTER_BYTES ,NFTA_COUNTER_PACKETS , +NFTA_COUNTER_NAME , __NFTA_COUNTER_MAX };#define NFTA_COUNTER_MAX (__NFTA_COUNTER_MAX - 1)/** +* enum nft_named_counter_attributes - nf_tables named counter netlink attributes +* +* @NFTA_NAMED_CTR_NAME: named counter name (NLA_STRING) +* @NFTA_NAMED_CTR_TABLE: table name (NLA_STRING) +* @NFTA_NAMED_CTR_USE: number of references to this named counter (NLA_U32) +* @NFTA_NAMED_CTR_ID: uniquely identifies a named counter in a transaction (NLA_U32) +* @NFTA_NAMED_CTR_BYTES: number of bytes (NLA_U64) +* @NFTA_NAMED_CTR_PACKETS: number of packets (NLA_U64) +*/ +enum nft_named_counter_attributes { +NFTA_NAMED_CTR_UNSPEC , +NFTA_NAMED_CTR_NAME , +NFTA_NAMED_CTR_TABLE , +NFTA_NAMED_CTR_USE , +NFTA_NAMED_CTR_ID , +NFTA_NAMED_CTR_BYTES , +NFTA_NAMED_CTR_PACKETS , + __NFTA_NAMED_CTR_MAX +}; +#define NFTA_NAMED_CTR_MAX (__NFTA_NAMED_CTR_MAX - 1) + +/** * enum nft_log_attributes - nf_tables log expression netlink attributes * * @NFTA_LOG_GROUP: netlink group to send messages to (NLA_U32)
include/mnl.h +8 -0
@@ -34,6 +34,14 @@ int mnl_nft_rule_delete(struct mnl_socket *nf_sock, struct nft_rule *r,struct nft_rule_list *mnl_nft_rule_dump (struct mnl_socket *nf_sock,int family); +int mnl_nft_counter_batch_add (struct nft_counter *nlc, +unsigned int flags,uint32_t seq); +int mnl_nft_counter_batch_del (struct nft_counter *nlc, +unsigned int flags,uint32_t seq); +int mnl_nft_counter_get (struct mnl_socket *nf_sock,struct nft_counter *nlc); +struct nft_counter_list *mnl_nft_counter_dump (struct mnl_socket *nf_sock, +int family,const char *table); +int mnl_nft_chain_add (struct mnl_socket *nf_sock,struct nft_chain *nlc,unsigned int flags); int mnl_nft_chain_batch_add(struct nft_chain *nlc,
include/netlink.h +22 -0
@@ -21,6 +21,7 @@ extern const struct location netlink_location;* @msgs: message queue * @list: list of parsed rules/chains/tables * @set: current set +* @counter: current counter * @data: pointer to pass data to callback * @seqnum: sequence number */
@@ -28,6 +29,7 @@ struct netlink_ctx {struct list_head *msgs;struct list_head list;struct set *set; +struct counter *counter;const void *data;uint32_t seqnum;bool batch_supported;
@@ -38,6 +40,7 @@ extern struct nft_chain *alloc_nft_chain(const struct handle *h);extern struct nft_rule *alloc_nft_rule (const struct handle *h);extern struct nft_rule_expr *alloc_nft_expr (const char *name);extern struct nft_set *alloc_nft_set (const struct handle *h); +extern struct nft_counter *alloc_nft_counter (const struct handle *h);struct nft_data_linearize {uint32_t len;
@@ -84,6 +87,24 @@ extern int netlink_del_rule_batch(struct netlink_ctx *ctx,const struct handle *h, const struct location *loc); +extern int netlink_add_counter (struct netlink_ctx *ctx,const struct handle *h, +struct counter *counter); +extern int netlink_rename_counter (struct netlink_ctx *ctx, +const struct handle *h, +const struct location *loc,const char *name); +extern int netlink_delete_counter (struct netlink_ctx *ctx, +const struct handle *h, +const struct location *loc); +extern int netlink_list_counters (struct netlink_ctx *ctx, +const struct handle *h, +const struct location *loc); +extern int netlink_get_counter (struct netlink_ctx *ctx,const struct handle *h, +const struct location *loc); +extern int netlink_flush_counter (struct netlink_ctx *ctx, +const struct handle *h, +const struct location *loc); + +extern int netlink_add_chain (struct netlink_ctx *ctx,const struct handle *h,const struct location *loc,const struct chain *chain,bool excl);
@@ -135,6 +156,7 @@ extern void netlink_dump_chain(struct nft_chain *nlc);extern void netlink_dump_rule (struct nft_rule *nlr);extern void netlink_dump_expr (struct nft_rule_expr *nle);extern void netlink_dump_set (struct nft_set *nls); +extern void netlink_dump_counter (struct nft_counter *nlc);extern int netlink_batch_send (struct list_head *err_list);
include/rule.h +47 -0
113 lines not on this page · raw message
include/statement.h +1 -0
@@ -13,6 +13,7 @@ extern struct stmt *verdict_stmt_alloc(const struct location *loc,struct counter_stmt {uint64_t packets;uint64_t bytes; +const char *name; };extern struct stmt *counter_stmt_alloc (const struct location *loc);
src/evaluate.c +11 -2
@@ -1824,6 +1824,7 @@ static int table_evaluate(struct eval_ctx *ctx, struct table *table)if (set_evaluate (ctx, set) <0 )return -1 ; } +list_for_each_entry (chain, &table->chains, list) {handle_merge (&chain->handle, &table->handle);if (chain_evaluate (ctx, chain) <0 )
@@ -1844,6 +1845,8 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd)case CMD_OBJ_RULE :handle_merge (&cmd->rule->handle, &cmd->handle);return rule_evaluate (ctx, cmd->rule); +case CMD_OBJ_COUNTER : +return 0 ;case CMD_OBJ_CHAIN :if (cmd->data ==NULL )return 0 ;
@@ -1863,6 +1866,7 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd)case CMD_OBJ_SETELEM :return setelem_evaluate (ctx, &cmd->expr);case CMD_OBJ_SET : +case CMD_OBJ_COUNTER :case CMD_OBJ_RULE :case CMD_OBJ_CHAIN :case CMD_OBJ_TABLE :
@@ -1892,13 +1896,16 @@ static uint32_t monitor_flags[CMD_MONITOR_EVENT_MAX][CMD_MONITOR_OBJ_MAX] = { (1 << NFT_MSG_DELSET), [CMD_MONITOR_OBJ_ELEMS ] = (1 <<NFT_MSG_NEWSETELEM ) | (1 << NFT_MSG_DELSETELEM), + [CMD_MONITOR_OBJ_COUNTERS ] = (1 <<NFT_MSG_NEWCOUNTER ) | + (1 << NFT_MSG_DELCOUNTER), }, [CMD_MONITOR_EVENT_NEW] = { [CMD_MONITOR_OBJ_ANY ] = (1 <<NFT_MSG_NEWTABLE ) | (1 <<NFT_MSG_NEWCHAIN ) | (1 <<NFT_MSG_NEWRULE ) | (1 <<NFT_MSG_NEWSET ) | - (1 << NFT_MSG_NEWSETELEM), + (1 <<NFT_MSG_NEWSETELEM )| + (1 << NFT_MSG_NEWCOUNTER), [CMD_MONITOR_OBJ_TABLES] = (1 << NFT_MSG_NEWTABLE), [CMD_MONITOR_OBJ_CHAINS] = (1 << NFT_MSG_NEWCHAIN), [CMD_MONITOR_OBJ_RULES] = (1 << NFT_MSG_NEWRULE),
@@ -1910,12 +1917,14 @@ static uint32_t monitor_flags[CMD_MONITOR_EVENT_MAX][CMD_MONITOR_OBJ_MAX] = { (1 <<NFT_MSG_DELCHAIN ) | (1 <<NFT_MSG_DELRULE ) | (1 <<NFT_MSG_DELSET ) | - (1 << NFT_MSG_DELSETELEM), + (1 <<NFT_MSG_DELSETELEM )| + (1 << NFT_MSG_DELCOUNTER), [CMD_MONITOR_OBJ_TABLES] = (1 << NFT_MSG_DELTABLE), [CMD_MONITOR_OBJ_CHAINS] = (1 << NFT_MSG_DELCHAIN), [CMD_MONITOR_OBJ_RULES] = (1 << NFT_MSG_DELRULE), [CMD_MONITOR_OBJ_SETS] = (1 << NFT_MSG_DELSET), [CMD_MONITOR_OBJ_ELEMS] = (1 << NFT_MSG_DELSETELEM), + [CMD_MONITOR_OBJ_COUNTERS] = (1 << NFT_MSG_DELCOUNTER), }, };
src/mnl.c +119 -0
131 lines not on this page · raw message
src/netlink.c +235 -0
277 lines not on this page · raw message
src/netlink_delinearize.c +3 -0
@@ -445,6 +445,7 @@ static void netlink_parse_ct(struct netlink_parse_ctx *ctx,netlink_parse_ct_stmt (ctx, loc, nle); } +static void netlink_parse_counter (struct netlink_parse_ctx *ctx,const struct location *loc,const struct nft_rule_expr *nle)
@@ -456,6 +457,8 @@ static void netlink_parse_counter(struct netlink_parse_ctx *ctx,nft_rule_expr_get_u64 (nle,NFT_EXPR_CTR_PACKETS ); stmt->counter.bytes =nft_rule_expr_get_u64 (nle,NFT_EXPR_CTR_BYTES ); + stmt->counter.name = +nft_rule_expr_get_str (nle,NFT_EXPR_CTR_NAME );list_add_tail (&stmt->list, &ctx->rule->stmts); }
src/netlink_linearize.c +4 -0
@@ -553,6 +553,10 @@ static void netlink_gen_counter_stmt(struct netlink_linearize_ctx *ctx,nft_rule_expr_set_u64 (nle,NFT_EXPR_CTR_BYTES , stmt->counter.bytes); } +if (stmt->counter.name) { +nft_rule_expr_set_str (nle,NFT_EXPR_CTR_NAME , + stmt->counter.name); + }nft_rule_add_expr (ctx->nlr, nle); }
src/parser_bison.y +57 -3
144 lines not on this page · raw message
src/rule.c +139 -0
252 lines not on this page · raw message
src/scanner.l +1 -0
@@ -279,6 +279,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "counter" { return COUNTER; } "packets" { return PACKETS; } "bytes" { return BYTES; } +"name" { return NAME; } "log" { return LOG; } "prefix" { return PREFIX; }
src/statement.c +6 -2
@@ -105,8 +105,12 @@ struct stmt *verdict_stmt_alloc(const struct location *loc, struct expr *expr)static void counter_stmt_print (const struct stmt *stmt) { -printf ("counter packets %" PRIu64" bytes %" PRIu64, - stmt->counter.packets, stmt->counter.bytes); +printf ("counter " ); +if (stmt->counter.name) +printf ("%s" , stmt->counter.name); +else +printf ("packets %" PRIu64" bytes %" PRIu64, + stmt->counter.packets, stmt->counter.bytes); }static const struct stmt_ops counter_stmt_ops = {
Signature · 1 line
1.7.10.4
PATCH v2 2/2 netfilter: named counter: add support to counters in nftables
In reply to Ana Rey BotelloFrom: Ana Rey <[email protected]>
This adds counter objects support to allow us to manipulate the nftables's extended accounting intraestructure.
Example of use in nft:
# nft add counter ip filter http-traffic # nft add counter ip filter https-traffic # nft add rule ip filter output tcp dport 80 counter name http-traffic # nft add rule ip filter output tcp dport 443 counter name https-traffic # nft delete counter ip filter https-traffic
Generate Some traffic:
# nft list table ip test
table ip filter {
counter http-traffic { pkts 779 bytes 99495}
counter https-traffic { pkts 189 bytes 37824}
chain output {
type filter hook output priority 0;
tcp dport http counter http-traffic
tcp dport https counter https-traffic
}
}--- include/net/netfilter/nf_tables.h | 49 +++ include/uapi/linux/netfilter/nf_tables.h | 34 +++ net/netfilter/nf_tables_api.c | 486 +++++++++++++++++++++++++++++- net/netfilter/nft_counter.c | 128 ++++++-- 4 files changed, 676 insertions(+), 21 deletions(-)
include/net/netfilter/nf_tables.h +49 -0
@@ -408,6 +408,16 @@ struct nft_trans {char data[0 ]; }; +struct nft_trans_counter { +struct nft_counter *counter; +u32 counter_id; +}; + +#define nft_trans_counter (trans) \ + (((struct nft_trans_counter *)trans->data)->counter) +#define nft_trans_counter_id (trans) \ + (((struct nft_trans_counter *)trans->data)->counter_id) +struct nft_trans_rule {struct nft_rule *rule; };
@@ -572,6 +582,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt,* @list: used internally * @chains: chains in the table * @sets: sets in the table +* @counters: counters in the table * @hgenerator: handle generator state * @use: number of chain references to this table * @flags: table flag (see enum nft_table_flags)
@@ -581,6 +592,7 @@ struct nft_table {struct list_head list;struct list_head chains;struct list_head sets; +struct list_head counters;u64 hgenerator;u32 use;u16 flags;
@@ -639,6 +651,43 @@ void nft_unregister_chain_type(const struct nf_chain_type *);int nft_register_expr (struct nft_expr_type *);void nft_unregister_expr (struct nft_expr_type *); +/** +* struct nft_counter_priv - nf_tables counter_priv instance +* +* @pkts: number of packets +* @bytes: number of bytes +*/ +struct nft_counter_priv { +seqlock_t lock; +u64 bytes; +u64 packets; +}; + +/** +* struct nft_counter - nf_tables counter instance +* +* @list: table counter list node +* @name: name of the counter +* @counter: nft_priv_counter +* @bytes: number of bytes +* @use: number of rule references to this counter +* @flags: counter flags +*/ +struct nft_counter { +struct list_head list; +char name[NFT_CTR_MAXNAMELEN ]; +struct nft_counter_priv counter; +u32 use:31 , + flags:1 ; +}; + +struct nft_counter *nft_counter_lookup (const struct nft_ctx *ctx, +const char *counter_name); +struct nft_counter *nf_tables_counter_lookup (const struct nft_table *table, +const struct nlattr *nla); +void nft_counter_put (struct nft_counter *counter); +int nft_counter_get (struct nft_counter *counter); +#define nft_dereference (p) \ nfnl_dereference(p, NFNL_SUBSYS_NFTABLES)
include/uapi/linux/netfilter/nf_tables.h +34 -0
@@ -2,6 +2,7 @@#define _LINUX_NF_TABLES_H#define NFT_CHAIN_MAXNAMELEN 32 +#define NFT_CTR_MAXNAMELEN 16#define NFT_USERDATA_MAXLEN 256enum nft_registers {
@@ -53,6 +54,10 @@ enum nft_verdicts {* @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes) * @NFT_MSG_NEWGEN: announce a new generation, only for events (enum nft_gen_attributes) * @NFT_MSG_GETGEN: get the rule-set generation (enum nft_gen_attributes) +* @NFT_MSG_NEWCOUNTER: create a new counter (enum nft_counter_attributes) +* @NFT_MSG_GETCOUNTER: get a counter (enum nft_counter_attributes) +* @NFT_MSG_GETCOUNTER_ZERO: get a reset counter (enum nft_counter_attributes) +* @NFT_MSG_DELCOUNTER: delete a counter (enum nft_counter_attributes) */ enum nf_tables_msg_types {NFT_MSG_NEWTABLE ,
@@ -72,6 +77,10 @@ enum nf_tables_msg_types {NFT_MSG_DELSETELEM ,NFT_MSG_NEWGEN ,NFT_MSG_GETGEN , +NFT_MSG_NEWCOUNTER , +NFT_MSG_GETCOUNTER , +NFT_MSG_GETCOUNTER_ZERO , +NFT_MSG_DELCOUNTER , NFT_MSG_MAX, };
@@ -695,16 +704,40 @@ enum nft_limit_attributes {* * @NFTA_COUNTER_BYTES: number of bytes (NLA_U64) * @NFTA_COUNTER_PACKETS: number of packets (NLA_U64) +* @NFTA_COUNTER_NAME: name of the counter (NLA_STRING) */ enum nft_counter_attributes {NFTA_COUNTER_UNSPEC ,NFTA_COUNTER_BYTES ,NFTA_COUNTER_PACKETS , +NFTA_COUNTER_NAME , __NFTA_COUNTER_MAX };#define NFTA_COUNTER_MAX (__NFTA_COUNTER_MAX - 1)/** +* enum nft_named_counter_attributes - nf_tables named counter netlink attributes +* +* @NFTA_NAMED_CTR_NAME: named counter name (NLA_STRING) +* @NFTA_NAMED_CTR_TABLE: table name (NLA_STRING) +* @NFTA_NAMED_CTR_USE: number of references to this named counter (NLA_U32) +* @NFTA_NAMED_CTR_ID: uniquely identifies a named counter in a transaction (NLA_U32) +* @NFTA_NAMED_CTR_BYTES: number of bytes (NLA_U64) +* @NFTA_NAMED_CTR_PACKETS: number of packets (NLA_U64) +*/ +enum nft_named_counter_attributes { +NFTA_NAMED_CTR_UNSPEC , +NFTA_NAMED_CTR_NAME , +NFTA_NAMED_CTR_TABLE , +NFTA_NAMED_CTR_USE , +NFTA_NAMED_CTR_ID , +NFTA_NAMED_CTR_BYTES , +NFTA_NAMED_CTR_PACKETS , + __NFTA_NAMED_CTR_MAX +}; +#define NFTA_NAMED_CTR_MAX (__NFTA_NAMED_CTR_MAX - 1) + +/** * enum nft_log_attributes - nf_tables log expression netlink attributes * * @NFTA_LOG_GROUP: netlink group to send messages to (NLA_U32)
@@ -867,4 +900,5 @@ enum nft_gen_attributes { };#define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1) +#endif /* _LINUX_NF_TABLES_H */
net/netfilter/nf_tables_api.c +482 -4
570 lines not on this page · raw message
net/netfilter/nft_counter.c +111 -17
171 lines not on this page · raw message
Signature · 1 line
1.7.10.4
PATCH v2 2/2 tests: add unit tests for counters
In reply to Ana Rey BotelloThis adds unit test for counters and updates the expr-counter test.
--- tests/Makefile.am | 4 ++ tests/nft-counter-test.c | 86 +++++++++++++++++++++++++++++++++++++++++ tests/nft-expr_counter-test.c | 4 ++ 3 files changed, 94 insertions(+) create mode 100644 tests/nft-counter-test.c
tests/Makefile.am +4 -0
@@ -9,6 +9,7 @@ check_PROGRAMS = nft-parsing-test \ nft-chain-test \ nft-rule-test \ nft-set-test \ + nft-counter-test \ nft-expr_bitwise-test \ nft-expr_byteorder-test \ nft-expr_counter-test \
@@ -44,6 +45,9 @@ nft_rule_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} nft_set_test_SOURCES = nft-set-test.c nft_set_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} +nft_counter_test_SOURCES = nft-counter-test.c +nft_counter_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} + nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c nft_expr_bitwise_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
tests/nft-counter-test.c new file +86 -0
86 lines not on this page · raw message
tests/nft-expr_counter-test.c +4 -0
@@ -36,6 +36,9 @@ static void cmp_nft_rule_expr(struct nft_rule_expr *rule_a,if (nft_rule_expr_get_u64 (rule_a,NFT_EXPR_CTR_PACKETS ) !=nft_rule_expr_get_u64 (rule_b,NFT_EXPR_CTR_PACKETS ))print_err ("Expr NFT_EXPR_CTR_PACKETS mismatches" ); +if (strcmp (nft_rule_expr_get_str (rule_a,NFT_EXPR_CTR_NAME ), +nft_rule_expr_get_str (rule_b,NFT_EXPR_CTR_NAME )) !=0 ) +print_err ("Expr NFT_EXPR_CTR_NAME mismatches" ); }int main (int argc,char *argv[])
@@ -56,6 +59,7 @@ int main(int argc, char *argv[])if (ex ==NULL )print_err ("OOM" ); +nft_rule_expr_set_str (ex,NFT_EXPR_CTR_NAME ,"counter-name" );nft_rule_expr_set_u64 (ex,NFT_EXPR_CTR_BYTES ,0x123456789abcdef0 );nft_rule_expr_set_u64 (ex,NFT_EXPR_CTR_PACKETS ,0x123456789abcdef0 );nft_rule_add_expr (a, ex);
Signature · 1 line
1.7.10.4
PATCH v2 2/2 tests: regression: Add counters support
In reply to Ana Rey BotelloFrom: Ana Rey <[email protected]>
This adds the accounter support into this regression test and the test file ip/counter.c.
--- tests/regression/ip/counter.t | 15 ++++++ tests/regression/nft-test.py | 110 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 tests/regression/ip/counter.t
tests/regression/ip/counter.t new file +15 -0
@@ -0,0 +1,15 @@ +*ip;test-ip4 +*inet;test-inet +:input;type filter hook input priority 0 + +> counter1;ok +> counter2;ok +> counter3;ok + +ip daddr 192.168.0.1 counter name counter1;ok;ip daddr 192.168.0.1 counter counter1 +ip daddr 192.168.0.2 counter name counter1;ok;ip daddr 192.168.0.2 counter counter1 + +ip daddr 192.168.0.1 counter name counter2;ok;ip daddr 192.168.0.1 counter counter2 +ip daddr 192.168.0.2 counter name counter3;ok;ip daddr 192.168.0.2 counter counter3 + +ip daddr 192.168.0.2 counter name not-counter;fail
tests/regression/nft-test.py +110 -0
152 lines not on this page · raw message
Signature · 1 line
1.7.10.4