netfilter: nftables: add connlabel set support
[cascardo/linux.git] / net / netfilter / nft_ct.c
index 25998fa..137e308 100644 (file)
@@ -197,6 +197,14 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
                        nf_conntrack_event_cache(IPCT_MARK, ct);
                }
                break;
+#endif
+#ifdef CONFIG_NF_CONNTRACK_LABELS
+       case NFT_CT_LABELS:
+               nf_connlabels_replace(ct,
+                                     &regs->data[priv->sreg],
+                                     &regs->data[priv->sreg],
+                                     NF_CT_LABELS_MAX_SIZE / sizeof(u32));
+               break;
 #endif
        default:
                break;
@@ -364,6 +372,16 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
        case NFT_CT_MARK:
                len = FIELD_SIZEOF(struct nf_conn, mark);
                break;
+#endif
+#ifdef CONFIG_NF_CONNTRACK_LABELS
+       case NFT_CT_LABELS:
+               if (tb[NFTA_CT_DIRECTION])
+                       return -EINVAL;
+               len = NF_CT_LABELS_MAX_SIZE;
+               err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
+               if (err)
+                       return err;
+               break;
 #endif
        default:
                return -EOPNOTSUPP;
@@ -384,6 +402,18 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
 static void nft_ct_destroy(const struct nft_ctx *ctx,
                           const struct nft_expr *expr)
 {
+       struct nft_ct *priv = nft_expr_priv(expr);
+
+       switch (priv->key) {
+#ifdef CONFIG_NF_CONNTRACK_LABELS
+       case NFT_CT_LABELS:
+               nf_connlabels_put(ctx->net);
+               break;
+#endif
+       default:
+               break;
+       }
+
        nft_ct_l3proto_module_put(ctx->afi->family);
 }