Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
0004  * Copyright (c) 2016 Pablo Neira Ayuso <pablo@netfilter.org>
0005  *
0006  * Development of this code funded by Astaro AG (http://www.astaro.com/)
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/netlink.h>
0013 #include <linux/netfilter.h>
0014 #include <linux/netfilter/nf_tables.h>
0015 #include <net/netfilter/nf_tables.h>
0016 #include <net/netfilter/nf_conntrack.h>
0017 #include <net/netfilter/nf_conntrack_acct.h>
0018 #include <net/netfilter/nf_conntrack_tuple.h>
0019 #include <net/netfilter/nf_conntrack_helper.h>
0020 #include <net/netfilter/nf_conntrack_ecache.h>
0021 #include <net/netfilter/nf_conntrack_labels.h>
0022 #include <net/netfilter/nf_conntrack_timeout.h>
0023 #include <net/netfilter/nf_conntrack_l4proto.h>
0024 #include <net/netfilter/nf_conntrack_expect.h>
0025 
0026 struct nft_ct {
0027     enum nft_ct_keys    key:8;
0028     enum ip_conntrack_dir   dir:8;
0029     u8          len;
0030     union {
0031         u8      dreg;
0032         u8      sreg;
0033     };
0034 };
0035 
0036 struct nft_ct_helper_obj  {
0037     struct nf_conntrack_helper *helper4;
0038     struct nf_conntrack_helper *helper6;
0039     u8 l4proto;
0040 };
0041 
0042 #ifdef CONFIG_NF_CONNTRACK_ZONES
0043 static DEFINE_PER_CPU(struct nf_conn *, nft_ct_pcpu_template);
0044 static unsigned int nft_ct_pcpu_template_refcnt __read_mostly;
0045 static DEFINE_MUTEX(nft_ct_pcpu_mutex);
0046 #endif
0047 
0048 static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c,
0049                    enum nft_ct_keys k,
0050                    enum ip_conntrack_dir d)
0051 {
0052     if (d < IP_CT_DIR_MAX)
0053         return k == NFT_CT_BYTES ? atomic64_read(&c[d].bytes) :
0054                        atomic64_read(&c[d].packets);
0055 
0056     return nft_ct_get_eval_counter(c, k, IP_CT_DIR_ORIGINAL) +
0057            nft_ct_get_eval_counter(c, k, IP_CT_DIR_REPLY);
0058 }
0059 
0060 static void nft_ct_get_eval(const struct nft_expr *expr,
0061                 struct nft_regs *regs,
0062                 const struct nft_pktinfo *pkt)
0063 {
0064     const struct nft_ct *priv = nft_expr_priv(expr);
0065     u32 *dest = &regs->data[priv->dreg];
0066     enum ip_conntrack_info ctinfo;
0067     const struct nf_conn *ct;
0068     const struct nf_conn_help *help;
0069     const struct nf_conntrack_tuple *tuple;
0070     const struct nf_conntrack_helper *helper;
0071     unsigned int state;
0072 
0073     ct = nf_ct_get(pkt->skb, &ctinfo);
0074 
0075     switch (priv->key) {
0076     case NFT_CT_STATE:
0077         if (ct)
0078             state = NF_CT_STATE_BIT(ctinfo);
0079         else if (ctinfo == IP_CT_UNTRACKED)
0080             state = NF_CT_STATE_UNTRACKED_BIT;
0081         else
0082             state = NF_CT_STATE_INVALID_BIT;
0083         *dest = state;
0084         return;
0085     default:
0086         break;
0087     }
0088 
0089     if (ct == NULL)
0090         goto err;
0091 
0092     switch (priv->key) {
0093     case NFT_CT_DIRECTION:
0094         nft_reg_store8(dest, CTINFO2DIR(ctinfo));
0095         return;
0096     case NFT_CT_STATUS:
0097         *dest = ct->status;
0098         return;
0099 #ifdef CONFIG_NF_CONNTRACK_MARK
0100     case NFT_CT_MARK:
0101         *dest = ct->mark;
0102         return;
0103 #endif
0104 #ifdef CONFIG_NF_CONNTRACK_SECMARK
0105     case NFT_CT_SECMARK:
0106         *dest = ct->secmark;
0107         return;
0108 #endif
0109     case NFT_CT_EXPIRATION:
0110         *dest = jiffies_to_msecs(nf_ct_expires(ct));
0111         return;
0112     case NFT_CT_HELPER:
0113         if (ct->master == NULL)
0114             goto err;
0115         help = nfct_help(ct->master);
0116         if (help == NULL)
0117             goto err;
0118         helper = rcu_dereference(help->helper);
0119         if (helper == NULL)
0120             goto err;
0121         strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN);
0122         return;
0123 #ifdef CONFIG_NF_CONNTRACK_LABELS
0124     case NFT_CT_LABELS: {
0125         struct nf_conn_labels *labels = nf_ct_labels_find(ct);
0126 
0127         if (labels)
0128             memcpy(dest, labels->bits, NF_CT_LABELS_MAX_SIZE);
0129         else
0130             memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
0131         return;
0132     }
0133 #endif
0134     case NFT_CT_BYTES:
0135     case NFT_CT_PKTS: {
0136         const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
0137         u64 count = 0;
0138 
0139         if (acct)
0140             count = nft_ct_get_eval_counter(acct->counter,
0141                             priv->key, priv->dir);
0142         memcpy(dest, &count, sizeof(count));
0143         return;
0144     }
0145     case NFT_CT_AVGPKT: {
0146         const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
0147         u64 avgcnt = 0, bcnt = 0, pcnt = 0;
0148 
0149         if (acct) {
0150             pcnt = nft_ct_get_eval_counter(acct->counter,
0151                                NFT_CT_PKTS, priv->dir);
0152             bcnt = nft_ct_get_eval_counter(acct->counter,
0153                                NFT_CT_BYTES, priv->dir);
0154             if (pcnt != 0)
0155                 avgcnt = div64_u64(bcnt, pcnt);
0156         }
0157 
0158         memcpy(dest, &avgcnt, sizeof(avgcnt));
0159         return;
0160     }
0161     case NFT_CT_L3PROTOCOL:
0162         nft_reg_store8(dest, nf_ct_l3num(ct));
0163         return;
0164     case NFT_CT_PROTOCOL:
0165         nft_reg_store8(dest, nf_ct_protonum(ct));
0166         return;
0167 #ifdef CONFIG_NF_CONNTRACK_ZONES
0168     case NFT_CT_ZONE: {
0169         const struct nf_conntrack_zone *zone = nf_ct_zone(ct);
0170         u16 zoneid;
0171 
0172         if (priv->dir < IP_CT_DIR_MAX)
0173             zoneid = nf_ct_zone_id(zone, priv->dir);
0174         else
0175             zoneid = zone->id;
0176 
0177         nft_reg_store16(dest, zoneid);
0178         return;
0179     }
0180 #endif
0181     case NFT_CT_ID:
0182         *dest = nf_ct_get_id(ct);
0183         return;
0184     default:
0185         break;
0186     }
0187 
0188     tuple = &ct->tuplehash[priv->dir].tuple;
0189     switch (priv->key) {
0190     case NFT_CT_SRC:
0191         memcpy(dest, tuple->src.u3.all,
0192                nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
0193         return;
0194     case NFT_CT_DST:
0195         memcpy(dest, tuple->dst.u3.all,
0196                nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
0197         return;
0198     case NFT_CT_PROTO_SRC:
0199         nft_reg_store16(dest, (__force u16)tuple->src.u.all);
0200         return;
0201     case NFT_CT_PROTO_DST:
0202         nft_reg_store16(dest, (__force u16)tuple->dst.u.all);
0203         return;
0204     case NFT_CT_SRC_IP:
0205         if (nf_ct_l3num(ct) != NFPROTO_IPV4)
0206             goto err;
0207         *dest = (__force __u32)tuple->src.u3.ip;
0208         return;
0209     case NFT_CT_DST_IP:
0210         if (nf_ct_l3num(ct) != NFPROTO_IPV4)
0211             goto err;
0212         *dest = (__force __u32)tuple->dst.u3.ip;
0213         return;
0214     case NFT_CT_SRC_IP6:
0215         if (nf_ct_l3num(ct) != NFPROTO_IPV6)
0216             goto err;
0217         memcpy(dest, tuple->src.u3.ip6, sizeof(struct in6_addr));
0218         return;
0219     case NFT_CT_DST_IP6:
0220         if (nf_ct_l3num(ct) != NFPROTO_IPV6)
0221             goto err;
0222         memcpy(dest, tuple->dst.u3.ip6, sizeof(struct in6_addr));
0223         return;
0224     default:
0225         break;
0226     }
0227     return;
0228 err:
0229     regs->verdict.code = NFT_BREAK;
0230 }
0231 
0232 #ifdef CONFIG_NF_CONNTRACK_ZONES
0233 static void nft_ct_set_zone_eval(const struct nft_expr *expr,
0234                  struct nft_regs *regs,
0235                  const struct nft_pktinfo *pkt)
0236 {
0237     struct nf_conntrack_zone zone = { .dir = NF_CT_DEFAULT_ZONE_DIR };
0238     const struct nft_ct *priv = nft_expr_priv(expr);
0239     struct sk_buff *skb = pkt->skb;
0240     enum ip_conntrack_info ctinfo;
0241     u16 value = nft_reg_load16(&regs->data[priv->sreg]);
0242     struct nf_conn *ct;
0243 
0244     ct = nf_ct_get(skb, &ctinfo);
0245     if (ct) /* already tracked */
0246         return;
0247 
0248     zone.id = value;
0249 
0250     switch (priv->dir) {
0251     case IP_CT_DIR_ORIGINAL:
0252         zone.dir = NF_CT_ZONE_DIR_ORIG;
0253         break;
0254     case IP_CT_DIR_REPLY:
0255         zone.dir = NF_CT_ZONE_DIR_REPL;
0256         break;
0257     default:
0258         break;
0259     }
0260 
0261     ct = this_cpu_read(nft_ct_pcpu_template);
0262 
0263     if (likely(refcount_read(&ct->ct_general.use) == 1)) {
0264         refcount_inc(&ct->ct_general.use);
0265         nf_ct_zone_add(ct, &zone);
0266     } else {
0267         /* previous skb got queued to userspace, allocate temporary
0268          * one until percpu template can be reused.
0269          */
0270         ct = nf_ct_tmpl_alloc(nft_net(pkt), &zone, GFP_ATOMIC);
0271         if (!ct) {
0272             regs->verdict.code = NF_DROP;
0273             return;
0274         }
0275     }
0276 
0277     nf_ct_set(skb, ct, IP_CT_NEW);
0278 }
0279 #endif
0280 
0281 static void nft_ct_set_eval(const struct nft_expr *expr,
0282                 struct nft_regs *regs,
0283                 const struct nft_pktinfo *pkt)
0284 {
0285     const struct nft_ct *priv = nft_expr_priv(expr);
0286     struct sk_buff *skb = pkt->skb;
0287 #if defined(CONFIG_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_SECMARK)
0288     u32 value = regs->data[priv->sreg];
0289 #endif
0290     enum ip_conntrack_info ctinfo;
0291     struct nf_conn *ct;
0292 
0293     ct = nf_ct_get(skb, &ctinfo);
0294     if (ct == NULL || nf_ct_is_template(ct))
0295         return;
0296 
0297     switch (priv->key) {
0298 #ifdef CONFIG_NF_CONNTRACK_MARK
0299     case NFT_CT_MARK:
0300         if (ct->mark != value) {
0301             ct->mark = value;
0302             nf_conntrack_event_cache(IPCT_MARK, ct);
0303         }
0304         break;
0305 #endif
0306 #ifdef CONFIG_NF_CONNTRACK_SECMARK
0307     case NFT_CT_SECMARK:
0308         if (ct->secmark != value) {
0309             ct->secmark = value;
0310             nf_conntrack_event_cache(IPCT_SECMARK, ct);
0311         }
0312         break;
0313 #endif
0314 #ifdef CONFIG_NF_CONNTRACK_LABELS
0315     case NFT_CT_LABELS:
0316         nf_connlabels_replace(ct,
0317                       &regs->data[priv->sreg],
0318                       &regs->data[priv->sreg],
0319                       NF_CT_LABELS_MAX_SIZE / sizeof(u32));
0320         break;
0321 #endif
0322 #ifdef CONFIG_NF_CONNTRACK_EVENTS
0323     case NFT_CT_EVENTMASK: {
0324         struct nf_conntrack_ecache *e = nf_ct_ecache_find(ct);
0325         u32 ctmask = regs->data[priv->sreg];
0326 
0327         if (e) {
0328             if (e->ctmask != ctmask)
0329                 e->ctmask = ctmask;
0330             break;
0331         }
0332 
0333         if (ctmask && !nf_ct_is_confirmed(ct))
0334             nf_ct_ecache_ext_add(ct, ctmask, 0, GFP_ATOMIC);
0335         break;
0336     }
0337 #endif
0338     default:
0339         break;
0340     }
0341 }
0342 
0343 static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = {
0344     [NFTA_CT_DREG]      = { .type = NLA_U32 },
0345     [NFTA_CT_KEY]       = { .type = NLA_U32 },
0346     [NFTA_CT_DIRECTION] = { .type = NLA_U8 },
0347     [NFTA_CT_SREG]      = { .type = NLA_U32 },
0348 };
0349 
0350 #ifdef CONFIG_NF_CONNTRACK_ZONES
0351 static void nft_ct_tmpl_put_pcpu(void)
0352 {
0353     struct nf_conn *ct;
0354     int cpu;
0355 
0356     for_each_possible_cpu(cpu) {
0357         ct = per_cpu(nft_ct_pcpu_template, cpu);
0358         if (!ct)
0359             break;
0360         nf_ct_put(ct);
0361         per_cpu(nft_ct_pcpu_template, cpu) = NULL;
0362     }
0363 }
0364 
0365 static bool nft_ct_tmpl_alloc_pcpu(void)
0366 {
0367     struct nf_conntrack_zone zone = { .id = 0 };
0368     struct nf_conn *tmp;
0369     int cpu;
0370 
0371     if (nft_ct_pcpu_template_refcnt)
0372         return true;
0373 
0374     for_each_possible_cpu(cpu) {
0375         tmp = nf_ct_tmpl_alloc(&init_net, &zone, GFP_KERNEL);
0376         if (!tmp) {
0377             nft_ct_tmpl_put_pcpu();
0378             return false;
0379         }
0380 
0381         per_cpu(nft_ct_pcpu_template, cpu) = tmp;
0382     }
0383 
0384     return true;
0385 }
0386 #endif
0387 
0388 static int nft_ct_get_init(const struct nft_ctx *ctx,
0389                const struct nft_expr *expr,
0390                const struct nlattr * const tb[])
0391 {
0392     struct nft_ct *priv = nft_expr_priv(expr);
0393     unsigned int len;
0394     int err;
0395 
0396     priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
0397     priv->dir = IP_CT_DIR_MAX;
0398     switch (priv->key) {
0399     case NFT_CT_DIRECTION:
0400         if (tb[NFTA_CT_DIRECTION] != NULL)
0401             return -EINVAL;
0402         len = sizeof(u8);
0403         break;
0404     case NFT_CT_STATE:
0405     case NFT_CT_STATUS:
0406 #ifdef CONFIG_NF_CONNTRACK_MARK
0407     case NFT_CT_MARK:
0408 #endif
0409 #ifdef CONFIG_NF_CONNTRACK_SECMARK
0410     case NFT_CT_SECMARK:
0411 #endif
0412     case NFT_CT_EXPIRATION:
0413         if (tb[NFTA_CT_DIRECTION] != NULL)
0414             return -EINVAL;
0415         len = sizeof(u32);
0416         break;
0417 #ifdef CONFIG_NF_CONNTRACK_LABELS
0418     case NFT_CT_LABELS:
0419         if (tb[NFTA_CT_DIRECTION] != NULL)
0420             return -EINVAL;
0421         len = NF_CT_LABELS_MAX_SIZE;
0422         break;
0423 #endif
0424     case NFT_CT_HELPER:
0425         if (tb[NFTA_CT_DIRECTION] != NULL)
0426             return -EINVAL;
0427         len = NF_CT_HELPER_NAME_LEN;
0428         break;
0429 
0430     case NFT_CT_L3PROTOCOL:
0431     case NFT_CT_PROTOCOL:
0432         /* For compatibility, do not report error if NFTA_CT_DIRECTION
0433          * attribute is specified.
0434          */
0435         len = sizeof(u8);
0436         break;
0437     case NFT_CT_SRC:
0438     case NFT_CT_DST:
0439         if (tb[NFTA_CT_DIRECTION] == NULL)
0440             return -EINVAL;
0441 
0442         switch (ctx->family) {
0443         case NFPROTO_IPV4:
0444             len = sizeof_field(struct nf_conntrack_tuple,
0445                        src.u3.ip);
0446             break;
0447         case NFPROTO_IPV6:
0448         case NFPROTO_INET:
0449             len = sizeof_field(struct nf_conntrack_tuple,
0450                        src.u3.ip6);
0451             break;
0452         default:
0453             return -EAFNOSUPPORT;
0454         }
0455         break;
0456     case NFT_CT_SRC_IP:
0457     case NFT_CT_DST_IP:
0458         if (tb[NFTA_CT_DIRECTION] == NULL)
0459             return -EINVAL;
0460 
0461         len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip);
0462         break;
0463     case NFT_CT_SRC_IP6:
0464     case NFT_CT_DST_IP6:
0465         if (tb[NFTA_CT_DIRECTION] == NULL)
0466             return -EINVAL;
0467 
0468         len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip6);
0469         break;
0470     case NFT_CT_PROTO_SRC:
0471     case NFT_CT_PROTO_DST:
0472         if (tb[NFTA_CT_DIRECTION] == NULL)
0473             return -EINVAL;
0474         len = sizeof_field(struct nf_conntrack_tuple, src.u.all);
0475         break;
0476     case NFT_CT_BYTES:
0477     case NFT_CT_PKTS:
0478     case NFT_CT_AVGPKT:
0479         len = sizeof(u64);
0480         break;
0481 #ifdef CONFIG_NF_CONNTRACK_ZONES
0482     case NFT_CT_ZONE:
0483         len = sizeof(u16);
0484         break;
0485 #endif
0486     case NFT_CT_ID:
0487         len = sizeof(u32);
0488         break;
0489     default:
0490         return -EOPNOTSUPP;
0491     }
0492 
0493     if (tb[NFTA_CT_DIRECTION] != NULL) {
0494         priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
0495         switch (priv->dir) {
0496         case IP_CT_DIR_ORIGINAL:
0497         case IP_CT_DIR_REPLY:
0498             break;
0499         default:
0500             return -EINVAL;
0501         }
0502     }
0503 
0504     priv->len = len;
0505     err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL,
0506                        NFT_DATA_VALUE, len);
0507     if (err < 0)
0508         return err;
0509 
0510     err = nf_ct_netns_get(ctx->net, ctx->family);
0511     if (err < 0)
0512         return err;
0513 
0514     if (priv->key == NFT_CT_BYTES ||
0515         priv->key == NFT_CT_PKTS  ||
0516         priv->key == NFT_CT_AVGPKT)
0517         nf_ct_set_acct(ctx->net, true);
0518 
0519     return 0;
0520 }
0521 
0522 static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv)
0523 {
0524     switch (priv->key) {
0525 #ifdef CONFIG_NF_CONNTRACK_LABELS
0526     case NFT_CT_LABELS:
0527         nf_connlabels_put(ctx->net);
0528         break;
0529 #endif
0530 #ifdef CONFIG_NF_CONNTRACK_ZONES
0531     case NFT_CT_ZONE:
0532         mutex_lock(&nft_ct_pcpu_mutex);
0533         if (--nft_ct_pcpu_template_refcnt == 0)
0534             nft_ct_tmpl_put_pcpu();
0535         mutex_unlock(&nft_ct_pcpu_mutex);
0536         break;
0537 #endif
0538     default:
0539         break;
0540     }
0541 }
0542 
0543 static int nft_ct_set_init(const struct nft_ctx *ctx,
0544                const struct nft_expr *expr,
0545                const struct nlattr * const tb[])
0546 {
0547     struct nft_ct *priv = nft_expr_priv(expr);
0548     unsigned int len;
0549     int err;
0550 
0551     priv->dir = IP_CT_DIR_MAX;
0552     priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
0553     switch (priv->key) {
0554 #ifdef CONFIG_NF_CONNTRACK_MARK
0555     case NFT_CT_MARK:
0556         if (tb[NFTA_CT_DIRECTION])
0557             return -EINVAL;
0558         len = sizeof_field(struct nf_conn, mark);
0559         break;
0560 #endif
0561 #ifdef CONFIG_NF_CONNTRACK_LABELS
0562     case NFT_CT_LABELS:
0563         if (tb[NFTA_CT_DIRECTION])
0564             return -EINVAL;
0565         len = NF_CT_LABELS_MAX_SIZE;
0566         err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
0567         if (err)
0568             return err;
0569         break;
0570 #endif
0571 #ifdef CONFIG_NF_CONNTRACK_ZONES
0572     case NFT_CT_ZONE:
0573         mutex_lock(&nft_ct_pcpu_mutex);
0574         if (!nft_ct_tmpl_alloc_pcpu()) {
0575             mutex_unlock(&nft_ct_pcpu_mutex);
0576             return -ENOMEM;
0577         }
0578         nft_ct_pcpu_template_refcnt++;
0579         mutex_unlock(&nft_ct_pcpu_mutex);
0580         len = sizeof(u16);
0581         break;
0582 #endif
0583 #ifdef CONFIG_NF_CONNTRACK_EVENTS
0584     case NFT_CT_EVENTMASK:
0585         if (tb[NFTA_CT_DIRECTION])
0586             return -EINVAL;
0587         len = sizeof(u32);
0588         break;
0589 #endif
0590 #ifdef CONFIG_NF_CONNTRACK_SECMARK
0591     case NFT_CT_SECMARK:
0592         if (tb[NFTA_CT_DIRECTION])
0593             return -EINVAL;
0594         len = sizeof(u32);
0595         break;
0596 #endif
0597     default:
0598         return -EOPNOTSUPP;
0599     }
0600 
0601     if (tb[NFTA_CT_DIRECTION]) {
0602         priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
0603         switch (priv->dir) {
0604         case IP_CT_DIR_ORIGINAL:
0605         case IP_CT_DIR_REPLY:
0606             break;
0607         default:
0608             err = -EINVAL;
0609             goto err1;
0610         }
0611     }
0612 
0613     priv->len = len;
0614     err = nft_parse_register_load(tb[NFTA_CT_SREG], &priv->sreg, len);
0615     if (err < 0)
0616         goto err1;
0617 
0618     err = nf_ct_netns_get(ctx->net, ctx->family);
0619     if (err < 0)
0620         goto err1;
0621 
0622     return 0;
0623 
0624 err1:
0625     __nft_ct_set_destroy(ctx, priv);
0626     return err;
0627 }
0628 
0629 static void nft_ct_get_destroy(const struct nft_ctx *ctx,
0630                    const struct nft_expr *expr)
0631 {
0632     nf_ct_netns_put(ctx->net, ctx->family);
0633 }
0634 
0635 static void nft_ct_set_destroy(const struct nft_ctx *ctx,
0636                    const struct nft_expr *expr)
0637 {
0638     struct nft_ct *priv = nft_expr_priv(expr);
0639 
0640     __nft_ct_set_destroy(ctx, priv);
0641     nf_ct_netns_put(ctx->net, ctx->family);
0642 }
0643 
0644 static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
0645 {
0646     const struct nft_ct *priv = nft_expr_priv(expr);
0647 
0648     if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg))
0649         goto nla_put_failure;
0650     if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
0651         goto nla_put_failure;
0652 
0653     switch (priv->key) {
0654     case NFT_CT_SRC:
0655     case NFT_CT_DST:
0656     case NFT_CT_SRC_IP:
0657     case NFT_CT_DST_IP:
0658     case NFT_CT_SRC_IP6:
0659     case NFT_CT_DST_IP6:
0660     case NFT_CT_PROTO_SRC:
0661     case NFT_CT_PROTO_DST:
0662         if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
0663             goto nla_put_failure;
0664         break;
0665     case NFT_CT_BYTES:
0666     case NFT_CT_PKTS:
0667     case NFT_CT_AVGPKT:
0668     case NFT_CT_ZONE:
0669         if (priv->dir < IP_CT_DIR_MAX &&
0670             nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
0671             goto nla_put_failure;
0672         break;
0673     default:
0674         break;
0675     }
0676 
0677     return 0;
0678 
0679 nla_put_failure:
0680     return -1;
0681 }
0682 
0683 static bool nft_ct_get_reduce(struct nft_regs_track *track,
0684                   const struct nft_expr *expr)
0685 {
0686     const struct nft_ct *priv = nft_expr_priv(expr);
0687     const struct nft_ct *ct;
0688 
0689     if (!nft_reg_track_cmp(track, expr, priv->dreg)) {
0690         nft_reg_track_update(track, expr, priv->dreg, priv->len);
0691         return false;
0692     }
0693 
0694     ct = nft_expr_priv(track->regs[priv->dreg].selector);
0695     if (priv->key != ct->key) {
0696         nft_reg_track_update(track, expr, priv->dreg, priv->len);
0697         return false;
0698     }
0699 
0700     if (!track->regs[priv->dreg].bitwise)
0701         return true;
0702 
0703     return nft_expr_reduce_bitwise(track, expr);
0704 }
0705 
0706 static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
0707 {
0708     const struct nft_ct *priv = nft_expr_priv(expr);
0709 
0710     if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg))
0711         goto nla_put_failure;
0712     if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
0713         goto nla_put_failure;
0714 
0715     switch (priv->key) {
0716     case NFT_CT_ZONE:
0717         if (priv->dir < IP_CT_DIR_MAX &&
0718             nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
0719             goto nla_put_failure;
0720         break;
0721     default:
0722         break;
0723     }
0724 
0725     return 0;
0726 
0727 nla_put_failure:
0728     return -1;
0729 }
0730 
0731 static struct nft_expr_type nft_ct_type;
0732 static const struct nft_expr_ops nft_ct_get_ops = {
0733     .type       = &nft_ct_type,
0734     .size       = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
0735     .eval       = nft_ct_get_eval,
0736     .init       = nft_ct_get_init,
0737     .destroy    = nft_ct_get_destroy,
0738     .dump       = nft_ct_get_dump,
0739     .reduce     = nft_ct_get_reduce,
0740 };
0741 
0742 static bool nft_ct_set_reduce(struct nft_regs_track *track,
0743                   const struct nft_expr *expr)
0744 {
0745     int i;
0746 
0747     for (i = 0; i < NFT_REG32_NUM; i++) {
0748         if (!track->regs[i].selector)
0749             continue;
0750 
0751         if (track->regs[i].selector->ops != &nft_ct_get_ops)
0752             continue;
0753 
0754         __nft_reg_track_cancel(track, i);
0755     }
0756 
0757     return false;
0758 }
0759 
0760 static const struct nft_expr_ops nft_ct_set_ops = {
0761     .type       = &nft_ct_type,
0762     .size       = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
0763     .eval       = nft_ct_set_eval,
0764     .init       = nft_ct_set_init,
0765     .destroy    = nft_ct_set_destroy,
0766     .dump       = nft_ct_set_dump,
0767     .reduce     = nft_ct_set_reduce,
0768 };
0769 
0770 #ifdef CONFIG_NF_CONNTRACK_ZONES
0771 static const struct nft_expr_ops nft_ct_set_zone_ops = {
0772     .type       = &nft_ct_type,
0773     .size       = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
0774     .eval       = nft_ct_set_zone_eval,
0775     .init       = nft_ct_set_init,
0776     .destroy    = nft_ct_set_destroy,
0777     .dump       = nft_ct_set_dump,
0778     .reduce     = nft_ct_set_reduce,
0779 };
0780 #endif
0781 
0782 static const struct nft_expr_ops *
0783 nft_ct_select_ops(const struct nft_ctx *ctx,
0784             const struct nlattr * const tb[])
0785 {
0786     if (tb[NFTA_CT_KEY] == NULL)
0787         return ERR_PTR(-EINVAL);
0788 
0789     if (tb[NFTA_CT_DREG] && tb[NFTA_CT_SREG])
0790         return ERR_PTR(-EINVAL);
0791 
0792     if (tb[NFTA_CT_DREG])
0793         return &nft_ct_get_ops;
0794 
0795     if (tb[NFTA_CT_SREG]) {
0796 #ifdef CONFIG_NF_CONNTRACK_ZONES
0797         if (nla_get_be32(tb[NFTA_CT_KEY]) == htonl(NFT_CT_ZONE))
0798             return &nft_ct_set_zone_ops;
0799 #endif
0800         return &nft_ct_set_ops;
0801     }
0802 
0803     return ERR_PTR(-EINVAL);
0804 }
0805 
0806 static struct nft_expr_type nft_ct_type __read_mostly = {
0807     .name       = "ct",
0808     .select_ops = nft_ct_select_ops,
0809     .policy     = nft_ct_policy,
0810     .maxattr    = NFTA_CT_MAX,
0811     .owner      = THIS_MODULE,
0812 };
0813 
0814 static void nft_notrack_eval(const struct nft_expr *expr,
0815                  struct nft_regs *regs,
0816                  const struct nft_pktinfo *pkt)
0817 {
0818     struct sk_buff *skb = pkt->skb;
0819     enum ip_conntrack_info ctinfo;
0820     struct nf_conn *ct;
0821 
0822     ct = nf_ct_get(pkt->skb, &ctinfo);
0823     /* Previously seen (loopback or untracked)?  Ignore. */
0824     if (ct || ctinfo == IP_CT_UNTRACKED)
0825         return;
0826 
0827     nf_ct_set(skb, ct, IP_CT_UNTRACKED);
0828 }
0829 
0830 static struct nft_expr_type nft_notrack_type;
0831 static const struct nft_expr_ops nft_notrack_ops = {
0832     .type       = &nft_notrack_type,
0833     .size       = NFT_EXPR_SIZE(0),
0834     .eval       = nft_notrack_eval,
0835     .reduce     = NFT_REDUCE_READONLY,
0836 };
0837 
0838 static struct nft_expr_type nft_notrack_type __read_mostly = {
0839     .name       = "notrack",
0840     .ops        = &nft_notrack_ops,
0841     .owner      = THIS_MODULE,
0842 };
0843 
0844 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
0845 static int
0846 nft_ct_timeout_parse_policy(void *timeouts,
0847                 const struct nf_conntrack_l4proto *l4proto,
0848                 struct net *net, const struct nlattr *attr)
0849 {
0850     struct nlattr **tb;
0851     int ret = 0;
0852 
0853     tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb),
0854              GFP_KERNEL);
0855 
0856     if (!tb)
0857         return -ENOMEM;
0858 
0859     ret = nla_parse_nested_deprecated(tb,
0860                       l4proto->ctnl_timeout.nlattr_max,
0861                       attr,
0862                       l4proto->ctnl_timeout.nla_policy,
0863                       NULL);
0864     if (ret < 0)
0865         goto err;
0866 
0867     ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeouts);
0868 
0869 err:
0870     kfree(tb);
0871     return ret;
0872 }
0873 
0874 struct nft_ct_timeout_obj {
0875     struct nf_ct_timeout    *timeout;
0876     u8          l4proto;
0877 };
0878 
0879 static void nft_ct_timeout_obj_eval(struct nft_object *obj,
0880                     struct nft_regs *regs,
0881                     const struct nft_pktinfo *pkt)
0882 {
0883     const struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
0884     struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb);
0885     struct nf_conn_timeout *timeout;
0886     const unsigned int *values;
0887 
0888     if (priv->l4proto != pkt->tprot)
0889         return;
0890 
0891     if (!ct || nf_ct_is_template(ct) || nf_ct_is_confirmed(ct))
0892         return;
0893 
0894     timeout = nf_ct_timeout_find(ct);
0895     if (!timeout) {
0896         timeout = nf_ct_timeout_ext_add(ct, priv->timeout, GFP_ATOMIC);
0897         if (!timeout) {
0898             regs->verdict.code = NF_DROP;
0899             return;
0900         }
0901     }
0902 
0903     rcu_assign_pointer(timeout->timeout, priv->timeout);
0904 
0905     /* adjust the timeout as per 'new' state. ct is unconfirmed,
0906      * so the current timestamp must not be added.
0907      */
0908     values = nf_ct_timeout_data(timeout);
0909     if (values)
0910         nf_ct_refresh(ct, pkt->skb, values[0]);
0911 }
0912 
0913 static int nft_ct_timeout_obj_init(const struct nft_ctx *ctx,
0914                    const struct nlattr * const tb[],
0915                    struct nft_object *obj)
0916 {
0917     struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
0918     const struct nf_conntrack_l4proto *l4proto;
0919     struct nf_ct_timeout *timeout;
0920     int l3num = ctx->family;
0921     __u8 l4num;
0922     int ret;
0923 
0924     if (!tb[NFTA_CT_TIMEOUT_L4PROTO] ||
0925         !tb[NFTA_CT_TIMEOUT_DATA])
0926         return -EINVAL;
0927 
0928     if (tb[NFTA_CT_TIMEOUT_L3PROTO])
0929         l3num = ntohs(nla_get_be16(tb[NFTA_CT_TIMEOUT_L3PROTO]));
0930 
0931     l4num = nla_get_u8(tb[NFTA_CT_TIMEOUT_L4PROTO]);
0932     priv->l4proto = l4num;
0933 
0934     l4proto = nf_ct_l4proto_find(l4num);
0935 
0936     if (l4proto->l4proto != l4num) {
0937         ret = -EOPNOTSUPP;
0938         goto err_proto_put;
0939     }
0940 
0941     timeout = kzalloc(sizeof(struct nf_ct_timeout) +
0942               l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
0943     if (timeout == NULL) {
0944         ret = -ENOMEM;
0945         goto err_proto_put;
0946     }
0947 
0948     ret = nft_ct_timeout_parse_policy(&timeout->data, l4proto, ctx->net,
0949                       tb[NFTA_CT_TIMEOUT_DATA]);
0950     if (ret < 0)
0951         goto err_free_timeout;
0952 
0953     timeout->l3num = l3num;
0954     timeout->l4proto = l4proto;
0955 
0956     ret = nf_ct_netns_get(ctx->net, ctx->family);
0957     if (ret < 0)
0958         goto err_free_timeout;
0959 
0960     priv->timeout = timeout;
0961     return 0;
0962 
0963 err_free_timeout:
0964     kfree(timeout);
0965 err_proto_put:
0966     return ret;
0967 }
0968 
0969 static void nft_ct_timeout_obj_destroy(const struct nft_ctx *ctx,
0970                        struct nft_object *obj)
0971 {
0972     struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
0973     struct nf_ct_timeout *timeout = priv->timeout;
0974 
0975     nf_ct_untimeout(ctx->net, timeout);
0976     nf_ct_netns_put(ctx->net, ctx->family);
0977     kfree(priv->timeout);
0978 }
0979 
0980 static int nft_ct_timeout_obj_dump(struct sk_buff *skb,
0981                    struct nft_object *obj, bool reset)
0982 {
0983     const struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
0984     const struct nf_ct_timeout *timeout = priv->timeout;
0985     struct nlattr *nest_params;
0986     int ret;
0987 
0988     if (nla_put_u8(skb, NFTA_CT_TIMEOUT_L4PROTO, timeout->l4proto->l4proto) ||
0989         nla_put_be16(skb, NFTA_CT_TIMEOUT_L3PROTO, htons(timeout->l3num)))
0990         return -1;
0991 
0992     nest_params = nla_nest_start(skb, NFTA_CT_TIMEOUT_DATA);
0993     if (!nest_params)
0994         return -1;
0995 
0996     ret = timeout->l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->data);
0997     if (ret < 0)
0998         return -1;
0999     nla_nest_end(skb, nest_params);
1000     return 0;
1001 }
1002 
1003 static 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 
1009 static struct nft_object_type nft_ct_timeout_obj_type;
1010 
1011 static 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 
1020 static 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 
1029 static 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     return 0;
1093 
1094 err_put_helper:
1095     if (priv->helper4)
1096         nf_conntrack_helper_put(priv->helper4);
1097     if (priv->helper6)
1098         nf_conntrack_helper_put(priv->helper6);
1099     return err;
1100 }
1101 
1102 static void nft_ct_helper_obj_destroy(const struct nft_ctx *ctx,
1103                       struct nft_object *obj)
1104 {
1105     struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1106 
1107     if (priv->helper4)
1108         nf_conntrack_helper_put(priv->helper4);
1109     if (priv->helper6)
1110         nf_conntrack_helper_put(priv->helper6);
1111 
1112     nf_ct_netns_put(ctx->net, ctx->family);
1113 }
1114 
1115 static void nft_ct_helper_obj_eval(struct nft_object *obj,
1116                    struct nft_regs *regs,
1117                    const struct nft_pktinfo *pkt)
1118 {
1119     const struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1120     struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb);
1121     struct nf_conntrack_helper *to_assign = NULL;
1122     struct nf_conn_help *help;
1123 
1124     if (!ct ||
1125         nf_ct_is_confirmed(ct) ||
1126         nf_ct_is_template(ct) ||
1127         priv->l4proto != nf_ct_protonum(ct))
1128         return;
1129 
1130     switch (nf_ct_l3num(ct)) {
1131     case NFPROTO_IPV4:
1132         to_assign = priv->helper4;
1133         break;
1134     case NFPROTO_IPV6:
1135         to_assign = priv->helper6;
1136         break;
1137     default:
1138         WARN_ON_ONCE(1);
1139         return;
1140     }
1141 
1142     if (!to_assign)
1143         return;
1144 
1145     if (test_bit(IPS_HELPER_BIT, &ct->status))
1146         return;
1147 
1148     help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
1149     if (help) {
1150         rcu_assign_pointer(help->helper, to_assign);
1151         set_bit(IPS_HELPER_BIT, &ct->status);
1152     }
1153 }
1154 
1155 static int nft_ct_helper_obj_dump(struct sk_buff *skb,
1156                   struct nft_object *obj, bool reset)
1157 {
1158     const struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1159     const struct nf_conntrack_helper *helper;
1160     u16 family;
1161 
1162     if (priv->helper4 && priv->helper6) {
1163         family = NFPROTO_INET;
1164         helper = priv->helper4;
1165     } else if (priv->helper6) {
1166         family = NFPROTO_IPV6;
1167         helper = priv->helper6;
1168     } else {
1169         family = NFPROTO_IPV4;
1170         helper = priv->helper4;
1171     }
1172 
1173     if (nla_put_string(skb, NFTA_CT_HELPER_NAME, helper->name))
1174         return -1;
1175 
1176     if (nla_put_u8(skb, NFTA_CT_HELPER_L4PROTO, priv->l4proto))
1177         return -1;
1178 
1179     if (nla_put_be16(skb, NFTA_CT_HELPER_L3PROTO, htons(family)))
1180         return -1;
1181 
1182     return 0;
1183 }
1184 
1185 static const struct nla_policy nft_ct_helper_policy[NFTA_CT_HELPER_MAX + 1] = {
1186     [NFTA_CT_HELPER_NAME] = { .type = NLA_STRING,
1187                   .len = NF_CT_HELPER_NAME_LEN - 1 },
1188     [NFTA_CT_HELPER_L3PROTO] = { .type = NLA_U16 },
1189     [NFTA_CT_HELPER_L4PROTO] = { .type = NLA_U8 },
1190 };
1191 
1192 static struct nft_object_type nft_ct_helper_obj_type;
1193 static const struct nft_object_ops nft_ct_helper_obj_ops = {
1194     .type       = &nft_ct_helper_obj_type,
1195     .size       = sizeof(struct nft_ct_helper_obj),
1196     .eval       = nft_ct_helper_obj_eval,
1197     .init       = nft_ct_helper_obj_init,
1198     .destroy    = nft_ct_helper_obj_destroy,
1199     .dump       = nft_ct_helper_obj_dump,
1200 };
1201 
1202 static struct nft_object_type nft_ct_helper_obj_type __read_mostly = {
1203     .type       = NFT_OBJECT_CT_HELPER,
1204     .ops        = &nft_ct_helper_obj_ops,
1205     .maxattr    = NFTA_CT_HELPER_MAX,
1206     .policy     = nft_ct_helper_policy,
1207     .owner      = THIS_MODULE,
1208 };
1209 
1210 struct nft_ct_expect_obj {
1211     u16     l3num;
1212     __be16      dport;
1213     u8      l4proto;
1214     u8      size;
1215     u32     timeout;
1216 };
1217 
1218 static int nft_ct_expect_obj_init(const struct nft_ctx *ctx,
1219                   const struct nlattr * const tb[],
1220                   struct nft_object *obj)
1221 {
1222     struct nft_ct_expect_obj *priv = nft_obj_data(obj);
1223 
1224     if (!tb[NFTA_CT_EXPECT_L4PROTO] ||
1225         !tb[NFTA_CT_EXPECT_DPORT] ||
1226         !tb[NFTA_CT_EXPECT_TIMEOUT] ||
1227         !tb[NFTA_CT_EXPECT_SIZE])
1228         return -EINVAL;
1229 
1230     priv->l3num = ctx->family;
1231     if (tb[NFTA_CT_EXPECT_L3PROTO])
1232         priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO]));
1233 
1234     priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]);
1235     priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]);
1236     priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]);
1237     priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]);
1238 
1239     return nf_ct_netns_get(ctx->net, ctx->family);
1240 }
1241 
1242 static void nft_ct_expect_obj_destroy(const struct nft_ctx *ctx,
1243                        struct nft_object *obj)
1244 {
1245     nf_ct_netns_put(ctx->net, ctx->family);
1246 }
1247 
1248 static int nft_ct_expect_obj_dump(struct sk_buff *skb,
1249                   struct nft_object *obj, bool reset)
1250 {
1251     const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
1252 
1253     if (nla_put_be16(skb, NFTA_CT_EXPECT_L3PROTO, htons(priv->l3num)) ||
1254         nla_put_u8(skb, NFTA_CT_EXPECT_L4PROTO, priv->l4proto) ||
1255         nla_put_be16(skb, NFTA_CT_EXPECT_DPORT, priv->dport) ||
1256         nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, priv->timeout) ||
1257         nla_put_u8(skb, NFTA_CT_EXPECT_SIZE, priv->size))
1258         return -1;
1259 
1260     return 0;
1261 }
1262 
1263 static void nft_ct_expect_obj_eval(struct nft_object *obj,
1264                    struct nft_regs *regs,
1265                    const struct nft_pktinfo *pkt)
1266 {
1267     const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
1268     struct nf_conntrack_expect *exp;
1269     enum ip_conntrack_info ctinfo;
1270     struct nf_conn_help *help;
1271     enum ip_conntrack_dir dir;
1272     u16 l3num = priv->l3num;
1273     struct nf_conn *ct;
1274 
1275     ct = nf_ct_get(pkt->skb, &ctinfo);
1276     if (!ct || nf_ct_is_confirmed(ct) || nf_ct_is_template(ct)) {
1277         regs->verdict.code = NFT_BREAK;
1278         return;
1279     }
1280     dir = CTINFO2DIR(ctinfo);
1281 
1282     help = nfct_help(ct);
1283     if (!help)
1284         help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
1285     if (!help) {
1286         regs->verdict.code = NF_DROP;
1287         return;
1288     }
1289 
1290     if (help->expecting[NF_CT_EXPECT_CLASS_DEFAULT] >= priv->size) {
1291         regs->verdict.code = NFT_BREAK;
1292         return;
1293     }
1294     if (l3num == NFPROTO_INET)
1295         l3num = nf_ct_l3num(ct);
1296 
1297     exp = nf_ct_expect_alloc(ct);
1298     if (exp == NULL) {
1299         regs->verdict.code = NF_DROP;
1300         return;
1301     }
1302     nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, l3num,
1303                   &ct->tuplehash[!dir].tuple.src.u3,
1304                   &ct->tuplehash[!dir].tuple.dst.u3,
1305                   priv->l4proto, NULL, &priv->dport);
1306     exp->timeout.expires = jiffies + priv->timeout * HZ;
1307 
1308     if (nf_ct_expect_related(exp, 0) != 0)
1309         regs->verdict.code = NF_DROP;
1310 }
1311 
1312 static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX + 1] = {
1313     [NFTA_CT_EXPECT_L3PROTO]    = { .type = NLA_U16 },
1314     [NFTA_CT_EXPECT_L4PROTO]    = { .type = NLA_U8 },
1315     [NFTA_CT_EXPECT_DPORT]      = { .type = NLA_U16 },
1316     [NFTA_CT_EXPECT_TIMEOUT]    = { .type = NLA_U32 },
1317     [NFTA_CT_EXPECT_SIZE]       = { .type = NLA_U8 },
1318 };
1319 
1320 static struct nft_object_type nft_ct_expect_obj_type;
1321 
1322 static const struct nft_object_ops nft_ct_expect_obj_ops = {
1323     .type       = &nft_ct_expect_obj_type,
1324     .size       = sizeof(struct nft_ct_expect_obj),
1325     .eval       = nft_ct_expect_obj_eval,
1326     .init       = nft_ct_expect_obj_init,
1327     .destroy    = nft_ct_expect_obj_destroy,
1328     .dump       = nft_ct_expect_obj_dump,
1329 };
1330 
1331 static struct nft_object_type nft_ct_expect_obj_type __read_mostly = {
1332     .type       = NFT_OBJECT_CT_EXPECT,
1333     .ops        = &nft_ct_expect_obj_ops,
1334     .maxattr    = NFTA_CT_EXPECT_MAX,
1335     .policy     = nft_ct_expect_policy,
1336     .owner      = THIS_MODULE,
1337 };
1338 
1339 static int __init nft_ct_module_init(void)
1340 {
1341     int err;
1342 
1343     BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > NFT_REG_SIZE);
1344 
1345     err = nft_register_expr(&nft_ct_type);
1346     if (err < 0)
1347         return err;
1348 
1349     err = nft_register_expr(&nft_notrack_type);
1350     if (err < 0)
1351         goto err1;
1352 
1353     err = nft_register_obj(&nft_ct_helper_obj_type);
1354     if (err < 0)
1355         goto err2;
1356 
1357     err = nft_register_obj(&nft_ct_expect_obj_type);
1358     if (err < 0)
1359         goto err3;
1360 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1361     err = nft_register_obj(&nft_ct_timeout_obj_type);
1362     if (err < 0)
1363         goto err4;
1364 #endif
1365     return 0;
1366 
1367 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1368 err4:
1369     nft_unregister_obj(&nft_ct_expect_obj_type);
1370 #endif
1371 err3:
1372     nft_unregister_obj(&nft_ct_helper_obj_type);
1373 err2:
1374     nft_unregister_expr(&nft_notrack_type);
1375 err1:
1376     nft_unregister_expr(&nft_ct_type);
1377     return err;
1378 }
1379 
1380 static void __exit nft_ct_module_exit(void)
1381 {
1382 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1383     nft_unregister_obj(&nft_ct_timeout_obj_type);
1384 #endif
1385     nft_unregister_obj(&nft_ct_expect_obj_type);
1386     nft_unregister_obj(&nft_ct_helper_obj_type);
1387     nft_unregister_expr(&nft_notrack_type);
1388     nft_unregister_expr(&nft_ct_type);
1389 }
1390 
1391 module_init(nft_ct_module_init);
1392 module_exit(nft_ct_module_exit);
1393 
1394 MODULE_LICENSE("GPL");
1395 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
1396 MODULE_ALIAS_NFT_EXPR("ct");
1397 MODULE_ALIAS_NFT_EXPR("notrack");
1398 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER);
1399 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT);
1400 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_EXPECT);
1401 MODULE_DESCRIPTION("Netfilter nf_tables conntrack module");