diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-11-09 03:42:55 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-06-06 19:18:43 +0200 |
commit | 30d45266bf38b209df33e4df1a116c60531ae3e5 (patch) | |
tree | af94699ae6d6a58edf84aabfff31bc82ff44e642 /src/netlink_delinearize.c | |
parent | 57e4a095edc4dab19e14fc8d1bca3febde1ca86c (diff) |
expr: extend fwd statement to support address and family
Allow to forward packets through to explicit destination and interface.
nft add rule netdev x y fwd ip to 192.168.2.200 device eth0
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_delinearize.c')
-rw-r--r-- | src/netlink_delinearize.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 7dbf596a..1c3a4fb7 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -1109,8 +1109,8 @@ static void netlink_parse_fwd(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nftnl_expr *nle) { - enum nft_registers reg1; - struct expr *dev; + enum nft_registers reg1, reg2; + struct expr *dev, *addr; struct stmt *stmt; stmt = fwd_stmt_alloc(loc); @@ -1125,7 +1125,37 @@ static void netlink_parse_fwd(struct netlink_parse_ctx *ctx, } expr_set_type(dev, &ifindex_type, BYTEORDER_HOST_ENDIAN); - stmt->fwd.to = dev; + stmt->fwd.dev = dev; + } + + if (nftnl_expr_is_set(nle, NFTNL_EXPR_FWD_NFPROTO)) { + stmt->fwd.family = + nftnl_expr_get_u32(nle, NFTNL_EXPR_FWD_NFPROTO); + } + + if (nftnl_expr_is_set(nle, NFTNL_EXPR_FWD_SREG_ADDR)) { + reg2 = netlink_parse_register(nle, NFTNL_EXPR_FWD_SREG_ADDR); + if (reg2) { + addr = netlink_get_register(ctx, loc, reg2); + if (addr == NULL) + return netlink_error(ctx, loc, + "fwd statement has no output expression"); + + switch (stmt->fwd.family) { + case AF_INET: + expr_set_type(addr, &ipaddr_type, + BYTEORDER_BIG_ENDIAN); + break; + case AF_INET6: + expr_set_type(addr, &ip6addr_type, + BYTEORDER_BIG_ENDIAN); + break; + default: + return netlink_error(ctx, loc, + "fwd statement has no family"); + } + stmt->fwd.addr = addr; + } } ctx->stmt = stmt; @@ -2398,8 +2428,9 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r expr_postprocess(&rctx, &stmt->dup.dev); break; case STMT_FWD: - if (stmt->fwd.to != NULL) - expr_postprocess(&rctx, &stmt->fwd.to); + expr_postprocess(&rctx, &stmt->fwd.dev); + if (stmt->fwd.addr != NULL) + expr_postprocess(&rctx, &stmt->fwd.addr); break; case STMT_XT: stmt_xt_postprocess(&rctx, stmt, rule); |