summaryrefslogtreecommitdiffstats
path: root/src/netlink_delinearize.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2017-11-09 03:42:55 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-06-06 19:18:43 +0200
commit30d45266bf38b209df33e4df1a116c60531ae3e5 (patch)
treeaf94699ae6d6a58edf84aabfff31bc82ff44e642 /src/netlink_delinearize.c
parent57e4a095edc4dab19e14fc8d1bca3febde1ca86c (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.c41
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);