xref: /openbmc/linux/net/netfilter/nft_payload.c (revision ae9e39a2)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
4  * Copyright (c) 2016 Pablo Neira Ayuso <pablo@netfilter.org>
5  *
6  * Development of this code funded by Astaro AG (http://www.astaro.com/)
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/if_vlan.h>
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/netlink.h>
14 #include <linux/netfilter.h>
15 #include <linux/netfilter/nf_tables.h>
16 #include <net/netfilter/nf_tables_core.h>
17 #include <net/netfilter/nf_tables.h>
18 #include <net/netfilter/nf_tables_offload.h>
19 /* For layer 4 checksum field offset. */
20 #include <linux/tcp.h>
21 #include <linux/udp.h>
22 #include <net/gre.h>
23 #include <linux/icmpv6.h>
24 #include <linux/ip.h>
25 #include <linux/ipv6.h>
26 #include <net/sctp/checksum.h>
27 
28 static bool nft_payload_rebuild_vlan_hdr(const struct sk_buff *skb, int mac_off,
29 					 struct vlan_ethhdr *veth)
30 {
31 	if (skb_copy_bits(skb, mac_off, veth, ETH_HLEN))
32 		return false;
33 
34 	veth->h_vlan_proto = skb->vlan_proto;
35 	veth->h_vlan_TCI = htons(skb_vlan_tag_get(skb));
36 	veth->h_vlan_encapsulated_proto = skb->protocol;
37 
38 	return true;
39 }
40 
41 /* add vlan header into the user buffer for if tag was removed by offloads */
42 static bool
43 nft_payload_copy_vlan(u32 *d, const struct sk_buff *skb, u8 offset, u8 len)
44 {
45 	int mac_off = skb_mac_header(skb) - skb->data;
46 	u8 *vlanh, *dst_u8 = (u8 *) d;
47 	struct vlan_ethhdr veth;
48 
49 	vlanh = (u8 *) &veth;
50 	if (offset < VLAN_ETH_HLEN) {
51 		u8 ethlen = len;
52 
53 		if (!nft_payload_rebuild_vlan_hdr(skb, mac_off, &veth))
54 			return false;
55 
56 		if (offset + len > VLAN_ETH_HLEN)
57 			ethlen -= offset + len - VLAN_ETH_HLEN;
58 
59 		memcpy(dst_u8, vlanh + offset, ethlen);
60 
61 		len -= ethlen;
62 		if (len == 0)
63 			return true;
64 
65 		dst_u8 += ethlen;
66 		offset = ETH_HLEN;
67 	} else {
68 		offset -= VLAN_HLEN;
69 	}
70 
71 	return skb_copy_bits(skb, offset + mac_off, dst_u8, len) == 0;
72 }
73 
74 static int __nft_payload_inner_offset(struct nft_pktinfo *pkt)
75 {
76 	unsigned int thoff = nft_thoff(pkt);
77 
78 	if (!(pkt->flags & NFT_PKTINFO_L4PROTO) || pkt->fragoff)
79 		return -1;
80 
81 	switch (pkt->tprot) {
82 	case IPPROTO_UDP:
83 		pkt->inneroff = thoff + sizeof(struct udphdr);
84 		break;
85 	case IPPROTO_TCP: {
86 		struct tcphdr *th, _tcph;
87 
88 		th = skb_header_pointer(pkt->skb, thoff, sizeof(_tcph), &_tcph);
89 		if (!th)
90 			return -1;
91 
92 		pkt->inneroff = thoff + __tcp_hdrlen(th);
93 		}
94 		break;
95 	case IPPROTO_GRE: {
96 		u32 offset = sizeof(struct gre_base_hdr);
97 		struct gre_base_hdr *gre, _gre;
98 		__be16 version;
99 
100 		gre = skb_header_pointer(pkt->skb, thoff, sizeof(_gre), &_gre);
101 		if (!gre)
102 			return -1;
103 
104 		version = gre->flags & GRE_VERSION;
105 		switch (version) {
106 		case GRE_VERSION_0:
107 			if (gre->flags & GRE_ROUTING)
108 				return -1;
109 
110 			if (gre->flags & GRE_CSUM) {
111 				offset += sizeof_field(struct gre_full_hdr, csum) +
112 					  sizeof_field(struct gre_full_hdr, reserved1);
113 			}
114 			if (gre->flags & GRE_KEY)
115 				offset += sizeof_field(struct gre_full_hdr, key);
116 
117 			if (gre->flags & GRE_SEQ)
118 				offset += sizeof_field(struct gre_full_hdr, seq);
119 			break;
120 		default:
121 			return -1;
122 		}
123 
124 		pkt->inneroff = thoff + offset;
125 		}
126 		break;
127 	case IPPROTO_IPIP:
128 		pkt->inneroff = thoff;
129 		break;
130 	default:
131 		return -1;
132 	}
133 
134 	pkt->flags |= NFT_PKTINFO_INNER;
135 
136 	return 0;
137 }
138 
139 int nft_payload_inner_offset(const struct nft_pktinfo *pkt)
140 {
141 	if (!(pkt->flags & NFT_PKTINFO_INNER) &&
142 	    __nft_payload_inner_offset((struct nft_pktinfo *)pkt) < 0)
143 		return -1;
144 
145 	return pkt->inneroff;
146 }
147 
148 static bool nft_payload_need_vlan_adjust(u32 offset, u32 len)
149 {
150 	unsigned int boundary = offset + len;
151 
152 	/* data past ether src/dst requested, copy needed */
153 	if (boundary > offsetof(struct ethhdr, h_proto))
154 		return true;
155 
156 	return false;
157 }
158 
159 void nft_payload_eval(const struct nft_expr *expr,
160 		      struct nft_regs *regs,
161 		      const struct nft_pktinfo *pkt)
162 {
163 	const struct nft_payload *priv = nft_expr_priv(expr);
164 	const struct sk_buff *skb = pkt->skb;
165 	u32 *dest = &regs->data[priv->dreg];
166 	int offset;
167 
168 	if (priv->len % NFT_REG32_SIZE)
169 		dest[priv->len / NFT_REG32_SIZE] = 0;
170 
171 	switch (priv->base) {
172 	case NFT_PAYLOAD_LL_HEADER:
173 		if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) == 0)
174 			goto err;
175 
176 		if (skb_vlan_tag_present(skb) &&
177 		    nft_payload_need_vlan_adjust(priv->offset, priv->len)) {
178 			if (!nft_payload_copy_vlan(dest, skb,
179 						   priv->offset, priv->len))
180 				goto err;
181 			return;
182 		}
183 		offset = skb_mac_header(skb) - skb->data;
184 		break;
185 	case NFT_PAYLOAD_NETWORK_HEADER:
186 		offset = skb_network_offset(skb);
187 		break;
188 	case NFT_PAYLOAD_TRANSPORT_HEADER:
189 		if (!(pkt->flags & NFT_PKTINFO_L4PROTO) || pkt->fragoff)
190 			goto err;
191 		offset = nft_thoff(pkt);
192 		break;
193 	case NFT_PAYLOAD_INNER_HEADER:
194 		offset = nft_payload_inner_offset(pkt);
195 		if (offset < 0)
196 			goto err;
197 		break;
198 	default:
199 		WARN_ON_ONCE(1);
200 		goto err;
201 	}
202 	offset += priv->offset;
203 
204 	if (skb_copy_bits(skb, offset, dest, priv->len) < 0)
205 		goto err;
206 	return;
207 err:
208 	regs->verdict.code = NFT_BREAK;
209 }
210 
211 static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = {
212 	[NFTA_PAYLOAD_SREG]		= { .type = NLA_U32 },
213 	[NFTA_PAYLOAD_DREG]		= { .type = NLA_U32 },
214 	[NFTA_PAYLOAD_BASE]		= { .type = NLA_U32 },
215 	[NFTA_PAYLOAD_OFFSET]		= NLA_POLICY_MAX(NLA_BE32, 255),
216 	[NFTA_PAYLOAD_LEN]		= NLA_POLICY_MAX(NLA_BE32, 255),
217 	[NFTA_PAYLOAD_CSUM_TYPE]	= { .type = NLA_U32 },
218 	[NFTA_PAYLOAD_CSUM_OFFSET]	= NLA_POLICY_MAX(NLA_BE32, 255),
219 	[NFTA_PAYLOAD_CSUM_FLAGS]	= { .type = NLA_U32 },
220 };
221 
222 static int nft_payload_init(const struct nft_ctx *ctx,
223 			    const struct nft_expr *expr,
224 			    const struct nlattr * const tb[])
225 {
226 	struct nft_payload *priv = nft_expr_priv(expr);
227 
228 	priv->base   = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
229 	priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
230 	priv->len    = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
231 
232 	return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
233 					&priv->dreg, NULL, NFT_DATA_VALUE,
234 					priv->len);
235 }
236 
237 static int nft_payload_dump(struct sk_buff *skb,
238 			    const struct nft_expr *expr, bool reset)
239 {
240 	const struct nft_payload *priv = nft_expr_priv(expr);
241 
242 	if (nft_dump_register(skb, NFTA_PAYLOAD_DREG, priv->dreg) ||
243 	    nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) ||
244 	    nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) ||
245 	    nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)))
246 		goto nla_put_failure;
247 	return 0;
248 
249 nla_put_failure:
250 	return -1;
251 }
252 
253 static bool nft_payload_reduce(struct nft_regs_track *track,
254 			       const struct nft_expr *expr)
255 {
256 	const struct nft_payload *priv = nft_expr_priv(expr);
257 	const struct nft_payload *payload;
258 
259 	if (!nft_reg_track_cmp(track, expr, priv->dreg)) {
260 		nft_reg_track_update(track, expr, priv->dreg, priv->len);
261 		return false;
262 	}
263 
264 	payload = nft_expr_priv(track->regs[priv->dreg].selector);
265 	if (priv->base != payload->base ||
266 	    priv->offset != payload->offset ||
267 	    priv->len != payload->len) {
268 		nft_reg_track_update(track, expr, priv->dreg, priv->len);
269 		return false;
270 	}
271 
272 	if (!track->regs[priv->dreg].bitwise)
273 		return true;
274 
275 	return nft_expr_reduce_bitwise(track, expr);
276 }
277 
278 static bool nft_payload_offload_mask(struct nft_offload_reg *reg,
279 				     u32 priv_len, u32 field_len)
280 {
281 	unsigned int remainder, delta, k;
282 	struct nft_data mask = {};
283 	__be32 remainder_mask;
284 
285 	if (priv_len == field_len) {
286 		memset(&reg->mask, 0xff, priv_len);
287 		return true;
288 	} else if (priv_len > field_len) {
289 		return false;
290 	}
291 
292 	memset(&mask, 0xff, field_len);
293 	remainder = priv_len % sizeof(u32);
294 	if (remainder) {
295 		k = priv_len / sizeof(u32);
296 		delta = field_len - priv_len;
297 		remainder_mask = htonl(~((1 << (delta * BITS_PER_BYTE)) - 1));
298 		mask.data[k] = (__force u32)remainder_mask;
299 	}
300 
301 	memcpy(&reg->mask, &mask, field_len);
302 
303 	return true;
304 }
305 
306 static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
307 				  struct nft_flow_rule *flow,
308 				  const struct nft_payload *priv)
309 {
310 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
311 
312 	switch (priv->offset) {
313 	case offsetof(struct ethhdr, h_source):
314 		if (!nft_payload_offload_mask(reg, priv->len, ETH_ALEN))
315 			return -EOPNOTSUPP;
316 
317 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
318 				  src, ETH_ALEN, reg);
319 		break;
320 	case offsetof(struct ethhdr, h_dest):
321 		if (!nft_payload_offload_mask(reg, priv->len, ETH_ALEN))
322 			return -EOPNOTSUPP;
323 
324 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
325 				  dst, ETH_ALEN, reg);
326 		break;
327 	case offsetof(struct ethhdr, h_proto):
328 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
329 			return -EOPNOTSUPP;
330 
331 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic,
332 				  n_proto, sizeof(__be16), reg);
333 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
334 		break;
335 	case offsetof(struct vlan_ethhdr, h_vlan_TCI):
336 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
337 			return -EOPNOTSUPP;
338 
339 		NFT_OFFLOAD_MATCH_FLAGS(FLOW_DISSECTOR_KEY_VLAN, vlan,
340 					vlan_tci, sizeof(__be16), reg,
341 					NFT_OFFLOAD_F_NETWORK2HOST);
342 		break;
343 	case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto):
344 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
345 			return -EOPNOTSUPP;
346 
347 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan,
348 				  vlan_tpid, sizeof(__be16), reg);
349 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
350 		break;
351 	case offsetof(struct vlan_ethhdr, h_vlan_TCI) + sizeof(struct vlan_hdr):
352 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
353 			return -EOPNOTSUPP;
354 
355 		NFT_OFFLOAD_MATCH_FLAGS(FLOW_DISSECTOR_KEY_CVLAN, cvlan,
356 					vlan_tci, sizeof(__be16), reg,
357 					NFT_OFFLOAD_F_NETWORK2HOST);
358 		break;
359 	case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto) +
360 							sizeof(struct vlan_hdr):
361 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
362 			return -EOPNOTSUPP;
363 
364 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, cvlan,
365 				  vlan_tpid, sizeof(__be16), reg);
366 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
367 		break;
368 	default:
369 		return -EOPNOTSUPP;
370 	}
371 
372 	return 0;
373 }
374 
375 static int nft_payload_offload_ip(struct nft_offload_ctx *ctx,
376 				  struct nft_flow_rule *flow,
377 				  const struct nft_payload *priv)
378 {
379 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
380 
381 	switch (priv->offset) {
382 	case offsetof(struct iphdr, saddr):
383 		if (!nft_payload_offload_mask(reg, priv->len,
384 					      sizeof(struct in_addr)))
385 			return -EOPNOTSUPP;
386 
387 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src,
388 				  sizeof(struct in_addr), reg);
389 		nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV4_ADDRS);
390 		break;
391 	case offsetof(struct iphdr, daddr):
392 		if (!nft_payload_offload_mask(reg, priv->len,
393 					      sizeof(struct in_addr)))
394 			return -EOPNOTSUPP;
395 
396 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst,
397 				  sizeof(struct in_addr), reg);
398 		nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV4_ADDRS);
399 		break;
400 	case offsetof(struct iphdr, protocol):
401 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__u8)))
402 			return -EOPNOTSUPP;
403 
404 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
405 				  sizeof(__u8), reg);
406 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
407 		break;
408 	default:
409 		return -EOPNOTSUPP;
410 	}
411 
412 	return 0;
413 }
414 
415 static int nft_payload_offload_ip6(struct nft_offload_ctx *ctx,
416 				  struct nft_flow_rule *flow,
417 				  const struct nft_payload *priv)
418 {
419 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
420 
421 	switch (priv->offset) {
422 	case offsetof(struct ipv6hdr, saddr):
423 		if (!nft_payload_offload_mask(reg, priv->len,
424 					      sizeof(struct in6_addr)))
425 			return -EOPNOTSUPP;
426 
427 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src,
428 				  sizeof(struct in6_addr), reg);
429 		nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV6_ADDRS);
430 		break;
431 	case offsetof(struct ipv6hdr, daddr):
432 		if (!nft_payload_offload_mask(reg, priv->len,
433 					      sizeof(struct in6_addr)))
434 			return -EOPNOTSUPP;
435 
436 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst,
437 				  sizeof(struct in6_addr), reg);
438 		nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV6_ADDRS);
439 		break;
440 	case offsetof(struct ipv6hdr, nexthdr):
441 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__u8)))
442 			return -EOPNOTSUPP;
443 
444 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
445 				  sizeof(__u8), reg);
446 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
447 		break;
448 	default:
449 		return -EOPNOTSUPP;
450 	}
451 
452 	return 0;
453 }
454 
455 static int nft_payload_offload_nh(struct nft_offload_ctx *ctx,
456 				  struct nft_flow_rule *flow,
457 				  const struct nft_payload *priv)
458 {
459 	int err;
460 
461 	switch (ctx->dep.l3num) {
462 	case htons(ETH_P_IP):
463 		err = nft_payload_offload_ip(ctx, flow, priv);
464 		break;
465 	case htons(ETH_P_IPV6):
466 		err = nft_payload_offload_ip6(ctx, flow, priv);
467 		break;
468 	default:
469 		return -EOPNOTSUPP;
470 	}
471 
472 	return err;
473 }
474 
475 static int nft_payload_offload_tcp(struct nft_offload_ctx *ctx,
476 				   struct nft_flow_rule *flow,
477 				   const struct nft_payload *priv)
478 {
479 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
480 
481 	switch (priv->offset) {
482 	case offsetof(struct tcphdr, source):
483 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
484 			return -EOPNOTSUPP;
485 
486 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
487 				  sizeof(__be16), reg);
488 		break;
489 	case offsetof(struct tcphdr, dest):
490 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
491 			return -EOPNOTSUPP;
492 
493 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
494 				  sizeof(__be16), reg);
495 		break;
496 	default:
497 		return -EOPNOTSUPP;
498 	}
499 
500 	return 0;
501 }
502 
503 static int nft_payload_offload_udp(struct nft_offload_ctx *ctx,
504 				   struct nft_flow_rule *flow,
505 				   const struct nft_payload *priv)
506 {
507 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
508 
509 	switch (priv->offset) {
510 	case offsetof(struct udphdr, source):
511 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
512 			return -EOPNOTSUPP;
513 
514 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
515 				  sizeof(__be16), reg);
516 		break;
517 	case offsetof(struct udphdr, dest):
518 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
519 			return -EOPNOTSUPP;
520 
521 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
522 				  sizeof(__be16), reg);
523 		break;
524 	default:
525 		return -EOPNOTSUPP;
526 	}
527 
528 	return 0;
529 }
530 
531 static int nft_payload_offload_th(struct nft_offload_ctx *ctx,
532 				  struct nft_flow_rule *flow,
533 				  const struct nft_payload *priv)
534 {
535 	int err;
536 
537 	switch (ctx->dep.protonum) {
538 	case IPPROTO_TCP:
539 		err = nft_payload_offload_tcp(ctx, flow, priv);
540 		break;
541 	case IPPROTO_UDP:
542 		err = nft_payload_offload_udp(ctx, flow, priv);
543 		break;
544 	default:
545 		return -EOPNOTSUPP;
546 	}
547 
548 	return err;
549 }
550 
551 static int nft_payload_offload(struct nft_offload_ctx *ctx,
552 			       struct nft_flow_rule *flow,
553 			       const struct nft_expr *expr)
554 {
555 	const struct nft_payload *priv = nft_expr_priv(expr);
556 	int err;
557 
558 	switch (priv->base) {
559 	case NFT_PAYLOAD_LL_HEADER:
560 		err = nft_payload_offload_ll(ctx, flow, priv);
561 		break;
562 	case NFT_PAYLOAD_NETWORK_HEADER:
563 		err = nft_payload_offload_nh(ctx, flow, priv);
564 		break;
565 	case NFT_PAYLOAD_TRANSPORT_HEADER:
566 		err = nft_payload_offload_th(ctx, flow, priv);
567 		break;
568 	default:
569 		err = -EOPNOTSUPP;
570 		break;
571 	}
572 	return err;
573 }
574 
575 static const struct nft_expr_ops nft_payload_ops = {
576 	.type		= &nft_payload_type,
577 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload)),
578 	.eval		= nft_payload_eval,
579 	.init		= nft_payload_init,
580 	.dump		= nft_payload_dump,
581 	.reduce		= nft_payload_reduce,
582 	.offload	= nft_payload_offload,
583 };
584 
585 const struct nft_expr_ops nft_payload_fast_ops = {
586 	.type		= &nft_payload_type,
587 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload)),
588 	.eval		= nft_payload_eval,
589 	.init		= nft_payload_init,
590 	.dump		= nft_payload_dump,
591 	.reduce		= nft_payload_reduce,
592 	.offload	= nft_payload_offload,
593 };
594 
595 void nft_payload_inner_eval(const struct nft_expr *expr, struct nft_regs *regs,
596 			    const struct nft_pktinfo *pkt,
597 			    struct nft_inner_tun_ctx *tun_ctx)
598 {
599 	const struct nft_payload *priv = nft_expr_priv(expr);
600 	const struct sk_buff *skb = pkt->skb;
601 	u32 *dest = &regs->data[priv->dreg];
602 	int offset;
603 
604 	if (priv->len % NFT_REG32_SIZE)
605 		dest[priv->len / NFT_REG32_SIZE] = 0;
606 
607 	switch (priv->base) {
608 	case NFT_PAYLOAD_TUN_HEADER:
609 		if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_TUN))
610 			goto err;
611 
612 		offset = tun_ctx->inner_tunoff;
613 		break;
614 	case NFT_PAYLOAD_LL_HEADER:
615 		if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_LL))
616 			goto err;
617 
618 		offset = tun_ctx->inner_lloff;
619 		break;
620 	case NFT_PAYLOAD_NETWORK_HEADER:
621 		if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_NH))
622 			goto err;
623 
624 		offset = tun_ctx->inner_nhoff;
625 		break;
626 	case NFT_PAYLOAD_TRANSPORT_HEADER:
627 		if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_TH))
628 			goto err;
629 
630 		offset = tun_ctx->inner_thoff;
631 		break;
632 	default:
633 		WARN_ON_ONCE(1);
634 		goto err;
635 	}
636 	offset += priv->offset;
637 
638 	if (skb_copy_bits(skb, offset, dest, priv->len) < 0)
639 		goto err;
640 
641 	return;
642 err:
643 	regs->verdict.code = NFT_BREAK;
644 }
645 
646 static int nft_payload_inner_init(const struct nft_ctx *ctx,
647 				  const struct nft_expr *expr,
648 				  const struct nlattr * const tb[])
649 {
650 	struct nft_payload *priv = nft_expr_priv(expr);
651 	u32 base;
652 
653 	base   = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
654 	switch (base) {
655 	case NFT_PAYLOAD_TUN_HEADER:
656 	case NFT_PAYLOAD_LL_HEADER:
657 	case NFT_PAYLOAD_NETWORK_HEADER:
658 	case NFT_PAYLOAD_TRANSPORT_HEADER:
659 		break;
660 	default:
661 		return -EOPNOTSUPP;
662 	}
663 
664 	priv->base   = base;
665 	priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
666 	priv->len    = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
667 
668 	return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
669 					&priv->dreg, NULL, NFT_DATA_VALUE,
670 					priv->len);
671 }
672 
673 static const struct nft_expr_ops nft_payload_inner_ops = {
674 	.type		= &nft_payload_type,
675 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload)),
676 	.init		= nft_payload_inner_init,
677 	.dump		= nft_payload_dump,
678 	/* direct call to nft_payload_inner_eval(). */
679 };
680 
681 static inline void nft_csum_replace(__sum16 *sum, __wsum fsum, __wsum tsum)
682 {
683 	*sum = csum_fold(csum_add(csum_sub(~csum_unfold(*sum), fsum), tsum));
684 	if (*sum == 0)
685 		*sum = CSUM_MANGLED_0;
686 }
687 
688 static bool nft_payload_udp_checksum(struct sk_buff *skb, unsigned int thoff)
689 {
690 	struct udphdr *uh, _uh;
691 
692 	uh = skb_header_pointer(skb, thoff, sizeof(_uh), &_uh);
693 	if (!uh)
694 		return false;
695 
696 	return (__force bool)uh->check;
697 }
698 
699 static int nft_payload_l4csum_offset(const struct nft_pktinfo *pkt,
700 				     struct sk_buff *skb,
701 				     unsigned int *l4csum_offset)
702 {
703 	if (pkt->fragoff)
704 		return -1;
705 
706 	switch (pkt->tprot) {
707 	case IPPROTO_TCP:
708 		*l4csum_offset = offsetof(struct tcphdr, check);
709 		break;
710 	case IPPROTO_UDP:
711 		if (!nft_payload_udp_checksum(skb, nft_thoff(pkt)))
712 			return -1;
713 		fallthrough;
714 	case IPPROTO_UDPLITE:
715 		*l4csum_offset = offsetof(struct udphdr, check);
716 		break;
717 	case IPPROTO_ICMPV6:
718 		*l4csum_offset = offsetof(struct icmp6hdr, icmp6_cksum);
719 		break;
720 	default:
721 		return -1;
722 	}
723 
724 	*l4csum_offset += nft_thoff(pkt);
725 	return 0;
726 }
727 
728 static int nft_payload_csum_sctp(struct sk_buff *skb, int offset)
729 {
730 	struct sctphdr *sh;
731 
732 	if (skb_ensure_writable(skb, offset + sizeof(*sh)))
733 		return -1;
734 
735 	sh = (struct sctphdr *)(skb->data + offset);
736 	sh->checksum = sctp_compute_cksum(skb, offset);
737 	skb->ip_summed = CHECKSUM_UNNECESSARY;
738 	return 0;
739 }
740 
741 static int nft_payload_l4csum_update(const struct nft_pktinfo *pkt,
742 				     struct sk_buff *skb,
743 				     __wsum fsum, __wsum tsum)
744 {
745 	int l4csum_offset;
746 	__sum16 sum;
747 
748 	/* If we cannot determine layer 4 checksum offset or this packet doesn't
749 	 * require layer 4 checksum recalculation, skip this packet.
750 	 */
751 	if (nft_payload_l4csum_offset(pkt, skb, &l4csum_offset) < 0)
752 		return 0;
753 
754 	if (skb_copy_bits(skb, l4csum_offset, &sum, sizeof(sum)) < 0)
755 		return -1;
756 
757 	/* Checksum mangling for an arbitrary amount of bytes, based on
758 	 * inet_proto_csum_replace*() functions.
759 	 */
760 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
761 		nft_csum_replace(&sum, fsum, tsum);
762 		if (skb->ip_summed == CHECKSUM_COMPLETE) {
763 			skb->csum = ~csum_add(csum_sub(~(skb->csum), fsum),
764 					      tsum);
765 		}
766 	} else {
767 		sum = ~csum_fold(csum_add(csum_sub(csum_unfold(sum), fsum),
768 					  tsum));
769 	}
770 
771 	if (skb_ensure_writable(skb, l4csum_offset + sizeof(sum)) ||
772 	    skb_store_bits(skb, l4csum_offset, &sum, sizeof(sum)) < 0)
773 		return -1;
774 
775 	return 0;
776 }
777 
778 static int nft_payload_csum_inet(struct sk_buff *skb, const u32 *src,
779 				 __wsum fsum, __wsum tsum, int csum_offset)
780 {
781 	__sum16 sum;
782 
783 	if (skb_copy_bits(skb, csum_offset, &sum, sizeof(sum)) < 0)
784 		return -1;
785 
786 	nft_csum_replace(&sum, fsum, tsum);
787 	if (skb_ensure_writable(skb, csum_offset + sizeof(sum)) ||
788 	    skb_store_bits(skb, csum_offset, &sum, sizeof(sum)) < 0)
789 		return -1;
790 
791 	return 0;
792 }
793 
794 struct nft_payload_set {
795 	enum nft_payload_bases	base:8;
796 	u8			offset;
797 	u8			len;
798 	u8			sreg;
799 	u8			csum_type;
800 	u8			csum_offset;
801 	u8			csum_flags;
802 };
803 
804 /* This is not struct vlan_hdr. */
805 struct nft_payload_vlan_hdr {
806 	__be16			h_vlan_proto;
807 	__be16			h_vlan_TCI;
808 };
809 
810 static bool
811 nft_payload_set_vlan(const u32 *src, struct sk_buff *skb, u8 offset, u8 len,
812 		     int *vlan_hlen)
813 {
814 	struct nft_payload_vlan_hdr *vlanh;
815 	__be16 vlan_proto;
816 	u16 vlan_tci;
817 
818 	if (offset >= offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto)) {
819 		*vlan_hlen = VLAN_HLEN;
820 		return true;
821 	}
822 
823 	switch (offset) {
824 	case offsetof(struct vlan_ethhdr, h_vlan_proto):
825 		if (len == 2) {
826 			vlan_proto = nft_reg_load_be16(src);
827 			skb->vlan_proto = vlan_proto;
828 		} else if (len == 4) {
829 			vlanh = (struct nft_payload_vlan_hdr *)src;
830 			__vlan_hwaccel_put_tag(skb, vlanh->h_vlan_proto,
831 					       ntohs(vlanh->h_vlan_TCI));
832 		} else {
833 			return false;
834 		}
835 		break;
836 	case offsetof(struct vlan_ethhdr, h_vlan_TCI):
837 		if (len != 2)
838 			return false;
839 
840 		vlan_tci = ntohs(nft_reg_load_be16(src));
841 		skb->vlan_tci = vlan_tci;
842 		break;
843 	default:
844 		return false;
845 	}
846 
847 	return true;
848 }
849 
850 static void nft_payload_set_eval(const struct nft_expr *expr,
851 				 struct nft_regs *regs,
852 				 const struct nft_pktinfo *pkt)
853 {
854 	const struct nft_payload_set *priv = nft_expr_priv(expr);
855 	const u32 *src = &regs->data[priv->sreg];
856 	int offset, csum_offset, vlan_hlen = 0;
857 	struct sk_buff *skb = pkt->skb;
858 	__wsum fsum, tsum;
859 
860 	switch (priv->base) {
861 	case NFT_PAYLOAD_LL_HEADER:
862 		if (!skb_mac_header_was_set(skb))
863 			goto err;
864 
865 		if (skb_vlan_tag_present(skb) &&
866 		    nft_payload_need_vlan_adjust(priv->offset, priv->len)) {
867 			if (!nft_payload_set_vlan(src, skb,
868 						  priv->offset, priv->len,
869 						  &vlan_hlen))
870 				goto err;
871 
872 			if (!vlan_hlen)
873 				return;
874 		}
875 
876 		offset = skb_mac_header(skb) - skb->data - vlan_hlen;
877 		break;
878 	case NFT_PAYLOAD_NETWORK_HEADER:
879 		offset = skb_network_offset(skb);
880 		break;
881 	case NFT_PAYLOAD_TRANSPORT_HEADER:
882 		if (!(pkt->flags & NFT_PKTINFO_L4PROTO) || pkt->fragoff)
883 			goto err;
884 		offset = nft_thoff(pkt);
885 		break;
886 	case NFT_PAYLOAD_INNER_HEADER:
887 		offset = nft_payload_inner_offset(pkt);
888 		if (offset < 0)
889 			goto err;
890 		break;
891 	default:
892 		WARN_ON_ONCE(1);
893 		goto err;
894 	}
895 
896 	csum_offset = offset + priv->csum_offset;
897 	offset += priv->offset;
898 
899 	if ((priv->csum_type == NFT_PAYLOAD_CSUM_INET || priv->csum_flags) &&
900 	    ((priv->base != NFT_PAYLOAD_TRANSPORT_HEADER &&
901 	      priv->base != NFT_PAYLOAD_INNER_HEADER) ||
902 	     skb->ip_summed != CHECKSUM_PARTIAL)) {
903 		fsum = skb_checksum(skb, offset, priv->len, 0);
904 		tsum = csum_partial(src, priv->len, 0);
905 
906 		if (priv->csum_type == NFT_PAYLOAD_CSUM_INET &&
907 		    nft_payload_csum_inet(skb, src, fsum, tsum, csum_offset))
908 			goto err;
909 
910 		if (priv->csum_flags &&
911 		    nft_payload_l4csum_update(pkt, skb, fsum, tsum) < 0)
912 			goto err;
913 	}
914 
915 	if (skb_ensure_writable(skb, max(offset + priv->len, 0)) ||
916 	    skb_store_bits(skb, offset, src, priv->len) < 0)
917 		goto err;
918 
919 	if (priv->csum_type == NFT_PAYLOAD_CSUM_SCTP &&
920 	    pkt->tprot == IPPROTO_SCTP &&
921 	    skb->ip_summed != CHECKSUM_PARTIAL) {
922 		if (pkt->fragoff == 0 &&
923 		    nft_payload_csum_sctp(skb, nft_thoff(pkt)))
924 			goto err;
925 	}
926 
927 	return;
928 err:
929 	regs->verdict.code = NFT_BREAK;
930 }
931 
932 static int nft_payload_set_init(const struct nft_ctx *ctx,
933 				const struct nft_expr *expr,
934 				const struct nlattr * const tb[])
935 {
936 	struct nft_payload_set *priv = nft_expr_priv(expr);
937 	u32 csum_offset, csum_type = NFT_PAYLOAD_CSUM_NONE;
938 	int err;
939 
940 	priv->base        = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
941 	priv->offset      = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
942 	priv->len         = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
943 
944 	if (tb[NFTA_PAYLOAD_CSUM_TYPE])
945 		csum_type = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE]));
946 	if (tb[NFTA_PAYLOAD_CSUM_OFFSET]) {
947 		err = nft_parse_u32_check(tb[NFTA_PAYLOAD_CSUM_OFFSET], U8_MAX,
948 					  &csum_offset);
949 		if (err < 0)
950 			return err;
951 
952 		priv->csum_offset = csum_offset;
953 	}
954 	if (tb[NFTA_PAYLOAD_CSUM_FLAGS]) {
955 		u32 flags;
956 
957 		flags = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_FLAGS]));
958 		if (flags & ~NFT_PAYLOAD_L4CSUM_PSEUDOHDR)
959 			return -EINVAL;
960 
961 		priv->csum_flags = flags;
962 	}
963 
964 	switch (csum_type) {
965 	case NFT_PAYLOAD_CSUM_NONE:
966 	case NFT_PAYLOAD_CSUM_INET:
967 		break;
968 	case NFT_PAYLOAD_CSUM_SCTP:
969 		if (priv->base != NFT_PAYLOAD_TRANSPORT_HEADER)
970 			return -EINVAL;
971 
972 		if (priv->csum_offset != offsetof(struct sctphdr, checksum))
973 			return -EINVAL;
974 		break;
975 	default:
976 		return -EOPNOTSUPP;
977 	}
978 	priv->csum_type = csum_type;
979 
980 	return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg,
981 				       priv->len);
982 }
983 
984 static int nft_payload_set_dump(struct sk_buff *skb,
985 				const struct nft_expr *expr, bool reset)
986 {
987 	const struct nft_payload_set *priv = nft_expr_priv(expr);
988 
989 	if (nft_dump_register(skb, NFTA_PAYLOAD_SREG, priv->sreg) ||
990 	    nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) ||
991 	    nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) ||
992 	    nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)) ||
993 	    nla_put_be32(skb, NFTA_PAYLOAD_CSUM_TYPE, htonl(priv->csum_type)) ||
994 	    nla_put_be32(skb, NFTA_PAYLOAD_CSUM_OFFSET,
995 			 htonl(priv->csum_offset)) ||
996 	    nla_put_be32(skb, NFTA_PAYLOAD_CSUM_FLAGS, htonl(priv->csum_flags)))
997 		goto nla_put_failure;
998 	return 0;
999 
1000 nla_put_failure:
1001 	return -1;
1002 }
1003 
1004 static bool nft_payload_set_reduce(struct nft_regs_track *track,
1005 				   const struct nft_expr *expr)
1006 {
1007 	int i;
1008 
1009 	for (i = 0; i < NFT_REG32_NUM; i++) {
1010 		if (!track->regs[i].selector)
1011 			continue;
1012 
1013 		if (track->regs[i].selector->ops != &nft_payload_ops &&
1014 		    track->regs[i].selector->ops != &nft_payload_fast_ops)
1015 			continue;
1016 
1017 		__nft_reg_track_cancel(track, i);
1018 	}
1019 
1020 	return false;
1021 }
1022 
1023 static const struct nft_expr_ops nft_payload_set_ops = {
1024 	.type		= &nft_payload_type,
1025 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload_set)),
1026 	.eval		= nft_payload_set_eval,
1027 	.init		= nft_payload_set_init,
1028 	.dump		= nft_payload_set_dump,
1029 	.reduce		= nft_payload_set_reduce,
1030 };
1031 
1032 static const struct nft_expr_ops *
1033 nft_payload_select_ops(const struct nft_ctx *ctx,
1034 		       const struct nlattr * const tb[])
1035 {
1036 	enum nft_payload_bases base;
1037 	unsigned int offset, len;
1038 	int err;
1039 
1040 	if (tb[NFTA_PAYLOAD_BASE] == NULL ||
1041 	    tb[NFTA_PAYLOAD_OFFSET] == NULL ||
1042 	    tb[NFTA_PAYLOAD_LEN] == NULL)
1043 		return ERR_PTR(-EINVAL);
1044 
1045 	base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
1046 	switch (base) {
1047 	case NFT_PAYLOAD_LL_HEADER:
1048 	case NFT_PAYLOAD_NETWORK_HEADER:
1049 	case NFT_PAYLOAD_TRANSPORT_HEADER:
1050 	case NFT_PAYLOAD_INNER_HEADER:
1051 		break;
1052 	default:
1053 		return ERR_PTR(-EOPNOTSUPP);
1054 	}
1055 
1056 	if (tb[NFTA_PAYLOAD_SREG] != NULL) {
1057 		if (tb[NFTA_PAYLOAD_DREG] != NULL)
1058 			return ERR_PTR(-EINVAL);
1059 		return &nft_payload_set_ops;
1060 	}
1061 
1062 	if (tb[NFTA_PAYLOAD_DREG] == NULL)
1063 		return ERR_PTR(-EINVAL);
1064 
1065 	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U8_MAX, &offset);
1066 	if (err < 0)
1067 		return ERR_PTR(err);
1068 
1069 	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_LEN], U8_MAX, &len);
1070 	if (err < 0)
1071 		return ERR_PTR(err);
1072 
1073 	if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) &&
1074 	    base != NFT_PAYLOAD_LL_HEADER && base != NFT_PAYLOAD_INNER_HEADER)
1075 		return &nft_payload_fast_ops;
1076 	else
1077 		return &nft_payload_ops;
1078 }
1079 
1080 struct nft_expr_type nft_payload_type __read_mostly = {
1081 	.name		= "payload",
1082 	.select_ops	= nft_payload_select_ops,
1083 	.inner_ops	= &nft_payload_inner_ops,
1084 	.policy		= nft_payload_policy,
1085 	.maxattr	= NFTA_PAYLOAD_MAX,
1086 	.owner		= THIS_MODULE,
1087 };
1088