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