* 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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox