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

conntrack.c (53013B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
      2/* Copyright (C) 2021 Corigine, Inc. */
      3
      4#include "conntrack.h"
      5#include "../nfp_port.h"
      6
      7const struct rhashtable_params nfp_tc_ct_merge_params = {
      8	.head_offset		= offsetof(struct nfp_fl_ct_tc_merge,
      9					   hash_node),
     10	.key_len		= sizeof(unsigned long) * 2,
     11	.key_offset		= offsetof(struct nfp_fl_ct_tc_merge, cookie),
     12	.automatic_shrinking	= true,
     13};
     14
     15const struct rhashtable_params nfp_nft_ct_merge_params = {
     16	.head_offset		= offsetof(struct nfp_fl_nft_tc_merge,
     17					   hash_node),
     18	.key_len		= sizeof(unsigned long) * 3,
     19	.key_offset		= offsetof(struct nfp_fl_nft_tc_merge, cookie),
     20	.automatic_shrinking	= true,
     21};
     22
     23static struct flow_action_entry *get_flow_act(struct flow_rule *rule,
     24					      enum flow_action_id act_id);
     25
     26/**
     27 * get_hashentry() - Wrapper around hashtable lookup.
     28 * @ht:		hashtable where entry could be found
     29 * @key:	key to lookup
     30 * @params:	hashtable params
     31 * @size:	size of entry to allocate if not in table
     32 *
     33 * Returns an entry from a hashtable. If entry does not exist
     34 * yet allocate the memory for it and return the new entry.
     35 */
     36static void *get_hashentry(struct rhashtable *ht, void *key,
     37			   const struct rhashtable_params params, size_t size)
     38{
     39	void *result;
     40
     41	result = rhashtable_lookup_fast(ht, key, params);
     42
     43	if (result)
     44		return result;
     45
     46	result = kzalloc(size, GFP_KERNEL);
     47	if (!result)
     48		return ERR_PTR(-ENOMEM);
     49
     50	return result;
     51}
     52
     53bool is_pre_ct_flow(struct flow_cls_offload *flow)
     54{
     55	struct flow_action_entry *act;
     56	int i;
     57
     58	flow_action_for_each(i, act, &flow->rule->action) {
     59		if (act->id == FLOW_ACTION_CT && !act->ct.action)
     60			return true;
     61	}
     62	return false;
     63}
     64
     65bool is_post_ct_flow(struct flow_cls_offload *flow)
     66{
     67	struct flow_rule *rule = flow_cls_offload_flow_rule(flow);
     68	struct flow_dissector *dissector = rule->match.dissector;
     69	struct flow_match_ct ct;
     70
     71	if (dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CT)) {
     72		flow_rule_match_ct(rule, &ct);
     73		if (ct.key->ct_state & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED)
     74			return true;
     75	}
     76	return false;
     77}
     78
     79/**
     80 * get_mangled_key() - Mangle the key if mangle act exists
     81 * @rule:	rule that carries the actions
     82 * @buf:	pointer to key to be mangled
     83 * @offset:	used to adjust mangled offset in L2/L3/L4 header
     84 * @key_sz:	key size
     85 * @htype:	mangling type
     86 *
     87 * Returns buf where the mangled key stores.
     88 */
     89static void *get_mangled_key(struct flow_rule *rule, void *buf,
     90			     u32 offset, size_t key_sz,
     91			     enum flow_action_mangle_base htype)
     92{
     93	struct flow_action_entry *act;
     94	u32 *val = (u32 *)buf;
     95	u32 off, msk, key;
     96	int i;
     97
     98	flow_action_for_each(i, act, &rule->action) {
     99		if (act->id == FLOW_ACTION_MANGLE &&
    100		    act->mangle.htype == htype) {
    101			off = act->mangle.offset - offset;
    102			msk = act->mangle.mask;
    103			key = act->mangle.val;
    104
    105			/* Mangling is supposed to be u32 aligned */
    106			if (off % 4 || off >= key_sz)
    107				continue;
    108
    109			val[off >> 2] &= msk;
    110			val[off >> 2] |= key;
    111		}
    112	}
    113
    114	return buf;
    115}
    116
    117/* Only tos and ttl are involved in flow_match_ip structure, which
    118 * doesn't conform to the layout of ip/ipv6 header definition. So
    119 * they need particular process here: fill them into the ip/ipv6
    120 * header, so that mangling actions can work directly.
    121 */
    122#define NFP_IPV4_TOS_MASK	GENMASK(23, 16)
    123#define NFP_IPV4_TTL_MASK	GENMASK(31, 24)
    124#define NFP_IPV6_TCLASS_MASK	GENMASK(27, 20)
    125#define NFP_IPV6_HLIMIT_MASK	GENMASK(7, 0)
    126static void *get_mangled_tos_ttl(struct flow_rule *rule, void *buf,
    127				 bool is_v6)
    128{
    129	struct flow_match_ip match;
    130	/* IPv4's ttl field is in third dword. */
    131	__be32 ip_hdr[3];
    132	u32 tmp, hdr_len;
    133
    134	flow_rule_match_ip(rule, &match);
    135
    136	if (is_v6) {
    137		tmp = FIELD_PREP(NFP_IPV6_TCLASS_MASK, match.key->tos);
    138		ip_hdr[0] = cpu_to_be32(tmp);
    139		tmp = FIELD_PREP(NFP_IPV6_HLIMIT_MASK, match.key->ttl);
    140		ip_hdr[1] = cpu_to_be32(tmp);
    141		hdr_len = 2 * sizeof(__be32);
    142	} else {
    143		tmp = FIELD_PREP(NFP_IPV4_TOS_MASK, match.key->tos);
    144		ip_hdr[0] = cpu_to_be32(tmp);
    145		tmp = FIELD_PREP(NFP_IPV4_TTL_MASK, match.key->ttl);
    146		ip_hdr[2] = cpu_to_be32(tmp);
    147		hdr_len = 3 * sizeof(__be32);
    148	}
    149
    150	get_mangled_key(rule, ip_hdr, 0, hdr_len,
    151			is_v6 ? FLOW_ACT_MANGLE_HDR_TYPE_IP6 :
    152				FLOW_ACT_MANGLE_HDR_TYPE_IP4);
    153
    154	match.key = buf;
    155
    156	if (is_v6) {
    157		tmp = be32_to_cpu(ip_hdr[0]);
    158		match.key->tos = FIELD_GET(NFP_IPV6_TCLASS_MASK, tmp);
    159		tmp = be32_to_cpu(ip_hdr[1]);
    160		match.key->ttl = FIELD_GET(NFP_IPV6_HLIMIT_MASK, tmp);
    161	} else {
    162		tmp = be32_to_cpu(ip_hdr[0]);
    163		match.key->tos = FIELD_GET(NFP_IPV4_TOS_MASK, tmp);
    164		tmp = be32_to_cpu(ip_hdr[2]);
    165		match.key->ttl = FIELD_GET(NFP_IPV4_TTL_MASK, tmp);
    166	}
    167
    168	return buf;
    169}
    170
    171/* Note entry1 and entry2 are not swappable, entry1 should be
    172 * the former flow whose mangle action need be taken into account
    173 * if existed, and entry2 should be the latter flow whose action
    174 * we don't care.
    175 */
    176static int nfp_ct_merge_check(struct nfp_fl_ct_flow_entry *entry1,
    177			      struct nfp_fl_ct_flow_entry *entry2)
    178{
    179	unsigned int ovlp_keys = entry1->rule->match.dissector->used_keys &
    180				 entry2->rule->match.dissector->used_keys;
    181	bool out, is_v6 = false;
    182	u8 ip_proto = 0;
    183	/* Temporary buffer for mangling keys, 64 is enough to cover max
    184	 * struct size of key in various fields that may be mangled.
    185	 * Supported fileds to mangle:
    186	 * mac_src/mac_dst(struct flow_match_eth_addrs, 12B)
    187	 * nw_tos/nw_ttl(struct flow_match_ip, 2B)
    188	 * nw_src/nw_dst(struct flow_match_ipv4/6_addrs, 32B)
    189	 * tp_src/tp_dst(struct flow_match_ports, 4B)
    190	 */
    191	char buf[64];
    192
    193	if (entry1->netdev && entry2->netdev &&
    194	    entry1->netdev != entry2->netdev)
    195		return -EINVAL;
    196
    197	/* check the overlapped fields one by one, the unmasked part
    198	 * should not conflict with each other.
    199	 */
    200	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) {
    201		struct flow_match_control match1, match2;
    202
    203		flow_rule_match_control(entry1->rule, &match1);
    204		flow_rule_match_control(entry2->rule, &match2);
    205		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    206		if (out)
    207			goto check_failed;
    208	}
    209
    210	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) {
    211		struct flow_match_basic match1, match2;
    212
    213		flow_rule_match_basic(entry1->rule, &match1);
    214		flow_rule_match_basic(entry2->rule, &match2);
    215
    216		/* n_proto field is a must in ct-related flows,
    217		 * it should be either ipv4 or ipv6.
    218		 */
    219		is_v6 = match1.key->n_proto == htons(ETH_P_IPV6);
    220		/* ip_proto field is a must when port field is cared */
    221		ip_proto = match1.key->ip_proto;
    222
    223		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    224		if (out)
    225			goto check_failed;
    226	}
    227
    228	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
    229		struct flow_match_ipv4_addrs match1, match2;
    230
    231		flow_rule_match_ipv4_addrs(entry1->rule, &match1);
    232		flow_rule_match_ipv4_addrs(entry2->rule, &match2);
    233
    234		memcpy(buf, match1.key, sizeof(*match1.key));
    235		match1.key = get_mangled_key(entry1->rule, buf,
    236					     offsetof(struct iphdr, saddr),
    237					     sizeof(*match1.key),
    238					     FLOW_ACT_MANGLE_HDR_TYPE_IP4);
    239
    240		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    241		if (out)
    242			goto check_failed;
    243	}
    244
    245	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
    246		struct flow_match_ipv6_addrs match1, match2;
    247
    248		flow_rule_match_ipv6_addrs(entry1->rule, &match1);
    249		flow_rule_match_ipv6_addrs(entry2->rule, &match2);
    250
    251		memcpy(buf, match1.key, sizeof(*match1.key));
    252		match1.key = get_mangled_key(entry1->rule, buf,
    253					     offsetof(struct ipv6hdr, saddr),
    254					     sizeof(*match1.key),
    255					     FLOW_ACT_MANGLE_HDR_TYPE_IP6);
    256
    257		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    258		if (out)
    259			goto check_failed;
    260	}
    261
    262	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_PORTS)) {
    263		enum flow_action_mangle_base htype = FLOW_ACT_MANGLE_UNSPEC;
    264		struct flow_match_ports match1, match2;
    265
    266		flow_rule_match_ports(entry1->rule, &match1);
    267		flow_rule_match_ports(entry2->rule, &match2);
    268
    269		if (ip_proto == IPPROTO_UDP)
    270			htype = FLOW_ACT_MANGLE_HDR_TYPE_UDP;
    271		else if (ip_proto == IPPROTO_TCP)
    272			htype = FLOW_ACT_MANGLE_HDR_TYPE_TCP;
    273
    274		memcpy(buf, match1.key, sizeof(*match1.key));
    275		match1.key = get_mangled_key(entry1->rule, buf, 0,
    276					     sizeof(*match1.key), htype);
    277
    278		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    279		if (out)
    280			goto check_failed;
    281	}
    282
    283	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
    284		struct flow_match_eth_addrs match1, match2;
    285
    286		flow_rule_match_eth_addrs(entry1->rule, &match1);
    287		flow_rule_match_eth_addrs(entry2->rule, &match2);
    288
    289		memcpy(buf, match1.key, sizeof(*match1.key));
    290		match1.key = get_mangled_key(entry1->rule, buf, 0,
    291					     sizeof(*match1.key),
    292					     FLOW_ACT_MANGLE_HDR_TYPE_ETH);
    293
    294		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    295		if (out)
    296			goto check_failed;
    297	}
    298
    299	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_VLAN)) {
    300		struct flow_match_vlan match1, match2;
    301
    302		flow_rule_match_vlan(entry1->rule, &match1);
    303		flow_rule_match_vlan(entry2->rule, &match2);
    304		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    305		if (out)
    306			goto check_failed;
    307	}
    308
    309	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_MPLS)) {
    310		struct flow_match_mpls match1, match2;
    311
    312		flow_rule_match_mpls(entry1->rule, &match1);
    313		flow_rule_match_mpls(entry2->rule, &match2);
    314		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    315		if (out)
    316			goto check_failed;
    317	}
    318
    319	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_TCP)) {
    320		struct flow_match_tcp match1, match2;
    321
    322		flow_rule_match_tcp(entry1->rule, &match1);
    323		flow_rule_match_tcp(entry2->rule, &match2);
    324		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    325		if (out)
    326			goto check_failed;
    327	}
    328
    329	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_IP)) {
    330		struct flow_match_ip match1, match2;
    331
    332		flow_rule_match_ip(entry1->rule, &match1);
    333		flow_rule_match_ip(entry2->rule, &match2);
    334
    335		match1.key = get_mangled_tos_ttl(entry1->rule, buf, is_v6);
    336		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    337		if (out)
    338			goto check_failed;
    339	}
    340
    341	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_ENC_KEYID)) {
    342		struct flow_match_enc_keyid match1, match2;
    343
    344		flow_rule_match_enc_keyid(entry1->rule, &match1);
    345		flow_rule_match_enc_keyid(entry2->rule, &match2);
    346		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    347		if (out)
    348			goto check_failed;
    349	}
    350
    351	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
    352		struct flow_match_ipv4_addrs match1, match2;
    353
    354		flow_rule_match_enc_ipv4_addrs(entry1->rule, &match1);
    355		flow_rule_match_enc_ipv4_addrs(entry2->rule, &match2);
    356		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    357		if (out)
    358			goto check_failed;
    359	}
    360
    361	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
    362		struct flow_match_ipv6_addrs match1, match2;
    363
    364		flow_rule_match_enc_ipv6_addrs(entry1->rule, &match1);
    365		flow_rule_match_enc_ipv6_addrs(entry2->rule, &match2);
    366		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    367		if (out)
    368			goto check_failed;
    369	}
    370
    371	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
    372		struct flow_match_control match1, match2;
    373
    374		flow_rule_match_enc_control(entry1->rule, &match1);
    375		flow_rule_match_enc_control(entry2->rule, &match2);
    376		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    377		if (out)
    378			goto check_failed;
    379	}
    380
    381	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_ENC_IP)) {
    382		struct flow_match_ip match1, match2;
    383
    384		flow_rule_match_enc_ip(entry1->rule, &match1);
    385		flow_rule_match_enc_ip(entry2->rule, &match2);
    386		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    387		if (out)
    388			goto check_failed;
    389	}
    390
    391	if (ovlp_keys & BIT(FLOW_DISSECTOR_KEY_ENC_OPTS)) {
    392		struct flow_match_enc_opts match1, match2;
    393
    394		flow_rule_match_enc_opts(entry1->rule, &match1);
    395		flow_rule_match_enc_opts(entry2->rule, &match2);
    396		COMPARE_UNMASKED_FIELDS(match1, match2, &out);
    397		if (out)
    398			goto check_failed;
    399	}
    400
    401	return 0;
    402
    403check_failed:
    404	return -EINVAL;
    405}
    406
    407static int nfp_ct_merge_act_check(struct nfp_fl_ct_flow_entry *pre_ct_entry,
    408				  struct nfp_fl_ct_flow_entry *post_ct_entry,
    409				  struct nfp_fl_ct_flow_entry *nft_entry)
    410{
    411	struct flow_action_entry *act;
    412	int i;
    413
    414	/* Check for pre_ct->action conflicts */
    415	flow_action_for_each(i, act, &pre_ct_entry->rule->action) {
    416		switch (act->id) {
    417		case FLOW_ACTION_VLAN_PUSH:
    418		case FLOW_ACTION_VLAN_POP:
    419		case FLOW_ACTION_VLAN_MANGLE:
    420		case FLOW_ACTION_MPLS_PUSH:
    421		case FLOW_ACTION_MPLS_POP:
    422		case FLOW_ACTION_MPLS_MANGLE:
    423			return -EOPNOTSUPP;
    424		default:
    425			break;
    426		}
    427	}
    428
    429	/* Check for nft->action conflicts */
    430	flow_action_for_each(i, act, &nft_entry->rule->action) {
    431		switch (act->id) {
    432		case FLOW_ACTION_VLAN_PUSH:
    433		case FLOW_ACTION_VLAN_POP:
    434		case FLOW_ACTION_VLAN_MANGLE:
    435		case FLOW_ACTION_MPLS_PUSH:
    436		case FLOW_ACTION_MPLS_POP:
    437		case FLOW_ACTION_MPLS_MANGLE:
    438			return -EOPNOTSUPP;
    439		default:
    440			break;
    441		}
    442	}
    443	return 0;
    444}
    445
    446static int nfp_ct_check_meta(struct nfp_fl_ct_flow_entry *post_ct_entry,
    447			     struct nfp_fl_ct_flow_entry *nft_entry)
    448{
    449	struct flow_dissector *dissector = post_ct_entry->rule->match.dissector;
    450	struct flow_action_entry *ct_met;
    451	struct flow_match_ct ct;
    452	int i;
    453
    454	ct_met = get_flow_act(nft_entry->rule, FLOW_ACTION_CT_METADATA);
    455	if (ct_met && (dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CT))) {
    456		u32 *act_lbl;
    457
    458		act_lbl = ct_met->ct_metadata.labels;
    459		flow_rule_match_ct(post_ct_entry->rule, &ct);
    460		for (i = 0; i < 4; i++) {
    461			if ((ct.key->ct_labels[i] & ct.mask->ct_labels[i]) ^
    462			    (act_lbl[i] & ct.mask->ct_labels[i]))
    463				return -EINVAL;
    464		}
    465
    466		if ((ct.key->ct_mark & ct.mask->ct_mark) ^
    467		    (ct_met->ct_metadata.mark & ct.mask->ct_mark))
    468			return -EINVAL;
    469
    470		return 0;
    471	}
    472
    473	return -EINVAL;
    474}
    475
    476static int
    477nfp_fl_calc_key_layers_sz(struct nfp_fl_key_ls in_key_ls, uint16_t *map)
    478{
    479	int key_size;
    480
    481	/* This field must always be present */
    482	key_size = sizeof(struct nfp_flower_meta_tci);
    483	map[FLOW_PAY_META_TCI] = 0;
    484
    485	if (in_key_ls.key_layer & NFP_FLOWER_LAYER_EXT_META) {
    486		map[FLOW_PAY_EXT_META] = key_size;
    487		key_size += sizeof(struct nfp_flower_ext_meta);
    488	}
    489	if (in_key_ls.key_layer & NFP_FLOWER_LAYER_PORT) {
    490		map[FLOW_PAY_INPORT] = key_size;
    491		key_size += sizeof(struct nfp_flower_in_port);
    492	}
    493	if (in_key_ls.key_layer & NFP_FLOWER_LAYER_MAC) {
    494		map[FLOW_PAY_MAC_MPLS] = key_size;
    495		key_size += sizeof(struct nfp_flower_mac_mpls);
    496	}
    497	if (in_key_ls.key_layer & NFP_FLOWER_LAYER_TP) {
    498		map[FLOW_PAY_L4] = key_size;
    499		key_size += sizeof(struct nfp_flower_tp_ports);
    500	}
    501	if (in_key_ls.key_layer & NFP_FLOWER_LAYER_IPV4) {
    502		map[FLOW_PAY_IPV4] = key_size;
    503		key_size += sizeof(struct nfp_flower_ipv4);
    504	}
    505	if (in_key_ls.key_layer & NFP_FLOWER_LAYER_IPV6) {
    506		map[FLOW_PAY_IPV6] = key_size;
    507		key_size += sizeof(struct nfp_flower_ipv6);
    508	}
    509
    510	if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_QINQ) {
    511		map[FLOW_PAY_QINQ] = key_size;
    512		key_size += sizeof(struct nfp_flower_vlan);
    513	}
    514
    515	if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_GRE) {
    516		map[FLOW_PAY_GRE] = key_size;
    517		if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6)
    518			key_size += sizeof(struct nfp_flower_ipv6_gre_tun);
    519		else
    520			key_size += sizeof(struct nfp_flower_ipv4_gre_tun);
    521	}
    522
    523	if ((in_key_ls.key_layer & NFP_FLOWER_LAYER_VXLAN) ||
    524	    (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_GENEVE)) {
    525		map[FLOW_PAY_UDP_TUN] = key_size;
    526		if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6)
    527			key_size += sizeof(struct nfp_flower_ipv6_udp_tun);
    528		else
    529			key_size += sizeof(struct nfp_flower_ipv4_udp_tun);
    530	}
    531
    532	if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_GENEVE_OP) {
    533		map[FLOW_PAY_GENEVE_OPT] = key_size;
    534		key_size += sizeof(struct nfp_flower_geneve_options);
    535	}
    536
    537	return key_size;
    538}
    539
    540static int nfp_fl_merge_actions_offload(struct flow_rule **rules,
    541					struct nfp_flower_priv *priv,
    542					struct net_device *netdev,
    543					struct nfp_fl_payload *flow_pay)
    544{
    545	struct flow_action_entry *a_in;
    546	int i, j, num_actions, id;
    547	struct flow_rule *a_rule;
    548	int err = 0, offset = 0;
    549
    550	num_actions = rules[CT_TYPE_PRE_CT]->action.num_entries +
    551		      rules[CT_TYPE_NFT]->action.num_entries +
    552		      rules[CT_TYPE_POST_CT]->action.num_entries;
    553
    554	a_rule = flow_rule_alloc(num_actions);
    555	if (!a_rule)
    556		return -ENOMEM;
    557
    558	/* Actions need a BASIC dissector. */
    559	a_rule->match = rules[CT_TYPE_PRE_CT]->match;
    560
    561	/* Copy actions */
    562	for (j = 0; j < _CT_TYPE_MAX; j++) {
    563		if (flow_rule_match_key(rules[j], FLOW_DISSECTOR_KEY_BASIC)) {
    564			struct flow_match_basic match;
    565
    566			/* ip_proto is the only field that needed in later compile_action,
    567			 * needed to set the correct checksum flags. It doesn't really matter
    568			 * which input rule's ip_proto field we take as the earlier merge checks
    569			 * would have made sure that they don't conflict. We do not know which
    570			 * of the subflows would have the ip_proto filled in, so we need to iterate
    571			 * through the subflows and assign the proper subflow to a_rule
    572			 */
    573			flow_rule_match_basic(rules[j], &match);
    574			if (match.mask->ip_proto)
    575				a_rule->match = rules[j]->match;
    576		}
    577
    578		for (i = 0; i < rules[j]->action.num_entries; i++) {
    579			a_in = &rules[j]->action.entries[i];
    580			id = a_in->id;
    581
    582			/* Ignore CT related actions as these would already have
    583			 * been taken care of by previous checks, and we do not send
    584			 * any CT actions to the firmware.
    585			 */
    586			switch (id) {
    587			case FLOW_ACTION_CT:
    588			case FLOW_ACTION_GOTO:
    589			case FLOW_ACTION_CT_METADATA:
    590				continue;
    591			default:
    592				memcpy(&a_rule->action.entries[offset++],
    593				       a_in, sizeof(struct flow_action_entry));
    594				break;
    595			}
    596		}
    597	}
    598
    599	/* Some actions would have been ignored, so update the num_entries field */
    600	a_rule->action.num_entries = offset;
    601	err = nfp_flower_compile_action(priv->app, a_rule, netdev, flow_pay, NULL);
    602	kfree(a_rule);
    603
    604	return err;
    605}
    606
    607static int nfp_fl_ct_add_offload(struct nfp_fl_nft_tc_merge *m_entry)
    608{
    609	enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
    610	struct nfp_fl_ct_zone_entry *zt = m_entry->zt;
    611	struct nfp_fl_key_ls key_layer, tmp_layer;
    612	struct nfp_flower_priv *priv = zt->priv;
    613	u16 key_map[_FLOW_PAY_LAYERS_MAX];
    614	struct nfp_fl_payload *flow_pay;
    615
    616	struct flow_rule *rules[_CT_TYPE_MAX];
    617	u8 *key, *msk, *kdata, *mdata;
    618	struct nfp_port *port = NULL;
    619	struct net_device *netdev;
    620	bool qinq_sup;
    621	u32 port_id;
    622	u16 offset;
    623	int i, err;
    624
    625	netdev = m_entry->netdev;
    626	qinq_sup = !!(priv->flower_ext_feats & NFP_FL_FEATS_VLAN_QINQ);
    627
    628	rules[CT_TYPE_PRE_CT] = m_entry->tc_m_parent->pre_ct_parent->rule;
    629	rules[CT_TYPE_NFT] = m_entry->nft_parent->rule;
    630	rules[CT_TYPE_POST_CT] = m_entry->tc_m_parent->post_ct_parent->rule;
    631
    632	memset(&key_layer, 0, sizeof(struct nfp_fl_key_ls));
    633	memset(&key_map, 0, sizeof(key_map));
    634
    635	/* Calculate the resultant key layer and size for offload */
    636	for (i = 0; i < _CT_TYPE_MAX; i++) {
    637		err = nfp_flower_calculate_key_layers(priv->app,
    638						      m_entry->netdev,
    639						      &tmp_layer, rules[i],
    640						      &tun_type, NULL);
    641		if (err)
    642			return err;
    643
    644		key_layer.key_layer |= tmp_layer.key_layer;
    645		key_layer.key_layer_two |= tmp_layer.key_layer_two;
    646	}
    647	key_layer.key_size = nfp_fl_calc_key_layers_sz(key_layer, key_map);
    648
    649	flow_pay = nfp_flower_allocate_new(&key_layer);
    650	if (!flow_pay)
    651		return -ENOMEM;
    652
    653	memset(flow_pay->unmasked_data, 0, key_layer.key_size);
    654	memset(flow_pay->mask_data, 0, key_layer.key_size);
    655
    656	kdata = flow_pay->unmasked_data;
    657	mdata = flow_pay->mask_data;
    658
    659	offset = key_map[FLOW_PAY_META_TCI];
    660	key = kdata + offset;
    661	msk = mdata + offset;
    662	nfp_flower_compile_meta((struct nfp_flower_meta_tci *)key,
    663				(struct nfp_flower_meta_tci *)msk,
    664				key_layer.key_layer);
    665
    666	if (NFP_FLOWER_LAYER_EXT_META & key_layer.key_layer) {
    667		offset =  key_map[FLOW_PAY_EXT_META];
    668		key = kdata + offset;
    669		msk = mdata + offset;
    670		nfp_flower_compile_ext_meta((struct nfp_flower_ext_meta *)key,
    671					    key_layer.key_layer_two);
    672		nfp_flower_compile_ext_meta((struct nfp_flower_ext_meta *)msk,
    673					    key_layer.key_layer_two);
    674	}
    675
    676	/* Using in_port from the -trk rule. The tc merge checks should already
    677	 * be checking that the ingress netdevs are the same
    678	 */
    679	port_id = nfp_flower_get_port_id_from_netdev(priv->app, netdev);
    680	offset = key_map[FLOW_PAY_INPORT];
    681	key = kdata + offset;
    682	msk = mdata + offset;
    683	err = nfp_flower_compile_port((struct nfp_flower_in_port *)key,
    684				      port_id, false, tun_type, NULL);
    685	if (err)
    686		goto ct_offload_err;
    687	err = nfp_flower_compile_port((struct nfp_flower_in_port *)msk,
    688				      port_id, true, tun_type, NULL);
    689	if (err)
    690		goto ct_offload_err;
    691
    692	/* This following part works on the assumption that previous checks has
    693	 * already filtered out flows that has different values for the different
    694	 * layers. Here we iterate through all three rules and merge their respective
    695	 * masked value(cared bits), basic method is:
    696	 * final_key = (r1_key & r1_mask) | (r2_key & r2_mask) | (r3_key & r3_mask)
    697	 * final_mask = r1_mask | r2_mask | r3_mask
    698	 * If none of the rules contains a match that is also fine, that simply means
    699	 * that the layer is not present.
    700	 */
    701	if (!qinq_sup) {
    702		for (i = 0; i < _CT_TYPE_MAX; i++) {
    703			offset = key_map[FLOW_PAY_META_TCI];
    704			key = kdata + offset;
    705			msk = mdata + offset;
    706			nfp_flower_compile_tci((struct nfp_flower_meta_tci *)key,
    707					       (struct nfp_flower_meta_tci *)msk,
    708					       rules[i]);
    709		}
    710	}
    711
    712	if (NFP_FLOWER_LAYER_MAC & key_layer.key_layer) {
    713		offset = key_map[FLOW_PAY_MAC_MPLS];
    714		key = kdata + offset;
    715		msk = mdata + offset;
    716		for (i = 0; i < _CT_TYPE_MAX; i++) {
    717			nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)key,
    718					       (struct nfp_flower_mac_mpls *)msk,
    719					       rules[i]);
    720			err = nfp_flower_compile_mpls((struct nfp_flower_mac_mpls *)key,
    721						      (struct nfp_flower_mac_mpls *)msk,
    722						      rules[i], NULL);
    723			if (err)
    724				goto ct_offload_err;
    725		}
    726	}
    727
    728	if (NFP_FLOWER_LAYER_IPV4 & key_layer.key_layer) {
    729		offset = key_map[FLOW_PAY_IPV4];
    730		key = kdata + offset;
    731		msk = mdata + offset;
    732		for (i = 0; i < _CT_TYPE_MAX; i++) {
    733			nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)key,
    734						(struct nfp_flower_ipv4 *)msk,
    735						rules[i]);
    736		}
    737	}
    738
    739	if (NFP_FLOWER_LAYER_IPV6 & key_layer.key_layer) {
    740		offset = key_map[FLOW_PAY_IPV6];
    741		key = kdata + offset;
    742		msk = mdata + offset;
    743		for (i = 0; i < _CT_TYPE_MAX; i++) {
    744			nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)key,
    745						(struct nfp_flower_ipv6 *)msk,
    746						rules[i]);
    747		}
    748	}
    749
    750	if (NFP_FLOWER_LAYER_TP & key_layer.key_layer) {
    751		offset = key_map[FLOW_PAY_L4];
    752		key = kdata + offset;
    753		msk = mdata + offset;
    754		for (i = 0; i < _CT_TYPE_MAX; i++) {
    755			nfp_flower_compile_tport((struct nfp_flower_tp_ports *)key,
    756						 (struct nfp_flower_tp_ports *)msk,
    757						 rules[i]);
    758		}
    759	}
    760
    761	if (NFP_FLOWER_LAYER2_QINQ & key_layer.key_layer_two) {
    762		offset = key_map[FLOW_PAY_QINQ];
    763		key = kdata + offset;
    764		msk = mdata + offset;
    765		for (i = 0; i < _CT_TYPE_MAX; i++) {
    766			nfp_flower_compile_vlan((struct nfp_flower_vlan *)key,
    767						(struct nfp_flower_vlan *)msk,
    768						rules[i]);
    769		}
    770	}
    771
    772	if (key_layer.key_layer_two & NFP_FLOWER_LAYER2_GRE) {
    773		offset = key_map[FLOW_PAY_GRE];
    774		key = kdata + offset;
    775		msk = mdata + offset;
    776		if (key_layer.key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) {
    777			struct nfp_flower_ipv6_gre_tun *gre_match;
    778			struct nfp_ipv6_addr_entry *entry;
    779			struct in6_addr *dst;
    780
    781			for (i = 0; i < _CT_TYPE_MAX; i++) {
    782				nfp_flower_compile_ipv6_gre_tun((void *)key,
    783								(void *)msk, rules[i]);
    784			}
    785			gre_match = (struct nfp_flower_ipv6_gre_tun *)key;
    786			dst = &gre_match->ipv6.dst;
    787
    788			entry = nfp_tunnel_add_ipv6_off(priv->app, dst);
    789			if (!entry) {
    790				err = -ENOMEM;
    791				goto ct_offload_err;
    792			}
    793
    794			flow_pay->nfp_tun_ipv6 = entry;
    795		} else {
    796			__be32 dst;
    797
    798			for (i = 0; i < _CT_TYPE_MAX; i++) {
    799				nfp_flower_compile_ipv4_gre_tun((void *)key,
    800								(void *)msk, rules[i]);
    801			}
    802			dst = ((struct nfp_flower_ipv4_gre_tun *)key)->ipv4.dst;
    803
    804			/* Store the tunnel destination in the rule data.
    805			 * This must be present and be an exact match.
    806			 */
    807			flow_pay->nfp_tun_ipv4_addr = dst;
    808			nfp_tunnel_add_ipv4_off(priv->app, dst);
    809		}
    810	}
    811
    812	if (key_layer.key_layer & NFP_FLOWER_LAYER_VXLAN ||
    813	    key_layer.key_layer_two & NFP_FLOWER_LAYER2_GENEVE) {
    814		offset = key_map[FLOW_PAY_UDP_TUN];
    815		key = kdata + offset;
    816		msk = mdata + offset;
    817		if (key_layer.key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) {
    818			struct nfp_flower_ipv6_udp_tun *udp_match;
    819			struct nfp_ipv6_addr_entry *entry;
    820			struct in6_addr *dst;
    821
    822			for (i = 0; i < _CT_TYPE_MAX; i++) {
    823				nfp_flower_compile_ipv6_udp_tun((void *)key,
    824								(void *)msk, rules[i]);
    825			}
    826			udp_match = (struct nfp_flower_ipv6_udp_tun *)key;
    827			dst = &udp_match->ipv6.dst;
    828
    829			entry = nfp_tunnel_add_ipv6_off(priv->app, dst);
    830			if (!entry) {
    831				err = -ENOMEM;
    832				goto ct_offload_err;
    833			}
    834
    835			flow_pay->nfp_tun_ipv6 = entry;
    836		} else {
    837			__be32 dst;
    838
    839			for (i = 0; i < _CT_TYPE_MAX; i++) {
    840				nfp_flower_compile_ipv4_udp_tun((void *)key,
    841								(void *)msk, rules[i]);
    842			}
    843			dst = ((struct nfp_flower_ipv4_udp_tun *)key)->ipv4.dst;
    844
    845			/* Store the tunnel destination in the rule data.
    846			 * This must be present and be an exact match.
    847			 */
    848			flow_pay->nfp_tun_ipv4_addr = dst;
    849			nfp_tunnel_add_ipv4_off(priv->app, dst);
    850		}
    851
    852		if (key_layer.key_layer_two & NFP_FLOWER_LAYER2_GENEVE_OP) {
    853			offset = key_map[FLOW_PAY_GENEVE_OPT];
    854			key = kdata + offset;
    855			msk = mdata + offset;
    856			for (i = 0; i < _CT_TYPE_MAX; i++)
    857				nfp_flower_compile_geneve_opt(key, msk, rules[i]);
    858		}
    859	}
    860
    861	/* Merge actions into flow_pay */
    862	err = nfp_fl_merge_actions_offload(rules, priv, netdev, flow_pay);
    863	if (err)
    864		goto ct_offload_err;
    865
    866	/* Use the pointer address as the cookie, but set the last bit to 1.
    867	 * This is to avoid the 'is_merge_flow' check from detecting this as
    868	 * an already merged flow. This works since address alignment means
    869	 * that the last bit for pointer addresses will be 0.
    870	 */
    871	flow_pay->tc_flower_cookie = ((unsigned long)flow_pay) | 0x1;
    872	err = nfp_compile_flow_metadata(priv->app, flow_pay->tc_flower_cookie,
    873					flow_pay, netdev, NULL);
    874	if (err)
    875		goto ct_offload_err;
    876
    877	if (nfp_netdev_is_nfp_repr(netdev))
    878		port = nfp_port_from_netdev(netdev);
    879
    880	err = rhashtable_insert_fast(&priv->flow_table, &flow_pay->fl_node,
    881				     nfp_flower_table_params);
    882	if (err)
    883		goto ct_release_offload_meta_err;
    884
    885	err = nfp_flower_xmit_flow(priv->app, flow_pay,
    886				   NFP_FLOWER_CMSG_TYPE_FLOW_ADD);
    887	if (err)
    888		goto ct_remove_rhash_err;
    889
    890	m_entry->tc_flower_cookie = flow_pay->tc_flower_cookie;
    891	m_entry->flow_pay = flow_pay;
    892
    893	if (port)
    894		port->tc_offload_cnt++;
    895
    896	return err;
    897
    898ct_remove_rhash_err:
    899	WARN_ON_ONCE(rhashtable_remove_fast(&priv->flow_table,
    900					    &flow_pay->fl_node,
    901					    nfp_flower_table_params));
    902ct_release_offload_meta_err:
    903	nfp_modify_flow_metadata(priv->app, flow_pay);
    904ct_offload_err:
    905	if (flow_pay->nfp_tun_ipv4_addr)
    906		nfp_tunnel_del_ipv4_off(priv->app, flow_pay->nfp_tun_ipv4_addr);
    907	if (flow_pay->nfp_tun_ipv6)
    908		nfp_tunnel_put_ipv6_off(priv->app, flow_pay->nfp_tun_ipv6);
    909	kfree(flow_pay->action_data);
    910	kfree(flow_pay->mask_data);
    911	kfree(flow_pay->unmasked_data);
    912	kfree(flow_pay);
    913	return err;
    914}
    915
    916static int nfp_fl_ct_del_offload(struct nfp_app *app, unsigned long cookie,
    917				 struct net_device *netdev)
    918{
    919	struct nfp_flower_priv *priv = app->priv;
    920	struct nfp_fl_payload *flow_pay;
    921	struct nfp_port *port = NULL;
    922	int err = 0;
    923
    924	if (nfp_netdev_is_nfp_repr(netdev))
    925		port = nfp_port_from_netdev(netdev);
    926
    927	flow_pay = nfp_flower_search_fl_table(app, cookie, netdev);
    928	if (!flow_pay)
    929		return -ENOENT;
    930
    931	err = nfp_modify_flow_metadata(app, flow_pay);
    932	if (err)
    933		goto err_free_merge_flow;
    934
    935	if (flow_pay->nfp_tun_ipv4_addr)
    936		nfp_tunnel_del_ipv4_off(app, flow_pay->nfp_tun_ipv4_addr);
    937
    938	if (flow_pay->nfp_tun_ipv6)
    939		nfp_tunnel_put_ipv6_off(app, flow_pay->nfp_tun_ipv6);
    940
    941	if (!flow_pay->in_hw) {
    942		err = 0;
    943		goto err_free_merge_flow;
    944	}
    945
    946	err = nfp_flower_xmit_flow(app, flow_pay,
    947				   NFP_FLOWER_CMSG_TYPE_FLOW_DEL);
    948
    949err_free_merge_flow:
    950	nfp_flower_del_linked_merge_flows(app, flow_pay);
    951	if (port)
    952		port->tc_offload_cnt--;
    953	kfree(flow_pay->action_data);
    954	kfree(flow_pay->mask_data);
    955	kfree(flow_pay->unmasked_data);
    956	WARN_ON_ONCE(rhashtable_remove_fast(&priv->flow_table,
    957					    &flow_pay->fl_node,
    958					    nfp_flower_table_params));
    959	kfree_rcu(flow_pay, rcu);
    960	return err;
    961}
    962
    963static int nfp_ct_do_nft_merge(struct nfp_fl_ct_zone_entry *zt,
    964			       struct nfp_fl_ct_flow_entry *nft_entry,
    965			       struct nfp_fl_ct_tc_merge *tc_m_entry)
    966{
    967	struct nfp_fl_ct_flow_entry *post_ct_entry, *pre_ct_entry;
    968	struct nfp_fl_nft_tc_merge *nft_m_entry;
    969	unsigned long new_cookie[3];
    970	int err;
    971
    972	pre_ct_entry = tc_m_entry->pre_ct_parent;
    973	post_ct_entry = tc_m_entry->post_ct_parent;
    974
    975	err = nfp_ct_merge_act_check(pre_ct_entry, post_ct_entry, nft_entry);
    976	if (err)
    977		return err;
    978
    979	/* Check that the two tc flows are also compatible with
    980	 * the nft entry. No need to check the pre_ct and post_ct
    981	 * entries as that was already done during pre_merge.
    982	 * The nft entry does not have a chain populated, so
    983	 * skip this check.
    984	 */
    985	err = nfp_ct_merge_check(pre_ct_entry, nft_entry);
    986	if (err)
    987		return err;
    988	err = nfp_ct_merge_check(nft_entry, post_ct_entry);
    989	if (err)
    990		return err;
    991	err = nfp_ct_check_meta(post_ct_entry, nft_entry);
    992	if (err)
    993		return err;
    994
    995	/* Combine tc_merge and nft cookies for this cookie. */
    996	new_cookie[0] = tc_m_entry->cookie[0];
    997	new_cookie[1] = tc_m_entry->cookie[1];
    998	new_cookie[2] = nft_entry->cookie;
    999	nft_m_entry = get_hashentry(&zt->nft_merge_tb,
   1000				    &new_cookie,
   1001				    nfp_nft_ct_merge_params,
   1002				    sizeof(*nft_m_entry));
   1003
   1004	if (IS_ERR(nft_m_entry))
   1005		return PTR_ERR(nft_m_entry);
   1006
   1007	/* nft_m_entry already present, not merging again */
   1008	if (!memcmp(&new_cookie, nft_m_entry->cookie, sizeof(new_cookie)))
   1009		return 0;
   1010
   1011	memcpy(&nft_m_entry->cookie, &new_cookie, sizeof(new_cookie));
   1012	nft_m_entry->zt = zt;
   1013	nft_m_entry->tc_m_parent = tc_m_entry;
   1014	nft_m_entry->nft_parent = nft_entry;
   1015	nft_m_entry->tc_flower_cookie = 0;
   1016	/* Copy the netdev from one the pre_ct entry. When the tc_m_entry was created
   1017	 * it only combined them if the netdevs were the same, so can use any of them.
   1018	 */
   1019	nft_m_entry->netdev = pre_ct_entry->netdev;
   1020
   1021	/* Add this entry to the tc_m_list and nft_flow lists */
   1022	list_add(&nft_m_entry->tc_merge_list, &tc_m_entry->children);
   1023	list_add(&nft_m_entry->nft_flow_list, &nft_entry->children);
   1024
   1025	/* Generate offload structure and send to nfp */
   1026	err = nfp_fl_ct_add_offload(nft_m_entry);
   1027	if (err)
   1028		goto err_nft_ct_offload;
   1029
   1030	err = rhashtable_insert_fast(&zt->nft_merge_tb, &nft_m_entry->hash_node,
   1031				     nfp_nft_ct_merge_params);
   1032	if (err)
   1033		goto err_nft_ct_merge_insert;
   1034
   1035	zt->nft_merge_count++;
   1036
   1037	return err;
   1038
   1039err_nft_ct_merge_insert:
   1040	nfp_fl_ct_del_offload(zt->priv->app, nft_m_entry->tc_flower_cookie,
   1041			      nft_m_entry->netdev);
   1042err_nft_ct_offload:
   1043	list_del(&nft_m_entry->tc_merge_list);
   1044	list_del(&nft_m_entry->nft_flow_list);
   1045	kfree(nft_m_entry);
   1046	return err;
   1047}
   1048
   1049static int nfp_ct_do_tc_merge(struct nfp_fl_ct_zone_entry *zt,
   1050			      struct nfp_fl_ct_flow_entry *ct_entry1,
   1051			      struct nfp_fl_ct_flow_entry *ct_entry2)
   1052{
   1053	struct nfp_fl_ct_flow_entry *post_ct_entry, *pre_ct_entry;
   1054	struct nfp_fl_ct_flow_entry *nft_entry, *nft_tmp;
   1055	struct nfp_fl_ct_tc_merge *m_entry;
   1056	unsigned long new_cookie[2];
   1057	int err;
   1058
   1059	if (ct_entry1->type == CT_TYPE_PRE_CT) {
   1060		pre_ct_entry = ct_entry1;
   1061		post_ct_entry = ct_entry2;
   1062	} else {
   1063		post_ct_entry = ct_entry1;
   1064		pre_ct_entry = ct_entry2;
   1065	}
   1066
   1067	/* Checks that the chain_index of the filter matches the
   1068	 * chain_index of the GOTO action.
   1069	 */
   1070	if (post_ct_entry->chain_index != pre_ct_entry->chain_index)
   1071		return -EINVAL;
   1072
   1073	err = nfp_ct_merge_check(pre_ct_entry, post_ct_entry);
   1074	if (err)
   1075		return err;
   1076
   1077	new_cookie[0] = pre_ct_entry->cookie;
   1078	new_cookie[1] = post_ct_entry->cookie;
   1079	m_entry = get_hashentry(&zt->tc_merge_tb, &new_cookie,
   1080				nfp_tc_ct_merge_params, sizeof(*m_entry));
   1081	if (IS_ERR(m_entry))
   1082		return PTR_ERR(m_entry);
   1083
   1084	/* m_entry already present, not merging again */
   1085	if (!memcmp(&new_cookie, m_entry->cookie, sizeof(new_cookie)))
   1086		return 0;
   1087
   1088	memcpy(&m_entry->cookie, &new_cookie, sizeof(new_cookie));
   1089	m_entry->zt = zt;
   1090	m_entry->post_ct_parent = post_ct_entry;
   1091	m_entry->pre_ct_parent = pre_ct_entry;
   1092
   1093	/* Add this entry to the pre_ct and post_ct lists */
   1094	list_add(&m_entry->post_ct_list, &post_ct_entry->children);
   1095	list_add(&m_entry->pre_ct_list, &pre_ct_entry->children);
   1096	INIT_LIST_HEAD(&m_entry->children);
   1097
   1098	err = rhashtable_insert_fast(&zt->tc_merge_tb, &m_entry->hash_node,
   1099				     nfp_tc_ct_merge_params);
   1100	if (err)
   1101		goto err_ct_tc_merge_insert;
   1102	zt->tc_merge_count++;
   1103
   1104	/* Merge with existing nft flows */
   1105	list_for_each_entry_safe(nft_entry, nft_tmp, &zt->nft_flows_list,
   1106				 list_node) {
   1107		nfp_ct_do_nft_merge(zt, nft_entry, m_entry);
   1108	}
   1109
   1110	return 0;
   1111
   1112err_ct_tc_merge_insert:
   1113	list_del(&m_entry->post_ct_list);
   1114	list_del(&m_entry->pre_ct_list);
   1115	kfree(m_entry);
   1116	return err;
   1117}
   1118
   1119static struct
   1120nfp_fl_ct_zone_entry *get_nfp_zone_entry(struct nfp_flower_priv *priv,
   1121					 u16 zone, bool wildcarded)
   1122{
   1123	struct nfp_fl_ct_zone_entry *zt;
   1124	int err;
   1125
   1126	if (wildcarded && priv->ct_zone_wc)
   1127		return priv->ct_zone_wc;
   1128
   1129	if (!wildcarded) {
   1130		zt = get_hashentry(&priv->ct_zone_table, &zone,
   1131				   nfp_zone_table_params, sizeof(*zt));
   1132
   1133		/* If priv is set this is an existing entry, just return it */
   1134		if (IS_ERR(zt) || zt->priv)
   1135			return zt;
   1136	} else {
   1137		zt = kzalloc(sizeof(*zt), GFP_KERNEL);
   1138		if (!zt)
   1139			return ERR_PTR(-ENOMEM);
   1140	}
   1141
   1142	zt->zone = zone;
   1143	zt->priv = priv;
   1144	zt->nft = NULL;
   1145
   1146	/* init the various hash tables and lists*/
   1147	INIT_LIST_HEAD(&zt->pre_ct_list);
   1148	INIT_LIST_HEAD(&zt->post_ct_list);
   1149	INIT_LIST_HEAD(&zt->nft_flows_list);
   1150
   1151	err = rhashtable_init(&zt->tc_merge_tb, &nfp_tc_ct_merge_params);
   1152	if (err)
   1153		goto err_tc_merge_tb_init;
   1154
   1155	err = rhashtable_init(&zt->nft_merge_tb, &nfp_nft_ct_merge_params);
   1156	if (err)
   1157		goto err_nft_merge_tb_init;
   1158
   1159	if (wildcarded) {
   1160		priv->ct_zone_wc = zt;
   1161	} else {
   1162		err = rhashtable_insert_fast(&priv->ct_zone_table,
   1163					     &zt->hash_node,
   1164					     nfp_zone_table_params);
   1165		if (err)
   1166			goto err_zone_insert;
   1167	}
   1168
   1169	return zt;
   1170
   1171err_zone_insert:
   1172	rhashtable_destroy(&zt->nft_merge_tb);
   1173err_nft_merge_tb_init:
   1174	rhashtable_destroy(&zt->tc_merge_tb);
   1175err_tc_merge_tb_init:
   1176	kfree(zt);
   1177	return ERR_PTR(err);
   1178}
   1179
   1180static struct net_device *get_netdev_from_rule(struct flow_rule *rule)
   1181{
   1182	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) {
   1183		struct flow_match_meta match;
   1184
   1185		flow_rule_match_meta(rule, &match);
   1186		if (match.key->ingress_ifindex & match.mask->ingress_ifindex)
   1187			return __dev_get_by_index(&init_net,
   1188						  match.key->ingress_ifindex);
   1189	}
   1190
   1191	return NULL;
   1192}
   1193
   1194static struct
   1195nfp_fl_ct_flow_entry *nfp_fl_ct_add_flow(struct nfp_fl_ct_zone_entry *zt,
   1196					 struct net_device *netdev,
   1197					 struct flow_cls_offload *flow,
   1198					 bool is_nft, struct netlink_ext_ack *extack)
   1199{
   1200	struct nf_flow_match *nft_match = NULL;
   1201	struct nfp_fl_ct_flow_entry *entry;
   1202	struct nfp_fl_ct_map_entry *map;
   1203	struct flow_action_entry *act;
   1204	int err, i;
   1205
   1206	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
   1207	if (!entry)
   1208		return ERR_PTR(-ENOMEM);
   1209
   1210	entry->rule = flow_rule_alloc(flow->rule->action.num_entries);
   1211	if (!entry->rule) {
   1212		err = -ENOMEM;
   1213		goto err_pre_ct_rule;
   1214	}
   1215
   1216	/* nft flows gets destroyed after callback return, so need
   1217	 * to do a full copy instead of just a reference.
   1218	 */
   1219	if (is_nft) {
   1220		nft_match = kzalloc(sizeof(*nft_match), GFP_KERNEL);
   1221		if (!nft_match) {
   1222			err = -ENOMEM;
   1223			goto err_pre_ct_act;
   1224		}
   1225		memcpy(&nft_match->dissector, flow->rule->match.dissector,
   1226		       sizeof(nft_match->dissector));
   1227		memcpy(&nft_match->mask, flow->rule->match.mask,
   1228		       sizeof(nft_match->mask));
   1229		memcpy(&nft_match->key, flow->rule->match.key,
   1230		       sizeof(nft_match->key));
   1231		entry->rule->match.dissector = &nft_match->dissector;
   1232		entry->rule->match.mask = &nft_match->mask;
   1233		entry->rule->match.key = &nft_match->key;
   1234
   1235		if (!netdev)
   1236			netdev = get_netdev_from_rule(entry->rule);
   1237	} else {
   1238		entry->rule->match.dissector = flow->rule->match.dissector;
   1239		entry->rule->match.mask = flow->rule->match.mask;
   1240		entry->rule->match.key = flow->rule->match.key;
   1241	}
   1242
   1243	entry->zt = zt;
   1244	entry->netdev = netdev;
   1245	entry->cookie = flow->cookie;
   1246	entry->chain_index = flow->common.chain_index;
   1247	entry->tun_offset = NFP_FL_CT_NO_TUN;
   1248
   1249	/* Copy over action data. Unfortunately we do not get a handle to the
   1250	 * original tcf_action data, and the flow objects gets destroyed, so we
   1251	 * cannot just save a pointer to this either, so need to copy over the
   1252	 * data unfortunately.
   1253	 */
   1254	entry->rule->action.num_entries = flow->rule->action.num_entries;
   1255	flow_action_for_each(i, act, &flow->rule->action) {
   1256		struct flow_action_entry *new_act;
   1257
   1258		new_act = &entry->rule->action.entries[i];
   1259		memcpy(new_act, act, sizeof(struct flow_action_entry));
   1260		/* Entunnel is a special case, need to allocate and copy
   1261		 * tunnel info.
   1262		 */
   1263		if (act->id == FLOW_ACTION_TUNNEL_ENCAP) {
   1264			struct ip_tunnel_info *tun = act->tunnel;
   1265			size_t tun_size = sizeof(*tun) + tun->options_len;
   1266
   1267			new_act->tunnel = kmemdup(tun, tun_size, GFP_ATOMIC);
   1268			if (!new_act->tunnel) {
   1269				err = -ENOMEM;
   1270				goto err_pre_ct_tun_cp;
   1271			}
   1272			entry->tun_offset = i;
   1273		}
   1274	}
   1275
   1276	INIT_LIST_HEAD(&entry->children);
   1277
   1278	/* Now add a ct map entry to flower-priv */
   1279	map = get_hashentry(&zt->priv->ct_map_table, &flow->cookie,
   1280			    nfp_ct_map_params, sizeof(*map));
   1281	if (IS_ERR(map)) {
   1282		NL_SET_ERR_MSG_MOD(extack,
   1283				   "offload error: ct map entry creation failed");
   1284		err = -ENOMEM;
   1285		goto err_ct_flow_insert;
   1286	}
   1287	map->cookie = flow->cookie;
   1288	map->ct_entry = entry;
   1289	err = rhashtable_insert_fast(&zt->priv->ct_map_table,
   1290				     &map->hash_node,
   1291				     nfp_ct_map_params);
   1292	if (err) {
   1293		NL_SET_ERR_MSG_MOD(extack,
   1294				   "offload error: ct map entry table add failed");
   1295		goto err_map_insert;
   1296	}
   1297
   1298	return entry;
   1299
   1300err_map_insert:
   1301	kfree(map);
   1302err_ct_flow_insert:
   1303	if (entry->tun_offset != NFP_FL_CT_NO_TUN)
   1304		kfree(entry->rule->action.entries[entry->tun_offset].tunnel);
   1305err_pre_ct_tun_cp:
   1306	kfree(nft_match);
   1307err_pre_ct_act:
   1308	kfree(entry->rule);
   1309err_pre_ct_rule:
   1310	kfree(entry);
   1311	return ERR_PTR(err);
   1312}
   1313
   1314static void cleanup_nft_merge_entry(struct nfp_fl_nft_tc_merge *m_entry)
   1315{
   1316	struct nfp_fl_ct_zone_entry *zt;
   1317	int err;
   1318
   1319	zt = m_entry->zt;
   1320
   1321	/* Flow is in HW, need to delete */
   1322	if (m_entry->tc_flower_cookie) {
   1323		err = nfp_fl_ct_del_offload(zt->priv->app, m_entry->tc_flower_cookie,
   1324					    m_entry->netdev);
   1325		if (err)
   1326			return;
   1327	}
   1328
   1329	WARN_ON_ONCE(rhashtable_remove_fast(&zt->nft_merge_tb,
   1330					    &m_entry->hash_node,
   1331					    nfp_nft_ct_merge_params));
   1332	zt->nft_merge_count--;
   1333	list_del(&m_entry->tc_merge_list);
   1334	list_del(&m_entry->nft_flow_list);
   1335
   1336	kfree(m_entry);
   1337}
   1338
   1339static void nfp_free_nft_merge_children(void *entry, bool is_nft_flow)
   1340{
   1341	struct nfp_fl_nft_tc_merge *m_entry, *tmp;
   1342
   1343	/* These post entries are parts of two lists, one is a list of nft_entries
   1344	 * and the other is of from a list of tc_merge structures. Iterate
   1345	 * through the relevant list and cleanup the entries.
   1346	 */
   1347
   1348	if (is_nft_flow) {
   1349		/* Need to iterate through list of nft_flow entries*/
   1350		struct nfp_fl_ct_flow_entry *ct_entry = entry;
   1351
   1352		list_for_each_entry_safe(m_entry, tmp, &ct_entry->children,
   1353					 nft_flow_list) {
   1354			cleanup_nft_merge_entry(m_entry);
   1355		}
   1356	} else {
   1357		/* Need to iterate through list of tc_merged_flow entries*/
   1358		struct nfp_fl_ct_tc_merge *ct_entry = entry;
   1359
   1360		list_for_each_entry_safe(m_entry, tmp, &ct_entry->children,
   1361					 tc_merge_list) {
   1362			cleanup_nft_merge_entry(m_entry);
   1363		}
   1364	}
   1365}
   1366
   1367static void nfp_del_tc_merge_entry(struct nfp_fl_ct_tc_merge *m_ent)
   1368{
   1369	struct nfp_fl_ct_zone_entry *zt;
   1370	int err;
   1371
   1372	zt = m_ent->zt;
   1373	err = rhashtable_remove_fast(&zt->tc_merge_tb,
   1374				     &m_ent->hash_node,
   1375				     nfp_tc_ct_merge_params);
   1376	if (err)
   1377		pr_warn("WARNING: could not remove merge_entry from hashtable\n");
   1378	zt->tc_merge_count--;
   1379	list_del(&m_ent->post_ct_list);
   1380	list_del(&m_ent->pre_ct_list);
   1381
   1382	if (!list_empty(&m_ent->children))
   1383		nfp_free_nft_merge_children(m_ent, false);
   1384	kfree(m_ent);
   1385}
   1386
   1387static void nfp_free_tc_merge_children(struct nfp_fl_ct_flow_entry *entry)
   1388{
   1389	struct nfp_fl_ct_tc_merge *m_ent, *tmp;
   1390
   1391	switch (entry->type) {
   1392	case CT_TYPE_PRE_CT:
   1393		list_for_each_entry_safe(m_ent, tmp, &entry->children, pre_ct_list) {
   1394			nfp_del_tc_merge_entry(m_ent);
   1395		}
   1396		break;
   1397	case CT_TYPE_POST_CT:
   1398		list_for_each_entry_safe(m_ent, tmp, &entry->children, post_ct_list) {
   1399			nfp_del_tc_merge_entry(m_ent);
   1400		}
   1401		break;
   1402	default:
   1403		break;
   1404	}
   1405}
   1406
   1407void nfp_fl_ct_clean_flow_entry(struct nfp_fl_ct_flow_entry *entry)
   1408{
   1409	list_del(&entry->list_node);
   1410
   1411	if (!list_empty(&entry->children)) {
   1412		if (entry->type == CT_TYPE_NFT)
   1413			nfp_free_nft_merge_children(entry, true);
   1414		else
   1415			nfp_free_tc_merge_children(entry);
   1416	}
   1417
   1418	if (entry->tun_offset != NFP_FL_CT_NO_TUN)
   1419		kfree(entry->rule->action.entries[entry->tun_offset].tunnel);
   1420
   1421	if (entry->type == CT_TYPE_NFT) {
   1422		struct nf_flow_match *nft_match;
   1423
   1424		nft_match = container_of(entry->rule->match.dissector,
   1425					 struct nf_flow_match, dissector);
   1426		kfree(nft_match);
   1427	}
   1428
   1429	kfree(entry->rule);
   1430	kfree(entry);
   1431}
   1432
   1433static struct flow_action_entry *get_flow_act(struct flow_rule *rule,
   1434					      enum flow_action_id act_id)
   1435{
   1436	struct flow_action_entry *act = NULL;
   1437	int i;
   1438
   1439	flow_action_for_each(i, act, &rule->action) {
   1440		if (act->id == act_id)
   1441			return act;
   1442	}
   1443	return NULL;
   1444}
   1445
   1446static void
   1447nfp_ct_merge_tc_entries(struct nfp_fl_ct_flow_entry *ct_entry1,
   1448			struct nfp_fl_ct_zone_entry *zt_src,
   1449			struct nfp_fl_ct_zone_entry *zt_dst)
   1450{
   1451	struct nfp_fl_ct_flow_entry *ct_entry2, *ct_tmp;
   1452	struct list_head *ct_list;
   1453
   1454	if (ct_entry1->type == CT_TYPE_PRE_CT)
   1455		ct_list = &zt_src->post_ct_list;
   1456	else if (ct_entry1->type == CT_TYPE_POST_CT)
   1457		ct_list = &zt_src->pre_ct_list;
   1458	else
   1459		return;
   1460
   1461	list_for_each_entry_safe(ct_entry2, ct_tmp, ct_list,
   1462				 list_node) {
   1463		nfp_ct_do_tc_merge(zt_dst, ct_entry2, ct_entry1);
   1464	}
   1465}
   1466
   1467static void
   1468nfp_ct_merge_nft_with_tc(struct nfp_fl_ct_flow_entry *nft_entry,
   1469			 struct nfp_fl_ct_zone_entry *zt)
   1470{
   1471	struct nfp_fl_ct_tc_merge *tc_merge_entry;
   1472	struct rhashtable_iter iter;
   1473
   1474	rhashtable_walk_enter(&zt->tc_merge_tb, &iter);
   1475	rhashtable_walk_start(&iter);
   1476	while ((tc_merge_entry = rhashtable_walk_next(&iter)) != NULL) {
   1477		if (IS_ERR(tc_merge_entry))
   1478			continue;
   1479		rhashtable_walk_stop(&iter);
   1480		nfp_ct_do_nft_merge(zt, nft_entry, tc_merge_entry);
   1481		rhashtable_walk_start(&iter);
   1482	}
   1483	rhashtable_walk_stop(&iter);
   1484	rhashtable_walk_exit(&iter);
   1485}
   1486
   1487int nfp_fl_ct_handle_pre_ct(struct nfp_flower_priv *priv,
   1488			    struct net_device *netdev,
   1489			    struct flow_cls_offload *flow,
   1490			    struct netlink_ext_ack *extack)
   1491{
   1492	struct flow_action_entry *ct_act, *ct_goto;
   1493	struct nfp_fl_ct_flow_entry *ct_entry;
   1494	struct nfp_fl_ct_zone_entry *zt;
   1495	int err;
   1496
   1497	ct_act = get_flow_act(flow->rule, FLOW_ACTION_CT);
   1498	if (!ct_act) {
   1499		NL_SET_ERR_MSG_MOD(extack,
   1500				   "unsupported offload: Conntrack action empty in conntrack offload");
   1501		return -EOPNOTSUPP;
   1502	}
   1503
   1504	ct_goto = get_flow_act(flow->rule, FLOW_ACTION_GOTO);
   1505	if (!ct_goto) {
   1506		NL_SET_ERR_MSG_MOD(extack,
   1507				   "unsupported offload: Conntrack requires ACTION_GOTO");
   1508		return -EOPNOTSUPP;
   1509	}
   1510
   1511	zt = get_nfp_zone_entry(priv, ct_act->ct.zone, false);
   1512	if (IS_ERR(zt)) {
   1513		NL_SET_ERR_MSG_MOD(extack,
   1514				   "offload error: Could not create zone table entry");
   1515		return PTR_ERR(zt);
   1516	}
   1517
   1518	if (!zt->nft) {
   1519		zt->nft = ct_act->ct.flow_table;
   1520		err = nf_flow_table_offload_add_cb(zt->nft, nfp_fl_ct_handle_nft_flow, zt);
   1521		if (err) {
   1522			NL_SET_ERR_MSG_MOD(extack,
   1523					   "offload error: Could not register nft_callback");
   1524			return err;
   1525		}
   1526	}
   1527
   1528	/* Add entry to pre_ct_list */
   1529	ct_entry = nfp_fl_ct_add_flow(zt, netdev, flow, false, extack);
   1530	if (IS_ERR(ct_entry))
   1531		return PTR_ERR(ct_entry);
   1532	ct_entry->type = CT_TYPE_PRE_CT;
   1533	ct_entry->chain_index = ct_goto->chain_index;
   1534	list_add(&ct_entry->list_node, &zt->pre_ct_list);
   1535	zt->pre_ct_count++;
   1536
   1537	nfp_ct_merge_tc_entries(ct_entry, zt, zt);
   1538
   1539	/* Need to check and merge with tables in the wc_zone as well */
   1540	if (priv->ct_zone_wc)
   1541		nfp_ct_merge_tc_entries(ct_entry, priv->ct_zone_wc, zt);
   1542
   1543	return 0;
   1544}
   1545
   1546int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv,
   1547			     struct net_device *netdev,
   1548			     struct flow_cls_offload *flow,
   1549			     struct netlink_ext_ack *extack)
   1550{
   1551	struct flow_rule *rule = flow_cls_offload_flow_rule(flow);
   1552	struct nfp_fl_ct_flow_entry *ct_entry;
   1553	struct nfp_fl_ct_zone_entry *zt;
   1554	bool wildcarded = false;
   1555	struct flow_match_ct ct;
   1556
   1557	flow_rule_match_ct(rule, &ct);
   1558	if (!ct.mask->ct_zone) {
   1559		wildcarded = true;
   1560	} else if (ct.mask->ct_zone != U16_MAX) {
   1561		NL_SET_ERR_MSG_MOD(extack,
   1562				   "unsupported offload: partially wildcarded ct_zone is not supported");
   1563		return -EOPNOTSUPP;
   1564	}
   1565
   1566	zt = get_nfp_zone_entry(priv, ct.key->ct_zone, wildcarded);
   1567	if (IS_ERR(zt)) {
   1568		NL_SET_ERR_MSG_MOD(extack,
   1569				   "offload error: Could not create zone table entry");
   1570		return PTR_ERR(zt);
   1571	}
   1572
   1573	/* Add entry to post_ct_list */
   1574	ct_entry = nfp_fl_ct_add_flow(zt, netdev, flow, false, extack);
   1575	if (IS_ERR(ct_entry))
   1576		return PTR_ERR(ct_entry);
   1577
   1578	ct_entry->type = CT_TYPE_POST_CT;
   1579	ct_entry->chain_index = flow->common.chain_index;
   1580	list_add(&ct_entry->list_node, &zt->post_ct_list);
   1581	zt->post_ct_count++;
   1582
   1583	if (wildcarded) {
   1584		/* Iterate through all zone tables if not empty, look for merges with
   1585		 * pre_ct entries and merge them.
   1586		 */
   1587		struct rhashtable_iter iter;
   1588		struct nfp_fl_ct_zone_entry *zone_table;
   1589
   1590		rhashtable_walk_enter(&priv->ct_zone_table, &iter);
   1591		rhashtable_walk_start(&iter);
   1592		while ((zone_table = rhashtable_walk_next(&iter)) != NULL) {
   1593			if (IS_ERR(zone_table))
   1594				continue;
   1595			rhashtable_walk_stop(&iter);
   1596			nfp_ct_merge_tc_entries(ct_entry, zone_table, zone_table);
   1597			rhashtable_walk_start(&iter);
   1598		}
   1599		rhashtable_walk_stop(&iter);
   1600		rhashtable_walk_exit(&iter);
   1601	} else {
   1602		nfp_ct_merge_tc_entries(ct_entry, zt, zt);
   1603	}
   1604
   1605	return 0;
   1606}
   1607
   1608static void
   1609nfp_fl_ct_sub_stats(struct nfp_fl_nft_tc_merge *nft_merge,
   1610		    enum ct_entry_type type, u64 *m_pkts,
   1611		    u64 *m_bytes, u64 *m_used)
   1612{
   1613	struct nfp_flower_priv *priv = nft_merge->zt->priv;
   1614	struct nfp_fl_payload *nfp_flow;
   1615	u32 ctx_id;
   1616
   1617	nfp_flow = nft_merge->flow_pay;
   1618	if (!nfp_flow)
   1619		return;
   1620
   1621	ctx_id = be32_to_cpu(nfp_flow->meta.host_ctx_id);
   1622	*m_pkts += priv->stats[ctx_id].pkts;
   1623	*m_bytes += priv->stats[ctx_id].bytes;
   1624	*m_used = max_t(u64, *m_used, priv->stats[ctx_id].used);
   1625
   1626	/* If request is for a sub_flow which is part of a tunnel merged
   1627	 * flow then update stats from tunnel merged flows first.
   1628	 */
   1629	if (!list_empty(&nfp_flow->linked_flows))
   1630		nfp_flower_update_merge_stats(priv->app, nfp_flow);
   1631
   1632	if (type != CT_TYPE_NFT) {
   1633		/* Update nft cached stats */
   1634		flow_stats_update(&nft_merge->nft_parent->stats,
   1635				  priv->stats[ctx_id].bytes,
   1636				  priv->stats[ctx_id].pkts,
   1637				  0, priv->stats[ctx_id].used,
   1638				  FLOW_ACTION_HW_STATS_DELAYED);
   1639	} else {
   1640		/* Update pre_ct cached stats */
   1641		flow_stats_update(&nft_merge->tc_m_parent->pre_ct_parent->stats,
   1642				  priv->stats[ctx_id].bytes,
   1643				  priv->stats[ctx_id].pkts,
   1644				  0, priv->stats[ctx_id].used,
   1645				  FLOW_ACTION_HW_STATS_DELAYED);
   1646		/* Update post_ct cached stats */
   1647		flow_stats_update(&nft_merge->tc_m_parent->post_ct_parent->stats,
   1648				  priv->stats[ctx_id].bytes,
   1649				  priv->stats[ctx_id].pkts,
   1650				  0, priv->stats[ctx_id].used,
   1651				  FLOW_ACTION_HW_STATS_DELAYED);
   1652	}
   1653	/* Reset stats from the nfp */
   1654	priv->stats[ctx_id].pkts = 0;
   1655	priv->stats[ctx_id].bytes = 0;
   1656}
   1657
   1658int nfp_fl_ct_stats(struct flow_cls_offload *flow,
   1659		    struct nfp_fl_ct_map_entry *ct_map_ent)
   1660{
   1661	struct nfp_fl_ct_flow_entry *ct_entry = ct_map_ent->ct_entry;
   1662	struct nfp_fl_nft_tc_merge *nft_merge, *nft_m_tmp;
   1663	struct nfp_fl_ct_tc_merge *tc_merge, *tc_m_tmp;
   1664
   1665	u64 pkts = 0, bytes = 0, used = 0;
   1666	u64 m_pkts, m_bytes, m_used;
   1667
   1668	spin_lock_bh(&ct_entry->zt->priv->stats_lock);
   1669
   1670	if (ct_entry->type == CT_TYPE_PRE_CT) {
   1671		/* Iterate tc_merge entries associated with this flow */
   1672		list_for_each_entry_safe(tc_merge, tc_m_tmp, &ct_entry->children,
   1673					 pre_ct_list) {
   1674			m_pkts = 0;
   1675			m_bytes = 0;
   1676			m_used = 0;
   1677			/* Iterate nft_merge entries associated with this tc_merge flow */
   1678			list_for_each_entry_safe(nft_merge, nft_m_tmp, &tc_merge->children,
   1679						 tc_merge_list) {
   1680				nfp_fl_ct_sub_stats(nft_merge, CT_TYPE_PRE_CT,
   1681						    &m_pkts, &m_bytes, &m_used);
   1682			}
   1683			pkts += m_pkts;
   1684			bytes += m_bytes;
   1685			used = max_t(u64, used, m_used);
   1686			/* Update post_ct partner */
   1687			flow_stats_update(&tc_merge->post_ct_parent->stats,
   1688					  m_bytes, m_pkts, 0, m_used,
   1689					  FLOW_ACTION_HW_STATS_DELAYED);
   1690		}
   1691	} else if (ct_entry->type == CT_TYPE_POST_CT) {
   1692		/* Iterate tc_merge entries associated with this flow */
   1693		list_for_each_entry_safe(tc_merge, tc_m_tmp, &ct_entry->children,
   1694					 post_ct_list) {
   1695			m_pkts = 0;
   1696			m_bytes = 0;
   1697			m_used = 0;
   1698			/* Iterate nft_merge entries associated with this tc_merge flow */
   1699			list_for_each_entry_safe(nft_merge, nft_m_tmp, &tc_merge->children,
   1700						 tc_merge_list) {
   1701				nfp_fl_ct_sub_stats(nft_merge, CT_TYPE_POST_CT,
   1702						    &m_pkts, &m_bytes, &m_used);
   1703			}
   1704			pkts += m_pkts;
   1705			bytes += m_bytes;
   1706			used = max_t(u64, used, m_used);
   1707			/* Update pre_ct partner */
   1708			flow_stats_update(&tc_merge->pre_ct_parent->stats,
   1709					  m_bytes, m_pkts, 0, m_used,
   1710					  FLOW_ACTION_HW_STATS_DELAYED);
   1711		}
   1712	} else  {
   1713		/* Iterate nft_merge entries associated with this nft flow */
   1714		list_for_each_entry_safe(nft_merge, nft_m_tmp, &ct_entry->children,
   1715					 nft_flow_list) {
   1716			nfp_fl_ct_sub_stats(nft_merge, CT_TYPE_NFT,
   1717					    &pkts, &bytes, &used);
   1718		}
   1719	}
   1720
   1721	/* Add stats from this request to stats potentially cached by
   1722	 * previous requests.
   1723	 */
   1724	flow_stats_update(&ct_entry->stats, bytes, pkts, 0, used,
   1725			  FLOW_ACTION_HW_STATS_DELAYED);
   1726	/* Finally update the flow stats from the original stats request */
   1727	flow_stats_update(&flow->stats, ct_entry->stats.bytes,
   1728			  ct_entry->stats.pkts, 0,
   1729			  ct_entry->stats.lastused,
   1730			  FLOW_ACTION_HW_STATS_DELAYED);
   1731	/* Stats has been synced to original flow, can now clear
   1732	 * the cache.
   1733	 */
   1734	ct_entry->stats.pkts = 0;
   1735	ct_entry->stats.bytes = 0;
   1736	spin_unlock_bh(&ct_entry->zt->priv->stats_lock);
   1737
   1738	return 0;
   1739}
   1740
   1741static int
   1742nfp_fl_ct_offload_nft_flow(struct nfp_fl_ct_zone_entry *zt, struct flow_cls_offload *flow)
   1743{
   1744	struct nfp_fl_ct_map_entry *ct_map_ent;
   1745	struct nfp_fl_ct_flow_entry *ct_entry;
   1746	struct netlink_ext_ack *extack = NULL;
   1747
   1748	ASSERT_RTNL();
   1749
   1750	extack = flow->common.extack;
   1751	switch (flow->command) {
   1752	case FLOW_CLS_REPLACE:
   1753		/* Netfilter can request offload multiple times for the same
   1754		 * flow - protect against adding duplicates.
   1755		 */
   1756		ct_map_ent = rhashtable_lookup_fast(&zt->priv->ct_map_table, &flow->cookie,
   1757						    nfp_ct_map_params);
   1758		if (!ct_map_ent) {
   1759			ct_entry = nfp_fl_ct_add_flow(zt, NULL, flow, true, extack);
   1760			if (IS_ERR(ct_entry))
   1761				return PTR_ERR(ct_entry);
   1762			ct_entry->type = CT_TYPE_NFT;
   1763			list_add(&ct_entry->list_node, &zt->nft_flows_list);
   1764			zt->nft_flows_count++;
   1765			nfp_ct_merge_nft_with_tc(ct_entry, zt);
   1766		}
   1767		return 0;
   1768	case FLOW_CLS_DESTROY:
   1769		ct_map_ent = rhashtable_lookup_fast(&zt->priv->ct_map_table, &flow->cookie,
   1770						    nfp_ct_map_params);
   1771		return nfp_fl_ct_del_flow(ct_map_ent);
   1772	case FLOW_CLS_STATS:
   1773		ct_map_ent = rhashtable_lookup_fast(&zt->priv->ct_map_table, &flow->cookie,
   1774						    nfp_ct_map_params);
   1775		if (ct_map_ent)
   1776			return nfp_fl_ct_stats(flow, ct_map_ent);
   1777		break;
   1778	default:
   1779		break;
   1780	}
   1781	return -EINVAL;
   1782}
   1783
   1784int nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data, void *cb_priv)
   1785{
   1786	struct flow_cls_offload *flow = type_data;
   1787	struct nfp_fl_ct_zone_entry *zt = cb_priv;
   1788	int err = -EOPNOTSUPP;
   1789
   1790	switch (type) {
   1791	case TC_SETUP_CLSFLOWER:
   1792		rtnl_lock();
   1793		err = nfp_fl_ct_offload_nft_flow(zt, flow);
   1794		rtnl_unlock();
   1795		break;
   1796	default:
   1797		return -EOPNOTSUPP;
   1798	}
   1799	return err;
   1800}
   1801
   1802static void
   1803nfp_fl_ct_clean_nft_entries(struct nfp_fl_ct_zone_entry *zt)
   1804{
   1805	struct nfp_fl_ct_flow_entry *nft_entry, *ct_tmp;
   1806	struct nfp_fl_ct_map_entry *ct_map_ent;
   1807
   1808	list_for_each_entry_safe(nft_entry, ct_tmp, &zt->nft_flows_list,
   1809				 list_node) {
   1810		ct_map_ent = rhashtable_lookup_fast(&zt->priv->ct_map_table,
   1811						    &nft_entry->cookie,
   1812						    nfp_ct_map_params);
   1813		nfp_fl_ct_del_flow(ct_map_ent);
   1814	}
   1815}
   1816
   1817int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent)
   1818{
   1819	struct nfp_fl_ct_flow_entry *ct_entry;
   1820	struct nfp_fl_ct_zone_entry *zt;
   1821	struct rhashtable *m_table;
   1822
   1823	if (!ct_map_ent)
   1824		return -ENOENT;
   1825
   1826	zt = ct_map_ent->ct_entry->zt;
   1827	ct_entry = ct_map_ent->ct_entry;
   1828	m_table = &zt->priv->ct_map_table;
   1829
   1830	switch (ct_entry->type) {
   1831	case CT_TYPE_PRE_CT:
   1832		zt->pre_ct_count--;
   1833		rhashtable_remove_fast(m_table, &ct_map_ent->hash_node,
   1834				       nfp_ct_map_params);
   1835		nfp_fl_ct_clean_flow_entry(ct_entry);
   1836		kfree(ct_map_ent);
   1837
   1838		if (!zt->pre_ct_count) {
   1839			zt->nft = NULL;
   1840			nfp_fl_ct_clean_nft_entries(zt);
   1841		}
   1842		break;
   1843	case CT_TYPE_POST_CT:
   1844		zt->post_ct_count--;
   1845		rhashtable_remove_fast(m_table, &ct_map_ent->hash_node,
   1846				       nfp_ct_map_params);
   1847		nfp_fl_ct_clean_flow_entry(ct_entry);
   1848		kfree(ct_map_ent);
   1849		break;
   1850	case CT_TYPE_NFT:
   1851		zt->nft_flows_count--;
   1852		rhashtable_remove_fast(m_table, &ct_map_ent->hash_node,
   1853				       nfp_ct_map_params);
   1854		nfp_fl_ct_clean_flow_entry(ct_map_ent->ct_entry);
   1855		kfree(ct_map_ent);
   1856		break;
   1857	default:
   1858		break;
   1859	}
   1860
   1861	return 0;
   1862}