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