21
21
#include <linux/ip.h>
22
22
#include <linux/ipv6.h>
23
23
24
+ static DEFINE_PER_CPU (struct nft_inner_tun_ctx , nft_pcpu_tun_ctx ) ;
25
+
24
26
/* Same layout as nft_expr but it embeds the private expression data area. */
25
27
struct __nft_expr {
26
28
const struct nft_expr_ops * ops ;
@@ -180,7 +182,7 @@ static int nft_inner_parse_tunhdr(const struct nft_inner *priv,
180
182
}
181
183
182
184
static int nft_inner_parse (const struct nft_inner * priv ,
183
- const struct nft_pktinfo * pkt ,
185
+ struct nft_pktinfo * pkt ,
184
186
struct nft_inner_tun_ctx * tun_ctx )
185
187
{
186
188
struct nft_inner_tun_ctx ctx = {};
@@ -199,25 +201,41 @@ static int nft_inner_parse(const struct nft_inner *priv,
199
201
}
200
202
201
203
* tun_ctx = ctx ;
204
+ tun_ctx -> type = priv -> type ;
205
+ pkt -> flags |= NFT_PKTINFO_INNER_FULL ;
202
206
203
207
return 0 ;
204
208
}
205
209
210
+ static bool nft_inner_parse_needed (const struct nft_inner * priv ,
211
+ const struct nft_pktinfo * pkt ,
212
+ const struct nft_inner_tun_ctx * tun_ctx )
213
+ {
214
+ if (!(pkt -> flags & NFT_PKTINFO_INNER_FULL ))
215
+ return true;
216
+
217
+ if (priv -> type != tun_ctx -> type )
218
+ return true;
219
+
220
+ return false;
221
+ }
222
+
206
223
static void nft_inner_eval (const struct nft_expr * expr , struct nft_regs * regs ,
207
224
const struct nft_pktinfo * pkt )
208
225
{
226
+ struct nft_inner_tun_ctx * tun_ctx = this_cpu_ptr (& nft_pcpu_tun_ctx );
209
227
const struct nft_inner * priv = nft_expr_priv (expr );
210
- struct nft_inner_tun_ctx tun_ctx = {};
211
228
212
229
if (nft_payload_inner_offset (pkt ) < 0 )
213
230
goto err ;
214
231
215
- if (nft_inner_parse (priv , pkt , & tun_ctx ) < 0 )
232
+ if (nft_inner_parse_needed (priv , pkt , tun_ctx ) &&
233
+ nft_inner_parse (priv , (struct nft_pktinfo * )pkt , tun_ctx ) < 0 )
216
234
goto err ;
217
235
218
236
switch (priv -> expr_type ) {
219
237
case NFT_INNER_EXPR_PAYLOAD :
220
- nft_payload_inner_eval ((struct nft_expr * )& priv -> expr , regs , pkt , & tun_ctx );
238
+ nft_payload_inner_eval ((struct nft_expr * )& priv -> expr , regs , pkt , tun_ctx );
221
239
break ;
222
240
default :
223
241
WARN_ON_ONCE (1 );
0 commit comments