cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nft_ct.c (33589B)


      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");