162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 262306a36Sopenharmony_ci/* Copyright (C) 2021 Corigine, Inc. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#ifndef __NFP_FLOWER_CONNTRACK_H__ 562306a36Sopenharmony_ci#define __NFP_FLOWER_CONNTRACK_H__ 1 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <net/netfilter/nf_flow_table.h> 862306a36Sopenharmony_ci#include "main.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define NFP_FL_CT_NO_TUN 0xff 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define COMPARE_UNMASKED_FIELDS(__match1, __match2, __out) \ 1362306a36Sopenharmony_ci do { \ 1462306a36Sopenharmony_ci typeof(__match1) _match1 = (__match1); \ 1562306a36Sopenharmony_ci typeof(__match2) _match2 = (__match2); \ 1662306a36Sopenharmony_ci bool *_out = (__out); \ 1762306a36Sopenharmony_ci int i, size = sizeof(*(_match1).key); \ 1862306a36Sopenharmony_ci char *k1, *m1, *k2, *m2; \ 1962306a36Sopenharmony_ci *_out = false; \ 2062306a36Sopenharmony_ci k1 = (char *)_match1.key; \ 2162306a36Sopenharmony_ci m1 = (char *)_match1.mask; \ 2262306a36Sopenharmony_ci k2 = (char *)_match2.key; \ 2362306a36Sopenharmony_ci m2 = (char *)_match2.mask; \ 2462306a36Sopenharmony_ci for (i = 0; i < size; i++) \ 2562306a36Sopenharmony_ci if ((k1[i] & m1[i] & m2[i]) ^ \ 2662306a36Sopenharmony_ci (k2[i] & m1[i] & m2[i])) { \ 2762306a36Sopenharmony_ci *_out = true; \ 2862306a36Sopenharmony_ci break; \ 2962306a36Sopenharmony_ci } \ 3062306a36Sopenharmony_ci } while (0) \ 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ciextern const struct rhashtable_params nfp_zone_table_params; 3362306a36Sopenharmony_ciextern const struct rhashtable_params nfp_ct_map_params; 3462306a36Sopenharmony_ciextern const struct rhashtable_params nfp_tc_ct_merge_params; 3562306a36Sopenharmony_ciextern const struct rhashtable_params nfp_nft_ct_merge_params; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/** 3862306a36Sopenharmony_ci * struct nfp_fl_ct_zone_entry - Zone entry containing conntrack flow information 3962306a36Sopenharmony_ci * @zone: The zone number, used as lookup key in hashtable 4062306a36Sopenharmony_ci * @hash_node: Used by the hashtable 4162306a36Sopenharmony_ci * @priv: Pointer to nfp_flower_priv data 4262306a36Sopenharmony_ci * @nft: Pointer to nf_flowtable for this zone 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * @pre_ct_list: The pre_ct_list of nfp_fl_ct_flow_entry entries 4562306a36Sopenharmony_ci * @pre_ct_count: Keep count of the number of pre_ct entries 4662306a36Sopenharmony_ci * 4762306a36Sopenharmony_ci * @post_ct_list: The post_ct_list of nfp_fl_ct_flow_entry entries 4862306a36Sopenharmony_ci * @post_ct_count: Keep count of the number of post_ct entries 4962306a36Sopenharmony_ci * 5062306a36Sopenharmony_ci * @tc_merge_tb: The table of merged tc flows 5162306a36Sopenharmony_ci * @tc_merge_count: Keep count of the number of merged tc entries 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * @nft_flows_list: The list of nft relatednfp_fl_ct_flow_entry entries 5462306a36Sopenharmony_ci * @nft_flows_count: Keep count of the number of nft_flow entries 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * @nft_merge_tb: The table of merged tc+nft flows 5762306a36Sopenharmony_ci * @nft_merge_count: Keep count of the number of merged tc+nft entries 5862306a36Sopenharmony_ci */ 5962306a36Sopenharmony_cistruct nfp_fl_ct_zone_entry { 6062306a36Sopenharmony_ci u16 zone; 6162306a36Sopenharmony_ci struct rhash_head hash_node; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci struct nfp_flower_priv *priv; 6462306a36Sopenharmony_ci struct nf_flowtable *nft; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci struct list_head pre_ct_list; 6762306a36Sopenharmony_ci unsigned int pre_ct_count; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci struct list_head post_ct_list; 7062306a36Sopenharmony_ci unsigned int post_ct_count; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci struct rhashtable tc_merge_tb; 7362306a36Sopenharmony_ci unsigned int tc_merge_count; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci struct list_head nft_flows_list; 7662306a36Sopenharmony_ci unsigned int nft_flows_count; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci struct rhashtable nft_merge_tb; 7962306a36Sopenharmony_ci unsigned int nft_merge_count; 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cienum ct_entry_type { 8362306a36Sopenharmony_ci CT_TYPE_PRE_CT, 8462306a36Sopenharmony_ci CT_TYPE_NFT, 8562306a36Sopenharmony_ci CT_TYPE_POST_CT, 8662306a36Sopenharmony_ci _CT_TYPE_MAX, 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci#define NFP_MAX_RECIRC_CT_ZONES 4 9062306a36Sopenharmony_ci#define NFP_MAX_ENTRY_RULES (NFP_MAX_RECIRC_CT_ZONES * 2 + 1) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cienum nfp_nfp_layer_name { 9362306a36Sopenharmony_ci FLOW_PAY_META_TCI = 0, 9462306a36Sopenharmony_ci FLOW_PAY_INPORT, 9562306a36Sopenharmony_ci FLOW_PAY_EXT_META, 9662306a36Sopenharmony_ci FLOW_PAY_MAC_MPLS, 9762306a36Sopenharmony_ci FLOW_PAY_L4, 9862306a36Sopenharmony_ci FLOW_PAY_IPV4, 9962306a36Sopenharmony_ci FLOW_PAY_IPV6, 10062306a36Sopenharmony_ci FLOW_PAY_CT, 10162306a36Sopenharmony_ci FLOW_PAY_GRE, 10262306a36Sopenharmony_ci FLOW_PAY_QINQ, 10362306a36Sopenharmony_ci FLOW_PAY_UDP_TUN, 10462306a36Sopenharmony_ci FLOW_PAY_GENEVE_OPT, 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci _FLOW_PAY_LAYERS_MAX 10762306a36Sopenharmony_ci}; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* NFP flow entry flags. */ 11062306a36Sopenharmony_ci#define NFP_FL_ACTION_DO_NAT BIT(0) 11162306a36Sopenharmony_ci#define NFP_FL_ACTION_DO_MANGLE BIT(1) 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/** 11462306a36Sopenharmony_ci * struct nfp_fl_ct_flow_entry - Flow entry containing conntrack flow information 11562306a36Sopenharmony_ci * @cookie: Flow cookie, same as original TC flow, used as key 11662306a36Sopenharmony_ci * @list_node: Used by the list 11762306a36Sopenharmony_ci * @chain_index: Chain index of the original flow 11862306a36Sopenharmony_ci * @goto_chain_index: goto chain index of the flow 11962306a36Sopenharmony_ci * @netdev: netdev structure. 12062306a36Sopenharmony_ci * @zt: Reference to the zone table this belongs to 12162306a36Sopenharmony_ci * @children: List of tc_merge flows this flow forms part of 12262306a36Sopenharmony_ci * @rule: Reference to the original TC flow rule 12362306a36Sopenharmony_ci * @stats: Used to cache stats for updating 12462306a36Sopenharmony_ci * @prev_m_entries: Array of all previous nft_tc_merge entries 12562306a36Sopenharmony_ci * @num_prev_m_entries: The number of all previous nft_tc_merge entries 12662306a36Sopenharmony_ci * @tun_offset: Used to indicate tunnel action offset in action list 12762306a36Sopenharmony_ci * @flags: Used to indicate flow flag like NAT which used by merge. 12862306a36Sopenharmony_ci * @type: Type of ct-entry from enum ct_entry_type 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_cistruct nfp_fl_ct_flow_entry { 13162306a36Sopenharmony_ci unsigned long cookie; 13262306a36Sopenharmony_ci struct list_head list_node; 13362306a36Sopenharmony_ci u32 chain_index; 13462306a36Sopenharmony_ci u32 goto_chain_index; 13562306a36Sopenharmony_ci struct net_device *netdev; 13662306a36Sopenharmony_ci struct nfp_fl_ct_zone_entry *zt; 13762306a36Sopenharmony_ci struct list_head children; 13862306a36Sopenharmony_ci struct flow_rule *rule; 13962306a36Sopenharmony_ci struct flow_stats stats; 14062306a36Sopenharmony_ci struct nfp_fl_nft_tc_merge *prev_m_entries[NFP_MAX_RECIRC_CT_ZONES - 1]; 14162306a36Sopenharmony_ci u8 num_prev_m_entries; 14262306a36Sopenharmony_ci u8 tun_offset; // Set to NFP_FL_CT_NO_TUN if no tun 14362306a36Sopenharmony_ci u8 flags; 14462306a36Sopenharmony_ci u8 type; 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/** 14862306a36Sopenharmony_ci * struct nfp_fl_ct_tc_merge - Merge of two flows from tc 14962306a36Sopenharmony_ci * @cookie: Flow cookie, combination of pre and post ct cookies 15062306a36Sopenharmony_ci * @hash_node: Used by the hashtable 15162306a36Sopenharmony_ci * @pre_ct_list: This entry is part of a pre_ct_list 15262306a36Sopenharmony_ci * @post_ct_list: This entry is part of a post_ct_list 15362306a36Sopenharmony_ci * @zt: Reference to the zone table this belongs to 15462306a36Sopenharmony_ci * @pre_ct_parent: The pre_ct_parent 15562306a36Sopenharmony_ci * @post_ct_parent: The post_ct_parent 15662306a36Sopenharmony_ci * @children: List of nft merged entries 15762306a36Sopenharmony_ci */ 15862306a36Sopenharmony_cistruct nfp_fl_ct_tc_merge { 15962306a36Sopenharmony_ci unsigned long cookie[2]; 16062306a36Sopenharmony_ci struct rhash_head hash_node; 16162306a36Sopenharmony_ci struct list_head pre_ct_list; 16262306a36Sopenharmony_ci struct list_head post_ct_list; 16362306a36Sopenharmony_ci struct nfp_fl_ct_zone_entry *zt; 16462306a36Sopenharmony_ci struct nfp_fl_ct_flow_entry *pre_ct_parent; 16562306a36Sopenharmony_ci struct nfp_fl_ct_flow_entry *post_ct_parent; 16662306a36Sopenharmony_ci struct list_head children; 16762306a36Sopenharmony_ci}; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci/** 17062306a36Sopenharmony_ci * struct nfp_fl_nft_tc_merge - Merge of tc_merge flows with nft flow 17162306a36Sopenharmony_ci * @netdev: Ingress netdev name 17262306a36Sopenharmony_ci * @cookie: Flow cookie, combination of tc_merge and nft cookies 17362306a36Sopenharmony_ci * @hash_node: Used by the hashtable 17462306a36Sopenharmony_ci * @zt: Reference to the zone table this belongs to 17562306a36Sopenharmony_ci * @nft_flow_list: This entry is part of a nft_flows_list 17662306a36Sopenharmony_ci * @tc_merge_list: This entry is part of a ct_merge_list 17762306a36Sopenharmony_ci * @tc_m_parent: The tc_merge parent 17862306a36Sopenharmony_ci * @nft_parent: The nft_entry parent 17962306a36Sopenharmony_ci * @tc_flower_cookie: The cookie of the flow offloaded to the nfp 18062306a36Sopenharmony_ci * @flow_pay: Reference to the offloaded flow struct 18162306a36Sopenharmony_ci * @next_pre_ct_entry: Reference to the next ct zone pre ct entry 18262306a36Sopenharmony_ci */ 18362306a36Sopenharmony_cistruct nfp_fl_nft_tc_merge { 18462306a36Sopenharmony_ci struct net_device *netdev; 18562306a36Sopenharmony_ci unsigned long cookie[3]; 18662306a36Sopenharmony_ci struct rhash_head hash_node; 18762306a36Sopenharmony_ci struct nfp_fl_ct_zone_entry *zt; 18862306a36Sopenharmony_ci struct list_head nft_flow_list; 18962306a36Sopenharmony_ci struct list_head tc_merge_list; 19062306a36Sopenharmony_ci struct nfp_fl_ct_tc_merge *tc_m_parent; 19162306a36Sopenharmony_ci struct nfp_fl_ct_flow_entry *nft_parent; 19262306a36Sopenharmony_ci unsigned long tc_flower_cookie; 19362306a36Sopenharmony_ci struct nfp_fl_payload *flow_pay; 19462306a36Sopenharmony_ci struct nfp_fl_ct_flow_entry *next_pre_ct_entry; 19562306a36Sopenharmony_ci}; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/** 19862306a36Sopenharmony_ci * struct nfp_fl_ct_map_entry - Map between flow cookie and specific ct_flow 19962306a36Sopenharmony_ci * @cookie: Flow cookie, same as original TC flow, used as key 20062306a36Sopenharmony_ci * @hash_node: Used by the hashtable 20162306a36Sopenharmony_ci * @ct_entry: Pointer to corresponding ct_entry 20262306a36Sopenharmony_ci */ 20362306a36Sopenharmony_cistruct nfp_fl_ct_map_entry { 20462306a36Sopenharmony_ci unsigned long cookie; 20562306a36Sopenharmony_ci struct rhash_head hash_node; 20662306a36Sopenharmony_ci struct nfp_fl_ct_flow_entry *ct_entry; 20762306a36Sopenharmony_ci}; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cibool is_pre_ct_flow(struct flow_cls_offload *flow); 21062306a36Sopenharmony_cibool is_post_ct_flow(struct flow_cls_offload *flow); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/** 21362306a36Sopenharmony_ci * nfp_fl_ct_handle_pre_ct() - Handles -trk conntrack rules 21462306a36Sopenharmony_ci * @priv: Pointer to app priv 21562306a36Sopenharmony_ci * @netdev: netdev structure. 21662306a36Sopenharmony_ci * @flow: TC flower classifier offload structure. 21762306a36Sopenharmony_ci * @extack: Extack pointer for errors 21862306a36Sopenharmony_ci * @m_entry:previous nfp_fl_nft_tc_merge entry 21962306a36Sopenharmony_ci * 22062306a36Sopenharmony_ci * Adds a new entry to the relevant zone table and tries to 22162306a36Sopenharmony_ci * merge with other +trk+est entries and offload if possible. 22262306a36Sopenharmony_ci * 22362306a36Sopenharmony_ci * Return: negative value on error, 0 if configured successfully. 22462306a36Sopenharmony_ci */ 22562306a36Sopenharmony_ciint nfp_fl_ct_handle_pre_ct(struct nfp_flower_priv *priv, 22662306a36Sopenharmony_ci struct net_device *netdev, 22762306a36Sopenharmony_ci struct flow_cls_offload *flow, 22862306a36Sopenharmony_ci struct netlink_ext_ack *extack, 22962306a36Sopenharmony_ci struct nfp_fl_nft_tc_merge *m_entry); 23062306a36Sopenharmony_ci/** 23162306a36Sopenharmony_ci * nfp_fl_ct_handle_post_ct() - Handles +trk+est conntrack rules 23262306a36Sopenharmony_ci * @priv: Pointer to app priv 23362306a36Sopenharmony_ci * @netdev: netdev structure. 23462306a36Sopenharmony_ci * @flow: TC flower classifier offload structure. 23562306a36Sopenharmony_ci * @extack: Extack pointer for errors 23662306a36Sopenharmony_ci * 23762306a36Sopenharmony_ci * Adds a new entry to the relevant zone table and tries to 23862306a36Sopenharmony_ci * merge with other -trk entries and offload if possible. 23962306a36Sopenharmony_ci * 24062306a36Sopenharmony_ci * Return: negative value on error, 0 if configured successfully. 24162306a36Sopenharmony_ci */ 24262306a36Sopenharmony_ciint nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv, 24362306a36Sopenharmony_ci struct net_device *netdev, 24462306a36Sopenharmony_ci struct flow_cls_offload *flow, 24562306a36Sopenharmony_ci struct netlink_ext_ack *extack); 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci/** 24862306a36Sopenharmony_ci * nfp_fl_create_new_pre_ct() - create next ct_zone -trk conntrack rules 24962306a36Sopenharmony_ci * @m_entry:previous nfp_fl_nft_tc_merge entry 25062306a36Sopenharmony_ci * 25162306a36Sopenharmony_ci * Create a new pre_ct entry from previous nfp_fl_nft_tc_merge entry 25262306a36Sopenharmony_ci * to the next relevant zone table. Try to merge with other +trk+est 25362306a36Sopenharmony_ci * entries and offload if possible. The created new pre_ct entry is 25462306a36Sopenharmony_ci * linked to the previous nfp_fl_nft_tc_merge entry. 25562306a36Sopenharmony_ci * 25662306a36Sopenharmony_ci * Return: negative value on error, 0 if configured successfully. 25762306a36Sopenharmony_ci */ 25862306a36Sopenharmony_ciint nfp_fl_create_new_pre_ct(struct nfp_fl_nft_tc_merge *m_entry); 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci/** 26162306a36Sopenharmony_ci * nfp_fl_ct_clean_flow_entry() - Free a nfp_fl_ct_flow_entry 26262306a36Sopenharmony_ci * @entry: Flow entry to cleanup 26362306a36Sopenharmony_ci */ 26462306a36Sopenharmony_civoid nfp_fl_ct_clean_flow_entry(struct nfp_fl_ct_flow_entry *entry); 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci/** 26762306a36Sopenharmony_ci * nfp_fl_ct_del_flow() - Handle flow_del callbacks for conntrack 26862306a36Sopenharmony_ci * @ct_map_ent: ct map entry for the flow that needs deleting 26962306a36Sopenharmony_ci */ 27062306a36Sopenharmony_ciint nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent); 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci/** 27362306a36Sopenharmony_ci * nfp_fl_ct_handle_nft_flow() - Handle flower flow callbacks for nft table 27462306a36Sopenharmony_ci * @type: Type provided by callback 27562306a36Sopenharmony_ci * @type_data: Callback data 27662306a36Sopenharmony_ci * @cb_priv: Pointer to data provided when registering the callback, in this 27762306a36Sopenharmony_ci * case it's the zone table. 27862306a36Sopenharmony_ci */ 27962306a36Sopenharmony_ciint nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data, 28062306a36Sopenharmony_ci void *cb_priv); 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci/** 28362306a36Sopenharmony_ci * nfp_fl_ct_stats() - Handle flower stats callbacks for ct flows 28462306a36Sopenharmony_ci * @flow: TC flower classifier offload structure. 28562306a36Sopenharmony_ci * @ct_map_ent: ct map entry for the flow that needs deleting 28662306a36Sopenharmony_ci */ 28762306a36Sopenharmony_ciint nfp_fl_ct_stats(struct flow_cls_offload *flow, 28862306a36Sopenharmony_ci struct nfp_fl_ct_map_entry *ct_map_ent); 28962306a36Sopenharmony_ci#endif 290