Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.16-rc1 1448 lines 35 kB view raw
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/init.h> 11#include <linux/module.h> 12#include <linux/netlink.h> 13#include <linux/netfilter.h> 14#include <linux/netfilter/nf_tables.h> 15#include <net/netfilter/nf_tables_core.h> 16#include <net/netfilter/nf_conntrack.h> 17#include <net/netfilter/nf_conntrack_acct.h> 18#include <net/netfilter/nf_conntrack_tuple.h> 19#include <net/netfilter/nf_conntrack_helper.h> 20#include <net/netfilter/nf_conntrack_ecache.h> 21#include <net/netfilter/nf_conntrack_labels.h> 22#include <net/netfilter/nf_conntrack_timeout.h> 23#include <net/netfilter/nf_conntrack_l4proto.h> 24#include <net/netfilter/nf_conntrack_expect.h> 25 26struct nft_ct_helper_obj { 27 struct nf_conntrack_helper *helper4; 28 struct nf_conntrack_helper *helper6; 29 u8 l4proto; 30}; 31 32#ifdef CONFIG_NF_CONNTRACK_ZONES 33static DEFINE_PER_CPU(struct nf_conn *, nft_ct_pcpu_template); 34static unsigned int nft_ct_pcpu_template_refcnt __read_mostly; 35static DEFINE_MUTEX(nft_ct_pcpu_mutex); 36#endif 37 38static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c, 39 enum nft_ct_keys k, 40 enum ip_conntrack_dir d) 41{ 42 if (d < IP_CT_DIR_MAX) 43 return k == NFT_CT_BYTES ? atomic64_read(&c[d].bytes) : 44 atomic64_read(&c[d].packets); 45 46 return nft_ct_get_eval_counter(c, k, IP_CT_DIR_ORIGINAL) + 47 nft_ct_get_eval_counter(c, k, IP_CT_DIR_REPLY); 48} 49 50static void nft_ct_get_eval(const struct nft_expr *expr, 51 struct nft_regs *regs, 52 const struct nft_pktinfo *pkt) 53{ 54 const struct nft_ct *priv = nft_expr_priv(expr); 55 u32 *dest = &regs->data[priv->dreg]; 56 enum ip_conntrack_info ctinfo; 57 const struct nf_conn *ct; 58 const struct nf_conn_help *help; 59 const struct nf_conntrack_tuple *tuple; 60 const struct nf_conntrack_helper *helper; 61 unsigned int state; 62 63 ct = nf_ct_get(pkt->skb, &ctinfo); 64 65 switch (priv->key) { 66 case NFT_CT_STATE: 67 if (ct) 68 state = NF_CT_STATE_BIT(ctinfo); 69 else if (ctinfo == IP_CT_UNTRACKED) 70 state = NF_CT_STATE_UNTRACKED_BIT; 71 else 72 state = NF_CT_STATE_INVALID_BIT; 73 *dest = state; 74 return; 75 default: 76 break; 77 } 78 79 if (ct == NULL) 80 goto err; 81 82 switch (priv->key) { 83 case NFT_CT_DIRECTION: 84 nft_reg_store8(dest, CTINFO2DIR(ctinfo)); 85 return; 86 case NFT_CT_STATUS: 87 *dest = ct->status; 88 return; 89#ifdef CONFIG_NF_CONNTRACK_MARK 90 case NFT_CT_MARK: 91 *dest = READ_ONCE(ct->mark); 92 return; 93#endif 94#ifdef CONFIG_NF_CONNTRACK_SECMARK 95 case NFT_CT_SECMARK: 96 *dest = ct->secmark; 97 return; 98#endif 99 case NFT_CT_EXPIRATION: 100 *dest = jiffies_to_msecs(nf_ct_expires(ct)); 101 return; 102 case NFT_CT_HELPER: 103 if (ct->master == NULL) 104 goto err; 105 help = nfct_help(ct->master); 106 if (help == NULL) 107 goto err; 108 helper = rcu_dereference(help->helper); 109 if (helper == NULL) 110 goto err; 111 strscpy_pad((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN); 112 return; 113#ifdef CONFIG_NF_CONNTRACK_LABELS 114 case NFT_CT_LABELS: { 115 struct nf_conn_labels *labels = nf_ct_labels_find(ct); 116 117 if (labels) 118 memcpy(dest, labels->bits, NF_CT_LABELS_MAX_SIZE); 119 else 120 memset(dest, 0, NF_CT_LABELS_MAX_SIZE); 121 return; 122 } 123#endif 124 case NFT_CT_BYTES: 125 case NFT_CT_PKTS: { 126 const struct nf_conn_acct *acct = nf_conn_acct_find(ct); 127 u64 count = 0; 128 129 if (acct) 130 count = nft_ct_get_eval_counter(acct->counter, 131 priv->key, priv->dir); 132 memcpy(dest, &count, sizeof(count)); 133 return; 134 } 135 case NFT_CT_AVGPKT: { 136 const struct nf_conn_acct *acct = nf_conn_acct_find(ct); 137 u64 avgcnt = 0, bcnt = 0, pcnt = 0; 138 139 if (acct) { 140 pcnt = nft_ct_get_eval_counter(acct->counter, 141 NFT_CT_PKTS, priv->dir); 142 bcnt = nft_ct_get_eval_counter(acct->counter, 143 NFT_CT_BYTES, priv->dir); 144 if (pcnt != 0) 145 avgcnt = div64_u64(bcnt, pcnt); 146 } 147 148 memcpy(dest, &avgcnt, sizeof(avgcnt)); 149 return; 150 } 151 case NFT_CT_L3PROTOCOL: 152 nft_reg_store8(dest, nf_ct_l3num(ct)); 153 return; 154 case NFT_CT_PROTOCOL: 155 nft_reg_store8(dest, nf_ct_protonum(ct)); 156 return; 157#ifdef CONFIG_NF_CONNTRACK_ZONES 158 case NFT_CT_ZONE: { 159 const struct nf_conntrack_zone *zone = nf_ct_zone(ct); 160 u16 zoneid; 161 162 if (priv->dir < IP_CT_DIR_MAX) 163 zoneid = nf_ct_zone_id(zone, priv->dir); 164 else 165 zoneid = zone->id; 166 167 nft_reg_store16(dest, zoneid); 168 return; 169 } 170#endif 171 case NFT_CT_ID: 172 *dest = nf_ct_get_id(ct); 173 return; 174 default: 175 break; 176 } 177 178 tuple = &ct->tuplehash[priv->dir].tuple; 179 switch (priv->key) { 180 case NFT_CT_SRC: 181 memcpy(dest, tuple->src.u3.all, 182 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); 183 return; 184 case NFT_CT_DST: 185 memcpy(dest, tuple->dst.u3.all, 186 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); 187 return; 188 case NFT_CT_PROTO_SRC: 189 nft_reg_store16(dest, (__force u16)tuple->src.u.all); 190 return; 191 case NFT_CT_PROTO_DST: 192 nft_reg_store16(dest, (__force u16)tuple->dst.u.all); 193 return; 194 case NFT_CT_SRC_IP: 195 if (nf_ct_l3num(ct) != NFPROTO_IPV4) 196 goto err; 197 *dest = (__force __u32)tuple->src.u3.ip; 198 return; 199 case NFT_CT_DST_IP: 200 if (nf_ct_l3num(ct) != NFPROTO_IPV4) 201 goto err; 202 *dest = (__force __u32)tuple->dst.u3.ip; 203 return; 204 case NFT_CT_SRC_IP6: 205 if (nf_ct_l3num(ct) != NFPROTO_IPV6) 206 goto err; 207 memcpy(dest, tuple->src.u3.ip6, sizeof(struct in6_addr)); 208 return; 209 case NFT_CT_DST_IP6: 210 if (nf_ct_l3num(ct) != NFPROTO_IPV6) 211 goto err; 212 memcpy(dest, tuple->dst.u3.ip6, sizeof(struct in6_addr)); 213 return; 214 default: 215 break; 216 } 217 return; 218err: 219 regs->verdict.code = NFT_BREAK; 220} 221 222#ifdef CONFIG_NF_CONNTRACK_ZONES 223static void nft_ct_set_zone_eval(const struct nft_expr *expr, 224 struct nft_regs *regs, 225 const struct nft_pktinfo *pkt) 226{ 227 struct nf_conntrack_zone zone = { .dir = NF_CT_DEFAULT_ZONE_DIR }; 228 const struct nft_ct *priv = nft_expr_priv(expr); 229 struct sk_buff *skb = pkt->skb; 230 enum ip_conntrack_info ctinfo; 231 u16 value = nft_reg_load16(&regs->data[priv->sreg]); 232 struct nf_conn *ct; 233 int oldcnt; 234 235 ct = nf_ct_get(skb, &ctinfo); 236 if (ct) /* already tracked */ 237 return; 238 239 zone.id = value; 240 241 switch (priv->dir) { 242 case IP_CT_DIR_ORIGINAL: 243 zone.dir = NF_CT_ZONE_DIR_ORIG; 244 break; 245 case IP_CT_DIR_REPLY: 246 zone.dir = NF_CT_ZONE_DIR_REPL; 247 break; 248 default: 249 break; 250 } 251 252 ct = this_cpu_read(nft_ct_pcpu_template); 253 254 __refcount_inc(&ct->ct_general.use, &oldcnt); 255 if (likely(oldcnt == 1)) { 256 nf_ct_zone_add(ct, &zone); 257 } else { 258 refcount_dec(&ct->ct_general.use); 259 /* previous skb got queued to userspace, allocate temporary 260 * one until percpu template can be reused. 261 */ 262 ct = nf_ct_tmpl_alloc(nft_net(pkt), &zone, GFP_ATOMIC); 263 if (!ct) { 264 regs->verdict.code = NF_DROP; 265 return; 266 } 267 __set_bit(IPS_CONFIRMED_BIT, &ct->status); 268 } 269 270 nf_ct_set(skb, ct, IP_CT_NEW); 271} 272#endif 273 274static void nft_ct_set_eval(const struct nft_expr *expr, 275 struct nft_regs *regs, 276 const struct nft_pktinfo *pkt) 277{ 278 const struct nft_ct *priv = nft_expr_priv(expr); 279 struct sk_buff *skb = pkt->skb; 280#if defined(CONFIG_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_SECMARK) 281 u32 value = regs->data[priv->sreg]; 282#endif 283 enum ip_conntrack_info ctinfo; 284 struct nf_conn *ct; 285 286 ct = nf_ct_get(skb, &ctinfo); 287 if (ct == NULL || nf_ct_is_template(ct)) 288 return; 289 290 switch (priv->key) { 291#ifdef CONFIG_NF_CONNTRACK_MARK 292 case NFT_CT_MARK: 293 if (READ_ONCE(ct->mark) != value) { 294 WRITE_ONCE(ct->mark, value); 295 nf_conntrack_event_cache(IPCT_MARK, ct); 296 } 297 break; 298#endif 299#ifdef CONFIG_NF_CONNTRACK_SECMARK 300 case NFT_CT_SECMARK: 301 if (ct->secmark != value) { 302 ct->secmark = value; 303 nf_conntrack_event_cache(IPCT_SECMARK, ct); 304 } 305 break; 306#endif 307#ifdef CONFIG_NF_CONNTRACK_LABELS 308 case NFT_CT_LABELS: 309 nf_connlabels_replace(ct, 310 &regs->data[priv->sreg], 311 &regs->data[priv->sreg], 312 NF_CT_LABELS_MAX_SIZE / sizeof(u32)); 313 break; 314#endif 315#ifdef CONFIG_NF_CONNTRACK_EVENTS 316 case NFT_CT_EVENTMASK: { 317 struct nf_conntrack_ecache *e = nf_ct_ecache_find(ct); 318 u32 ctmask = regs->data[priv->sreg]; 319 320 if (e) { 321 if (e->ctmask != ctmask) 322 e->ctmask = ctmask; 323 break; 324 } 325 326 if (ctmask && !nf_ct_is_confirmed(ct)) 327 nf_ct_ecache_ext_add(ct, ctmask, 0, GFP_ATOMIC); 328 break; 329 } 330#endif 331 default: 332 break; 333 } 334} 335 336static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = { 337 [NFTA_CT_DREG] = { .type = NLA_U32 }, 338 [NFTA_CT_KEY] = NLA_POLICY_MAX(NLA_BE32, 255), 339 [NFTA_CT_DIRECTION] = { .type = NLA_U8 }, 340 [NFTA_CT_SREG] = { .type = NLA_U32 }, 341}; 342 343#ifdef CONFIG_NF_CONNTRACK_ZONES 344static void nft_ct_tmpl_put_pcpu(void) 345{ 346 struct nf_conn *ct; 347 int cpu; 348 349 for_each_possible_cpu(cpu) { 350 ct = per_cpu(nft_ct_pcpu_template, cpu); 351 if (!ct) 352 break; 353 nf_ct_put(ct); 354 per_cpu(nft_ct_pcpu_template, cpu) = NULL; 355 } 356} 357 358static bool nft_ct_tmpl_alloc_pcpu(void) 359{ 360 struct nf_conntrack_zone zone = { .id = 0 }; 361 struct nf_conn *tmp; 362 int cpu; 363 364 if (nft_ct_pcpu_template_refcnt) 365 return true; 366 367 for_each_possible_cpu(cpu) { 368 tmp = nf_ct_tmpl_alloc(&init_net, &zone, GFP_KERNEL); 369 if (!tmp) { 370 nft_ct_tmpl_put_pcpu(); 371 return false; 372 } 373 374 __set_bit(IPS_CONFIRMED_BIT, &tmp->status); 375 per_cpu(nft_ct_pcpu_template, cpu) = tmp; 376 } 377 378 return true; 379} 380#endif 381 382static int nft_ct_get_init(const struct nft_ctx *ctx, 383 const struct nft_expr *expr, 384 const struct nlattr * const tb[]) 385{ 386 struct nft_ct *priv = nft_expr_priv(expr); 387 unsigned int len; 388 int err; 389 390 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 391 priv->dir = IP_CT_DIR_MAX; 392 switch (priv->key) { 393 case NFT_CT_DIRECTION: 394 if (tb[NFTA_CT_DIRECTION] != NULL) 395 return -EINVAL; 396 len = sizeof(u8); 397 break; 398 case NFT_CT_STATE: 399 case NFT_CT_STATUS: 400#ifdef CONFIG_NF_CONNTRACK_MARK 401 case NFT_CT_MARK: 402#endif 403#ifdef CONFIG_NF_CONNTRACK_SECMARK 404 case NFT_CT_SECMARK: 405#endif 406 case NFT_CT_EXPIRATION: 407 if (tb[NFTA_CT_DIRECTION] != NULL) 408 return -EINVAL; 409 len = sizeof(u32); 410 break; 411#ifdef CONFIG_NF_CONNTRACK_LABELS 412 case NFT_CT_LABELS: 413 if (tb[NFTA_CT_DIRECTION] != NULL) 414 return -EINVAL; 415 len = NF_CT_LABELS_MAX_SIZE; 416 break; 417#endif 418 case NFT_CT_HELPER: 419 if (tb[NFTA_CT_DIRECTION] != NULL) 420 return -EINVAL; 421 len = NF_CT_HELPER_NAME_LEN; 422 break; 423 424 case NFT_CT_L3PROTOCOL: 425 case NFT_CT_PROTOCOL: 426 /* For compatibility, do not report error if NFTA_CT_DIRECTION 427 * attribute is specified. 428 */ 429 len = sizeof(u8); 430 break; 431 case NFT_CT_SRC: 432 case NFT_CT_DST: 433 if (tb[NFTA_CT_DIRECTION] == NULL) 434 return -EINVAL; 435 436 switch (ctx->family) { 437 case NFPROTO_IPV4: 438 len = sizeof_field(struct nf_conntrack_tuple, 439 src.u3.ip); 440 break; 441 case NFPROTO_IPV6: 442 case NFPROTO_INET: 443 len = sizeof_field(struct nf_conntrack_tuple, 444 src.u3.ip6); 445 break; 446 default: 447 return -EAFNOSUPPORT; 448 } 449 break; 450 case NFT_CT_SRC_IP: 451 case NFT_CT_DST_IP: 452 if (tb[NFTA_CT_DIRECTION] == NULL) 453 return -EINVAL; 454 455 len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip); 456 break; 457 case NFT_CT_SRC_IP6: 458 case NFT_CT_DST_IP6: 459 if (tb[NFTA_CT_DIRECTION] == NULL) 460 return -EINVAL; 461 462 len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip6); 463 break; 464 case NFT_CT_PROTO_SRC: 465 case NFT_CT_PROTO_DST: 466 if (tb[NFTA_CT_DIRECTION] == NULL) 467 return -EINVAL; 468 len = sizeof_field(struct nf_conntrack_tuple, src.u.all); 469 break; 470 case NFT_CT_BYTES: 471 case NFT_CT_PKTS: 472 case NFT_CT_AVGPKT: 473 len = sizeof(u64); 474 break; 475#ifdef CONFIG_NF_CONNTRACK_ZONES 476 case NFT_CT_ZONE: 477 len = sizeof(u16); 478 break; 479#endif 480 case NFT_CT_ID: 481 if (tb[NFTA_CT_DIRECTION]) 482 return -EINVAL; 483 484 len = sizeof(u32); 485 break; 486 default: 487 return -EOPNOTSUPP; 488 } 489 490 if (tb[NFTA_CT_DIRECTION] != NULL) { 491 priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]); 492 switch (priv->dir) { 493 case IP_CT_DIR_ORIGINAL: 494 case IP_CT_DIR_REPLY: 495 break; 496 default: 497 return -EINVAL; 498 } 499 } 500 501 priv->len = len; 502 err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL, 503 NFT_DATA_VALUE, len); 504 if (err < 0) 505 return err; 506 507 err = nf_ct_netns_get(ctx->net, ctx->family); 508 if (err < 0) 509 return err; 510 511 if (priv->key == NFT_CT_BYTES || 512 priv->key == NFT_CT_PKTS || 513 priv->key == NFT_CT_AVGPKT) 514 nf_ct_set_acct(ctx->net, true); 515 516 return 0; 517} 518 519static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv) 520{ 521 switch (priv->key) { 522#ifdef CONFIG_NF_CONNTRACK_LABELS 523 case NFT_CT_LABELS: 524 nf_connlabels_put(ctx->net); 525 break; 526#endif 527#ifdef CONFIG_NF_CONNTRACK_ZONES 528 case NFT_CT_ZONE: 529 mutex_lock(&nft_ct_pcpu_mutex); 530 if (--nft_ct_pcpu_template_refcnt == 0) 531 nft_ct_tmpl_put_pcpu(); 532 mutex_unlock(&nft_ct_pcpu_mutex); 533 break; 534#endif 535 default: 536 break; 537 } 538} 539 540static int nft_ct_set_init(const struct nft_ctx *ctx, 541 const struct nft_expr *expr, 542 const struct nlattr * const tb[]) 543{ 544 struct nft_ct *priv = nft_expr_priv(expr); 545 unsigned int len; 546 int err; 547 548 priv->dir = IP_CT_DIR_MAX; 549 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 550 switch (priv->key) { 551#ifdef CONFIG_NF_CONNTRACK_MARK 552 case NFT_CT_MARK: 553 if (tb[NFTA_CT_DIRECTION]) 554 return -EINVAL; 555 len = sizeof_field(struct nf_conn, mark); 556 break; 557#endif 558#ifdef CONFIG_NF_CONNTRACK_LABELS 559 case NFT_CT_LABELS: 560 if (tb[NFTA_CT_DIRECTION]) 561 return -EINVAL; 562 len = NF_CT_LABELS_MAX_SIZE; 563 err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1); 564 if (err) 565 return err; 566 break; 567#endif 568#ifdef CONFIG_NF_CONNTRACK_ZONES 569 case NFT_CT_ZONE: 570 mutex_lock(&nft_ct_pcpu_mutex); 571 if (!nft_ct_tmpl_alloc_pcpu()) { 572 mutex_unlock(&nft_ct_pcpu_mutex); 573 return -ENOMEM; 574 } 575 nft_ct_pcpu_template_refcnt++; 576 mutex_unlock(&nft_ct_pcpu_mutex); 577 len = sizeof(u16); 578 break; 579#endif 580#ifdef CONFIG_NF_CONNTRACK_EVENTS 581 case NFT_CT_EVENTMASK: 582 if (tb[NFTA_CT_DIRECTION]) 583 return -EINVAL; 584 len = sizeof(u32); 585 break; 586#endif 587#ifdef CONFIG_NF_CONNTRACK_SECMARK 588 case NFT_CT_SECMARK: 589 if (tb[NFTA_CT_DIRECTION]) 590 return -EINVAL; 591 len = sizeof(u32); 592 break; 593#endif 594 default: 595 return -EOPNOTSUPP; 596 } 597 598 if (tb[NFTA_CT_DIRECTION]) { 599 priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]); 600 switch (priv->dir) { 601 case IP_CT_DIR_ORIGINAL: 602 case IP_CT_DIR_REPLY: 603 break; 604 default: 605 err = -EINVAL; 606 goto err1; 607 } 608 } 609 610 priv->len = len; 611 err = nft_parse_register_load(ctx, tb[NFTA_CT_SREG], &priv->sreg, len); 612 if (err < 0) 613 goto err1; 614 615 err = nf_ct_netns_get(ctx->net, ctx->family); 616 if (err < 0) 617 goto err1; 618 619 return 0; 620 621err1: 622 __nft_ct_set_destroy(ctx, priv); 623 return err; 624} 625 626static void nft_ct_get_destroy(const struct nft_ctx *ctx, 627 const struct nft_expr *expr) 628{ 629 nf_ct_netns_put(ctx->net, ctx->family); 630} 631 632static void nft_ct_set_destroy(const struct nft_ctx *ctx, 633 const struct nft_expr *expr) 634{ 635 struct nft_ct *priv = nft_expr_priv(expr); 636 637 __nft_ct_set_destroy(ctx, priv); 638 nf_ct_netns_put(ctx->net, ctx->family); 639} 640 641static int nft_ct_get_dump(struct sk_buff *skb, 642 const struct nft_expr *expr, bool reset) 643{ 644 const struct nft_ct *priv = nft_expr_priv(expr); 645 646 if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg)) 647 goto nla_put_failure; 648 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 649 goto nla_put_failure; 650 651 switch (priv->key) { 652 case NFT_CT_SRC: 653 case NFT_CT_DST: 654 case NFT_CT_SRC_IP: 655 case NFT_CT_DST_IP: 656 case NFT_CT_SRC_IP6: 657 case NFT_CT_DST_IP6: 658 case NFT_CT_PROTO_SRC: 659 case NFT_CT_PROTO_DST: 660 if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) 661 goto nla_put_failure; 662 break; 663 case NFT_CT_BYTES: 664 case NFT_CT_PKTS: 665 case NFT_CT_AVGPKT: 666 case NFT_CT_ZONE: 667 if (priv->dir < IP_CT_DIR_MAX && 668 nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) 669 goto nla_put_failure; 670 break; 671 default: 672 break; 673 } 674 675 return 0; 676 677nla_put_failure: 678 return -1; 679} 680 681static bool nft_ct_get_reduce(struct nft_regs_track *track, 682 const struct nft_expr *expr) 683{ 684 const struct nft_ct *priv = nft_expr_priv(expr); 685 const struct nft_ct *ct; 686 687 if (!nft_reg_track_cmp(track, expr, priv->dreg)) { 688 nft_reg_track_update(track, expr, priv->dreg, priv->len); 689 return false; 690 } 691 692 ct = nft_expr_priv(track->regs[priv->dreg].selector); 693 if (priv->key != ct->key) { 694 nft_reg_track_update(track, expr, priv->dreg, priv->len); 695 return false; 696 } 697 698 if (!track->regs[priv->dreg].bitwise) 699 return true; 700 701 return nft_expr_reduce_bitwise(track, expr); 702} 703 704static int nft_ct_set_dump(struct sk_buff *skb, 705 const struct nft_expr *expr, bool reset) 706{ 707 const struct nft_ct *priv = nft_expr_priv(expr); 708 709 if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg)) 710 goto nla_put_failure; 711 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 712 goto nla_put_failure; 713 714 switch (priv->key) { 715 case NFT_CT_ZONE: 716 if (priv->dir < IP_CT_DIR_MAX && 717 nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) 718 goto nla_put_failure; 719 break; 720 default: 721 break; 722 } 723 724 return 0; 725 726nla_put_failure: 727 return -1; 728} 729 730static struct nft_expr_type nft_ct_type; 731static const struct nft_expr_ops nft_ct_get_ops = { 732 .type = &nft_ct_type, 733 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), 734 .eval = nft_ct_get_eval, 735 .init = nft_ct_get_init, 736 .destroy = nft_ct_get_destroy, 737 .dump = nft_ct_get_dump, 738 .reduce = nft_ct_get_reduce, 739}; 740 741static bool nft_ct_set_reduce(struct nft_regs_track *track, 742 const struct nft_expr *expr) 743{ 744 int i; 745 746 for (i = 0; i < NFT_REG32_NUM; i++) { 747 if (!track->regs[i].selector) 748 continue; 749 750 if (track->regs[i].selector->ops != &nft_ct_get_ops) 751 continue; 752 753 __nft_reg_track_cancel(track, i); 754 } 755 756 return false; 757} 758 759#ifdef CONFIG_MITIGATION_RETPOLINE 760static const struct nft_expr_ops nft_ct_get_fast_ops = { 761 .type = &nft_ct_type, 762 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), 763 .eval = nft_ct_get_fast_eval, 764 .init = nft_ct_get_init, 765 .destroy = nft_ct_get_destroy, 766 .dump = nft_ct_get_dump, 767 .reduce = nft_ct_set_reduce, 768}; 769#endif 770 771static const struct nft_expr_ops nft_ct_set_ops = { 772 .type = &nft_ct_type, 773 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), 774 .eval = nft_ct_set_eval, 775 .init = nft_ct_set_init, 776 .destroy = nft_ct_set_destroy, 777 .dump = nft_ct_set_dump, 778 .reduce = nft_ct_set_reduce, 779}; 780 781#ifdef CONFIG_NF_CONNTRACK_ZONES 782static const struct nft_expr_ops nft_ct_set_zone_ops = { 783 .type = &nft_ct_type, 784 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), 785 .eval = nft_ct_set_zone_eval, 786 .init = nft_ct_set_init, 787 .destroy = nft_ct_set_destroy, 788 .dump = nft_ct_set_dump, 789 .reduce = nft_ct_set_reduce, 790}; 791#endif 792 793static const struct nft_expr_ops * 794nft_ct_select_ops(const struct nft_ctx *ctx, 795 const struct nlattr * const tb[]) 796{ 797 if (tb[NFTA_CT_KEY] == NULL) 798 return ERR_PTR(-EINVAL); 799 800 if (tb[NFTA_CT_DREG] && tb[NFTA_CT_SREG]) 801 return ERR_PTR(-EINVAL); 802 803 if (tb[NFTA_CT_DREG]) { 804#ifdef CONFIG_MITIGATION_RETPOLINE 805 u32 k = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 806 807 switch (k) { 808 case NFT_CT_STATE: 809 case NFT_CT_DIRECTION: 810 case NFT_CT_STATUS: 811 case NFT_CT_MARK: 812 case NFT_CT_SECMARK: 813 return &nft_ct_get_fast_ops; 814 } 815#endif 816 return &nft_ct_get_ops; 817 } 818 819 if (tb[NFTA_CT_SREG]) { 820#ifdef CONFIG_NF_CONNTRACK_ZONES 821 if (nla_get_be32(tb[NFTA_CT_KEY]) == htonl(NFT_CT_ZONE)) 822 return &nft_ct_set_zone_ops; 823#endif 824 return &nft_ct_set_ops; 825 } 826 827 return ERR_PTR(-EINVAL); 828} 829 830static struct nft_expr_type nft_ct_type __read_mostly = { 831 .name = "ct", 832 .select_ops = nft_ct_select_ops, 833 .policy = nft_ct_policy, 834 .maxattr = NFTA_CT_MAX, 835 .owner = THIS_MODULE, 836}; 837 838static void nft_notrack_eval(const struct nft_expr *expr, 839 struct nft_regs *regs, 840 const struct nft_pktinfo *pkt) 841{ 842 struct sk_buff *skb = pkt->skb; 843 enum ip_conntrack_info ctinfo; 844 struct nf_conn *ct; 845 846 ct = nf_ct_get(pkt->skb, &ctinfo); 847 /* Previously seen (loopback or untracked)? Ignore. */ 848 if (ct || ctinfo == IP_CT_UNTRACKED) 849 return; 850 851 nf_ct_set(skb, ct, IP_CT_UNTRACKED); 852} 853 854static struct nft_expr_type nft_notrack_type; 855static const struct nft_expr_ops nft_notrack_ops = { 856 .type = &nft_notrack_type, 857 .size = NFT_EXPR_SIZE(0), 858 .eval = nft_notrack_eval, 859 .reduce = NFT_REDUCE_READONLY, 860}; 861 862static struct nft_expr_type nft_notrack_type __read_mostly = { 863 .name = "notrack", 864 .ops = &nft_notrack_ops, 865 .owner = THIS_MODULE, 866}; 867 868#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 869static int 870nft_ct_timeout_parse_policy(void *timeouts, 871 const struct nf_conntrack_l4proto *l4proto, 872 struct net *net, const struct nlattr *attr) 873{ 874 struct nlattr **tb; 875 int ret = 0; 876 877 tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb), 878 GFP_KERNEL); 879 880 if (!tb) 881 return -ENOMEM; 882 883 ret = nla_parse_nested_deprecated(tb, 884 l4proto->ctnl_timeout.nlattr_max, 885 attr, 886 l4proto->ctnl_timeout.nla_policy, 887 NULL); 888 if (ret < 0) 889 goto err; 890 891 ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeouts); 892 893err: 894 kfree(tb); 895 return ret; 896} 897 898struct nft_ct_timeout_obj { 899 struct nf_ct_timeout *timeout; 900 u8 l4proto; 901}; 902 903static void nft_ct_timeout_obj_eval(struct nft_object *obj, 904 struct nft_regs *regs, 905 const struct nft_pktinfo *pkt) 906{ 907 const struct nft_ct_timeout_obj *priv = nft_obj_data(obj); 908 struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb); 909 struct nf_conn_timeout *timeout; 910 const unsigned int *values; 911 912 if (priv->l4proto != pkt->tprot) 913 return; 914 915 if (!ct || nf_ct_is_template(ct) || nf_ct_is_confirmed(ct)) 916 return; 917 918 timeout = nf_ct_timeout_find(ct); 919 if (!timeout) { 920 timeout = nf_ct_timeout_ext_add(ct, priv->timeout, GFP_ATOMIC); 921 if (!timeout) { 922 regs->verdict.code = NF_DROP; 923 return; 924 } 925 } 926 927 rcu_assign_pointer(timeout->timeout, priv->timeout); 928 929 /* adjust the timeout as per 'new' state. ct is unconfirmed, 930 * so the current timestamp must not be added. 931 */ 932 values = nf_ct_timeout_data(timeout); 933 if (values) 934 nf_ct_refresh(ct, values[0]); 935} 936 937static int nft_ct_timeout_obj_init(const struct nft_ctx *ctx, 938 const struct nlattr * const tb[], 939 struct nft_object *obj) 940{ 941 struct nft_ct_timeout_obj *priv = nft_obj_data(obj); 942 const struct nf_conntrack_l4proto *l4proto; 943 struct nf_ct_timeout *timeout; 944 int l3num = ctx->family; 945 __u8 l4num; 946 int ret; 947 948 if (!tb[NFTA_CT_TIMEOUT_L4PROTO] || 949 !tb[NFTA_CT_TIMEOUT_DATA]) 950 return -EINVAL; 951 952 if (tb[NFTA_CT_TIMEOUT_L3PROTO]) 953 l3num = ntohs(nla_get_be16(tb[NFTA_CT_TIMEOUT_L3PROTO])); 954 955 l4num = nla_get_u8(tb[NFTA_CT_TIMEOUT_L4PROTO]); 956 priv->l4proto = l4num; 957 958 l4proto = nf_ct_l4proto_find(l4num); 959 960 if (l4proto->l4proto != l4num) { 961 ret = -EOPNOTSUPP; 962 goto err_proto_put; 963 } 964 965 timeout = kzalloc(sizeof(struct nf_ct_timeout) + 966 l4proto->ctnl_timeout.obj_size, GFP_KERNEL); 967 if (timeout == NULL) { 968 ret = -ENOMEM; 969 goto err_proto_put; 970 } 971 972 ret = nft_ct_timeout_parse_policy(&timeout->data, l4proto, ctx->net, 973 tb[NFTA_CT_TIMEOUT_DATA]); 974 if (ret < 0) 975 goto err_free_timeout; 976 977 timeout->l3num = l3num; 978 timeout->l4proto = l4proto; 979 980 ret = nf_ct_netns_get(ctx->net, ctx->family); 981 if (ret < 0) 982 goto err_free_timeout; 983 984 priv->timeout = timeout; 985 return 0; 986 987err_free_timeout: 988 kfree(timeout); 989err_proto_put: 990 return ret; 991} 992 993static void nft_ct_timeout_obj_destroy(const struct nft_ctx *ctx, 994 struct nft_object *obj) 995{ 996 struct nft_ct_timeout_obj *priv = nft_obj_data(obj); 997 struct nf_ct_timeout *timeout = priv->timeout; 998 999 nf_ct_untimeout(ctx->net, timeout); 1000 nf_ct_netns_put(ctx->net, ctx->family); 1001 kfree(priv->timeout); 1002} 1003 1004static int nft_ct_timeout_obj_dump(struct sk_buff *skb, 1005 struct nft_object *obj, bool reset) 1006{ 1007 const struct nft_ct_timeout_obj *priv = nft_obj_data(obj); 1008 const struct nf_ct_timeout *timeout = priv->timeout; 1009 struct nlattr *nest_params; 1010 int ret; 1011 1012 if (nla_put_u8(skb, NFTA_CT_TIMEOUT_L4PROTO, timeout->l4proto->l4proto) || 1013 nla_put_be16(skb, NFTA_CT_TIMEOUT_L3PROTO, htons(timeout->l3num))) 1014 return -1; 1015 1016 nest_params = nla_nest_start(skb, NFTA_CT_TIMEOUT_DATA); 1017 if (!nest_params) 1018 return -1; 1019 1020 ret = timeout->l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->data); 1021 if (ret < 0) 1022 return -1; 1023 nla_nest_end(skb, nest_params); 1024 return 0; 1025} 1026 1027static const struct nla_policy nft_ct_timeout_policy[NFTA_CT_TIMEOUT_MAX + 1] = { 1028 [NFTA_CT_TIMEOUT_L3PROTO] = {.type = NLA_U16 }, 1029 [NFTA_CT_TIMEOUT_L4PROTO] = {.type = NLA_U8 }, 1030 [NFTA_CT_TIMEOUT_DATA] = {.type = NLA_NESTED }, 1031}; 1032 1033static struct nft_object_type nft_ct_timeout_obj_type; 1034 1035static const struct nft_object_ops nft_ct_timeout_obj_ops = { 1036 .type = &nft_ct_timeout_obj_type, 1037 .size = sizeof(struct nft_ct_timeout_obj), 1038 .eval = nft_ct_timeout_obj_eval, 1039 .init = nft_ct_timeout_obj_init, 1040 .destroy = nft_ct_timeout_obj_destroy, 1041 .dump = nft_ct_timeout_obj_dump, 1042}; 1043 1044static struct nft_object_type nft_ct_timeout_obj_type __read_mostly = { 1045 .type = NFT_OBJECT_CT_TIMEOUT, 1046 .ops = &nft_ct_timeout_obj_ops, 1047 .maxattr = NFTA_CT_TIMEOUT_MAX, 1048 .policy = nft_ct_timeout_policy, 1049 .owner = THIS_MODULE, 1050}; 1051#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ 1052 1053static int nft_ct_helper_obj_init(const struct nft_ctx *ctx, 1054 const struct nlattr * const tb[], 1055 struct nft_object *obj) 1056{ 1057 struct nft_ct_helper_obj *priv = nft_obj_data(obj); 1058 struct nf_conntrack_helper *help4, *help6; 1059 char name[NF_CT_HELPER_NAME_LEN]; 1060 int family = ctx->family; 1061 int err; 1062 1063 if (!tb[NFTA_CT_HELPER_NAME] || !tb[NFTA_CT_HELPER_L4PROTO]) 1064 return -EINVAL; 1065 1066 priv->l4proto = nla_get_u8(tb[NFTA_CT_HELPER_L4PROTO]); 1067 if (!priv->l4proto) 1068 return -ENOENT; 1069 1070 nla_strscpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name)); 1071 1072 if (tb[NFTA_CT_HELPER_L3PROTO]) 1073 family = ntohs(nla_get_be16(tb[NFTA_CT_HELPER_L3PROTO])); 1074 1075 help4 = NULL; 1076 help6 = NULL; 1077 1078 switch (family) { 1079 case NFPROTO_IPV4: 1080 if (ctx->family == NFPROTO_IPV6) 1081 return -EINVAL; 1082 1083 help4 = nf_conntrack_helper_try_module_get(name, family, 1084 priv->l4proto); 1085 break; 1086 case NFPROTO_IPV6: 1087 if (ctx->family == NFPROTO_IPV4) 1088 return -EINVAL; 1089 1090 help6 = nf_conntrack_helper_try_module_get(name, family, 1091 priv->l4proto); 1092 break; 1093 case NFPROTO_NETDEV: 1094 case NFPROTO_BRIDGE: 1095 case NFPROTO_INET: 1096 help4 = nf_conntrack_helper_try_module_get(name, NFPROTO_IPV4, 1097 priv->l4proto); 1098 help6 = nf_conntrack_helper_try_module_get(name, NFPROTO_IPV6, 1099 priv->l4proto); 1100 break; 1101 default: 1102 return -EAFNOSUPPORT; 1103 } 1104 1105 /* && is intentional; only error if INET found neither ipv4 or ipv6 */ 1106 if (!help4 && !help6) 1107 return -ENOENT; 1108 1109 priv->helper4 = help4; 1110 priv->helper6 = help6; 1111 1112 err = nf_ct_netns_get(ctx->net, ctx->family); 1113 if (err < 0) 1114 goto err_put_helper; 1115 1116 return 0; 1117 1118err_put_helper: 1119 if (priv->helper4) 1120 nf_conntrack_helper_put(priv->helper4); 1121 if (priv->helper6) 1122 nf_conntrack_helper_put(priv->helper6); 1123 return err; 1124} 1125 1126static void nft_ct_helper_obj_destroy(const struct nft_ctx *ctx, 1127 struct nft_object *obj) 1128{ 1129 struct nft_ct_helper_obj *priv = nft_obj_data(obj); 1130 1131 if (priv->helper4) 1132 nf_conntrack_helper_put(priv->helper4); 1133 if (priv->helper6) 1134 nf_conntrack_helper_put(priv->helper6); 1135 1136 nf_ct_netns_put(ctx->net, ctx->family); 1137} 1138 1139static void nft_ct_helper_obj_eval(struct nft_object *obj, 1140 struct nft_regs *regs, 1141 const struct nft_pktinfo *pkt) 1142{ 1143 const struct nft_ct_helper_obj *priv = nft_obj_data(obj); 1144 struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb); 1145 struct nf_conntrack_helper *to_assign = NULL; 1146 struct nf_conn_help *help; 1147 1148 if (!ct || 1149 nf_ct_is_confirmed(ct) || 1150 nf_ct_is_template(ct) || 1151 priv->l4proto != nf_ct_protonum(ct)) 1152 return; 1153 1154 switch (nf_ct_l3num(ct)) { 1155 case NFPROTO_IPV4: 1156 to_assign = priv->helper4; 1157 break; 1158 case NFPROTO_IPV6: 1159 to_assign = priv->helper6; 1160 break; 1161 default: 1162 WARN_ON_ONCE(1); 1163 return; 1164 } 1165 1166 if (!to_assign) 1167 return; 1168 1169 if (test_bit(IPS_HELPER_BIT, &ct->status)) 1170 return; 1171 1172 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); 1173 if (help) { 1174 rcu_assign_pointer(help->helper, to_assign); 1175 set_bit(IPS_HELPER_BIT, &ct->status); 1176 } 1177} 1178 1179static int nft_ct_helper_obj_dump(struct sk_buff *skb, 1180 struct nft_object *obj, bool reset) 1181{ 1182 const struct nft_ct_helper_obj *priv = nft_obj_data(obj); 1183 const struct nf_conntrack_helper *helper; 1184 u16 family; 1185 1186 if (priv->helper4 && priv->helper6) { 1187 family = NFPROTO_INET; 1188 helper = priv->helper4; 1189 } else if (priv->helper6) { 1190 family = NFPROTO_IPV6; 1191 helper = priv->helper6; 1192 } else { 1193 family = NFPROTO_IPV4; 1194 helper = priv->helper4; 1195 } 1196 1197 if (nla_put_string(skb, NFTA_CT_HELPER_NAME, helper->name)) 1198 return -1; 1199 1200 if (nla_put_u8(skb, NFTA_CT_HELPER_L4PROTO, priv->l4proto)) 1201 return -1; 1202 1203 if (nla_put_be16(skb, NFTA_CT_HELPER_L3PROTO, htons(family))) 1204 return -1; 1205 1206 return 0; 1207} 1208 1209static const struct nla_policy nft_ct_helper_policy[NFTA_CT_HELPER_MAX + 1] = { 1210 [NFTA_CT_HELPER_NAME] = { .type = NLA_STRING, 1211 .len = NF_CT_HELPER_NAME_LEN - 1 }, 1212 [NFTA_CT_HELPER_L3PROTO] = { .type = NLA_U16 }, 1213 [NFTA_CT_HELPER_L4PROTO] = { .type = NLA_U8 }, 1214}; 1215 1216static struct nft_object_type nft_ct_helper_obj_type; 1217static const struct nft_object_ops nft_ct_helper_obj_ops = { 1218 .type = &nft_ct_helper_obj_type, 1219 .size = sizeof(struct nft_ct_helper_obj), 1220 .eval = nft_ct_helper_obj_eval, 1221 .init = nft_ct_helper_obj_init, 1222 .destroy = nft_ct_helper_obj_destroy, 1223 .dump = nft_ct_helper_obj_dump, 1224}; 1225 1226static struct nft_object_type nft_ct_helper_obj_type __read_mostly = { 1227 .type = NFT_OBJECT_CT_HELPER, 1228 .ops = &nft_ct_helper_obj_ops, 1229 .maxattr = NFTA_CT_HELPER_MAX, 1230 .policy = nft_ct_helper_policy, 1231 .owner = THIS_MODULE, 1232}; 1233 1234struct nft_ct_expect_obj { 1235 u16 l3num; 1236 __be16 dport; 1237 u8 l4proto; 1238 u8 size; 1239 u32 timeout; 1240}; 1241 1242static int nft_ct_expect_obj_init(const struct nft_ctx *ctx, 1243 const struct nlattr * const tb[], 1244 struct nft_object *obj) 1245{ 1246 struct nft_ct_expect_obj *priv = nft_obj_data(obj); 1247 1248 if (!tb[NFTA_CT_EXPECT_L4PROTO] || 1249 !tb[NFTA_CT_EXPECT_DPORT] || 1250 !tb[NFTA_CT_EXPECT_TIMEOUT] || 1251 !tb[NFTA_CT_EXPECT_SIZE]) 1252 return -EINVAL; 1253 1254 priv->l3num = ctx->family; 1255 if (tb[NFTA_CT_EXPECT_L3PROTO]) 1256 priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO])); 1257 1258 switch (priv->l3num) { 1259 case NFPROTO_IPV4: 1260 case NFPROTO_IPV6: 1261 if (priv->l3num == ctx->family || ctx->family == NFPROTO_INET) 1262 break; 1263 1264 return -EINVAL; 1265 case NFPROTO_INET: /* tuple.src.l3num supports NFPROTO_IPV4/6 only */ 1266 default: 1267 return -EAFNOSUPPORT; 1268 } 1269 1270 priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]); 1271 switch (priv->l4proto) { 1272 case IPPROTO_TCP: 1273 case IPPROTO_UDP: 1274 case IPPROTO_UDPLITE: 1275 case IPPROTO_DCCP: 1276 case IPPROTO_SCTP: 1277 break; 1278 default: 1279 return -EOPNOTSUPP; 1280 } 1281 1282 priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]); 1283 priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]); 1284 priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]); 1285 1286 return nf_ct_netns_get(ctx->net, ctx->family); 1287} 1288 1289static void nft_ct_expect_obj_destroy(const struct nft_ctx *ctx, 1290 struct nft_object *obj) 1291{ 1292 nf_ct_netns_put(ctx->net, ctx->family); 1293} 1294 1295static int nft_ct_expect_obj_dump(struct sk_buff *skb, 1296 struct nft_object *obj, bool reset) 1297{ 1298 const struct nft_ct_expect_obj *priv = nft_obj_data(obj); 1299 1300 if (nla_put_be16(skb, NFTA_CT_EXPECT_L3PROTO, htons(priv->l3num)) || 1301 nla_put_u8(skb, NFTA_CT_EXPECT_L4PROTO, priv->l4proto) || 1302 nla_put_be16(skb, NFTA_CT_EXPECT_DPORT, priv->dport) || 1303 nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, priv->timeout) || 1304 nla_put_u8(skb, NFTA_CT_EXPECT_SIZE, priv->size)) 1305 return -1; 1306 1307 return 0; 1308} 1309 1310static void nft_ct_expect_obj_eval(struct nft_object *obj, 1311 struct nft_regs *regs, 1312 const struct nft_pktinfo *pkt) 1313{ 1314 const struct nft_ct_expect_obj *priv = nft_obj_data(obj); 1315 struct nf_conntrack_expect *exp; 1316 enum ip_conntrack_info ctinfo; 1317 struct nf_conn_help *help; 1318 enum ip_conntrack_dir dir; 1319 u16 l3num = priv->l3num; 1320 struct nf_conn *ct; 1321 1322 ct = nf_ct_get(pkt->skb, &ctinfo); 1323 if (!ct || nf_ct_is_confirmed(ct) || nf_ct_is_template(ct)) { 1324 regs->verdict.code = NFT_BREAK; 1325 return; 1326 } 1327 dir = CTINFO2DIR(ctinfo); 1328 1329 help = nfct_help(ct); 1330 if (!help) 1331 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); 1332 if (!help) { 1333 regs->verdict.code = NF_DROP; 1334 return; 1335 } 1336 1337 if (help->expecting[NF_CT_EXPECT_CLASS_DEFAULT] >= priv->size) { 1338 regs->verdict.code = NFT_BREAK; 1339 return; 1340 } 1341 if (l3num == NFPROTO_INET) 1342 l3num = nf_ct_l3num(ct); 1343 1344 exp = nf_ct_expect_alloc(ct); 1345 if (exp == NULL) { 1346 regs->verdict.code = NF_DROP; 1347 return; 1348 } 1349 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, l3num, 1350 &ct->tuplehash[!dir].tuple.src.u3, 1351 &ct->tuplehash[!dir].tuple.dst.u3, 1352 priv->l4proto, NULL, &priv->dport); 1353 exp->timeout.expires = jiffies + priv->timeout * HZ; 1354 1355 if (nf_ct_expect_related(exp, 0) != 0) 1356 regs->verdict.code = NF_DROP; 1357} 1358 1359static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX + 1] = { 1360 [NFTA_CT_EXPECT_L3PROTO] = { .type = NLA_U16 }, 1361 [NFTA_CT_EXPECT_L4PROTO] = { .type = NLA_U8 }, 1362 [NFTA_CT_EXPECT_DPORT] = { .type = NLA_U16 }, 1363 [NFTA_CT_EXPECT_TIMEOUT] = { .type = NLA_U32 }, 1364 [NFTA_CT_EXPECT_SIZE] = { .type = NLA_U8 }, 1365}; 1366 1367static struct nft_object_type nft_ct_expect_obj_type; 1368 1369static const struct nft_object_ops nft_ct_expect_obj_ops = { 1370 .type = &nft_ct_expect_obj_type, 1371 .size = sizeof(struct nft_ct_expect_obj), 1372 .eval = nft_ct_expect_obj_eval, 1373 .init = nft_ct_expect_obj_init, 1374 .destroy = nft_ct_expect_obj_destroy, 1375 .dump = nft_ct_expect_obj_dump, 1376}; 1377 1378static struct nft_object_type nft_ct_expect_obj_type __read_mostly = { 1379 .type = NFT_OBJECT_CT_EXPECT, 1380 .ops = &nft_ct_expect_obj_ops, 1381 .maxattr = NFTA_CT_EXPECT_MAX, 1382 .policy = nft_ct_expect_policy, 1383 .owner = THIS_MODULE, 1384}; 1385 1386static int __init nft_ct_module_init(void) 1387{ 1388 int err; 1389 1390 BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > NFT_REG_SIZE); 1391 1392 err = nft_register_expr(&nft_ct_type); 1393 if (err < 0) 1394 return err; 1395 1396 err = nft_register_expr(&nft_notrack_type); 1397 if (err < 0) 1398 goto err1; 1399 1400 err = nft_register_obj(&nft_ct_helper_obj_type); 1401 if (err < 0) 1402 goto err2; 1403 1404 err = nft_register_obj(&nft_ct_expect_obj_type); 1405 if (err < 0) 1406 goto err3; 1407#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 1408 err = nft_register_obj(&nft_ct_timeout_obj_type); 1409 if (err < 0) 1410 goto err4; 1411#endif 1412 return 0; 1413 1414#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 1415err4: 1416 nft_unregister_obj(&nft_ct_expect_obj_type); 1417#endif 1418err3: 1419 nft_unregister_obj(&nft_ct_helper_obj_type); 1420err2: 1421 nft_unregister_expr(&nft_notrack_type); 1422err1: 1423 nft_unregister_expr(&nft_ct_type); 1424 return err; 1425} 1426 1427static void __exit nft_ct_module_exit(void) 1428{ 1429#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 1430 nft_unregister_obj(&nft_ct_timeout_obj_type); 1431#endif 1432 nft_unregister_obj(&nft_ct_expect_obj_type); 1433 nft_unregister_obj(&nft_ct_helper_obj_type); 1434 nft_unregister_expr(&nft_notrack_type); 1435 nft_unregister_expr(&nft_ct_type); 1436} 1437 1438module_init(nft_ct_module_init); 1439module_exit(nft_ct_module_exit); 1440 1441MODULE_LICENSE("GPL"); 1442MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 1443MODULE_ALIAS_NFT_EXPR("ct"); 1444MODULE_ALIAS_NFT_EXPR("notrack"); 1445MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER); 1446MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT); 1447MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_EXPECT); 1448MODULE_DESCRIPTION("Netfilter nf_tables conntrack module");