From patchwork Wed Oct 31 09:28:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Bursztyka X-Patchwork-Id: 195777 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 BA1ED2C0176 for ; Wed, 31 Oct 2012 20:28:37 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756000Ab2JaJ2g (ORCPT ); Wed, 31 Oct 2012 05:28:36 -0400 Received: from mga03.intel.com ([143.182.124.21]:7772 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754480Ab2JaJ2f (ORCPT ); Wed, 31 Oct 2012 05:28:35 -0400 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga101.ch.intel.com with ESMTP; 31 Oct 2012 02:28:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.80,687,1344236400"; d="scan'208";a="162785812" Received: from rd-180.fi.intel.com ([10.237.68.32]) by AZSMGA002.ch.intel.com with ESMTP; 31 Oct 2012 02:28:33 -0700 From: Tomasz Bursztyka To: netfilter-devel@vger.kernel.org Cc: Tomasz Bursztyka Subject: [nf-next/nf_tables-experiments - PATCH 1/2] nf_tables: Add support for changing users chain's name Date: Wed, 31 Oct 2012 11:28:28 +0200 Message-Id: <1351675709-14127-2-git-send-email-tomasz.bursztyka@linux.intel.com> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1351675709-14127-1-git-send-email-tomasz.bursztyka@linux.intel.com> References: <1351675709-14127-1-git-send-email-tomasz.bursztyka@linux.intel.com> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Tomasz Bursztyka --- include/linux/netfilter/nf_tables.h | 1 + net/netfilter/nf_tables_api.c | 58 ++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 0115a2f..542b654 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -67,6 +67,7 @@ enum nft_chain_attributes { NFTA_CHAIN_HOOK, NFTA_CHAIN_POLICY, NFTA_CHAIN_USE, + NFTA_CHAIN_NEW_NAME, __NFTA_CHAIN_MAX }; #define NFTA_CHAIN_MAX (__NFTA_CHAIN_MAX - 1) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index e0e4616..fd1b624 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -676,6 +676,62 @@ nf_tables_chain_policy(struct nft_chain *chain, const struct nlattr *attr) return 0; } +static int nf_tables_mvchain(struct sk_buff *skb, const struct nlmsghdr *nlh, + struct nft_table *table, + struct nft_chain *old_chain, + const struct nlattr * const nla[]) +{ + const struct nfgenmsg *nfmsg = nlmsg_data(nlh); + int family = nfmsg->nfgen_family; + struct nft_chain *new_chain; + const struct nlattr *name; + unsigned int size; + + if (!nla[NFTA_CHAIN_NEW_NAME]) + return -EINVAL; + + if (old_chain->flags & NFT_CHAIN_BUILTIN || + old_chain->flags & NFT_BASE_CHAIN) + return -EOPNOTSUPP; + + if (old_chain->use > 0) + return -EBUSY; + + name = nla[NFTA_CHAIN_NEW_NAME]; + new_chain = nf_tables_chain_lookup(table, name); + if (IS_ERR(new_chain)) { + if (PTR_ERR(new_chain) != -ENOENT) + return PTR_ERR(new_chain); + new_chain = NULL; + } + + if (new_chain != NULL) + return -EEXIST; + + size = nla_len(name); + new_chain = kzalloc(sizeof(*new_chain) + size, GFP_KERNEL); + if (new_chain == NULL) + return -ENOMEM; + + list_del(&old_chain->list); + + INIT_LIST_HEAD(&new_chain->rules); + nla_strlcpy(new_chain->name, name, size); + + /* Copying content from old chain */ + new_chain->flags = old_chain->flags; + list_replace_init(&old_chain->rules, &new_chain->rules); + + list_add_tail(&new_chain->list, &table->chains); + + nf_tables_chain_notify(skb, nlh, table, old_chain, NFT_MSG_DELCHAIN, + family); + kfree(old_chain); + nf_tables_chain_notify(skb, nlh, table, new_chain, NFT_MSG_NEWCHAIN, + family); + return 0; +} + static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nla[]) @@ -714,7 +770,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, if (nlh->nlmsg_flags & NLM_F_EXCL) return -EEXIST; if (nlh->nlmsg_flags & NLM_F_REPLACE) - return -EOPNOTSUPP; + return nf_tables_mvchain(skb, nlh, table, chain, nla); if ((chain->flags & NFT_BASE_CHAIN) && nla[NFTA_CHAIN_POLICY]) { return nf_tables_chain_policy(chain,