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