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