These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / net / netfilter / nf_conntrack_labels.c
index bb53f12..3ce5c31 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;
@@ -48,7 +50,6 @@ int nf_connlabel_set(struct nf_conn *ct, u16 bit)
 }
 EXPORT_SYMBOL_GPL(nf_connlabel_set);
 
-#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
 static void replace_u32(u32 *address, u32 mask, u32 new)
 {
        u32 old, tmp;
@@ -89,7 +90,35 @@ int nf_connlabels_replace(struct nf_conn *ct,
        return 0;
 }
 EXPORT_SYMBOL_GPL(nf_connlabels_replace);
-#endif
+
+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),
@@ -99,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);
 }