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