]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
netfilter: connlabels: Export setting connlabel length
authorJoe Stringer <joestringer@nicira.com>
Wed, 26 Aug 2015 18:31:51 +0000 (11:31 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 27 Aug 2015 18:40:43 +0000 (11:40 -0700)
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 <fw@strlen.de>
Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Florian Westphal <fw@strlen.de>
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/netfilter/nf_conntrack_labels.h
net/netfilter/nf_conntrack_labels.c
net/netfilter/xt_connlabel.c

index dec6336bf850f77928f54f4cd04d37b3ebe3e16a..7e2b1d025f5037fc764a8376693680546c3835f6 100644 (file)
@@ -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
index daa7c1383becc499e3170d5c72f1c86f232becf9..3ce5c314ea4bc63ebe5cfc294f6f335726ed85c0 100644 (file)
@@ -14,6 +14,8 @@
 #include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_conntrack_labels.h>
 
+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);
 }
 
index 9f8719df20019f4804b68f0fcc5e5a86f729e44a..bb9cbeb188686f5f858ba8e35493457063d3f6ea 100644 (file)
@@ -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);
 }