Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nft_tunnel: track register operations

Check if the destination register already contains the data that this
tunnel expression performs. This allows to skip this redundant operation.
If the destination contains a different selector, update the register
tracking information. This patch does not perform bitwise tracking.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+28
+28
net/netfilter/nft_tunnel.c
··· 17 17 enum nft_tunnel_keys key:8; 18 18 u8 dreg; 19 19 enum nft_tunnel_mode mode:8; 20 + u8 len; 20 21 }; 21 22 22 23 static void nft_tunnel_get_eval(const struct nft_expr *expr, ··· 102 101 priv->mode = NFT_TUNNEL_MODE_NONE; 103 102 } 104 103 104 + priv->len = len; 105 105 return nft_parse_register_store(ctx, tb[NFTA_TUNNEL_DREG], &priv->dreg, 106 106 NULL, NFT_DATA_VALUE, len); 107 107 } ··· 124 122 return -1; 125 123 } 126 124 125 + static bool nft_tunnel_get_reduce(struct nft_regs_track *track, 126 + const struct nft_expr *expr) 127 + { 128 + const struct nft_tunnel *priv = nft_expr_priv(expr); 129 + const struct nft_tunnel *tunnel; 130 + 131 + if (!nft_reg_track_cmp(track, expr, priv->dreg)) { 132 + nft_reg_track_update(track, expr, priv->dreg, priv->len); 133 + return false; 134 + } 135 + 136 + tunnel = nft_expr_priv(track->regs[priv->dreg].selector); 137 + if (priv->key != tunnel->key || 138 + priv->dreg != tunnel->dreg || 139 + priv->mode != tunnel->mode) { 140 + nft_reg_track_update(track, expr, priv->dreg, priv->len); 141 + return false; 142 + } 143 + 144 + if (!track->regs[priv->dreg].bitwise) 145 + return true; 146 + 147 + return false; 148 + } 149 + 127 150 static struct nft_expr_type nft_tunnel_type; 128 151 static const struct nft_expr_ops nft_tunnel_get_ops = { 129 152 .type = &nft_tunnel_type, ··· 156 129 .eval = nft_tunnel_get_eval, 157 130 .init = nft_tunnel_get_init, 158 131 .dump = nft_tunnel_get_dump, 132 + .reduce = nft_tunnel_get_reduce, 159 133 }; 160 134 161 135 static struct nft_expr_type nft_tunnel_type __read_mostly = {