On Fri, Sep 23, 2022 at 02:17:08PM +0200, Florian Westphal wrote: > Instead of assuming only one register is used, track all 16 regs > individually. > > This avoids need for the 'PREV_PAYLOAD' hack and also avoids the need to > clear out old flags: > > When we see that register 'x' will be written to, that register state is > reset automatically. > > Existing dissector decodes > ip saddr 1.2.3.4 meta l4proto tcp > ... as > -s 6.0.0.0 -p tcp > > iptables-nft -s 1.2.3.4 -p tcp is decoded correctly because the expressions > are ordered like: > > meta l4proto tcp ip saddr 1.2.3.4 > | > ... and 'meta l4proto' did clear the PAYLOAD flag. > > The simpler fix is: > ctx->flags &= ~NFT_XT_CTX_PAYLOAD; > > in nft_parse_cmp(), but that breaks dissection of '1-42', because > the second compare ('cmp lte 42') will not find the > payload expression anymore. > > Link: https://lore.kernel.org/netfilter-devel/20220922143544.GA22541@xxxxxxxxxxxxx/T/#t > Signed-off-by: Florian Westphal <fw@xxxxxxxxx> Reviewed-by: Phil Sutter <phil@xxxxxx> Just a typo spotted: [...] > @@ -883,7 +933,17 @@ static void nft_parse_transport(struct nft_xt_ctx *ctx, > nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len); > op = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP); > > - switch(ctx->payload.offset) { > + reg = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_SREG); > + sreg = nft_xt_ctx_get_sreg(ctx, reg); > + if (!sreg) > + return; > + > + if (sreg->type != NFT_XT_REG_PAYLOAD) { > + ctx->errmsg = "sgreg not payload"; ^^^^^ > + return; > + } > + > + switch(sreg->payload.offset) { > case 0: /* th->sport */ > switch (len) { > case 2: /* load sport only */