1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net> 4 * Copyright (c) 2014 Intel Corporation 5 * Author: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> 6 * 7 * Development of this code funded by Astaro AG (http://www.astaro.com/) 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/netlink.h> 12 #include <linux/netfilter.h> 13 #include <linux/netfilter/nf_tables.h> 14 #include <linux/in.h> 15 #include <linux/ip.h> 16 #include <linux/ipv6.h> 17 #include <linux/random.h> 18 #include <linux/smp.h> 19 #include <linux/static_key.h> 20 #include <net/dst.h> 21 #include <net/ip.h> 22 #include <net/sock.h> 23 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */ 24 #include <net/netfilter/nf_tables.h> 25 #include <net/netfilter/nf_tables_core.h> 26 #include <net/netfilter/nft_meta.h> 27 #include <net/netfilter/nf_tables_offload.h> 28 29 #include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */ 30 31 #define NFT_META_SECS_PER_MINUTE 60 32 #define NFT_META_SECS_PER_HOUR 3600 33 #define NFT_META_SECS_PER_DAY 86400 34 #define NFT_META_DAYS_PER_WEEK 7 35 36 static u8 nft_meta_weekday(void) 37 { 38 time64_t secs = ktime_get_real_seconds(); 39 unsigned int dse; 40 u8 wday; 41 42 secs -= NFT_META_SECS_PER_MINUTE * sys_tz.tz_minuteswest; 43 dse = div_u64(secs, NFT_META_SECS_PER_DAY); 44 wday = (4 + dse) % NFT_META_DAYS_PER_WEEK; 45 46 return wday; 47 } 48 49 static u32 nft_meta_hour(time64_t secs) 50 { 51 struct tm tm; 52 53 time64_to_tm(secs, 0, &tm); 54 55 return tm.tm_hour * NFT_META_SECS_PER_HOUR 56 + tm.tm_min * NFT_META_SECS_PER_MINUTE 57 + tm.tm_sec; 58 } 59 60 static noinline_for_stack void 61 nft_meta_get_eval_time(enum nft_meta_keys key, 62 u32 *dest) 63 { 64 switch (key) { 65 case NFT_META_TIME_NS: 66 nft_reg_store64(dest, ktime_get_real_ns()); 67 break; 68 case NFT_META_TIME_DAY: 69 nft_reg_store8(dest, nft_meta_weekday()); 70 break; 71 case NFT_META_TIME_HOUR: 72 *dest = nft_meta_hour(ktime_get_real_seconds()); 73 break; 74 default: 75 break; 76 } 77 } 78 79 static noinline bool 80 nft_meta_get_eval_pkttype_lo(const struct nft_pktinfo *pkt, 81 u32 *dest) 82 { 83 const struct sk_buff *skb = pkt->skb; 84 85 switch (nft_pf(pkt)) { 86 case NFPROTO_IPV4: 87 if (ipv4_is_multicast(ip_hdr(skb)->daddr)) 88 nft_reg_store8(dest, PACKET_MULTICAST); 89 else 90 nft_reg_store8(dest, PACKET_BROADCAST); 91 break; 92 case NFPROTO_IPV6: 93 nft_reg_store8(dest, PACKET_MULTICAST); 94 break; 95 case NFPROTO_NETDEV: 96 switch (skb->protocol) { 97 case htons(ETH_P_IP): { 98 int noff = skb_network_offset(skb); 99 struct iphdr *iph, _iph; 100 101 iph = skb_header_pointer(skb, noff, 102 sizeof(_iph), &_iph); 103 if (!iph) 104 return false; 105 106 if (ipv4_is_multicast(iph->daddr)) 107 nft_reg_store8(dest, PACKET_MULTICAST); 108 else 109 nft_reg_store8(dest, PACKET_BROADCAST); 110 111 break; 112 } 113 case htons(ETH_P_IPV6): 114 nft_reg_store8(dest, PACKET_MULTICAST); 115 break; 116 default: 117 WARN_ON_ONCE(1); 118 return false; 119 } 120 break; 121 default: 122 WARN_ON_ONCE(1); 123 return false; 124 } 125 126 return true; 127 } 128 129 static noinline bool 130 nft_meta_get_eval_skugid(enum nft_meta_keys key, 131 u32 *dest, 132 const struct nft_pktinfo *pkt) 133 { 134 struct sock *sk = skb_to_full_sk(pkt->skb); 135 struct socket *sock; 136 137 if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk))) 138 return false; 139 140 read_lock_bh(&sk->sk_callback_lock); 141 sock = sk->sk_socket; 142 if (!sock || !sock->file) { 143 read_unlock_bh(&sk->sk_callback_lock); 144 return false; 145 } 146 147 switch (key) { 148 case NFT_META_SKUID: 149 *dest = from_kuid_munged(sock_net(sk)->user_ns, 150 sock->file->f_cred->fsuid); 151 break; 152 case NFT_META_SKGID: 153 *dest = from_kgid_munged(sock_net(sk)->user_ns, 154 sock->file->f_cred->fsgid); 155 break; 156 default: 157 break; 158 } 159 160 read_unlock_bh(&sk->sk_callback_lock); 161 return true; 162 } 163 164 #ifdef CONFIG_CGROUP_NET_CLASSID 165 static noinline bool 166 nft_meta_get_eval_cgroup(u32 *dest, const struct nft_pktinfo *pkt) 167 { 168 struct sock *sk = skb_to_full_sk(pkt->skb); 169 170 if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk))) 171 return false; 172 173 *dest = sock_cgroup_classid(&sk->sk_cgrp_data); 174 return true; 175 } 176 #endif 177 178 static noinline bool nft_meta_get_eval_kind(enum nft_meta_keys key, 179 u32 *dest, 180 const struct nft_pktinfo *pkt) 181 { 182 const struct net_device *in = nft_in(pkt), *out = nft_out(pkt); 183 184 switch (key) { 185 case NFT_META_IIFKIND: 186 if (!in || !in->rtnl_link_ops) 187 return false; 188 strncpy((char *)dest, in->rtnl_link_ops->kind, IFNAMSIZ); 189 break; 190 case NFT_META_OIFKIND: 191 if (!out || !out->rtnl_link_ops) 192 return false; 193 strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ); 194 break; 195 default: 196 return false; 197 } 198 199 return true; 200 } 201 202 static void nft_meta_store_ifindex(u32 *dest, const struct net_device *dev) 203 { 204 *dest = dev ? dev->ifindex : 0; 205 } 206 207 static void nft_meta_store_ifname(u32 *dest, const struct net_device *dev) 208 { 209 strncpy((char *)dest, dev ? dev->name : "", IFNAMSIZ); 210 } 211 212 static bool nft_meta_store_iftype(u32 *dest, const struct net_device *dev) 213 { 214 if (!dev) 215 return false; 216 217 nft_reg_store16(dest, dev->type); 218 return true; 219 } 220 221 static bool nft_meta_store_ifgroup(u32 *dest, const struct net_device *dev) 222 { 223 if (!dev) 224 return false; 225 226 *dest = dev->group; 227 return true; 228 } 229 230 static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest, 231 const struct nft_pktinfo *pkt) 232 { 233 switch (key) { 234 case NFT_META_IIFNAME: 235 nft_meta_store_ifname(dest, nft_in(pkt)); 236 break; 237 case NFT_META_OIFNAME: 238 nft_meta_store_ifname(dest, nft_out(pkt)); 239 break; 240 case NFT_META_IIF: 241 nft_meta_store_ifindex(dest, nft_in(pkt)); 242 break; 243 case NFT_META_OIF: 244 nft_meta_store_ifindex(dest, nft_out(pkt)); 245 break; 246 case NFT_META_IFTYPE: 247 if (!nft_meta_store_iftype(dest, pkt->skb->dev)) 248 return false; 249 break; 250 case __NFT_META_IIFTYPE: 251 if (!nft_meta_store_iftype(dest, nft_in(pkt))) 252 return false; 253 break; 254 case NFT_META_OIFTYPE: 255 if (!nft_meta_store_iftype(dest, nft_out(pkt))) 256 return false; 257 break; 258 case NFT_META_IIFGROUP: 259 if (!nft_meta_store_ifgroup(dest, nft_in(pkt))) 260 return false; 261 break; 262 case NFT_META_OIFGROUP: 263 if (!nft_meta_store_ifgroup(dest, nft_out(pkt))) 264 return false; 265 break; 266 default: 267 return false; 268 } 269 270 return true; 271 } 272 273 #ifdef CONFIG_IP_ROUTE_CLASSID 274 static noinline bool 275 nft_meta_get_eval_rtclassid(const struct sk_buff *skb, u32 *dest) 276 { 277 const struct dst_entry *dst = skb_dst(skb); 278 279 if (!dst) 280 return false; 281 282 *dest = dst->tclassid; 283 return true; 284 } 285 #endif 286 287 static noinline u32 nft_meta_get_eval_sdif(const struct nft_pktinfo *pkt) 288 { 289 switch (nft_pf(pkt)) { 290 case NFPROTO_IPV4: 291 return inet_sdif(pkt->skb); 292 case NFPROTO_IPV6: 293 return inet6_sdif(pkt->skb); 294 } 295 296 return 0; 297 } 298 299 static noinline void 300 nft_meta_get_eval_sdifname(u32 *dest, const struct nft_pktinfo *pkt) 301 { 302 u32 sdif = nft_meta_get_eval_sdif(pkt); 303 const struct net_device *dev; 304 305 dev = sdif ? dev_get_by_index_rcu(nft_net(pkt), sdif) : NULL; 306 nft_meta_store_ifname(dest, dev); 307 } 308 309 void nft_meta_get_eval(const struct nft_expr *expr, 310 struct nft_regs *regs, 311 const struct nft_pktinfo *pkt) 312 { 313 const struct nft_meta *priv = nft_expr_priv(expr); 314 const struct sk_buff *skb = pkt->skb; 315 u32 *dest = ®s->data[priv->dreg]; 316 317 switch (priv->key) { 318 case NFT_META_LEN: 319 *dest = skb->len; 320 break; 321 case NFT_META_PROTOCOL: 322 nft_reg_store16(dest, (__force u16)skb->protocol); 323 break; 324 case NFT_META_NFPROTO: 325 nft_reg_store8(dest, nft_pf(pkt)); 326 break; 327 case NFT_META_L4PROTO: 328 if (!(pkt->flags & NFT_PKTINFO_L4PROTO)) 329 goto err; 330 nft_reg_store8(dest, pkt->tprot); 331 break; 332 case NFT_META_PRIORITY: 333 *dest = skb->priority; 334 break; 335 case NFT_META_MARK: 336 *dest = skb->mark; 337 break; 338 case NFT_META_IIF: 339 case NFT_META_OIF: 340 case NFT_META_IIFNAME: 341 case NFT_META_OIFNAME: 342 case NFT_META_IIFTYPE: 343 case NFT_META_OIFTYPE: 344 case NFT_META_IIFGROUP: 345 case NFT_META_OIFGROUP: 346 if (!nft_meta_get_eval_ifname(priv->key, dest, pkt)) 347 goto err; 348 break; 349 case NFT_META_SKUID: 350 case NFT_META_SKGID: 351 if (!nft_meta_get_eval_skugid(priv->key, dest, pkt)) 352 goto err; 353 break; 354 #ifdef CONFIG_IP_ROUTE_CLASSID 355 case NFT_META_RTCLASSID: 356 if (!nft_meta_get_eval_rtclassid(skb, dest)) 357 goto err; 358 break; 359 #endif 360 #ifdef CONFIG_NETWORK_SECMARK 361 case NFT_META_SECMARK: 362 *dest = skb->secmark; 363 break; 364 #endif 365 case NFT_META_PKTTYPE: 366 if (skb->pkt_type != PACKET_LOOPBACK) { 367 nft_reg_store8(dest, skb->pkt_type); 368 break; 369 } 370 371 if (!nft_meta_get_eval_pkttype_lo(pkt, dest)) 372 goto err; 373 break; 374 case NFT_META_CPU: 375 *dest = raw_smp_processor_id(); 376 break; 377 #ifdef CONFIG_CGROUP_NET_CLASSID 378 case NFT_META_CGROUP: 379 if (!nft_meta_get_eval_cgroup(dest, pkt)) 380 goto err; 381 break; 382 #endif 383 case NFT_META_PRANDOM: 384 *dest = get_random_u32(); 385 break; 386 #ifdef CONFIG_XFRM 387 case NFT_META_SECPATH: 388 nft_reg_store8(dest, secpath_exists(skb)); 389 break; 390 #endif 391 case NFT_META_IIFKIND: 392 case NFT_META_OIFKIND: 393 if (!nft_meta_get_eval_kind(priv->key, dest, pkt)) 394 goto err; 395 break; 396 case NFT_META_TIME_NS: 397 case NFT_META_TIME_DAY: 398 case NFT_META_TIME_HOUR: 399 nft_meta_get_eval_time(priv->key, dest); 400 break; 401 case NFT_META_SDIF: 402 *dest = nft_meta_get_eval_sdif(pkt); 403 break; 404 case NFT_META_SDIFNAME: 405 nft_meta_get_eval_sdifname(dest, pkt); 406 break; 407 default: 408 WARN_ON(1); 409 goto err; 410 } 411 return; 412 413 err: 414 regs->verdict.code = NFT_BREAK; 415 } 416 EXPORT_SYMBOL_GPL(nft_meta_get_eval); 417 418 void nft_meta_set_eval(const struct nft_expr *expr, 419 struct nft_regs *regs, 420 const struct nft_pktinfo *pkt) 421 { 422 const struct nft_meta *meta = nft_expr_priv(expr); 423 struct sk_buff *skb = pkt->skb; 424 u32 *sreg = ®s->data[meta->sreg]; 425 u32 value = *sreg; 426 u8 value8; 427 428 switch (meta->key) { 429 case NFT_META_MARK: 430 skb->mark = value; 431 break; 432 case NFT_META_PRIORITY: 433 skb->priority = value; 434 break; 435 case NFT_META_PKTTYPE: 436 value8 = nft_reg_load8(sreg); 437 438 if (skb->pkt_type != value8 && 439 skb_pkt_type_ok(value8) && 440 skb_pkt_type_ok(skb->pkt_type)) 441 skb->pkt_type = value8; 442 break; 443 case NFT_META_NFTRACE: 444 value8 = nft_reg_load8(sreg); 445 446 skb->nf_trace = !!value8; 447 break; 448 #ifdef CONFIG_NETWORK_SECMARK 449 case NFT_META_SECMARK: 450 skb->secmark = value; 451 break; 452 #endif 453 default: 454 WARN_ON(1); 455 } 456 } 457 EXPORT_SYMBOL_GPL(nft_meta_set_eval); 458 459 const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = { 460 [NFTA_META_DREG] = { .type = NLA_U32 }, 461 [NFTA_META_KEY] = { .type = NLA_U32 }, 462 [NFTA_META_SREG] = { .type = NLA_U32 }, 463 }; 464 EXPORT_SYMBOL_GPL(nft_meta_policy); 465 466 int nft_meta_get_init(const struct nft_ctx *ctx, 467 const struct nft_expr *expr, 468 const struct nlattr * const tb[]) 469 { 470 struct nft_meta *priv = nft_expr_priv(expr); 471 unsigned int len; 472 473 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 474 switch (priv->key) { 475 case NFT_META_PROTOCOL: 476 case NFT_META_IIFTYPE: 477 case NFT_META_OIFTYPE: 478 len = sizeof(u16); 479 break; 480 case NFT_META_NFPROTO: 481 case NFT_META_L4PROTO: 482 case NFT_META_LEN: 483 case NFT_META_PRIORITY: 484 case NFT_META_MARK: 485 case NFT_META_IIF: 486 case NFT_META_OIF: 487 case NFT_META_SDIF: 488 case NFT_META_SKUID: 489 case NFT_META_SKGID: 490 #ifdef CONFIG_IP_ROUTE_CLASSID 491 case NFT_META_RTCLASSID: 492 #endif 493 #ifdef CONFIG_NETWORK_SECMARK 494 case NFT_META_SECMARK: 495 #endif 496 case NFT_META_PKTTYPE: 497 case NFT_META_CPU: 498 case NFT_META_IIFGROUP: 499 case NFT_META_OIFGROUP: 500 #ifdef CONFIG_CGROUP_NET_CLASSID 501 case NFT_META_CGROUP: 502 #endif 503 len = sizeof(u32); 504 break; 505 case NFT_META_IIFNAME: 506 case NFT_META_OIFNAME: 507 case NFT_META_IIFKIND: 508 case NFT_META_OIFKIND: 509 case NFT_META_SDIFNAME: 510 len = IFNAMSIZ; 511 break; 512 case NFT_META_PRANDOM: 513 len = sizeof(u32); 514 break; 515 #ifdef CONFIG_XFRM 516 case NFT_META_SECPATH: 517 len = sizeof(u8); 518 break; 519 #endif 520 case NFT_META_TIME_NS: 521 len = sizeof(u64); 522 break; 523 case NFT_META_TIME_DAY: 524 len = sizeof(u8); 525 break; 526 case NFT_META_TIME_HOUR: 527 len = sizeof(u32); 528 break; 529 default: 530 return -EOPNOTSUPP; 531 } 532 533 priv->len = len; 534 return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg, 535 NULL, NFT_DATA_VALUE, len); 536 } 537 EXPORT_SYMBOL_GPL(nft_meta_get_init); 538 539 static int nft_meta_get_validate_sdif(const struct nft_ctx *ctx) 540 { 541 unsigned int hooks; 542 543 switch (ctx->family) { 544 case NFPROTO_IPV4: 545 case NFPROTO_IPV6: 546 case NFPROTO_INET: 547 hooks = (1 << NF_INET_LOCAL_IN) | 548 (1 << NF_INET_FORWARD); 549 break; 550 default: 551 return -EOPNOTSUPP; 552 } 553 554 return nft_chain_validate_hooks(ctx->chain, hooks); 555 } 556 557 static int nft_meta_get_validate_xfrm(const struct nft_ctx *ctx) 558 { 559 #ifdef CONFIG_XFRM 560 unsigned int hooks; 561 562 switch (ctx->family) { 563 case NFPROTO_NETDEV: 564 hooks = 1 << NF_NETDEV_INGRESS; 565 break; 566 case NFPROTO_IPV4: 567 case NFPROTO_IPV6: 568 case NFPROTO_INET: 569 hooks = (1 << NF_INET_PRE_ROUTING) | 570 (1 << NF_INET_LOCAL_IN) | 571 (1 << NF_INET_FORWARD); 572 break; 573 default: 574 return -EOPNOTSUPP; 575 } 576 577 return nft_chain_validate_hooks(ctx->chain, hooks); 578 #else 579 return 0; 580 #endif 581 } 582 583 static int nft_meta_get_validate(const struct nft_ctx *ctx, 584 const struct nft_expr *expr, 585 const struct nft_data **data) 586 { 587 const struct nft_meta *priv = nft_expr_priv(expr); 588 589 switch (priv->key) { 590 case NFT_META_SECPATH: 591 return nft_meta_get_validate_xfrm(ctx); 592 case NFT_META_SDIF: 593 case NFT_META_SDIFNAME: 594 return nft_meta_get_validate_sdif(ctx); 595 default: 596 break; 597 } 598 599 return 0; 600 } 601 602 int nft_meta_set_validate(const struct nft_ctx *ctx, 603 const struct nft_expr *expr, 604 const struct nft_data **data) 605 { 606 struct nft_meta *priv = nft_expr_priv(expr); 607 unsigned int hooks; 608 609 if (priv->key != NFT_META_PKTTYPE) 610 return 0; 611 612 switch (ctx->family) { 613 case NFPROTO_BRIDGE: 614 hooks = 1 << NF_BR_PRE_ROUTING; 615 break; 616 case NFPROTO_NETDEV: 617 hooks = 1 << NF_NETDEV_INGRESS; 618 break; 619 case NFPROTO_IPV4: 620 case NFPROTO_IPV6: 621 case NFPROTO_INET: 622 hooks = 1 << NF_INET_PRE_ROUTING; 623 break; 624 default: 625 return -EOPNOTSUPP; 626 } 627 628 return nft_chain_validate_hooks(ctx->chain, hooks); 629 } 630 EXPORT_SYMBOL_GPL(nft_meta_set_validate); 631 632 int nft_meta_set_init(const struct nft_ctx *ctx, 633 const struct nft_expr *expr, 634 const struct nlattr * const tb[]) 635 { 636 struct nft_meta *priv = nft_expr_priv(expr); 637 unsigned int len; 638 int err; 639 640 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 641 switch (priv->key) { 642 case NFT_META_MARK: 643 case NFT_META_PRIORITY: 644 #ifdef CONFIG_NETWORK_SECMARK 645 case NFT_META_SECMARK: 646 #endif 647 len = sizeof(u32); 648 break; 649 case NFT_META_NFTRACE: 650 len = sizeof(u8); 651 break; 652 case NFT_META_PKTTYPE: 653 len = sizeof(u8); 654 break; 655 default: 656 return -EOPNOTSUPP; 657 } 658 659 priv->len = len; 660 err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len); 661 if (err < 0) 662 return err; 663 664 if (priv->key == NFT_META_NFTRACE) 665 static_branch_inc(&nft_trace_enabled); 666 667 return 0; 668 } 669 EXPORT_SYMBOL_GPL(nft_meta_set_init); 670 671 int nft_meta_get_dump(struct sk_buff *skb, 672 const struct nft_expr *expr, bool reset) 673 { 674 const struct nft_meta *priv = nft_expr_priv(expr); 675 676 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) 677 goto nla_put_failure; 678 if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg)) 679 goto nla_put_failure; 680 return 0; 681 682 nla_put_failure: 683 return -1; 684 } 685 EXPORT_SYMBOL_GPL(nft_meta_get_dump); 686 687 int nft_meta_set_dump(struct sk_buff *skb, 688 const struct nft_expr *expr, bool reset) 689 { 690 const struct nft_meta *priv = nft_expr_priv(expr); 691 692 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) 693 goto nla_put_failure; 694 if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg)) 695 goto nla_put_failure; 696 697 return 0; 698 699 nla_put_failure: 700 return -1; 701 } 702 EXPORT_SYMBOL_GPL(nft_meta_set_dump); 703 704 void nft_meta_set_destroy(const struct nft_ctx *ctx, 705 const struct nft_expr *expr) 706 { 707 const struct nft_meta *priv = nft_expr_priv(expr); 708 709 if (priv->key == NFT_META_NFTRACE) 710 static_branch_dec(&nft_trace_enabled); 711 } 712 EXPORT_SYMBOL_GPL(nft_meta_set_destroy); 713 714 static int nft_meta_get_offload(struct nft_offload_ctx *ctx, 715 struct nft_flow_rule *flow, 716 const struct nft_expr *expr) 717 { 718 const struct nft_meta *priv = nft_expr_priv(expr); 719 struct nft_offload_reg *reg = &ctx->regs[priv->dreg]; 720 721 switch (priv->key) { 722 case NFT_META_PROTOCOL: 723 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC, basic, n_proto, 724 sizeof(__u16), reg); 725 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK); 726 break; 727 case NFT_META_L4PROTO: 728 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, 729 sizeof(__u8), reg); 730 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT); 731 break; 732 case NFT_META_IIF: 733 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META, meta, 734 ingress_ifindex, sizeof(__u32), reg); 735 break; 736 case NFT_META_IIFTYPE: 737 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META, meta, 738 ingress_iftype, sizeof(__u16), reg); 739 break; 740 default: 741 return -EOPNOTSUPP; 742 } 743 744 return 0; 745 } 746 747 bool nft_meta_get_reduce(struct nft_regs_track *track, 748 const struct nft_expr *expr) 749 { 750 const struct nft_meta *priv = nft_expr_priv(expr); 751 const struct nft_meta *meta; 752 753 if (!nft_reg_track_cmp(track, expr, priv->dreg)) { 754 nft_reg_track_update(track, expr, priv->dreg, priv->len); 755 return false; 756 } 757 758 meta = nft_expr_priv(track->regs[priv->dreg].selector); 759 if (priv->key != meta->key || 760 priv->dreg != meta->dreg) { 761 nft_reg_track_update(track, expr, priv->dreg, priv->len); 762 return false; 763 } 764 765 if (!track->regs[priv->dreg].bitwise) 766 return true; 767 768 return nft_expr_reduce_bitwise(track, expr); 769 } 770 EXPORT_SYMBOL_GPL(nft_meta_get_reduce); 771 772 static const struct nft_expr_ops nft_meta_get_ops = { 773 .type = &nft_meta_type, 774 .size = NFT_EXPR_SIZE(sizeof(struct nft_meta)), 775 .eval = nft_meta_get_eval, 776 .init = nft_meta_get_init, 777 .dump = nft_meta_get_dump, 778 .reduce = nft_meta_get_reduce, 779 .validate = nft_meta_get_validate, 780 .offload = nft_meta_get_offload, 781 }; 782 783 static bool nft_meta_set_reduce(struct nft_regs_track *track, 784 const struct nft_expr *expr) 785 { 786 int i; 787 788 for (i = 0; i < NFT_REG32_NUM; i++) { 789 if (!track->regs[i].selector) 790 continue; 791 792 if (track->regs[i].selector->ops != &nft_meta_get_ops) 793 continue; 794 795 __nft_reg_track_cancel(track, i); 796 } 797 798 return false; 799 } 800 801 static const struct nft_expr_ops nft_meta_set_ops = { 802 .type = &nft_meta_type, 803 .size = NFT_EXPR_SIZE(sizeof(struct nft_meta)), 804 .eval = nft_meta_set_eval, 805 .init = nft_meta_set_init, 806 .destroy = nft_meta_set_destroy, 807 .dump = nft_meta_set_dump, 808 .reduce = nft_meta_set_reduce, 809 .validate = nft_meta_set_validate, 810 }; 811 812 static const struct nft_expr_ops * 813 nft_meta_select_ops(const struct nft_ctx *ctx, 814 const struct nlattr * const tb[]) 815 { 816 if (tb[NFTA_META_KEY] == NULL) 817 return ERR_PTR(-EINVAL); 818 819 if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG]) 820 return ERR_PTR(-EINVAL); 821 822 #if IS_ENABLED(CONFIG_NF_TABLES_BRIDGE) && IS_MODULE(CONFIG_NFT_BRIDGE_META) 823 if (ctx->family == NFPROTO_BRIDGE) 824 return ERR_PTR(-EAGAIN); 825 #endif 826 if (tb[NFTA_META_DREG]) 827 return &nft_meta_get_ops; 828 829 if (tb[NFTA_META_SREG]) 830 return &nft_meta_set_ops; 831 832 return ERR_PTR(-EINVAL); 833 } 834 835 static int nft_meta_inner_init(const struct nft_ctx *ctx, 836 const struct nft_expr *expr, 837 const struct nlattr * const tb[]) 838 { 839 struct nft_meta *priv = nft_expr_priv(expr); 840 unsigned int len; 841 842 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 843 switch (priv->key) { 844 case NFT_META_PROTOCOL: 845 len = sizeof(u16); 846 break; 847 case NFT_META_L4PROTO: 848 len = sizeof(u32); 849 break; 850 default: 851 return -EOPNOTSUPP; 852 } 853 priv->len = len; 854 855 return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg, 856 NULL, NFT_DATA_VALUE, len); 857 } 858 859 void nft_meta_inner_eval(const struct nft_expr *expr, 860 struct nft_regs *regs, 861 const struct nft_pktinfo *pkt, 862 struct nft_inner_tun_ctx *tun_ctx) 863 { 864 const struct nft_meta *priv = nft_expr_priv(expr); 865 u32 *dest = ®s->data[priv->dreg]; 866 867 switch (priv->key) { 868 case NFT_META_PROTOCOL: 869 nft_reg_store16(dest, (__force u16)tun_ctx->llproto); 870 break; 871 case NFT_META_L4PROTO: 872 if (!(tun_ctx->flags & NFT_PAYLOAD_CTX_INNER_TH)) 873 goto err; 874 875 nft_reg_store8(dest, tun_ctx->l4proto); 876 break; 877 default: 878 WARN_ON_ONCE(1); 879 goto err; 880 } 881 return; 882 883 err: 884 regs->verdict.code = NFT_BREAK; 885 } 886 EXPORT_SYMBOL_GPL(nft_meta_inner_eval); 887 888 static const struct nft_expr_ops nft_meta_inner_ops = { 889 .type = &nft_meta_type, 890 .size = NFT_EXPR_SIZE(sizeof(struct nft_meta)), 891 .init = nft_meta_inner_init, 892 .dump = nft_meta_get_dump, 893 /* direct call to nft_meta_inner_eval(). */ 894 }; 895 896 struct nft_expr_type nft_meta_type __read_mostly = { 897 .name = "meta", 898 .select_ops = nft_meta_select_ops, 899 .inner_ops = &nft_meta_inner_ops, 900 .policy = nft_meta_policy, 901 .maxattr = NFTA_META_MAX, 902 .owner = THIS_MODULE, 903 }; 904 905 #ifdef CONFIG_NETWORK_SECMARK 906 struct nft_secmark { 907 u32 secid; 908 char *ctx; 909 }; 910 911 static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { 912 [NFTA_SECMARK_CTX] = { .type = NLA_STRING, .len = NFT_SECMARK_CTX_MAXLEN }, 913 }; 914 915 static int nft_secmark_compute_secid(struct nft_secmark *priv) 916 { 917 u32 tmp_secid = 0; 918 int err; 919 920 err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid); 921 if (err) 922 return err; 923 924 if (!tmp_secid) 925 return -ENOENT; 926 927 err = security_secmark_relabel_packet(tmp_secid); 928 if (err) 929 return err; 930 931 priv->secid = tmp_secid; 932 return 0; 933 } 934 935 static void nft_secmark_obj_eval(struct nft_object *obj, struct nft_regs *regs, 936 const struct nft_pktinfo *pkt) 937 { 938 const struct nft_secmark *priv = nft_obj_data(obj); 939 struct sk_buff *skb = pkt->skb; 940 941 skb->secmark = priv->secid; 942 } 943 944 static int nft_secmark_obj_init(const struct nft_ctx *ctx, 945 const struct nlattr * const tb[], 946 struct nft_object *obj) 947 { 948 struct nft_secmark *priv = nft_obj_data(obj); 949 int err; 950 951 if (tb[NFTA_SECMARK_CTX] == NULL) 952 return -EINVAL; 953 954 priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL); 955 if (!priv->ctx) 956 return -ENOMEM; 957 958 err = nft_secmark_compute_secid(priv); 959 if (err) { 960 kfree(priv->ctx); 961 return err; 962 } 963 964 security_secmark_refcount_inc(); 965 966 return 0; 967 } 968 969 static int nft_secmark_obj_dump(struct sk_buff *skb, struct nft_object *obj, 970 bool reset) 971 { 972 struct nft_secmark *priv = nft_obj_data(obj); 973 int err; 974 975 if (nla_put_string(skb, NFTA_SECMARK_CTX, priv->ctx)) 976 return -1; 977 978 if (reset) { 979 err = nft_secmark_compute_secid(priv); 980 if (err) 981 return err; 982 } 983 984 return 0; 985 } 986 987 static void nft_secmark_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj) 988 { 989 struct nft_secmark *priv = nft_obj_data(obj); 990 991 security_secmark_refcount_dec(); 992 993 kfree(priv->ctx); 994 } 995 996 static const struct nft_object_ops nft_secmark_obj_ops = { 997 .type = &nft_secmark_obj_type, 998 .size = sizeof(struct nft_secmark), 999 .init = nft_secmark_obj_init, 1000 .eval = nft_secmark_obj_eval, 1001 .dump = nft_secmark_obj_dump, 1002 .destroy = nft_secmark_obj_destroy, 1003 }; 1004 struct nft_object_type nft_secmark_obj_type __read_mostly = { 1005 .type = NFT_OBJECT_SECMARK, 1006 .ops = &nft_secmark_obj_ops, 1007 .maxattr = NFTA_SECMARK_MAX, 1008 .policy = nft_secmark_policy, 1009 .owner = THIS_MODULE, 1010 }; 1011 #endif /* CONFIG_NETWORK_SECMARK */ 1012