1 /* 2 * Copyright (c) 2008-2009 Patrick McHardy <[email protected]> 3 * Copyright (c) 2016 Pablo Neira Ayuso <[email protected]> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Development of this code funded by Astaro AG (http://www.astaro.com/) 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/netlink.h> 16 #include <linux/netfilter.h> 17 #include <linux/netfilter/nf_tables.h> 18 #include <net/netfilter/nf_tables.h> 19 #include <net/netfilter/nf_conntrack.h> 20 #include <net/netfilter/nf_conntrack_acct.h> 21 #include <net/netfilter/nf_conntrack_tuple.h> 22 #include <net/netfilter/nf_conntrack_helper.h> 23 #include <net/netfilter/nf_conntrack_ecache.h> 24 #include <net/netfilter/nf_conntrack_labels.h> 25 26 struct nft_ct { 27 enum nft_ct_keys key:8; 28 enum ip_conntrack_dir dir:8; 29 union { 30 enum nft_registers dreg:8; 31 enum nft_registers sreg:8; 32 }; 33 }; 34 35 #ifdef CONFIG_NF_CONNTRACK_ZONES 36 static DEFINE_PER_CPU(struct nf_conn *, nft_ct_pcpu_template); 37 static unsigned int nft_ct_pcpu_template_refcnt __read_mostly; 38 #endif 39 40 static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c, 41 enum nft_ct_keys k, 42 enum ip_conntrack_dir d) 43 { 44 if (d < IP_CT_DIR_MAX) 45 return k == NFT_CT_BYTES ? atomic64_read(&c[d].bytes) : 46 atomic64_read(&c[d].packets); 47 48 return nft_ct_get_eval_counter(c, k, IP_CT_DIR_ORIGINAL) + 49 nft_ct_get_eval_counter(c, k, IP_CT_DIR_REPLY); 50 } 51 52 static void nft_ct_get_eval(const struct nft_expr *expr, 53 struct nft_regs *regs, 54 const struct nft_pktinfo *pkt) 55 { 56 const struct nft_ct *priv = nft_expr_priv(expr); 57 u32 *dest = ®s->data[priv->dreg]; 58 enum ip_conntrack_info ctinfo; 59 const struct nf_conn *ct; 60 const struct nf_conn_help *help; 61 const struct nf_conntrack_tuple *tuple; 62 const struct nf_conntrack_helper *helper; 63 unsigned int state; 64 65 ct = nf_ct_get(pkt->skb, &ctinfo); 66 67 switch (priv->key) { 68 case NFT_CT_STATE: 69 if (ct == NULL) 70 state = NF_CT_STATE_INVALID_BIT; 71 else if (nf_ct_is_untracked(ct)) 72 state = NF_CT_STATE_UNTRACKED_BIT; 73 else 74 state = NF_CT_STATE_BIT(ctinfo); 75 *dest = state; 76 return; 77 default: 78 break; 79 } 80 81 if (ct == NULL) 82 goto err; 83 84 switch (priv->key) { 85 case NFT_CT_DIRECTION: 86 nft_reg_store8(dest, CTINFO2DIR(ctinfo)); 87 return; 88 case NFT_CT_STATUS: 89 *dest = ct->status; 90 return; 91 #ifdef CONFIG_NF_CONNTRACK_MARK 92 case NFT_CT_MARK: 93 *dest = ct->mark; 94 return; 95 #endif 96 #ifdef CONFIG_NF_CONNTRACK_SECMARK 97 case NFT_CT_SECMARK: 98 *dest = ct->secmark; 99 return; 100 #endif 101 case NFT_CT_EXPIRATION: 102 *dest = jiffies_to_msecs(nf_ct_expires(ct)); 103 return; 104 case NFT_CT_HELPER: 105 if (ct->master == NULL) 106 goto err; 107 help = nfct_help(ct->master); 108 if (help == NULL) 109 goto err; 110 helper = rcu_dereference(help->helper); 111 if (helper == NULL) 112 goto err; 113 strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN); 114 return; 115 #ifdef CONFIG_NF_CONNTRACK_LABELS 116 case NFT_CT_LABELS: { 117 struct nf_conn_labels *labels = nf_ct_labels_find(ct); 118 119 if (labels) 120 memcpy(dest, labels->bits, NF_CT_LABELS_MAX_SIZE); 121 else 122 memset(dest, 0, NF_CT_LABELS_MAX_SIZE); 123 return; 124 } 125 #endif 126 case NFT_CT_BYTES: /* fallthrough */ 127 case NFT_CT_PKTS: { 128 const struct nf_conn_acct *acct = nf_conn_acct_find(ct); 129 u64 count = 0; 130 131 if (acct) 132 count = nft_ct_get_eval_counter(acct->counter, 133 priv->key, priv->dir); 134 memcpy(dest, &count, sizeof(count)); 135 return; 136 } 137 case NFT_CT_AVGPKT: { 138 const struct nf_conn_acct *acct = nf_conn_acct_find(ct); 139 u64 avgcnt = 0, bcnt = 0, pcnt = 0; 140 141 if (acct) { 142 pcnt = nft_ct_get_eval_counter(acct->counter, 143 NFT_CT_PKTS, priv->dir); 144 bcnt = nft_ct_get_eval_counter(acct->counter, 145 NFT_CT_BYTES, priv->dir); 146 if (pcnt != 0) 147 avgcnt = div64_u64(bcnt, pcnt); 148 } 149 150 memcpy(dest, &avgcnt, sizeof(avgcnt)); 151 return; 152 } 153 case NFT_CT_L3PROTOCOL: 154 nft_reg_store8(dest, nf_ct_l3num(ct)); 155 return; 156 case NFT_CT_PROTOCOL: 157 nft_reg_store8(dest, nf_ct_protonum(ct)); 158 return; 159 #ifdef CONFIG_NF_CONNTRACK_ZONES 160 case NFT_CT_ZONE: { 161 const struct nf_conntrack_zone *zone = nf_ct_zone(ct); 162 u16 zoneid; 163 164 if (priv->dir < IP_CT_DIR_MAX) 165 zoneid = nf_ct_zone_id(zone, priv->dir); 166 else 167 zoneid = zone->id; 168 169 nft_reg_store16(dest, zoneid); 170 return; 171 } 172 #endif 173 default: 174 break; 175 } 176 177 tuple = &ct->tuplehash[priv->dir].tuple; 178 switch (priv->key) { 179 case NFT_CT_SRC: 180 memcpy(dest, tuple->src.u3.all, 181 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); 182 return; 183 case NFT_CT_DST: 184 memcpy(dest, tuple->dst.u3.all, 185 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); 186 return; 187 case NFT_CT_PROTO_SRC: 188 nft_reg_store16(dest, (__force u16)tuple->src.u.all); 189 return; 190 case NFT_CT_PROTO_DST: 191 nft_reg_store16(dest, (__force u16)tuple->dst.u.all); 192 return; 193 default: 194 break; 195 } 196 return; 197 err: 198 regs->verdict.code = NFT_BREAK; 199 } 200 201 #ifdef CONFIG_NF_CONNTRACK_ZONES 202 static void nft_ct_set_zone_eval(const struct nft_expr *expr, 203 struct nft_regs *regs, 204 const struct nft_pktinfo *pkt) 205 { 206 struct nf_conntrack_zone zone = { .dir = NF_CT_DEFAULT_ZONE_DIR }; 207 const struct nft_ct *priv = nft_expr_priv(expr); 208 struct sk_buff *skb = pkt->skb; 209 enum ip_conntrack_info ctinfo; 210 u16 value = nft_reg_load16(®s->data[priv->sreg]); 211 struct nf_conn *ct; 212 213 ct = nf_ct_get(skb, &ctinfo); 214 if (ct) /* already tracked */ 215 return; 216 217 zone.id = value; 218 219 switch (priv->dir) { 220 case IP_CT_DIR_ORIGINAL: 221 zone.dir = NF_CT_ZONE_DIR_ORIG; 222 break; 223 case IP_CT_DIR_REPLY: 224 zone.dir = NF_CT_ZONE_DIR_REPL; 225 break; 226 default: 227 break; 228 } 229 230 ct = this_cpu_read(nft_ct_pcpu_template); 231 232 if (likely(atomic_read(&ct->ct_general.use) == 1)) { 233 nf_ct_zone_add(ct, &zone); 234 } else { 235 /* previous skb got queued to userspace */ 236 ct = nf_ct_tmpl_alloc(nft_net(pkt), &zone, GFP_ATOMIC); 237 if (!ct) { 238 regs->verdict.code = NF_DROP; 239 return; 240 } 241 } 242 243 atomic_inc(&ct->ct_general.use); 244 nf_ct_set(skb, ct, IP_CT_NEW); 245 } 246 #endif 247 248 static void nft_ct_set_eval(const struct nft_expr *expr, 249 struct nft_regs *regs, 250 const struct nft_pktinfo *pkt) 251 { 252 const struct nft_ct *priv = nft_expr_priv(expr); 253 struct sk_buff *skb = pkt->skb; 254 #ifdef CONFIG_NF_CONNTRACK_MARK 255 u32 value = regs->data[priv->sreg]; 256 #endif 257 enum ip_conntrack_info ctinfo; 258 struct nf_conn *ct; 259 260 ct = nf_ct_get(skb, &ctinfo); 261 if (ct == NULL) 262 return; 263 264 switch (priv->key) { 265 #ifdef CONFIG_NF_CONNTRACK_MARK 266 case NFT_CT_MARK: 267 if (ct->mark != value) { 268 ct->mark = value; 269 nf_conntrack_event_cache(IPCT_MARK, ct); 270 } 271 break; 272 #endif 273 #ifdef CONFIG_NF_CONNTRACK_LABELS 274 case NFT_CT_LABELS: 275 nf_connlabels_replace(ct, 276 ®s->data[priv->sreg], 277 ®s->data[priv->sreg], 278 NF_CT_LABELS_MAX_SIZE / sizeof(u32)); 279 break; 280 #endif 281 default: 282 break; 283 } 284 } 285 286 static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = { 287 [NFTA_CT_DREG] = { .type = NLA_U32 }, 288 [NFTA_CT_KEY] = { .type = NLA_U32 }, 289 [NFTA_CT_DIRECTION] = { .type = NLA_U8 }, 290 [NFTA_CT_SREG] = { .type = NLA_U32 }, 291 }; 292 293 static int nft_ct_netns_get(struct net *net, uint8_t family) 294 { 295 int err; 296 297 if (family == NFPROTO_INET) { 298 err = nf_ct_netns_get(net, NFPROTO_IPV4); 299 if (err < 0) 300 goto err1; 301 err = nf_ct_netns_get(net, NFPROTO_IPV6); 302 if (err < 0) 303 goto err2; 304 } else { 305 err = nf_ct_netns_get(net, family); 306 if (err < 0) 307 goto err1; 308 } 309 return 0; 310 311 err2: 312 nf_ct_netns_put(net, NFPROTO_IPV4); 313 err1: 314 return err; 315 } 316 317 static void nft_ct_netns_put(struct net *net, uint8_t family) 318 { 319 if (family == NFPROTO_INET) { 320 nf_ct_netns_put(net, NFPROTO_IPV4); 321 nf_ct_netns_put(net, NFPROTO_IPV6); 322 } else 323 nf_ct_netns_put(net, family); 324 } 325 326 #ifdef CONFIG_NF_CONNTRACK_ZONES 327 static void nft_ct_tmpl_put_pcpu(void) 328 { 329 struct nf_conn *ct; 330 int cpu; 331 332 for_each_possible_cpu(cpu) { 333 ct = per_cpu(nft_ct_pcpu_template, cpu); 334 if (!ct) 335 break; 336 nf_ct_put(ct); 337 per_cpu(nft_ct_pcpu_template, cpu) = NULL; 338 } 339 } 340 341 static bool nft_ct_tmpl_alloc_pcpu(void) 342 { 343 struct nf_conntrack_zone zone = { .id = 0 }; 344 struct nf_conn *tmp; 345 int cpu; 346 347 if (nft_ct_pcpu_template_refcnt) 348 return true; 349 350 for_each_possible_cpu(cpu) { 351 tmp = nf_ct_tmpl_alloc(&init_net, &zone, GFP_KERNEL); 352 if (!tmp) { 353 nft_ct_tmpl_put_pcpu(); 354 return false; 355 } 356 357 atomic_set(&tmp->ct_general.use, 1); 358 per_cpu(nft_ct_pcpu_template, cpu) = tmp; 359 } 360 361 return true; 362 } 363 #endif 364 365 static int nft_ct_get_init(const struct nft_ctx *ctx, 366 const struct nft_expr *expr, 367 const struct nlattr * const tb[]) 368 { 369 struct nft_ct *priv = nft_expr_priv(expr); 370 unsigned int len; 371 int err; 372 373 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 374 priv->dir = IP_CT_DIR_MAX; 375 switch (priv->key) { 376 case NFT_CT_DIRECTION: 377 if (tb[NFTA_CT_DIRECTION] != NULL) 378 return -EINVAL; 379 len = sizeof(u8); 380 break; 381 case NFT_CT_STATE: 382 case NFT_CT_STATUS: 383 #ifdef CONFIG_NF_CONNTRACK_MARK 384 case NFT_CT_MARK: 385 #endif 386 #ifdef CONFIG_NF_CONNTRACK_SECMARK 387 case NFT_CT_SECMARK: 388 #endif 389 case NFT_CT_EXPIRATION: 390 if (tb[NFTA_CT_DIRECTION] != NULL) 391 return -EINVAL; 392 len = sizeof(u32); 393 break; 394 #ifdef CONFIG_NF_CONNTRACK_LABELS 395 case NFT_CT_LABELS: 396 if (tb[NFTA_CT_DIRECTION] != NULL) 397 return -EINVAL; 398 len = NF_CT_LABELS_MAX_SIZE; 399 break; 400 #endif 401 case NFT_CT_HELPER: 402 if (tb[NFTA_CT_DIRECTION] != NULL) 403 return -EINVAL; 404 len = NF_CT_HELPER_NAME_LEN; 405 break; 406 407 case NFT_CT_L3PROTOCOL: 408 case NFT_CT_PROTOCOL: 409 /* For compatibility, do not report error if NFTA_CT_DIRECTION 410 * attribute is specified. 411 */ 412 len = sizeof(u8); 413 break; 414 case NFT_CT_SRC: 415 case NFT_CT_DST: 416 if (tb[NFTA_CT_DIRECTION] == NULL) 417 return -EINVAL; 418 419 switch (ctx->afi->family) { 420 case NFPROTO_IPV4: 421 len = FIELD_SIZEOF(struct nf_conntrack_tuple, 422 src.u3.ip); 423 break; 424 case NFPROTO_IPV6: 425 case NFPROTO_INET: 426 len = FIELD_SIZEOF(struct nf_conntrack_tuple, 427 src.u3.ip6); 428 break; 429 default: 430 return -EAFNOSUPPORT; 431 } 432 break; 433 case NFT_CT_PROTO_SRC: 434 case NFT_CT_PROTO_DST: 435 if (tb[NFTA_CT_DIRECTION] == NULL) 436 return -EINVAL; 437 len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all); 438 break; 439 case NFT_CT_BYTES: 440 case NFT_CT_PKTS: 441 case NFT_CT_AVGPKT: 442 len = sizeof(u64); 443 break; 444 #ifdef CONFIG_NF_CONNTRACK_ZONES 445 case NFT_CT_ZONE: 446 len = sizeof(u16); 447 break; 448 #endif 449 default: 450 return -EOPNOTSUPP; 451 } 452 453 if (tb[NFTA_CT_DIRECTION] != NULL) { 454 priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]); 455 switch (priv->dir) { 456 case IP_CT_DIR_ORIGINAL: 457 case IP_CT_DIR_REPLY: 458 break; 459 default: 460 return -EINVAL; 461 } 462 } 463 464 priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]); 465 err = nft_validate_register_store(ctx, priv->dreg, NULL, 466 NFT_DATA_VALUE, len); 467 if (err < 0) 468 return err; 469 470 err = nft_ct_netns_get(ctx->net, ctx->afi->family); 471 if (err < 0) 472 return err; 473 474 if (priv->key == NFT_CT_BYTES || 475 priv->key == NFT_CT_PKTS || 476 priv->key == NFT_CT_AVGPKT) 477 nf_ct_set_acct(ctx->net, true); 478 479 return 0; 480 } 481 482 static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv) 483 { 484 switch (priv->key) { 485 #ifdef CONFIG_NF_CONNTRACK_LABELS 486 case NFT_CT_LABELS: 487 nf_connlabels_put(ctx->net); 488 break; 489 #endif 490 #ifdef CONFIG_NF_CONNTRACK_ZONES 491 case NFT_CT_ZONE: 492 if (--nft_ct_pcpu_template_refcnt == 0) 493 nft_ct_tmpl_put_pcpu(); 494 #endif 495 default: 496 break; 497 } 498 } 499 500 static int nft_ct_set_init(const struct nft_ctx *ctx, 501 const struct nft_expr *expr, 502 const struct nlattr * const tb[]) 503 { 504 struct nft_ct *priv = nft_expr_priv(expr); 505 unsigned int len; 506 int err; 507 508 priv->dir = IP_CT_DIR_MAX; 509 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 510 switch (priv->key) { 511 #ifdef CONFIG_NF_CONNTRACK_MARK 512 case NFT_CT_MARK: 513 if (tb[NFTA_CT_DIRECTION]) 514 return -EINVAL; 515 len = FIELD_SIZEOF(struct nf_conn, mark); 516 break; 517 #endif 518 #ifdef CONFIG_NF_CONNTRACK_LABELS 519 case NFT_CT_LABELS: 520 if (tb[NFTA_CT_DIRECTION]) 521 return -EINVAL; 522 len = NF_CT_LABELS_MAX_SIZE; 523 err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1); 524 if (err) 525 return err; 526 break; 527 #endif 528 #ifdef CONFIG_NF_CONNTRACK_ZONES 529 case NFT_CT_ZONE: 530 if (!nft_ct_tmpl_alloc_pcpu()) 531 return -ENOMEM; 532 nft_ct_pcpu_template_refcnt++; 533 len = sizeof(u16); 534 break; 535 #endif 536 default: 537 return -EOPNOTSUPP; 538 } 539 540 if (tb[NFTA_CT_DIRECTION]) { 541 priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]); 542 switch (priv->dir) { 543 case IP_CT_DIR_ORIGINAL: 544 case IP_CT_DIR_REPLY: 545 break; 546 default: 547 err = -EINVAL; 548 goto err1; 549 } 550 } 551 552 priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]); 553 err = nft_validate_register_load(priv->sreg, len); 554 if (err < 0) 555 goto err1; 556 557 err = nft_ct_netns_get(ctx->net, ctx->afi->family); 558 if (err < 0) 559 goto err1; 560 561 return 0; 562 563 err1: 564 __nft_ct_set_destroy(ctx, priv); 565 return err; 566 } 567 568 static void nft_ct_get_destroy(const struct nft_ctx *ctx, 569 const struct nft_expr *expr) 570 { 571 nf_ct_netns_put(ctx->net, ctx->afi->family); 572 } 573 574 static void nft_ct_set_destroy(const struct nft_ctx *ctx, 575 const struct nft_expr *expr) 576 { 577 struct nft_ct *priv = nft_expr_priv(expr); 578 579 __nft_ct_set_destroy(ctx, priv); 580 nft_ct_netns_put(ctx->net, ctx->afi->family); 581 } 582 583 static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr) 584 { 585 const struct nft_ct *priv = nft_expr_priv(expr); 586 587 if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg)) 588 goto nla_put_failure; 589 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 590 goto nla_put_failure; 591 592 switch (priv->key) { 593 case NFT_CT_SRC: 594 case NFT_CT_DST: 595 case NFT_CT_PROTO_SRC: 596 case NFT_CT_PROTO_DST: 597 if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) 598 goto nla_put_failure; 599 break; 600 case NFT_CT_BYTES: 601 case NFT_CT_PKTS: 602 case NFT_CT_AVGPKT: 603 case NFT_CT_ZONE: 604 if (priv->dir < IP_CT_DIR_MAX && 605 nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) 606 goto nla_put_failure; 607 break; 608 default: 609 break; 610 } 611 612 return 0; 613 614 nla_put_failure: 615 return -1; 616 } 617 618 static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr) 619 { 620 const struct nft_ct *priv = nft_expr_priv(expr); 621 622 if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg)) 623 goto nla_put_failure; 624 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 625 goto nla_put_failure; 626 627 switch (priv->key) { 628 case NFT_CT_ZONE: 629 if (priv->dir < IP_CT_DIR_MAX && 630 nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) 631 goto nla_put_failure; 632 break; 633 default: 634 break; 635 } 636 637 return 0; 638 639 nla_put_failure: 640 return -1; 641 } 642 643 static struct nft_expr_type nft_ct_type; 644 static const struct nft_expr_ops nft_ct_get_ops = { 645 .type = &nft_ct_type, 646 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), 647 .eval = nft_ct_get_eval, 648 .init = nft_ct_get_init, 649 .destroy = nft_ct_get_destroy, 650 .dump = nft_ct_get_dump, 651 }; 652 653 static const struct nft_expr_ops nft_ct_set_ops = { 654 .type = &nft_ct_type, 655 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), 656 .eval = nft_ct_set_eval, 657 .init = nft_ct_set_init, 658 .destroy = nft_ct_set_destroy, 659 .dump = nft_ct_set_dump, 660 }; 661 662 #ifdef CONFIG_NF_CONNTRACK_ZONES 663 static const struct nft_expr_ops nft_ct_set_zone_ops = { 664 .type = &nft_ct_type, 665 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), 666 .eval = nft_ct_set_zone_eval, 667 .init = nft_ct_set_init, 668 .destroy = nft_ct_set_destroy, 669 .dump = nft_ct_set_dump, 670 }; 671 #endif 672 673 static const struct nft_expr_ops * 674 nft_ct_select_ops(const struct nft_ctx *ctx, 675 const struct nlattr * const tb[]) 676 { 677 if (tb[NFTA_CT_KEY] == NULL) 678 return ERR_PTR(-EINVAL); 679 680 if (tb[NFTA_CT_DREG] && tb[NFTA_CT_SREG]) 681 return ERR_PTR(-EINVAL); 682 683 if (tb[NFTA_CT_DREG]) 684 return &nft_ct_get_ops; 685 686 if (tb[NFTA_CT_SREG]) { 687 #ifdef CONFIG_NF_CONNTRACK_ZONES 688 if (nla_get_be32(tb[NFTA_CT_KEY]) == htonl(NFT_CT_ZONE)) 689 return &nft_ct_set_zone_ops; 690 #endif 691 return &nft_ct_set_ops; 692 } 693 694 return ERR_PTR(-EINVAL); 695 } 696 697 static struct nft_expr_type nft_ct_type __read_mostly = { 698 .name = "ct", 699 .select_ops = &nft_ct_select_ops, 700 .policy = nft_ct_policy, 701 .maxattr = NFTA_CT_MAX, 702 .owner = THIS_MODULE, 703 }; 704 705 static void nft_notrack_eval(const struct nft_expr *expr, 706 struct nft_regs *regs, 707 const struct nft_pktinfo *pkt) 708 { 709 struct sk_buff *skb = pkt->skb; 710 enum ip_conntrack_info ctinfo; 711 struct nf_conn *ct; 712 713 ct = nf_ct_get(pkt->skb, &ctinfo); 714 /* Previously seen (loopback or untracked)? Ignore. */ 715 if (ct) 716 return; 717 718 ct = nf_ct_untracked_get(); 719 atomic_inc(&ct->ct_general.use); 720 nf_ct_set(skb, ct, IP_CT_NEW); 721 } 722 723 static struct nft_expr_type nft_notrack_type; 724 static const struct nft_expr_ops nft_notrack_ops = { 725 .type = &nft_notrack_type, 726 .size = NFT_EXPR_SIZE(0), 727 .eval = nft_notrack_eval, 728 }; 729 730 static struct nft_expr_type nft_notrack_type __read_mostly = { 731 .name = "notrack", 732 .ops = &nft_notrack_ops, 733 .owner = THIS_MODULE, 734 }; 735 736 static int __init nft_ct_module_init(void) 737 { 738 int err; 739 740 BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > NFT_REG_SIZE); 741 742 err = nft_register_expr(&nft_ct_type); 743 if (err < 0) 744 return err; 745 746 err = nft_register_expr(&nft_notrack_type); 747 if (err < 0) 748 goto err1; 749 750 return 0; 751 err1: 752 nft_unregister_expr(&nft_ct_type); 753 return err; 754 } 755 756 static void __exit nft_ct_module_exit(void) 757 { 758 nft_unregister_expr(&nft_notrack_type); 759 nft_unregister_expr(&nft_ct_type); 760 } 761 762 module_init(nft_ct_module_init); 763 module_exit(nft_ct_module_exit); 764 765 MODULE_LICENSE("GPL"); 766 MODULE_AUTHOR("Patrick McHardy <[email protected]>"); 767 MODULE_ALIAS_NFT_EXPR("ct"); 768 MODULE_ALIAS_NFT_EXPR("notrack"); 769