1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net> 4 * Copyright (c) 2016 Pablo Neira Ayuso <pablo@netfilter.org> 5 * 6 * Development of this code funded by Astaro AG (http://www.astaro.com/) 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/if_vlan.h> 11 #include <linux/init.h> 12 #include <linux/module.h> 13 #include <linux/netlink.h> 14 #include <linux/netfilter.h> 15 #include <linux/netfilter/nf_tables.h> 16 #include <net/netfilter/nf_tables_core.h> 17 #include <net/netfilter/nf_tables.h> 18 #include <net/netfilter/nf_tables_offload.h> 19 /* For layer 4 checksum field offset. */ 20 #include <linux/tcp.h> 21 #include <linux/udp.h> 22 #include <net/gre.h> 23 #include <linux/icmpv6.h> 24 #include <linux/ip.h> 25 #include <linux/ipv6.h> 26 #include <net/sctp/checksum.h> 27 28 static bool nft_payload_rebuild_vlan_hdr(const struct sk_buff *skb, int mac_off, 29 struct vlan_ethhdr *veth) 30 { 31 if (skb_copy_bits(skb, mac_off, veth, ETH_HLEN)) 32 return false; 33 34 veth->h_vlan_proto = skb->vlan_proto; 35 veth->h_vlan_TCI = htons(skb_vlan_tag_get(skb)); 36 veth->h_vlan_encapsulated_proto = skb->protocol; 37 38 return true; 39 } 40 41 /* add vlan header into the user buffer for if tag was removed by offloads */ 42 static bool 43 nft_payload_copy_vlan(u32 *d, const struct sk_buff *skb, 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 74 static int __nft_payload_inner_offset(struct nft_pktinfo *pkt) 75 { 76 unsigned int thoff = nft_thoff(pkt); 77 78 if (!(pkt->flags & NFT_PKTINFO_L4PROTO) || pkt->fragoff) 79 return -1; 80 81 switch (pkt->tprot) { 82 case IPPROTO_UDP: 83 pkt->inneroff = thoff + sizeof(struct udphdr); 84 break; 85 case IPPROTO_TCP: { 86 struct tcphdr *th, _tcph; 87 88 th = skb_header_pointer(pkt->skb, thoff, sizeof(_tcph), &_tcph); 89 if (!th) 90 return -1; 91 92 pkt->inneroff = thoff + __tcp_hdrlen(th); 93 } 94 break; 95 case IPPROTO_GRE: { 96 u32 offset = sizeof(struct gre_base_hdr); 97 struct gre_base_hdr *gre, _gre; 98 __be16 version; 99 100 gre = skb_header_pointer(pkt->skb, thoff, sizeof(_gre), &_gre); 101 if (!gre) 102 return -1; 103 104 version = gre->flags & GRE_VERSION; 105 switch (version) { 106 case GRE_VERSION_0: 107 if (gre->flags & GRE_ROUTING) 108 return -1; 109 110 if (gre->flags & GRE_CSUM) { 111 offset += sizeof_field(struct gre_full_hdr, csum) + 112 sizeof_field(struct gre_full_hdr, reserved1); 113 } 114 if (gre->flags & GRE_KEY) 115 offset += sizeof_field(struct gre_full_hdr, key); 116 117 if (gre->flags & GRE_SEQ) 118 offset += sizeof_field(struct gre_full_hdr, seq); 119 break; 120 default: 121 return -1; 122 } 123 124 pkt->inneroff = thoff + offset; 125 } 126 break; 127 case IPPROTO_IPIP: 128 pkt->inneroff = thoff; 129 break; 130 default: 131 return -1; 132 } 133 134 pkt->flags |= NFT_PKTINFO_INNER; 135 136 return 0; 137 } 138 139 int nft_payload_inner_offset(const struct nft_pktinfo *pkt) 140 { 141 if (!(pkt->flags & NFT_PKTINFO_INNER) && 142 __nft_payload_inner_offset((struct nft_pktinfo *)pkt) < 0) 143 return -1; 144 145 return pkt->inneroff; 146 } 147 148 static bool nft_payload_need_vlan_adjust(u32 offset, u32 len) 149 { 150 unsigned int boundary = offset + len; 151 152 /* data past ether src/dst requested, copy needed */ 153 if (boundary > offsetof(struct ethhdr, h_proto)) 154 return true; 155 156 return false; 157 } 158 159 void nft_payload_eval(const struct nft_expr *expr, 160 struct nft_regs *regs, 161 const struct nft_pktinfo *pkt) 162 { 163 const struct nft_payload *priv = nft_expr_priv(expr); 164 const struct sk_buff *skb = pkt->skb; 165 u32 *dest = ®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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 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. */ 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 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 */ 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 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 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 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 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 * 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