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 unsigned int remainder, delta, k;
263 struct nft_data mask = {};
264 __be32 remainder_mask;
265
266 if (priv_len == field_len) {
267 memset(®->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(®->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 = ®s->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 = ®s->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