Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
[deliverable/linux.git] / net / netfilter / nft_ct.c
index 81fbb450783e59932ecc1c67147fc0ca89b475d3..51e180f2a00374d3d28860817a6d5e40b3d27c6b 100644 (file)
@@ -109,18 +109,11 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
 #ifdef CONFIG_NF_CONNTRACK_LABELS
        case NFT_CT_LABELS: {
                struct nf_conn_labels *labels = nf_ct_labels_find(ct);
-               unsigned int size;
 
-               if (!labels) {
+               if (labels)
+                       memcpy(dest, labels->bits, NF_CT_LABELS_MAX_SIZE);
+               else
                        memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
-                       return;
-               }
-
-               size = labels->words * sizeof(long);
-               memcpy(dest, labels->bits, size);
-               if (size < NF_CT_LABELS_MAX_SIZE)
-                       memset(((char *) dest) + size, 0,
-                              NF_CT_LABELS_MAX_SIZE - size);
                return;
        }
 #endif
@@ -351,6 +344,9 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
        if (err < 0)
                return err;
 
+       if (priv->key == NFT_CT_BYTES || priv->key == NFT_CT_PKTS)
+               nf_ct_set_acct(ctx->net, true);
+
        return 0;
 }
 
@@ -359,6 +355,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
                           const struct nlattr * const tb[])
 {
        struct nft_ct *priv = nft_expr_priv(expr);
+       bool label_got = false;
        unsigned int len;
        int err;
 
@@ -377,6 +374,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
                err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
                if (err)
                        return err;
+               label_got = true;
                break;
 #endif
        default:
@@ -386,17 +384,28 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
        priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
        err = nft_validate_register_load(priv->sreg, len);
        if (err < 0)
-               return err;
+               goto err1;
 
        err = nft_ct_l3proto_try_module_get(ctx->afi->family);
        if (err < 0)
-               return err;
+               goto err1;
 
        return 0;
+
+err1:
+       if (label_got)
+               nf_connlabels_put(ctx->net);
+       return err;
+}
+
+static void nft_ct_get_destroy(const struct nft_ctx *ctx,
+                              const struct nft_expr *expr)
+{
+       nft_ct_l3proto_module_put(ctx->afi->family);
 }
 
-static void nft_ct_destroy(const struct nft_ctx *ctx,
-                          const struct nft_expr *expr)
+static void nft_ct_set_destroy(const struct nft_ctx *ctx,
+                              const struct nft_expr *expr)
 {
        struct nft_ct *priv = nft_expr_priv(expr);
 
@@ -468,7 +477,7 @@ static const struct nft_expr_ops nft_ct_get_ops = {
        .size           = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
        .eval           = nft_ct_get_eval,
        .init           = nft_ct_get_init,
-       .destroy        = nft_ct_destroy,
+       .destroy        = nft_ct_get_destroy,
        .dump           = nft_ct_get_dump,
 };
 
@@ -477,7 +486,7 @@ static const struct nft_expr_ops nft_ct_set_ops = {
        .size           = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
        .eval           = nft_ct_set_eval,
        .init           = nft_ct_set_init,
-       .destroy        = nft_ct_destroy,
+       .destroy        = nft_ct_set_destroy,
        .dump           = nft_ct_set_dump,
 };
 
This page took 0.027568 seconds and 5 git commands to generate.