xref: /linux/net/netfilter/nft_payload.c (revision 49bda4826843be0ef97a162009a29ea3a63f3935)
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 
nft_payload_rebuild_vlan_hdr(const struct sk_buff * skb,int mac_off,struct vlan_ethhdr * veth)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
nft_payload_copy_vlan(u32 * d,const struct sk_buff * skb,u16 offset,u8 len)43 nft_payload_copy_vlan(u32 *d, const struct sk_buff *skb, u16 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 
__nft_payload_inner_offset(struct nft_pktinfo * pkt)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 
nft_payload_inner_offset(const struct nft_pktinfo * pkt)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 
nft_payload_need_vlan_adjust(u32 offset,u32 len)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 
nft_payload_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)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) + pkt->nhoff;
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 		DEBUG_NET_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]		= NLA_POLICY_MAX(NLA_BE32, NFT_REG32_MAX),
213 	[NFTA_PAYLOAD_DREG]		= NLA_POLICY_MAX(NLA_BE32, NFT_REG32_MAX),
214 	[NFTA_PAYLOAD_BASE]		= { .type = NLA_U32 },
215 	[NFTA_PAYLOAD_OFFSET]		= { .type = NLA_BE32 },
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]	= NLA_POLICY_MASK(NLA_BE32, NFT_PAYLOAD_L4CSUM_PSEUDOHDR),
220 };
221 
nft_payload_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[])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 	u32 offset;
228 	int err;
229 
230 	priv->base   = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
231 	priv->len    = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
232 
233 	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U16_MAX, &offset);
234 	if (err < 0)
235 		return err;
236 	priv->offset = offset;
237 
238 	return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
239 					&priv->dreg, NULL, NFT_DATA_VALUE,
240 					priv->len);
241 }
242 
nft_payload_dump(struct sk_buff * skb,const struct nft_expr * expr,bool reset)243 static int nft_payload_dump(struct sk_buff *skb,
244 			    const struct nft_expr *expr, bool reset)
245 {
246 	const struct nft_payload *priv = nft_expr_priv(expr);
247 
248 	if (nft_dump_register(skb, NFTA_PAYLOAD_DREG, priv->dreg) ||
249 	    nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) ||
250 	    nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) ||
251 	    nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)))
252 		goto nla_put_failure;
253 	return 0;
254 
255 nla_put_failure:
256 	return -1;
257 }
258 
nft_payload_offload_mask(struct nft_offload_reg * reg,u32 priv_len,u32 field_len)259 static bool nft_payload_offload_mask(struct nft_offload_reg *reg,
260 				     u32 priv_len, u32 field_len)
261 {
262 	struct nft_data mask = {};
263 
264 	if (priv_len == field_len) {
265 		memset(&reg->mask, 0xff, priv_len);
266 		return true;
267 	} else if (priv_len > field_len) {
268 		return false;
269 	}
270 
271 	memset(&mask, 0xff, priv_len);
272 	memcpy(&reg->mask, &mask, field_len);
273 
274 	return true;
275 }
276 
nft_payload_offload_ll(struct nft_offload_ctx * ctx,struct nft_flow_rule * flow,const struct nft_payload * priv)277 static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
278 				  struct nft_flow_rule *flow,
279 				  const struct nft_payload *priv)
280 {
281 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
282 
283 	switch (priv->offset) {
284 	case offsetof(struct ethhdr, h_source):
285 		if (!nft_payload_offload_mask(reg, priv->len, ETH_ALEN))
286 			return -EOPNOTSUPP;
287 
288 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
289 				  src, ETH_ALEN, reg);
290 		break;
291 	case offsetof(struct ethhdr, h_dest):
292 		if (!nft_payload_offload_mask(reg, priv->len, ETH_ALEN))
293 			return -EOPNOTSUPP;
294 
295 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
296 				  dst, ETH_ALEN, reg);
297 		break;
298 	case offsetof(struct ethhdr, h_proto):
299 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
300 			return -EOPNOTSUPP;
301 
302 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic,
303 				  n_proto, sizeof(__be16), reg);
304 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
305 		break;
306 	case offsetof(struct vlan_ethhdr, h_vlan_TCI):
307 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
308 			return -EOPNOTSUPP;
309 
310 		NFT_OFFLOAD_MATCH_FLAGS(FLOW_DISSECTOR_KEY_VLAN, vlan,
311 					vlan_tci, sizeof(__be16), reg,
312 					NFT_OFFLOAD_F_NETWORK2HOST);
313 		break;
314 	case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto):
315 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
316 			return -EOPNOTSUPP;
317 
318 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan,
319 				  vlan_tpid, sizeof(__be16), reg);
320 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
321 		break;
322 	case offsetof(struct vlan_ethhdr, h_vlan_TCI) + sizeof(struct vlan_hdr):
323 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
324 			return -EOPNOTSUPP;
325 
326 		NFT_OFFLOAD_MATCH_FLAGS(FLOW_DISSECTOR_KEY_CVLAN, cvlan,
327 					vlan_tci, sizeof(__be16), reg,
328 					NFT_OFFLOAD_F_NETWORK2HOST);
329 		break;
330 	case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto) +
331 							sizeof(struct vlan_hdr):
332 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
333 			return -EOPNOTSUPP;
334 
335 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, cvlan,
336 				  vlan_tpid, sizeof(__be16), reg);
337 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
338 		break;
339 	default:
340 		return -EOPNOTSUPP;
341 	}
342 
343 	return 0;
344 }
345 
nft_payload_offload_ip(struct nft_offload_ctx * ctx,struct nft_flow_rule * flow,const struct nft_payload * priv)346 static int nft_payload_offload_ip(struct nft_offload_ctx *ctx,
347 				  struct nft_flow_rule *flow,
348 				  const struct nft_payload *priv)
349 {
350 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
351 
352 	switch (priv->offset) {
353 	case offsetof(struct iphdr, saddr):
354 		if (!nft_payload_offload_mask(reg, priv->len,
355 					      sizeof(struct in_addr)))
356 			return -EOPNOTSUPP;
357 
358 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src,
359 				  sizeof(struct in_addr), reg);
360 		nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV4_ADDRS);
361 		break;
362 	case offsetof(struct iphdr, daddr):
363 		if (!nft_payload_offload_mask(reg, priv->len,
364 					      sizeof(struct in_addr)))
365 			return -EOPNOTSUPP;
366 
367 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst,
368 				  sizeof(struct in_addr), reg);
369 		nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV4_ADDRS);
370 		break;
371 	case offsetof(struct iphdr, protocol):
372 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__u8)))
373 			return -EOPNOTSUPP;
374 
375 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
376 				  sizeof(__u8), reg);
377 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
378 		break;
379 	default:
380 		return -EOPNOTSUPP;
381 	}
382 
383 	return 0;
384 }
385 
nft_payload_offload_ip6(struct nft_offload_ctx * ctx,struct nft_flow_rule * flow,const struct nft_payload * priv)386 static int nft_payload_offload_ip6(struct nft_offload_ctx *ctx,
387 				  struct nft_flow_rule *flow,
388 				  const struct nft_payload *priv)
389 {
390 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
391 
392 	switch (priv->offset) {
393 	case offsetof(struct ipv6hdr, saddr):
394 		if (!nft_payload_offload_mask(reg, priv->len,
395 					      sizeof(struct in6_addr)))
396 			return -EOPNOTSUPP;
397 
398 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src,
399 				  sizeof(struct in6_addr), reg);
400 		nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV6_ADDRS);
401 		break;
402 	case offsetof(struct ipv6hdr, daddr):
403 		if (!nft_payload_offload_mask(reg, priv->len,
404 					      sizeof(struct in6_addr)))
405 			return -EOPNOTSUPP;
406 
407 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst,
408 				  sizeof(struct in6_addr), reg);
409 		nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV6_ADDRS);
410 		break;
411 	case offsetof(struct ipv6hdr, nexthdr):
412 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__u8)))
413 			return -EOPNOTSUPP;
414 
415 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
416 				  sizeof(__u8), reg);
417 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
418 		break;
419 	default:
420 		return -EOPNOTSUPP;
421 	}
422 
423 	return 0;
424 }
425 
nft_payload_offload_nh(struct nft_offload_ctx * ctx,struct nft_flow_rule * flow,const struct nft_payload * priv)426 static int nft_payload_offload_nh(struct nft_offload_ctx *ctx,
427 				  struct nft_flow_rule *flow,
428 				  const struct nft_payload *priv)
429 {
430 	int err;
431 
432 	switch (ctx->dep.l3num) {
433 	case htons(ETH_P_IP):
434 		err = nft_payload_offload_ip(ctx, flow, priv);
435 		break;
436 	case htons(ETH_P_IPV6):
437 		err = nft_payload_offload_ip6(ctx, flow, priv);
438 		break;
439 	default:
440 		return -EOPNOTSUPP;
441 	}
442 
443 	return err;
444 }
445 
nft_payload_offload_tcp(struct nft_offload_ctx * ctx,struct nft_flow_rule * flow,const struct nft_payload * priv)446 static int nft_payload_offload_tcp(struct nft_offload_ctx *ctx,
447 				   struct nft_flow_rule *flow,
448 				   const struct nft_payload *priv)
449 {
450 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
451 
452 	switch (priv->offset) {
453 	case offsetof(struct tcphdr, source):
454 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
455 			return -EOPNOTSUPP;
456 
457 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
458 				  sizeof(__be16), reg);
459 		break;
460 	case offsetof(struct tcphdr, dest):
461 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
462 			return -EOPNOTSUPP;
463 
464 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
465 				  sizeof(__be16), reg);
466 		break;
467 	default:
468 		return -EOPNOTSUPP;
469 	}
470 
471 	return 0;
472 }
473 
nft_payload_offload_udp(struct nft_offload_ctx * ctx,struct nft_flow_rule * flow,const struct nft_payload * priv)474 static int nft_payload_offload_udp(struct nft_offload_ctx *ctx,
475 				   struct nft_flow_rule *flow,
476 				   const struct nft_payload *priv)
477 {
478 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
479 
480 	switch (priv->offset) {
481 	case offsetof(struct udphdr, source):
482 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
483 			return -EOPNOTSUPP;
484 
485 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
486 				  sizeof(__be16), reg);
487 		break;
488 	case offsetof(struct udphdr, dest):
489 		if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
490 			return -EOPNOTSUPP;
491 
492 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
493 				  sizeof(__be16), reg);
494 		break;
495 	default:
496 		return -EOPNOTSUPP;
497 	}
498 
499 	return 0;
500 }
501 
nft_payload_offload_th(struct nft_offload_ctx * ctx,struct nft_flow_rule * flow,const struct nft_payload * priv)502 static int nft_payload_offload_th(struct nft_offload_ctx *ctx,
503 				  struct nft_flow_rule *flow,
504 				  const struct nft_payload *priv)
505 {
506 	int err;
507 
508 	switch (ctx->dep.protonum) {
509 	case IPPROTO_TCP:
510 		err = nft_payload_offload_tcp(ctx, flow, priv);
511 		break;
512 	case IPPROTO_UDP:
513 		err = nft_payload_offload_udp(ctx, flow, priv);
514 		break;
515 	default:
516 		return -EOPNOTSUPP;
517 	}
518 
519 	return err;
520 }
521 
nft_payload_offload(struct nft_offload_ctx * ctx,struct nft_flow_rule * flow,const struct nft_expr * expr)522 static int nft_payload_offload(struct nft_offload_ctx *ctx,
523 			       struct nft_flow_rule *flow,
524 			       const struct nft_expr *expr)
525 {
526 	const struct nft_payload *priv = nft_expr_priv(expr);
527 	int err;
528 
529 	switch (priv->base) {
530 	case NFT_PAYLOAD_LL_HEADER:
531 		err = nft_payload_offload_ll(ctx, flow, priv);
532 		break;
533 	case NFT_PAYLOAD_NETWORK_HEADER:
534 		err = nft_payload_offload_nh(ctx, flow, priv);
535 		break;
536 	case NFT_PAYLOAD_TRANSPORT_HEADER:
537 		err = nft_payload_offload_th(ctx, flow, priv);
538 		break;
539 	default:
540 		err = -EOPNOTSUPP;
541 		break;
542 	}
543 	return err;
544 }
545 
546 static const struct nft_expr_ops nft_payload_ops = {
547 	.type		= &nft_payload_type,
548 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload)),
549 	.eval		= nft_payload_eval,
550 	.init		= nft_payload_init,
551 	.dump		= nft_payload_dump,
552 	.offload	= nft_payload_offload,
553 };
554 
555 const struct nft_expr_ops nft_payload_fast_ops = {
556 	.type		= &nft_payload_type,
557 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload)),
558 	.eval		= nft_payload_eval,
559 	.init		= nft_payload_init,
560 	.dump		= nft_payload_dump,
561 	.offload	= nft_payload_offload,
562 };
563 
nft_payload_inner_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt,struct nft_inner_tun_ctx * tun_ctx)564 void nft_payload_inner_eval(const struct nft_expr *expr, struct nft_regs *regs,
565 			    const struct nft_pktinfo *pkt,
566 			    struct nft_inner_tun_ctx *tun_ctx)
567 {
568 	const struct nft_payload *priv = nft_expr_priv(expr);
569 	const struct sk_buff *skb = pkt->skb;
570 	u32 *dest = &regs->data[priv->dreg];
571 	int offset;
572 
573 	if (priv->len % NFT_REG32_SIZE)
574 		dest[priv->len / NFT_REG32_SIZE] = 0;
575 
576 	switch (priv->base) {
577 	case NFT_PAYLOAD_TUN_HEADER:
578 		if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_TUN))
579 			goto err;
580 
581 		offset = tun_ctx->inner_tunoff;
582 		break;
583 	case NFT_PAYLOAD_LL_HEADER:
584 		if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_LL))
585 			goto err;
586 
587 		offset = tun_ctx->inner_lloff;
588 		break;
589 	case NFT_PAYLOAD_NETWORK_HEADER:
590 		if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_NH))
591 			goto err;
592 
593 		offset = tun_ctx->inner_nhoff;
594 		break;
595 	case NFT_PAYLOAD_TRANSPORT_HEADER:
596 		if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_TH))
597 			goto err;
598 
599 		offset = tun_ctx->inner_thoff;
600 		break;
601 	default:
602 		DEBUG_NET_WARN_ON_ONCE(1);
603 		goto err;
604 	}
605 	offset += priv->offset;
606 
607 	if (skb_copy_bits(skb, offset, dest, priv->len) < 0)
608 		goto err;
609 
610 	return;
611 err:
612 	regs->verdict.code = NFT_BREAK;
613 }
614 
nft_payload_inner_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[])615 static int nft_payload_inner_init(const struct nft_ctx *ctx,
616 				  const struct nft_expr *expr,
617 				  const struct nlattr * const tb[])
618 {
619 	struct nft_payload *priv = nft_expr_priv(expr);
620 	u32 base, offset;
621 	int err;
622 
623 	if (!tb[NFTA_PAYLOAD_BASE] || !tb[NFTA_PAYLOAD_OFFSET] ||
624 	    !tb[NFTA_PAYLOAD_LEN] || !tb[NFTA_PAYLOAD_DREG])
625 		return -EINVAL;
626 
627 	base   = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
628 	switch (base) {
629 	case NFT_PAYLOAD_TUN_HEADER:
630 	case NFT_PAYLOAD_LL_HEADER:
631 	case NFT_PAYLOAD_NETWORK_HEADER:
632 	case NFT_PAYLOAD_TRANSPORT_HEADER:
633 		break;
634 	default:
635 		return -EOPNOTSUPP;
636 	}
637 
638 	priv->base   = base;
639 	priv->len    = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
640 	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U16_MAX, &offset);
641 	if (err < 0)
642 		return err;
643 	priv->offset = offset;
644 
645 	return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
646 					&priv->dreg, NULL, NFT_DATA_VALUE,
647 					priv->len);
648 }
649 
650 static const struct nft_expr_ops nft_payload_inner_ops = {
651 	.type		= &nft_payload_type,
652 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload)),
653 	.init		= nft_payload_inner_init,
654 	.dump		= nft_payload_dump,
655 	/* direct call to nft_payload_inner_eval(). */
656 };
657 
nft_csum_replace(__sum16 * sum,__wsum fsum,__wsum tsum)658 static inline void nft_csum_replace(__sum16 *sum, __wsum fsum, __wsum tsum)
659 {
660 	csum_replace4(sum, (__force __be32)fsum, (__force __be32)tsum);
661 	if (*sum == 0)
662 		*sum = CSUM_MANGLED_0;
663 }
664 
nft_payload_udp_checksum(struct sk_buff * skb,unsigned int thoff)665 static bool nft_payload_udp_checksum(struct sk_buff *skb, unsigned int thoff)
666 {
667 	struct udphdr *uh, _uh;
668 
669 	uh = skb_header_pointer(skb, thoff, sizeof(_uh), &_uh);
670 	if (!uh)
671 		return false;
672 
673 	return (__force bool)uh->check;
674 }
675 
nft_payload_l4csum_offset(const struct nft_pktinfo * pkt,struct sk_buff * skb,unsigned int * l4csum_offset)676 static int nft_payload_l4csum_offset(const struct nft_pktinfo *pkt,
677 				     struct sk_buff *skb,
678 				     unsigned int *l4csum_offset)
679 {
680 	if (pkt->fragoff)
681 		return -1;
682 
683 	switch (pkt->tprot) {
684 	case IPPROTO_TCP:
685 		*l4csum_offset = offsetof(struct tcphdr, check);
686 		break;
687 	case IPPROTO_UDP:
688 		if (!nft_payload_udp_checksum(skb, nft_thoff(pkt)))
689 			return -1;
690 		fallthrough;
691 	case IPPROTO_UDPLITE:
692 		*l4csum_offset = offsetof(struct udphdr, check);
693 		break;
694 	case IPPROTO_ICMPV6:
695 		*l4csum_offset = offsetof(struct icmp6hdr, icmp6_cksum);
696 		break;
697 	default:
698 		return -1;
699 	}
700 
701 	*l4csum_offset += nft_thoff(pkt);
702 	return 0;
703 }
704 
nft_payload_csum_sctp(struct sk_buff * skb,int offset)705 static int nft_payload_csum_sctp(struct sk_buff *skb, int offset)
706 {
707 	struct sctphdr *sh;
708 
709 	if (skb_ensure_writable(skb, offset + sizeof(*sh)))
710 		return -1;
711 
712 	sh = (struct sctphdr *)(skb->data + offset);
713 	sh->checksum = sctp_compute_cksum(skb, offset);
714 	skb->ip_summed = CHECKSUM_UNNECESSARY;
715 	return 0;
716 }
717 
nft_payload_l4csum_update(const struct nft_pktinfo * pkt,struct sk_buff * skb,__wsum fsum,__wsum tsum)718 static int nft_payload_l4csum_update(const struct nft_pktinfo *pkt,
719 				     struct sk_buff *skb,
720 				     __wsum fsum, __wsum tsum)
721 {
722 	int l4csum_offset;
723 	__sum16 sum;
724 
725 	/* If we cannot determine layer 4 checksum offset or this packet doesn't
726 	 * require layer 4 checksum recalculation, skip this packet.
727 	 */
728 	if (nft_payload_l4csum_offset(pkt, skb, &l4csum_offset) < 0)
729 		return 0;
730 
731 	if (skb_copy_bits(skb, l4csum_offset, &sum, sizeof(sum)) < 0)
732 		return -1;
733 
734 	/* Checksum mangling for an arbitrary amount of bytes, based on
735 	 * inet_proto_csum_replace*() functions.
736 	 */
737 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
738 		nft_csum_replace(&sum, fsum, tsum);
739 		if (skb->ip_summed == CHECKSUM_COMPLETE) {
740 			skb->csum = ~csum_add(csum_sub(~(skb->csum), fsum),
741 					      tsum);
742 		}
743 	} else {
744 		sum = ~csum_fold(csum_add(csum_sub(csum_unfold(sum), fsum),
745 					  tsum));
746 	}
747 
748 	if (skb_ensure_writable(skb, l4csum_offset + sizeof(sum)) ||
749 	    skb_store_bits(skb, l4csum_offset, &sum, sizeof(sum)) < 0)
750 		return -1;
751 
752 	return 0;
753 }
754 
nft_payload_csum_inet(struct sk_buff * skb,const u32 * src,__wsum fsum,__wsum tsum,int csum_offset)755 static int nft_payload_csum_inet(struct sk_buff *skb, const u32 *src,
756 				 __wsum fsum, __wsum tsum, int csum_offset)
757 {
758 	__sum16 sum;
759 
760 	if (skb_copy_bits(skb, csum_offset, &sum, sizeof(sum)) < 0)
761 		return -1;
762 
763 	nft_csum_replace(&sum, fsum, tsum);
764 	if (skb_ensure_writable(skb, csum_offset + sizeof(sum)) ||
765 	    skb_store_bits(skb, csum_offset, &sum, sizeof(sum)) < 0)
766 		return -1;
767 
768 	return 0;
769 }
770 
771 struct nft_payload_set {
772 	enum nft_payload_bases	base:8;
773 	u16			offset;
774 	u8			len;
775 	u8			sreg;
776 	u8			csum_type;
777 	u8			csum_offset;
778 	u8			csum_flags;
779 };
780 
781 /* This is not struct vlan_hdr. */
782 struct nft_payload_vlan_hdr {
783 	__be16			h_vlan_proto;
784 	__be16			h_vlan_TCI;
785 };
786 
787 static bool
nft_payload_set_vlan(const u32 * src,struct sk_buff * skb,u16 offset,u8 len,int * vlan_hlen)788 nft_payload_set_vlan(const u32 *src, struct sk_buff *skb, u16 offset, u8 len,
789 		     int *vlan_hlen)
790 {
791 	struct nft_payload_vlan_hdr *vlanh;
792 	__be16 vlan_proto;
793 	u16 vlan_tci;
794 
795 	if (offset >= offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto)) {
796 		*vlan_hlen = VLAN_HLEN;
797 		return true;
798 	}
799 
800 	switch (offset) {
801 	case offsetof(struct vlan_ethhdr, h_vlan_proto):
802 		if (len == 2) {
803 			vlan_proto = nft_reg_load_be16(src);
804 			skb->vlan_proto = vlan_proto;
805 		} else if (len == 4) {
806 			vlanh = (struct nft_payload_vlan_hdr *)src;
807 			__vlan_hwaccel_put_tag(skb, vlanh->h_vlan_proto,
808 					       ntohs(vlanh->h_vlan_TCI));
809 		} else {
810 			return false;
811 		}
812 		break;
813 	case offsetof(struct vlan_ethhdr, h_vlan_TCI):
814 		if (len != 2)
815 			return false;
816 
817 		vlan_tci = ntohs(nft_reg_load_be16(src));
818 		skb->vlan_tci = vlan_tci;
819 		break;
820 	default:
821 		return false;
822 	}
823 
824 	return true;
825 }
826 
827 /* Ingress is very early, before l3 protocol handlers.
828  * There should be no in-tree code that trusts l3/l4 headers
829  * between ingress and NF_INET_PRE_ROUTING hooks.
830  */
nft_in_ingress(const struct nf_hook_state * s)831 static bool nft_in_ingress(const struct nf_hook_state *s)
832 {
833 	return s->pf == NFPROTO_NETDEV && s->hook == NF_NETDEV_INGRESS;
834 }
835 
nft_nh_write_ok_ip4(const struct nft_pktinfo * pkt,const struct nft_payload_set * priv,const u32 * src)836 static bool nft_nh_write_ok_ip4(const struct nft_pktinfo *pkt,
837 				const struct nft_payload_set *priv,
838 				const u32 *src)
839 {
840 	unsigned int offset = priv->offset + skb_network_offset(pkt->skb);
841 	const u8 *new_octets = (const u8 *)src;
842 	u8 old_octet;
843 
844 	switch (priv->offset) {
845 	case 0: /* csum fixups does expand dscp/tos store to 2 bytes.
846 		 * make sure ihl/version remain unchanged.
847 		 */
848 		if (skb_copy_bits(pkt->skb, offset, &old_octet, sizeof(old_octet)))
849 			return false;
850 
851 		return priv->len == 2 &&
852 		       *new_octets == old_octet;
853 	case offsetof(struct iphdr, tos):
854 		return priv->len == 1;
855 	case offsetof(struct iphdr, id):
856 		return priv->len == 2;
857 	case offsetof(struct iphdr, ttl):
858 		if (priv->len == 1)
859 			return true;
860 
861 		if (priv->len != 2)
862 			return false;
863 
864 		/* same, csum fixup does expand ttl store to two bytes.
865 		 * check protocol is not altered.
866 		 */
867 		if (skb_copy_bits(pkt->skb, offset + 1, &old_octet, sizeof(old_octet)))
868 			return false;
869 
870 		return new_octets[1] == old_octet;
871 	case offsetof(struct iphdr, check):
872 		return priv->len <= 2 + 4 + 4;
873 	case offsetof(struct iphdr, saddr):
874 		return priv->len <= 4 + 4;
875 	case offsetof(struct iphdr, daddr):
876 		return priv->len <= 4;
877 	}
878 
879 	return false;
880 }
881 
nft_nh_write_ok_ip6(const struct nft_pktinfo * pkt,const struct nft_payload_set * priv,const u32 * src)882 static bool nft_nh_write_ok_ip6(const struct nft_pktinfo *pkt,
883 				const struct nft_payload_set *priv,
884 				const u32 *src)
885 {
886 	const struct ipv6hdr *ih = (const void *)src;
887 
888 	switch (priv->offset) {
889 	case 0: /* store to dscp must not alter ip6 version */
890 		return priv->len <= 4 && ih->version == 6;
891 	case 2:
892 		return priv->len <= 2;
893 	case offsetof(struct ipv6hdr, hop_limit):
894 		return priv->len == 1;
895 	case offsetof(struct ipv6hdr, saddr):
896 		return priv->len <= 16 + 16;
897 	case offsetof(struct ipv6hdr, daddr):
898 		return priv->len <= 16;
899 	}
900 
901 	return false;
902 }
903 
nft_nh_write_ok_arp(const struct nft_payload_set * priv)904 static bool nft_nh_write_ok_arp(const struct nft_payload_set *priv)
905 {
906 	/* Variable size for standard ethernet arp */
907 	const unsigned int eth_ip = 2 * (ETH_ALEN + 4);
908 	unsigned int offset = priv->offset;
909 
910 	switch (offset) {
911 	case offsetof(struct arphdr, ar_op):
912 		return priv->len == 2;
913 	default:
914 		break;
915 	}
916 
917 	/* permit writes post fixed arp header size. offset + len are
918 	 * checked vs skb size via skb_ensure_writable.
919 	 */
920 	return offset >= sizeof(struct arphdr) && priv->len <= eth_ip;
921 }
922 
nft_nh_write_ok_netdev(const struct nft_pktinfo * pkt,const struct nft_payload_set * priv,const u32 * src)923 static bool nft_nh_write_ok_netdev(const struct nft_pktinfo *pkt,
924 				   const struct nft_payload_set *priv,
925 				   const u32 *src)
926 {
927 #ifdef CONFIG_NF_TABLES_NETDEV
928 	switch (pkt->skb->protocol) {
929 	case htons(ETH_P_ARP):
930 		return nft_nh_write_ok_arp(priv);
931 	case htons(ETH_P_IP):
932 		return nft_nh_write_ok_ip4(pkt, priv, src);
933 	case htons(ETH_P_IPV6):
934 		return nft_nh_write_ok_ip6(pkt, priv, src);
935 	}
936 #endif
937 	/* default to false for now, relax later in case we have
938 	 * use-cases that need inner header manipulation for
939 	 * encapsulated traffic like vlan or PPPoE.
940 	 */
941 	return false;
942 }
943 
nft_nh_write_ok_bridge(const struct nft_pktinfo * pkt,const struct nft_payload_set * priv,const u32 * src)944 static bool nft_nh_write_ok_bridge(const struct nft_pktinfo *pkt,
945 				   const struct nft_payload_set *priv,
946 				   const u32 *src)
947 {
948 #if IS_ENABLED(CONFIG_NF_TABLES_BRIDGE)
949 	switch (pkt->ethertype) {
950 	case htons(ETH_P_ARP):
951 		return nft_nh_write_ok_arp(priv);
952 	case htons(ETH_P_IP):
953 		return nft_nh_write_ok_ip4(pkt, priv, src);
954 	case htons(ETH_P_IPV6):
955 		return nft_nh_write_ok_ip6(pkt, priv, src);
956 	}
957 #endif
958 	/* see nft_nh_write_ok_netdev: default to false */
959 	return false;
960 }
961 
nft_nh_write_ok(const struct nft_pktinfo * pkt,const struct nft_payload_set * priv,const u32 * src)962 static bool nft_nh_write_ok(const struct nft_pktinfo *pkt,
963 			    const struct nft_payload_set *priv,
964 			    const u32 *src)
965 {
966 	switch (pkt->state->pf) {
967 	case NFPROTO_ARP:
968 		return nft_nh_write_ok_arp(priv);
969 	case NFPROTO_BRIDGE:
970 		return nft_nh_write_ok_bridge(pkt, priv, src);
971 	case NFPROTO_IPV4:
972 		return nft_nh_write_ok_ip4(pkt, priv, src);
973 	case NFPROTO_IPV6:
974 		return nft_nh_write_ok_ip6(pkt, priv, src);
975 	case NFPROTO_NETDEV:
976 		if (pkt->state->hook == NF_NETDEV_INGRESS)
977 			return true;
978 		return nft_nh_write_ok_netdev(pkt, priv, src);
979 	}
980 
981 	return false;
982 }
983 
984 /* check linklayer modifications don't spill into network header. */
nft_ll_write_ok(const struct nft_pktinfo * pkt,int offset)985 static bool nft_ll_write_ok(const struct nft_pktinfo *pkt, int offset)
986 {
987 	if (nft_in_ingress(pkt->state))
988 		return true;
989 
990 	return offset <= skb_network_offset(pkt->skb);
991 }
992 
nft_payload_validate_inet_csum_offset(const struct nft_ctx * ctx,const struct nft_payload_set * priv)993 static bool nft_payload_validate_inet_csum_offset(const struct nft_ctx *ctx,
994 						  const struct nft_payload_set *priv)
995 {
996 	switch (priv->base) {
997 	case NFT_PAYLOAD_LL_HEADER:
998 		break;
999 	case NFT_PAYLOAD_NETWORK_HEADER:
1000 		if (ctx->family == NFPROTO_IPV4) {
1001 			if (offsetof(struct iphdr, check) == priv->csum_offset)
1002 				return true;
1003 
1004 			return false;
1005 		}
1006 		return true; /* run time validation required */
1007 	case NFT_PAYLOAD_TRANSPORT_HEADER:
1008 		if (priv->csum_flags) /* makes no sense, asks for "re-update" of L4 checksum */
1009 			return false;
1010 
1011 		/* no further check here; offset can't be negative so bogus
1012 		 * offsets can corrupt L4 or payload but not l3 headers.
1013 		 * We already allow arbitrary l4/inner payload writes.
1014 		 */
1015 		return true;
1016 	case NFT_PAYLOAD_INNER_HEADER:
1017 		return true;
1018 	case NFT_PAYLOAD_TUN_HEADER:
1019 		break;
1020 	}
1021 
1022 	return false;
1023 }
1024 
1025 /* do not allow arbitrary network header mangling via bogus csum_off.
1026  * We only support ipv4.  Only NFPROTO_IPV4 can be checked from control
1027  * plane.
1028  */
nft_payload_csum_nh_write_ok(const struct nft_payload_set * priv,const struct nft_pktinfo * pkt)1029 static bool nft_payload_csum_nh_write_ok(const struct nft_payload_set *priv,
1030 					 const struct nft_pktinfo *pkt)
1031 {
1032 	switch (pkt->state->pf) {
1033 	case NFPROTO_IPV4:
1034 		/* Warning: NFPROTO_INET was not checked; we can't return true here. */
1035 		return priv->csum_offset == offsetof(struct iphdr, check);
1036 	case NFPROTO_IPV6:
1037 		return false;
1038 	case NFPROTO_BRIDGE:
1039 		return pkt->ethertype == htons(ETH_P_IP) &&
1040 		       priv->csum_offset == offsetof(struct iphdr, check);
1041 	case NFPROTO_NETDEV:
1042 		return pkt->skb->protocol == htons(ETH_P_IP) &&
1043 		       priv->csum_offset == offsetof(struct iphdr, check);
1044 	}
1045 
1046 	return false;
1047 }
1048 
nft_payload_csum_write_ok(const struct nft_pktinfo * pkt,const struct nft_payload_set * priv)1049 static bool nft_payload_csum_write_ok(const struct nft_pktinfo *pkt,
1050 				      const struct nft_payload_set *priv)
1051 {
1052 	switch (priv->base) {
1053 	case NFT_PAYLOAD_LL_HEADER:
1054 		break;
1055 	case NFT_PAYLOAD_NETWORK_HEADER:
1056 		return nft_payload_csum_nh_write_ok(priv, pkt);
1057 	case NFT_PAYLOAD_TRANSPORT_HEADER:
1058 	case NFT_PAYLOAD_INNER_HEADER:
1059 		/* neither offsets are validated, offsets cannot be
1060 		 * negative so real l3 headers cannot be mangled.
1061 		 */
1062 		return true;
1063 	case NFT_PAYLOAD_TUN_HEADER:
1064 		break;
1065 	}
1066 
1067 	return false;
1068 }
1069 
nft_th_write_ok(const struct nft_pktinfo * pkt,const struct nft_payload_set * priv)1070 static bool nft_th_write_ok(const struct nft_pktinfo *pkt,
1071 			    const struct nft_payload_set *priv)
1072 {
1073 	unsigned int doff = offsetof(struct tcphdr, ack_seq) + sizeof(__be32);
1074 
1075 	if (pkt->tprot != IPPROTO_TCP)
1076 		return true;
1077 
1078 	return priv->offset > doff || priv->offset + priv->len <= doff;
1079 }
1080 
nft_payload_set_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)1081 static void nft_payload_set_eval(const struct nft_expr *expr,
1082 				 struct nft_regs *regs,
1083 				 const struct nft_pktinfo *pkt)
1084 {
1085 	const struct nft_payload_set *priv = nft_expr_priv(expr);
1086 	const u32 *src = &regs->data[priv->sreg];
1087 	int offset, csum_offset, vlan_hlen = 0;
1088 	struct sk_buff *skb = pkt->skb;
1089 	__wsum fsum, tsum;
1090 
1091 	switch (priv->base) {
1092 	case NFT_PAYLOAD_LL_HEADER:
1093 		if (!skb_mac_header_was_set(skb))
1094 			goto err;
1095 
1096 		if (skb_vlan_tag_present(skb) &&
1097 		    nft_payload_need_vlan_adjust(priv->offset, priv->len)) {
1098 			if (!nft_payload_set_vlan(src, skb,
1099 						  priv->offset, priv->len,
1100 						  &vlan_hlen))
1101 				goto err;
1102 
1103 			if (!vlan_hlen)
1104 				return;
1105 		}
1106 
1107 		offset = skb_mac_header(skb) - skb->data - vlan_hlen;
1108 		if (!nft_ll_write_ok(pkt, priv->len + priv->offset + offset))
1109 			goto err;
1110 		break;
1111 	case NFT_PAYLOAD_NETWORK_HEADER:
1112 		if (!nft_nh_write_ok(pkt, priv, src))
1113 			goto err;
1114 		offset = skb_network_offset(skb);
1115 		break;
1116 	case NFT_PAYLOAD_TRANSPORT_HEADER:
1117 		if (!(pkt->flags & NFT_PKTINFO_L4PROTO) || pkt->fragoff)
1118 			goto err;
1119 		if (!nft_th_write_ok(pkt, priv))
1120 			goto err;
1121 		offset = nft_thoff(pkt);
1122 		break;
1123 	case NFT_PAYLOAD_INNER_HEADER:
1124 		offset = nft_payload_inner_offset(pkt);
1125 		if (offset < 0)
1126 			goto err;
1127 		break;
1128 	default:
1129 		DEBUG_NET_WARN_ON_ONCE(1);
1130 		goto err;
1131 	}
1132 
1133 	csum_offset = offset + priv->csum_offset;
1134 	offset += priv->offset;
1135 
1136 	if ((priv->csum_type == NFT_PAYLOAD_CSUM_INET || priv->csum_flags) &&
1137 	    ((priv->base != NFT_PAYLOAD_TRANSPORT_HEADER &&
1138 	      priv->base != NFT_PAYLOAD_INNER_HEADER) ||
1139 	     skb->ip_summed != CHECKSUM_PARTIAL)) {
1140 		if (offset + priv->len > skb->len)
1141 			goto err;
1142 
1143 		fsum = skb_checksum(skb, offset, priv->len, 0);
1144 		tsum = csum_partial(src, priv->len, 0);
1145 
1146 		if (priv->csum_type == NFT_PAYLOAD_CSUM_INET &&
1147 		    nft_payload_csum_write_ok(pkt, priv) &&
1148 		    nft_payload_csum_inet(skb, src, fsum, tsum, csum_offset))
1149 			goto err;
1150 
1151 		if (priv->csum_flags &&
1152 		    nft_payload_l4csum_update(pkt, skb, fsum, tsum) < 0)
1153 			goto err;
1154 	}
1155 
1156 	if (skb_ensure_writable(skb, max(offset + priv->len, 0)) ||
1157 	    skb_store_bits(skb, offset, src, priv->len) < 0)
1158 		goto err;
1159 
1160 	if (priv->csum_type == NFT_PAYLOAD_CSUM_SCTP &&
1161 	    pkt->tprot == IPPROTO_SCTP &&
1162 	    skb->ip_summed != CHECKSUM_PARTIAL) {
1163 		if (pkt->fragoff == 0 &&
1164 		    nft_payload_csum_sctp(skb, nft_thoff(pkt)))
1165 			goto err;
1166 	}
1167 
1168 	return;
1169 err:
1170 	regs->verdict.code = NFT_BREAK;
1171 }
1172 
nft_payload_set_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[])1173 static int nft_payload_set_init(const struct nft_ctx *ctx,
1174 				const struct nft_expr *expr,
1175 				const struct nlattr * const tb[])
1176 {
1177 	u32 csum_offset, offset, csum_type = NFT_PAYLOAD_CSUM_NONE;
1178 	struct nft_payload_set *priv = nft_expr_priv(expr);
1179 	int err;
1180 
1181 	if (ctx->net->user_ns != &init_user_ns)
1182 		return -EPERM;
1183 
1184 	priv->base        = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
1185 	priv->len         = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
1186 
1187 	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U16_MAX, &offset);
1188 	if (err < 0)
1189 		return err;
1190 	priv->offset = offset;
1191 
1192 	if (tb[NFTA_PAYLOAD_CSUM_TYPE])
1193 		csum_type = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE]));
1194 	if (tb[NFTA_PAYLOAD_CSUM_OFFSET]) {
1195 		err = nft_parse_u32_check(tb[NFTA_PAYLOAD_CSUM_OFFSET], U8_MAX,
1196 					  &csum_offset);
1197 		if (err < 0)
1198 			return err;
1199 
1200 		priv->csum_offset = csum_offset;
1201 	}
1202 	if (tb[NFTA_PAYLOAD_CSUM_FLAGS]) {
1203 		u32 flags;
1204 
1205 		flags = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_FLAGS]));
1206 		if (flags & ~NFT_PAYLOAD_L4CSUM_PSEUDOHDR)
1207 			return -EINVAL;
1208 
1209 		priv->csum_flags = flags;
1210 	}
1211 
1212 	switch (csum_type) {
1213 	case NFT_PAYLOAD_CSUM_NONE:
1214 		if (priv->csum_offset) /* nonsensical */
1215 			return -EINVAL;
1216 
1217 		if (priv->csum_flags == 0)
1218 			break;
1219 
1220 		/* Userspace requests L4 checksum update, e.g.:
1221 		 * - IPv6 stateless NAT (no l3 csum)
1222 		 * - transport header mangling
1223 		 * - inner data mangling
1224 		 */
1225 		if (priv->base == NFT_PAYLOAD_NETWORK_HEADER ||
1226 		    priv->base == NFT_PAYLOAD_TRANSPORT_HEADER ||
1227 		    priv->base == NFT_PAYLOAD_INNER_HEADER)
1228 			break;
1229 
1230 		return -EINVAL;
1231 	case NFT_PAYLOAD_CSUM_INET:
1232 		if (!nft_payload_validate_inet_csum_offset(ctx, priv))
1233 			return -EINVAL;
1234 		break;
1235 	case NFT_PAYLOAD_CSUM_SCTP:
1236 		if (priv->base != NFT_PAYLOAD_TRANSPORT_HEADER)
1237 			return -EINVAL;
1238 
1239 		if (priv->csum_offset != offsetof(struct sctphdr, checksum))
1240 			return -EINVAL;
1241 
1242 		if (priv->csum_flags)
1243 			return -EINVAL;
1244 		break;
1245 	default:
1246 		return -EOPNOTSUPP;
1247 	}
1248 	priv->csum_type = csum_type;
1249 
1250 	return nft_parse_register_load(ctx, tb[NFTA_PAYLOAD_SREG], &priv->sreg,
1251 				       priv->len);
1252 }
1253 
nft_payload_set_dump(struct sk_buff * skb,const struct nft_expr * expr,bool reset)1254 static int nft_payload_set_dump(struct sk_buff *skb,
1255 				const struct nft_expr *expr, bool reset)
1256 {
1257 	const struct nft_payload_set *priv = nft_expr_priv(expr);
1258 
1259 	if (nft_dump_register(skb, NFTA_PAYLOAD_SREG, priv->sreg) ||
1260 	    nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) ||
1261 	    nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) ||
1262 	    nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)) ||
1263 	    nla_put_be32(skb, NFTA_PAYLOAD_CSUM_TYPE, htonl(priv->csum_type)) ||
1264 	    nla_put_be32(skb, NFTA_PAYLOAD_CSUM_OFFSET,
1265 			 htonl(priv->csum_offset)) ||
1266 	    nla_put_be32(skb, NFTA_PAYLOAD_CSUM_FLAGS, htonl(priv->csum_flags)))
1267 		goto nla_put_failure;
1268 	return 0;
1269 
1270 nla_put_failure:
1271 	return -1;
1272 }
1273 
1274 static const struct nft_expr_ops nft_payload_set_ops = {
1275 	.type		= &nft_payload_type,
1276 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload_set)),
1277 	.eval		= nft_payload_set_eval,
1278 	.init		= nft_payload_set_init,
1279 	.dump		= nft_payload_set_dump,
1280 };
1281 
1282 static const struct nft_expr_ops *
nft_payload_select_ops(const struct nft_ctx * ctx,const struct nlattr * const tb[])1283 nft_payload_select_ops(const struct nft_ctx *ctx,
1284 		       const struct nlattr * const tb[])
1285 {
1286 	enum nft_payload_bases base;
1287 	unsigned int offset, len;
1288 	int err;
1289 
1290 	if (tb[NFTA_PAYLOAD_BASE] == NULL ||
1291 	    tb[NFTA_PAYLOAD_OFFSET] == NULL ||
1292 	    tb[NFTA_PAYLOAD_LEN] == NULL)
1293 		return ERR_PTR(-EINVAL);
1294 
1295 	base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
1296 	switch (base) {
1297 	case NFT_PAYLOAD_LL_HEADER:
1298 	case NFT_PAYLOAD_NETWORK_HEADER:
1299 	case NFT_PAYLOAD_TRANSPORT_HEADER:
1300 	case NFT_PAYLOAD_INNER_HEADER:
1301 		break;
1302 	default:
1303 		return ERR_PTR(-EOPNOTSUPP);
1304 	}
1305 
1306 	if (tb[NFTA_PAYLOAD_SREG] != NULL) {
1307 		if (tb[NFTA_PAYLOAD_DREG] != NULL)
1308 			return ERR_PTR(-EINVAL);
1309 		return &nft_payload_set_ops;
1310 	}
1311 
1312 	if (tb[NFTA_PAYLOAD_DREG] == NULL)
1313 		return ERR_PTR(-EINVAL);
1314 
1315 	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U16_MAX, &offset);
1316 	if (err < 0)
1317 		return ERR_PTR(err);
1318 
1319 	err = nft_parse_u32_check(tb[NFTA_PAYLOAD_LEN], U8_MAX, &len);
1320 	if (err < 0)
1321 		return ERR_PTR(err);
1322 
1323 	if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) &&
1324 	    base != NFT_PAYLOAD_LL_HEADER && base != NFT_PAYLOAD_INNER_HEADER)
1325 		return &nft_payload_fast_ops;
1326 	else
1327 		return &nft_payload_ops;
1328 }
1329 
1330 struct nft_expr_type nft_payload_type __read_mostly = {
1331 	.name		= "payload",
1332 	.select_ops	= nft_payload_select_ops,
1333 	.inner_ops	= &nft_payload_inner_ops,
1334 	.policy		= nft_payload_policy,
1335 	.maxattr	= NFTA_PAYLOAD_MAX,
1336 	.owner		= THIS_MODULE,
1337 };
1338