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 = ®s->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(®->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(®->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 = ®s->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 = ®s->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