summaryrefslogtreecommitdiffstats
path: root/src/netlink_linearize.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-06-22 19:12:24 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-06-24 14:06:09 +0200
commitda015ff415f021294aed8668ddf212acb279cd68 (patch)
treec5d181ee2720c8710c7810d0e750c9d9452b19e1 /src/netlink_linearize.c
parentaae836a7aa628af4d4d5dd97d0eefa898e8f5245 (diff)
netlink: fix network address prefix
eg. nft add rule filter output ip daddr 192.168.1.0/24 counter so far, this operation was only possible using sets. nft add rule filter output ip daddr \{ 192.168.1.0/24 \} counter While at it, move all binop postprocess code to a new function that contains this transformation and the existing bitmask to constant (as used by eg. ct state new,established). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_linearize.c')
-rw-r--r--src/netlink_linearize.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 044815a3..e507f912 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -184,18 +184,36 @@ static void netlink_gen_cmp(struct netlink_linearize_ctx *ctx,
{
struct nft_rule_expr *nle;
enum nft_registers sreg;
- struct nft_data_linearize nld;
+ struct nft_data_linearize nld, zero = {};
+ struct expr *right;
assert(dreg == NFT_REG_VERDICT);
sreg = get_register(ctx);
netlink_gen_expr(ctx, expr->left, sreg);
+ if (expr->right->ops->type == EXPR_PREFIX) {
+ right = expr->right->prefix;
+
+ netlink_gen_data(expr->right, &nld);
+ zero.len = nld.len;
+
+ nle = alloc_nft_expr("bitwise");
+ nft_rule_expr_set_u32(nle, NFT_EXPR_BITWISE_SREG, sreg);
+ nft_rule_expr_set_u32(nle, NFT_EXPR_BITWISE_DREG, sreg);
+ nft_rule_expr_set_u32(nle, NFT_EXPR_BITWISE_LEN, nld.len);
+ nft_rule_expr_set(nle, NFT_EXPR_BITWISE_MASK, &nld.value, nld.len);
+ nft_rule_expr_set(nle, NFT_EXPR_BITWISE_XOR, &zero.value, zero.len);
+ nft_rule_add_expr(ctx->nlr, nle);
+ } else {
+ right = expr->right;
+ }
+
nle = alloc_nft_expr("cmp");
nft_rule_expr_set_u8(nle, NFT_EXPR_CMP_SREG, sreg);
nft_rule_expr_set_u8(nle, NFT_EXPR_CMP_OP,
- netlink_gen_cmp_op(expr->op));
- netlink_gen_data(expr->right, &nld);
+ netlink_gen_cmp_op(expr->op));
+ netlink_gen_data(right, &nld);
nft_rule_expr_set(nle, NFT_EXPR_CMP_DATA, nld.value, nld.len);
release_register(ctx);