diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2022-03-14 20:23:06 +0300 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2022-03-20 02:29:47 +0300 |
commit | ffe6488e624e1edd71efcac3cd512d234939a96d (patch) | |
tree | 462ab6d49d25b7d0ef0c1d61ef54c9c74c495e03 /net/netfilter/nft_osf.c | |
parent | 4e2b29d8816805f3add34fb295e72539eba46a31 (diff) | |
download | linux-ffe6488e624e1edd71efcac3cd512d234939a96d.tar.xz |
netfilter: nft_osf: track register operations
Allow to recycle the previous output of the OS fingerprint expression
if flags and ttl are the same.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nft_osf.c')
-rw-r--r-- | net/netfilter/nft_osf.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c index d82677e83400..5eed18f90b02 100644 --- a/net/netfilter/nft_osf.c +++ b/net/netfilter/nft_osf.c @@ -120,6 +120,30 @@ static int nft_osf_validate(const struct nft_ctx *ctx, (1 << NF_INET_FORWARD)); } +static bool nft_osf_reduce(struct nft_regs_track *track, + const struct nft_expr *expr) +{ + struct nft_osf *priv = nft_expr_priv(expr); + struct nft_osf *osf; + + if (!nft_reg_track_cmp(track, expr, priv->dreg)) { + nft_reg_track_update(track, expr, priv->dreg, NFT_OSF_MAXGENRELEN); + return false; + } + + osf = nft_expr_priv(track->regs[priv->dreg].selector); + if (priv->flags != osf->flags || + priv->ttl != osf->ttl) { + nft_reg_track_update(track, expr, priv->dreg, NFT_OSF_MAXGENRELEN); + return false; + } + + if (!track->regs[priv->dreg].bitwise) + return true; + + return false; +} + static struct nft_expr_type nft_osf_type; static const struct nft_expr_ops nft_osf_op = { .eval = nft_osf_eval, @@ -128,6 +152,7 @@ static const struct nft_expr_ops nft_osf_op = { .dump = nft_osf_dump, .type = &nft_osf_type, .validate = nft_osf_validate, + .reduce = nft_osf_reduce, }; static struct nft_expr_type nft_osf_type __read_mostly = { |