From patchwork Tue Sep 17 10:43:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 275420 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4145A2C00D6 for ; Tue, 17 Sep 2013 20:43:32 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752531Ab3IQKnb (ORCPT ); Tue, 17 Sep 2013 06:43:31 -0400 Received: from mail.us.es ([193.147.175.20]:52642 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752450Ab3IQKna (ORCPT ); Tue, 17 Sep 2013 06:43:30 -0400 Received: (qmail 5412 invoked from network); 17 Sep 2013 12:43:28 +0200 Received: from unknown (HELO us.es) (192.168.2.12) by us.es with SMTP; 17 Sep 2013 12:43:28 +0200 Received: (qmail 10014 invoked by uid 507); 17 Sep 2013 10:43:28 -0000 X-Qmail-Scanner-Diagnostics: from 127.0.0.1 by antivirus2 (envelope-from , uid 501) with qmail-scanner-2.10 (clamdscan: 0.97.8/17867. spamassassin: 3.3.2. Clear:RC:1(127.0.0.1):SA:0(-95.6/7.5):. Processed in 4.14808 secs); 17 Sep 2013 10:43:28 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on antivirus2 X-Spam-Level: X-Spam-Status: No, score=-95.6 required=7.5 tests=BAYES_50,RCVD_IN_BRBL, RCVD_IN_BRBL_LASTEXT,RCVD_IN_PBL,RCVD_IN_RP_RNBL,RCVD_IN_SORBS_DUL, RDNS_DYNAMIC,USER_IN_WHITELIST autolearn=disabled version=3.3.2 X-Spam-ASN: AS12715 95.20.0.0/16 X-Envelope-From: pablo@netfilter.org Received: from unknown (HELO antivirus2) (127.0.0.1) by us.es with SMTP; 17 Sep 2013 10:43:24 -0000 Received: from 192.168.1.13 (192.168.1.13) by antivirus2 (F-Secure/fsigk_smtp/410/antivirus2); Tue, 17 Sep 2013 12:43:24 +0200 (CEST) X-Virus-Status: clean(F-Secure/fsigk_smtp/410/antivirus2) Received: (qmail 26256 invoked from network); 17 Sep 2013 12:43:24 +0200 Received: from 89.63.20.95.dynamic.jazztel.es (HELO localhost.localdomain) (pneira@us.es@95.20.63.89) by mail.us.es with SMTP; 17 Sep 2013 12:43:24 +0200 From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH -nftables v2 2/4] netfilter: nf_tables: use per netns commit list Date: Tue, 17 Sep 2013 12:43:11 +0200 Message-Id: <1379414593-17956-3-git-send-email-pablo@netfilter.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1379414593-17956-1-git-send-email-pablo@netfilter.org> References: <1379414593-17956-1-git-send-email-pablo@netfilter.org> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Instead of one list per chain. Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 6 +- include/net/netns/nftables.h | 1 + net/netfilter/nf_tables_api.c | 109 +++++++++++++------------------------ 3 files changed, 44 insertions(+), 72 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index fe08cf4..6b644c2 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -342,11 +342,15 @@ struct nft_rule { * * @list: used internally * @rule: rule that needs to be updated + * @chain: chain that this rule belongs to + * @table: table for which this chain applies * @family: family expressesed as AF_* */ struct nft_rule_trans { struct list_head list; struct nft_rule *rule; + const struct nft_chain *chain; + const struct nft_table *table; u8 family; }; @@ -383,7 +387,6 @@ enum nft_chain_flags { * struct nft_chain - nf_tables chain * * @rules: list of rules in the chain - * @dirty_rules: rules that need an update after next generation * @list: used internally * @rcu_head: used internally * @net: net namespace that this chain belongs to @@ -396,7 +399,6 @@ enum nft_chain_flags { */ struct nft_chain { struct list_head rules; - struct list_head dirty_rules; struct list_head list; struct rcu_head rcu_head; struct net *net; diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h index 9b35901..15d056d 100644 --- a/include/net/netns/nftables.h +++ b/include/net/netns/nftables.h @@ -7,6 +7,7 @@ struct nft_af_info; struct netns_nftables { struct list_head af_info; + struct list_head commit_list; struct nft_af_info *ipv4; struct nft_af_info *ipv6; struct nft_af_info *arp; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index f099d0d..8c78d36 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -976,7 +976,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, } INIT_LIST_HEAD(&chain->rules); - INIT_LIST_HEAD(&chain->dirty_rules); chain->handle = nf_tables_alloc_handle(table); chain->net = net; chain->table = table; @@ -1540,15 +1539,16 @@ static struct nft_expr_info *info; static int nf_tables_trans_add(struct nft_rule *rule, const struct nft_ctx *ctx) { struct nft_rule_trans *rupd; - struct nft_chain *chain = (struct nft_chain *)ctx->chain; rupd = kmalloc(sizeof(struct nft_rule_trans), GFP_KERNEL); if (rupd == NULL) return -ENOMEM; + rupd->chain = ctx->chain; + rupd->table = ctx->table; rupd->rule = rule; rupd->family = ctx->afi->family; - list_add(&rupd->list, &chain->dirty_rules); + list_add(&rupd->list, &ctx->net->nft.commit_list); return 0; } @@ -1776,19 +1776,8 @@ static int nf_tables_commit(struct sock *nlsk, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nla[]) { - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); - const struct nft_af_info *afi; struct net *net = sock_net(skb->sk); - struct nft_table *table; - struct nft_chain *chain; struct nft_rule_trans *rupd, *tmp; - bool create; - - create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; - - afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create); - if (IS_ERR(afi)) - return PTR_ERR(afi); /* Bump generation counter, invalidate any dump in progress */ net->nft.genctr++; @@ -1801,37 +1790,31 @@ static int nf_tables_commit(struct sock *nlsk, struct sk_buff *skb, */ synchronize_rcu(); - list_for_each_entry(table, &afi->tables, list) { - list_for_each_entry(chain, &table->chains, list) { - list_for_each_entry_safe(rupd, tmp, &chain->dirty_rules, list) { - /* Delete this rule from the dirty list */ - list_del(&rupd->list); - - /* This rule was inactive in the past and just - * became active. Clear the next bit of the - * genmask since its meaning has changed, now - * it is the future. - */ - if (nft_rule_is_active(net, rupd->rule)) { - nft_rule_clear(net, rupd->rule); - nf_tables_rule_notify(skb, nlh, table, - chain, rupd->rule, - NFT_MSG_NEWRULE, - 0, - rupd->family); - kfree(rupd); - continue; - } + list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) { + /* Delete this rule from the dirty list */ + list_del(&rupd->list); - /* This rule is in the past, get rid of it */ - list_del_rcu(&rupd->rule->list); - nf_tables_rule_notify(skb, nlh, table, chain, - rupd->rule, NFT_MSG_DELRULE, 0, - rupd->family); - nf_tables_rule_destroy(rupd->rule); - kfree(rupd); - } + /* This rule was inactive in the past and just became active. + * Clear the next bit of the genmask since its meaning has + * changed, now it is the future. + */ + if (nft_rule_is_active(net, rupd->rule)) { + nft_rule_clear(net, rupd->rule); + nf_tables_rule_notify(skb, nlh, rupd->table, + rupd->chain, rupd->rule, + NFT_MSG_NEWRULE, 0, + rupd->family); + kfree(rupd); + continue; } + + /* This rule is in the past, get rid of it */ + list_del_rcu(&rupd->rule->list); + nf_tables_rule_notify(skb, nlh, rupd->table, rupd->chain, + rupd->rule, NFT_MSG_DELRULE, 0, + rupd->family); + nf_tables_rule_destroy(rupd->rule); + kfree(rupd); } return 0; @@ -1841,38 +1824,23 @@ static int nf_tables_abort(struct sock *nlsk, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nla[]) { - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); - const struct nft_af_info *afi; struct net *net = sock_net(skb->sk); - struct nft_table *table; - struct nft_chain *chain; struct nft_rule_trans *rupd, *tmp; - bool create; - - create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; - - afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create); - if (IS_ERR(afi)) - return PTR_ERR(afi); - list_for_each_entry(table, &afi->tables, list) { - list_for_each_entry(chain, &table->chains, list) { - list_for_each_entry_safe(rupd, tmp, &chain->dirty_rules, list) { - /* Delete all rules from the dirty list */ - list_del(&rupd->list); - - if (!nft_rule_is_active_next(net, rupd->rule)) { - nft_rule_clear(net, rupd->rule); - kfree(rupd); - continue; - } + list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) { + /* Delete all rules from the dirty list */ + list_del(&rupd->list); - /* This rule is inactive, get rid of it */ - list_del_rcu(&rupd->rule->list); - nf_tables_rule_destroy(rupd->rule); - kfree(rupd); - } + if (!nft_rule_is_active_next(net, rupd->rule)) { + nft_rule_clear(net, rupd->rule); + kfree(rupd); + continue; } + + /* This rule is inactive, get rid of it */ + list_del_rcu(&rupd->rule->list); + nf_tables_rule_destroy(rupd->rule); + kfree(rupd); } return 0; } @@ -3224,6 +3192,7 @@ EXPORT_SYMBOL_GPL(nft_data_dump); static int nf_tables_init_net(struct net *net) { INIT_LIST_HEAD(&net->nft.af_info); + INIT_LIST_HEAD(&net->nft.commit_list); return 0; }