Commit 3f8d9eb0 authored by Jeremy Sowden's avatar Jeremy Sowden Committed by Pablo Neira Ayuso
Browse files

netfilter: bitwise: add helper for initializing boolean operations.



Split the code specific to initializing bitwise boolean operations out
into a separate function.  A similar function will be added later for
shift operations.

Signed-off-by: default avatarJeremy Sowden <jeremy@azazel.net>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 9d1f9799
Loading
Loading
Loading
Loading
+41 −25
Original line number Diff line number Diff line
@@ -45,20 +45,53 @@ static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
	[NFTA_BITWISE_OP]	= { .type = NLA_U32 },
};

static int nft_bitwise_init_bool(struct nft_bitwise *priv,
				 const struct nlattr *const tb[])
{
	struct nft_data_desc d1, d2;
	int err;

	if (!tb[NFTA_BITWISE_MASK] ||
	    !tb[NFTA_BITWISE_XOR])
		return -EINVAL;

	err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1,
			    tb[NFTA_BITWISE_MASK]);
	if (err < 0)
		return err;
	if (d1.type != NFT_DATA_VALUE || d1.len != priv->len) {
		err = -EINVAL;
		goto err1;
	}

	err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &d2,
			    tb[NFTA_BITWISE_XOR]);
	if (err < 0)
		goto err1;
	if (d2.type != NFT_DATA_VALUE || d2.len != priv->len) {
		err = -EINVAL;
		goto err2;
	}

	return 0;
err2:
	nft_data_release(&priv->xor, d2.type);
err1:
	nft_data_release(&priv->mask, d1.type);
	return err;
}

static int nft_bitwise_init(const struct nft_ctx *ctx,
			    const struct nft_expr *expr,
			    const struct nlattr * const tb[])
{
	struct nft_bitwise *priv = nft_expr_priv(expr);
	struct nft_data_desc d1, d2;
	u32 len;
	int err;

	if (!tb[NFTA_BITWISE_SREG] ||
	    !tb[NFTA_BITWISE_DREG] ||
	    !tb[NFTA_BITWISE_LEN]  ||
	    !tb[NFTA_BITWISE_MASK] ||
	    !tb[NFTA_BITWISE_XOR])
	    !tb[NFTA_BITWISE_LEN])
		return -EINVAL;

	err = nft_parse_u32_check(tb[NFTA_BITWISE_LEN], U8_MAX, &len);
@@ -90,29 +123,12 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
		priv->op = NFT_BITWISE_BOOL;
	}

	err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1,
			    tb[NFTA_BITWISE_MASK]);
	if (err < 0)
		return err;
	if (d1.type != NFT_DATA_VALUE || d1.len != priv->len) {
		err = -EINVAL;
		goto err1;
	}

	err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &d2,
			    tb[NFTA_BITWISE_XOR]);
	if (err < 0)
		goto err1;
	if (d2.type != NFT_DATA_VALUE || d2.len != priv->len) {
		err = -EINVAL;
		goto err2;
	switch(priv->op) {
	case NFT_BITWISE_BOOL:
		err = nft_bitwise_init_bool(priv, tb);
		break;
	}

	return 0;
err2:
	nft_data_release(&priv->xor, d2.type);
err1:
	nft_data_release(&priv->mask, d1.type);
	return err;
}