From: Florian Westphal <fw@xxxxxxxxx> Mixing nftables and iptables-nft in the same table doesn't work, but some people do this. v1.8.8 ignored rules it could not represent in iptables syntax, v1.8.9 bails in this case. Add parsing of meta mark expressions so iptables-nft can render them as -j MARK rules. This is flawed, nft has features that have no corresponding syntax in iptables, but we can't undo this. Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1659 Signed-off-by: Florian Westphal <fw@xxxxxxxxx> Signed-off-by: Phil Sutter <phil@xxxxxx> --- iptables/nft-ruleparse.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/iptables/nft-ruleparse.c b/iptables/nft-ruleparse.c index a5eb6d098084a..c8322f936acd9 100644 --- a/iptables/nft-ruleparse.c +++ b/iptables/nft-ruleparse.c @@ -146,11 +146,6 @@ static bool nft_parse_meta_set_common(struct nft_xt_ctx* ctx, return false; } - if (sreg->immediate.data[0] == 0) { - ctx->errmsg = "meta sreg immediate is 0"; - return false; - } - return true; } @@ -159,7 +154,6 @@ static void nft_parse_meta_set(struct nft_xt_ctx *ctx, { struct nft_xt_ctx_reg *sreg; enum nft_registers sregnum; - const char *targname; sregnum = nftnl_expr_get_u32(e, NFTNL_EXPR_META_SREG); sreg = nft_xt_ctx_get_sreg(ctx, sregnum); @@ -171,21 +165,43 @@ static void nft_parse_meta_set(struct nft_xt_ctx *ctx, if (!nft_parse_meta_set_common(ctx, sreg)) return; - targname = "TRACE"; + if (sreg->immediate.data[0] == 0) { + ctx->errmsg = "meta sreg immediate is 0"; + return; + } + + if (!nft_create_target(ctx, "TRACE")) + ctx->errmsg = "target TRACE not found"; break; case NFT_META_BRI_BROUTE: if (!nft_parse_meta_set_common(ctx, sreg)) return; ctx->cs->jumpto = "DROP"; - return; + break; + case NFT_META_MARK: { + struct xt_mark_tginfo2 *mt; + + if (!nft_parse_meta_set_common(ctx, sreg)) + return; + + mt = nft_create_target(ctx, "MARK"); + if (!mt) { + ctx->errmsg = "target MARK not found"; + return; + } + + mt->mark = sreg->immediate.data[0]; + if (sreg->bitwise.set) + mt->mask = sreg->bitwise.mask[0]; + else + mt->mask = ~0u; + break; + } default: ctx->errmsg = "meta sreg key not supported"; - return; + break; } - - if (!nft_create_target(ctx, targname)) - ctx->errmsg = "target TRACE not found"; } static void nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e) -- 2.40.0