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