From patchwork Tue Aug 25 00:32:18 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 510341 X-Patchwork-Delegate: pablo@netfilter.org 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 1DA1414056B for ; Tue, 25 Aug 2015 10:32:57 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755110AbbHYAcm (ORCPT ); Mon, 24 Aug 2015 20:32:42 -0400 Received: from mail-pa0-f42.google.com ([209.85.220.42]:33303 "EHLO mail-pa0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755083AbbHYAch (ORCPT ); Mon, 24 Aug 2015 20:32:37 -0400 Received: by pacti10 with SMTP id ti10so35605560pac.0 for ; Mon, 24 Aug 2015 17:32:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DCzJI7+3XFqVaeBHciSsKtqvjO3FwJc2f81Ir4gxPi8=; b=hqwaFf+9TsQ9FniATE4aZwsp0c+cATEndNOPzIgM6044fxljsgsp7PCIi3wB6L07n+ x97l4i06H85bCBepRfUR+12b+rf1HgPU+HnSluO6ZQuiT+kdinUxeasgpB1G1888McZ9 LyvNtCGmDlUbcufkSdPfQhWfnPZKa8rRU+MoHmzEtPkEgPIRaSzmWxPSTSj8ebsT+ex0 b69kHzEqMPU8Crkk497bPVAyCYZKPDhIOQ8jLRLUxrzmiGquQtsszY52mVy0nOum0fAg NTHF27SXWCpN+S0enH/2abBGYC10mx2eOT2Twlq+EIhwaMzqj8aSrK8Upe89KmHEhhKg 6Ejg== X-Gm-Message-State: ALoCoQmw9Kw5HTz9tpT7bAOwbJb1XVOQgjEbJQMiRQy5Q6WUhRKinfbjtoppDIUA1tXBJ+26/tJc X-Received: by 10.68.113.37 with SMTP id iv5mr51315890pbb.104.1440462757456; Mon, 24 Aug 2015 17:32:37 -0700 (PDT) Received: from localhost.localdomain ([208.91.2.4]) by smtp.gmail.com with ESMTPSA id hu13sm18727996pdb.72.2015.08.24.17.32.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 24 Aug 2015 17:32:36 -0700 (PDT) From: Joe Stringer To: netdev@vger.kernel.org, pshelar@nicira.com Cc: linux-kernel@vger.kernel.org, pablo@netfilter.org, fwestpha@redhat.com, hannes@redhat.com, tgraf@suug.ch, jpettit@nicira.com, jesse@nicira.com, netfilter-devel@vger.kernel.org Subject: [PATCHv5 net-next 08/10] netfilter: connlabels: Export setting connlabel length Date: Mon, 24 Aug 2015 17:32:18 -0700 Message-Id: <1440462740-23358-9-git-send-email-joestringer@nicira.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1440462740-23358-1-git-send-email-joestringer@nicira.com> References: <1440462740-23358-1-git-send-email-joestringer@nicira.com> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Add functions to change connlabel length into nf_conntrack_labels.c so they may be reused by other modules like OVS and nftables without needing to jump through xt_match_check() hoops. Suggested-by: Florian Westphal Signed-off-by: Joe Stringer Acked-by: Florian Westphal Acked-by: Thomas Graf --- v2: Protect connlabel modification with spinlock. Fix reference leak in error case. Style fixups. v3: No change. v4-v5: Add acks. --- include/net/netfilter/nf_conntrack_labels.h | 4 ++++ net/netfilter/nf_conntrack_labels.c | 32 +++++++++++++++++++++++++++++ net/netfilter/xt_connlabel.c | 16 ++++----------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_labels.h b/include/net/netfilter/nf_conntrack_labels.h index dec6336..7e2b1d0 100644 --- a/include/net/netfilter/nf_conntrack_labels.h +++ b/include/net/netfilter/nf_conntrack_labels.h @@ -54,7 +54,11 @@ int nf_connlabels_replace(struct nf_conn *ct, #ifdef CONFIG_NF_CONNTRACK_LABELS int nf_conntrack_labels_init(void); void nf_conntrack_labels_fini(void); +int nf_connlabels_get(struct net *net, unsigned int n_bits); +void nf_connlabels_put(struct net *net); #else static inline int nf_conntrack_labels_init(void) { return 0; } static inline void nf_conntrack_labels_fini(void) {} +static inline int nf_connlabels_get(struct net *net, unsigned int n_bits) { return 0; } +static inline void nf_connlabels_put(struct net *net) {} #endif diff --git a/net/netfilter/nf_conntrack_labels.c b/net/netfilter/nf_conntrack_labels.c index daa7c13..3ce5c31 100644 --- a/net/netfilter/nf_conntrack_labels.c +++ b/net/netfilter/nf_conntrack_labels.c @@ -14,6 +14,8 @@ #include #include +static spinlock_t nf_connlabels_lock; + static unsigned int label_bits(const struct nf_conn_labels *l) { unsigned int longs = l->words; @@ -89,6 +91,35 @@ int nf_connlabels_replace(struct nf_conn *ct, } EXPORT_SYMBOL_GPL(nf_connlabels_replace); +int nf_connlabels_get(struct net *net, unsigned int n_bits) +{ + size_t words; + + if (n_bits > (NF_CT_LABELS_MAX_SIZE * BITS_PER_BYTE)) + return -ERANGE; + + words = BITS_TO_LONGS(n_bits); + + spin_lock(&nf_connlabels_lock); + net->ct.labels_used++; + if (words > net->ct.label_words) + net->ct.label_words = words; + spin_unlock(&nf_connlabels_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(nf_connlabels_get); + +void nf_connlabels_put(struct net *net) +{ + spin_lock(&nf_connlabels_lock); + net->ct.labels_used--; + if (net->ct.labels_used == 0) + net->ct.label_words = 0; + spin_unlock(&nf_connlabels_lock); +} +EXPORT_SYMBOL_GPL(nf_connlabels_put); + static struct nf_ct_ext_type labels_extend __read_mostly = { .len = sizeof(struct nf_conn_labels), .align = __alignof__(struct nf_conn_labels), @@ -97,6 +128,7 @@ static struct nf_ct_ext_type labels_extend __read_mostly = { int nf_conntrack_labels_init(void) { + spin_lock_init(&nf_connlabels_lock); return nf_ct_extend_register(&labels_extend); } diff --git a/net/netfilter/xt_connlabel.c b/net/netfilter/xt_connlabel.c index 9f8719d..bb9cbeb 100644 --- a/net/netfilter/xt_connlabel.c +++ b/net/netfilter/xt_connlabel.c @@ -42,10 +42,6 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par) XT_CONNLABEL_OP_SET; struct xt_connlabel_mtinfo *info = par->matchinfo; int ret; - size_t words; - - if (info->bit > XT_CONNLABEL_MAXBIT) - return -ERANGE; if (info->options & ~options) { pr_err("Unknown options in mask %x\n", info->options); @@ -59,19 +55,15 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par) return ret; } - par->net->ct.labels_used++; - words = BITS_TO_LONGS(info->bit+1); - if (words > par->net->ct.label_words) - par->net->ct.label_words = words; - + ret = nf_connlabels_get(par->net, info->bit + 1); + if (ret < 0) + nf_ct_l3proto_module_put(par->family); return ret; } static void connlabel_mt_destroy(const struct xt_mtdtor_param *par) { - par->net->ct.labels_used--; - if (par->net->ct.labels_used == 0) - par->net->ct.label_words = 0; + nf_connlabels_put(par->net); nf_ct_l3proto_module_put(par->family); }