* netfilter/nftables: chain rule dumps
@ 2016-07-13 12:41 jalvarez
2016-07-13 14:40 ` Pablo Neira Ayuso
0 siblings, 1 reply; 7+ messages in thread
From: jalvarez @ 2016-07-13 12:41 UTC (permalink / raw)
To: netfilter
Hi,
First I want to thank the netfilter developpers for nftables as it is
really great ! :)
My problem is mostly about libnftnl / libmnl.
I am currently trying to port an IPTC application to work with nftables
for a high performance firewall, those rules (~50000) are updated very
often (from 5 to 60 times per second).
I know it is not really supported, but i can't afford using nft from
command line as it is too slow and offers less control than the low
level C APIs.
I have been looking at the code of libmnl, libnftnl and nftables, and I
currently didn't see any way of doing the following :
- dumping the rules for a specific chain or table. I saw it is indeed
possible to dump the rules for a specific family as it is done in
mnl_nft_rule_dump, but i didn't see any way of doing so for a specific
chain.
- getting the handle id of a rule after sending a message to add it
without the need to dump the whole ruleset. In other words, is it
possible to retrieve the handle of the rule right after its insertion to
the ruleset ? Or is there a reliable way to predict this handle ?
Did I miss something ? Does those features exist or are they planned ?
I would need these because I want to avoid unnecessary dumping
operations, as they were the bottleneck of the firewall when using IPTC
(the whole -huge- ruleset was copied from kernel space to user space and
back each time I wanted to do something with it).
Thank you very much for your help !
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: netfilter/nftables: chain rule dumps
2016-07-13 12:41 netfilter/nftables: chain rule dumps jalvarez
@ 2016-07-13 14:40 ` Pablo Neira Ayuso
2016-07-19 8:59 ` jalvarez
0 siblings, 1 reply; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-07-13 14:40 UTC (permalink / raw)
To: jalvarez; +Cc: netfilter
On Wed, Jul 13, 2016 at 02:41:26PM +0200, jalvarez wrote:
> Hi,
>
> First I want to thank the netfilter developpers for nftables as it is really
> great ! :)
>
> My problem is mostly about libnftnl / libmnl.
>
> I am currently trying to port an IPTC application to work with nftables for
> a high performance firewall, those rules (~50000) are updated very often
> (from 5 to 60 times per second).
> I know it is not really supported, but i can't afford using nft from command
> line as it is too slow and offers less control than the low level C APIs.
>
> I have been looking at the code of libmnl, libnftnl and nftables, and I
> currently didn't see any way of doing the following :
> - dumping the rules for a specific chain or table. I saw it is indeed
> possible to dump the rules for a specific family as it is done in
> mnl_nft_rule_dump, but i didn't see any way of doing so for a specific
> chain.
There is no support for this selective dumping yet in the kernel, but
it should be very easy to add by enhancing the rule dumping. You can
attach .data via netlink_dump_control structure. You only have to
define a container structure like:
struct nft_rule_dump {
const char *table;
const char *chain;
};
The idea is to strdup() the string that comes with NFTA_RULE_TABLE and
NFTA_RULE_CHAIN and attach this to the container structure above, then
use this information from nf_tables_dump_rules(). Don't forget to
release these two pointers by setting .done callback in
netlink_dump_control.
The file to modify is net/netfilter/nf_tables_api.c under the kernel
tree, this should result in a relatively small patch. Would you
contribute this update?
> - getting the handle id of a rule after sending a message to add it
> without the need to dump the whole ruleset. In other words, is it
> possible to retrieve the handle of the rule right after its
> insertion to the ruleset ? Or is there a reliable way to predict
> this handle ?
You can get this through the NLM_F_ECHO flag. This flag makes the
netlink event notification report back to you what rule you have
created, including the 64-bit ID that was allocated. You just have to
invoke recvmsg() after sendmsg().
You can probably enhance the existing libnftnl example to support
this and print the rule ID after creation.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: netfilter/nftables: chain rule dumps
2016-07-13 14:40 ` Pablo Neira Ayuso
@ 2016-07-19 8:59 ` jalvarez
2016-07-19 10:28 ` Pablo Neira Ayuso
0 siblings, 1 reply; 7+ messages in thread
From: jalvarez @ 2016-07-19 8:59 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter
On 13/07/2016 16:40, Pablo Neira Ayuso wrote:
> On Wed, Jul 13, 2016 at 02:41:26PM +0200, jalvarez wrote:
>> (...)
>> I have been looking at the code of libmnl, libnftnl and nftables, and I
>> currently didn't see any way of doing the following :
>> - dumping the rules for a specific chain or table. I saw it is indeed
>> possible to dump the rules for a specific family as it is done in
>> mnl_nft_rule_dump, but i didn't see any way of doing so for a specific
>> chain.
> There is no support for this selective dumping yet in the kernel, but
> it should be very easy to add by enhancing the rule dumping. You can
> attach .data via netlink_dump_control structure. You only have to
> define a container structure like:
>
> struct nft_rule_dump {
> const char *table;
> const char *chain;
> };
>
> The idea is to strdup() the string that comes with NFTA_RULE_TABLE and
> NFTA_RULE_CHAIN and attach this to the container structure above, then
> use this information from nf_tables_dump_rules(). Don't forget to
> release these two pointers by setting .done callback in
> netlink_dump_control.
>
> The file to modify is net/netfilter/nf_tables_api.c under the kernel
> tree, this should result in a relatively small patch. Would you
> contribute this update?
Thank you for your answer.
I dug into the kernel code yesterday and I have come up with a small
patch (see below).
I am a complete newbie in kernel development, please feel free to
correct me if there is anything I did wrong.
The kernel builds ok but I didn't tested my changes yet. Have you an
idea of what the best approach
should be to test these changes (using User Mode Linux maybe ?) ?
Also, I would like to know what is the exact meaning and expected
behavior of the idx counter in nf_tables_dump_rules().
My current changes might actually break the expected behavior if it was
some kind of "rule id counter" instead of "iteration counter". If it is
possible, I would rather not put the continues in the rules loop, as the
goal of these changes is mostly to avoid looping through the whole ruleset.
Again, I am very thankful for your help.
Here is the patch :
---
diff --git a/include/net/netfilter/nf_tables.h
b/include/net/netfilter/nf_tables.h
index 3ae969e..a7c3ddf 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -92,6 +92,19 @@ struct nft_ctx {
bool report;
};
+
+/**
+ * struct nft_rule_dump_ctx - nf_tables context for rule dumping.
+ *
+ * @table: the table the chain is contained in.
+ * @chain: the chain the rules to be dumped are contained in.
+ */
+struct nft_rule_dump_ctx {
+ const char *table;
+ const char *chain;
+};
+
+
struct nft_data_desc {
enum nft_data_types type;
unsigned int len;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 3b3ddb4..a11213fa 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1756,6 +1756,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
const struct nft_table *table;
const struct nft_chain *chain;
const struct nft_rule *rule;
+ const struct nft_rule_dump_ctx *ctx = cb->data;
unsigned int idx = 0, s_idx = cb->args[0];
struct net *net = sock_net(skb->sk);
int family = nfmsg->nfgen_family;
@@ -1768,7 +1769,13 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
continue;
list_for_each_entry_rcu(table, &afi->tables, list) {
+ if(ctx->table != NULL && (strcmp(ctx->table,
table->name) != 0))
+ continue;
+
list_for_each_entry_rcu(chain, &table->chains,
list) {
+ if(ctx->chain != NULL &&
(strcmp(ctx->chain, chain->name) != 0))
+ continue;
+
list_for_each_entry_rcu(rule,
&chain->rules, list) {
if (!nft_rule_is_active(net, rule))
goto cont;
@@ -1798,6 +1805,49 @@ done:
return skb->len;
}
+
+static int nf_tables_fill_rule_dump_ctx(struct nft_rule_dump_ctx *ctx,
+ const struct nlattr * const nla[])
+{
+ const struct nlattr* table_nla;
+ const struct nlattr* chain_nla;
+ char* buf;
+ size_t buflen;
+
+ table_nla = nla[NFTA_RULE_TABLE];
+ if(table_nla != NULL) {
+ buflen = nla_len(table_nla);
+ buf = kmalloc(buflen, GFP_KERNEL);
+ nla_strlcpy(buf, table_nla, buflen);
+ ctx->table = buf;
+ } else {
+ ctx->table = NULL;
+ }
+
+ chain_nla = nla[NFTA_RULE_CHAIN];
+ if(chain_nla != NULL) {
+ buflen = nla_len(chain_nla);
+ buf = kmalloc(buflen, GFP_KERNEL);
+ nla_strlcpy(buf, chain_nla, buflen);
+ ctx->chain = buf;
+ } else {
+ ctx->chain = NULL;
+ }
+
+ return 0;
+}
+
+static int nf_tables_dump_rules_done(struct netlink_callback *cb)
+{
+ if(cb->data != NULL) {
+ struct nft_rule_dump_ctx *ctx = cb->data;
+ kfree(ctx->table);
+ kfree(ctx->chain);
+ }
+ kfree(cb->data);
+ return 0;
+}
+
static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const nla[])
@@ -1813,9 +1863,14 @@ static int nf_tables_getrule(struct sock *nlsk,
struct sk_buff *skb,
int err;
if (nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct nft_rule_dump_ctx *ctx = kmalloc(sizeof(*ctx),
GFP_KERNEL);
struct netlink_dump_control c = {
.dump = nf_tables_dump_rules,
+ .done = nf_tables_dump_rules_done,
+ .data = ctx
};
+
+ nf_tables_fill_rule_dump_ctx(ctx, nla);
return netlink_dump_start(nlsk, skb, nlh, &c);
}
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: netfilter/nftables: chain rule dumps
2016-07-19 8:59 ` jalvarez
@ 2016-07-19 10:28 ` Pablo Neira Ayuso
2016-07-19 13:47 ` jalvarez
0 siblings, 1 reply; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-07-19 10:28 UTC (permalink / raw)
To: jalvarez; +Cc: netfilter
On Tue, Jul 19, 2016 at 10:59:28AM +0200, jalvarez wrote:
> I dug into the kernel code yesterday and I have come up with a small patch
> (see below).
> I am a complete newbie in kernel development, please feel free to correct me
> if there is anything I did wrong.
>
> The kernel builds ok but I didn't tested my changes yet. Have you an idea of
> what the best approach
> should be to test these changes (using User Mode Linux maybe ?) ?
You can mangle one of the existing examples in libnftnl to set the
table and/or chain when listing rules, specifically examples/nft-rule-get.c
You only have to set the table and/or chain attributes.
> Also, I would like to know what is the exact meaning and expected behavior
> of the idx counter in nf_tables_dump_rules().
Every time you call recvmsg(), the dump routine runs and fill a page
with entries, if there are more entries that can fit into the page,
the idx tells us where to follow up from in the next recvmsg()
invocation.
> My current changes might actually break the expected behavior if it was some
> kind of "rule id counter" instead of "iteration counter". If it is possible,
> I would rather not put the continues in the rules loop, as the goal of these
> changes is mostly to avoid looping through the whole ruleset.
>
> Again, I am very thankful for your help.
>
> Here is the patch
Just sent a patch to netfilter-devel, I've Cc'ed you. It would be good
if you can test it.
Thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: netfilter/nftables: chain rule dumps
2016-07-19 10:28 ` Pablo Neira Ayuso
@ 2016-07-19 13:47 ` jalvarez
2016-07-19 13:55 ` Pablo Neira Ayuso
0 siblings, 1 reply; 7+ messages in thread
From: jalvarez @ 2016-07-19 13:47 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter
On 19/07/2016 12:28, Pablo Neira Ayuso wrote:
> On Tue, Jul 19, 2016 at 10:59:28AM +0200, jalvarez wrote:
>> My current changes might actually break the expected behavior if it was some
>> kind of "rule id counter" instead of "iteration counter". If it is possible,
>> I would rather not put the continues in the rules loop, as the goal of these
>> changes is mostly to avoid looping through the whole ruleset.
>>
>> Again, I am very thankful for your help.
>>
>> Here is the patch
> Just sent a patch to netfilter-devel, I've Cc'ed you. It would be good
> if you can test it.
>
> Thanks.
Thank you.
I'll be testing this as soon as my test environment is ready.
Would you like me to send the changes to the nft-rule-get.c example in
libnftnl afterwards ?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: netfilter/nftables: chain rule dumps
2016-07-19 13:47 ` jalvarez
@ 2016-07-19 13:55 ` Pablo Neira Ayuso
2016-07-20 14:03 ` jalvarez
0 siblings, 1 reply; 7+ messages in thread
From: Pablo Neira Ayuso @ 2016-07-19 13:55 UTC (permalink / raw)
To: jalvarez; +Cc: netfilter
On Tue, Jul 19, 2016 at 03:47:41PM +0200, jalvarez wrote:
> On 19/07/2016 12:28, Pablo Neira Ayuso wrote:
> >On Tue, Jul 19, 2016 at 10:59:28AM +0200, jalvarez wrote:
> >>My current changes might actually break the expected behavior if it was some
> >>kind of "rule id counter" instead of "iteration counter". If it is possible,
> >>I would rather not put the continues in the rules loop, as the goal of these
> >>changes is mostly to avoid looping through the whole ruleset.
> >>
> >>Again, I am very thankful for your help.
> >>
> >>Here is the patch
> >Just sent a patch to netfilter-devel, I've Cc'ed you. It would be good
> >if you can test it.
> >
> >Thanks.
>
> Thank you.
> I'll be testing this as soon as my test environment is ready.
>
> Would you like me to send the changes to the nft-rule-get.c example in
> libnftnl afterwards ?
Yes please, this also provides a good way to test this. Thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: netfilter/nftables: chain rule dumps
2016-07-19 13:55 ` Pablo Neira Ayuso
@ 2016-07-20 14:03 ` jalvarez
0 siblings, 0 replies; 7+ messages in thread
From: jalvarez @ 2016-07-20 14:03 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter
On 19/07/2016 15:55, Pablo Neira Ayuso wrote:
> Yes please, this also provides a good way to test this. Thanks.
I just posted both the fixed patch and the test :
- patch : http://marc.info/?l=netfilter-devel&m=146902304323436&w=2
- example : http://marc.info/?l=netfilter-devel&m=146902182423018&w=2
I worked just fine !
Thank you for your help so far.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-07-20 14:03 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-13 12:41 netfilter/nftables: chain rule dumps jalvarez
2016-07-13 14:40 ` Pablo Neira Ayuso
2016-07-19 8:59 ` jalvarez
2016-07-19 10:28 ` Pablo Neira Ayuso
2016-07-19 13:47 ` jalvarez
2016-07-19 13:55 ` Pablo Neira Ayuso
2016-07-20 14:03 ` jalvarez
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.