From b870b949470af0b1b578590b38efdd80048b539e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 29 Sep 2015 18:21:54 +0200 Subject: src: add dup statement support This allows you to clone packets to destination address, eg. ... dup to 172.20.0.2 ... dup to 172.20.0.2 device eth1 ... dup to ip saddr map { 192.168.0.2 : 172.20.0.2, ... } device eth1 Signed-off-by: Pablo Neira Ayuso --- src/netlink_delinearize.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src/netlink_delinearize.c') diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 2360681d..09f5932a 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -749,6 +749,52 @@ static void netlink_parse_redir(struct netlink_parse_ctx *ctx, list_add_tail(&stmt->list, &ctx->rule->stmts); } +static void netlink_parse_dup(struct netlink_parse_ctx *ctx, + const struct location *loc, + const struct nftnl_expr *nle) +{ + enum nft_registers reg1, reg2; + struct expr *addr, *dev; + struct stmt *stmt; + + stmt = dup_stmt_alloc(loc); + + reg1 = netlink_parse_register(nle, NFTNL_EXPR_DUP_SREG_ADDR); + if (reg1) { + addr = netlink_get_register(ctx, loc, reg1); + if (addr == NULL) + return netlink_error(ctx, loc, + "DUP statement has no destination expression"); + + switch (ctx->table->handle.family) { + case NFPROTO_IPV4: + expr_set_type(addr, &ipaddr_type, BYTEORDER_BIG_ENDIAN); + break; + case NFPROTO_IPV6: + expr_set_type(addr, &ip6addr_type, + BYTEORDER_BIG_ENDIAN); + break; + } + stmt->dup.to = addr; + } + + reg2 = netlink_parse_register(nle, NFTNL_EXPR_DUP_SREG_DEV); + if (reg2) { + dev = netlink_get_register(ctx, loc, reg2); + if (dev == NULL) + return netlink_error(ctx, loc, + "DUP statement has no output expression"); + + expr_set_type(dev, &ifindex_type, BYTEORDER_HOST_ENDIAN); + if (stmt->dup.to == NULL) + stmt->dup.to = dev; + else + stmt->dup.dev = dev; + } + + list_add_tail(&stmt->list, &ctx->rule->stmts); +} + static void netlink_parse_queue(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nftnl_expr *nle) @@ -837,6 +883,7 @@ static const struct { { .name = "nat", .parse = netlink_parse_nat }, { .name = "masq", .parse = netlink_parse_masq }, { .name = "redir", .parse = netlink_parse_redir }, + { .name = "dup", .parse = netlink_parse_dup }, { .name = "queue", .parse = netlink_parse_queue }, { .name = "dynset", .parse = netlink_parse_dynset }, }; @@ -1460,6 +1507,12 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r case STMT_SET: expr_postprocess(&rctx, &stmt->set.key); break; + case STMT_DUP: + if (stmt->dup.to != NULL) + expr_postprocess(&rctx, &stmt->dup.to); + if (stmt->dup.dev != NULL) + expr_postprocess(&rctx, &stmt->dup.dev); + break; default: break; } -- cgit v1.2.3