1c8b034fbSLouis Peens /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 2c8b034fbSLouis Peens /* Copyright (C) 2021 Corigine, Inc. */ 3c8b034fbSLouis Peens 4c8b034fbSLouis Peens #ifndef __NFP_FLOWER_CONNTRACK_H__ 5c8b034fbSLouis Peens #define __NFP_FLOWER_CONNTRACK_H__ 1 6c8b034fbSLouis Peens 762268e78SLouis Peens #include <net/netfilter/nf_flow_table.h> 8c8b034fbSLouis Peens #include "main.h" 9c8b034fbSLouis Peens 10072c089cSLouis Peens #define NFP_FL_CT_NO_TUN 0xff 11072c089cSLouis Peens 12c698e2adSLouis Peens #define COMPARE_UNMASKED_FIELDS(__match1, __match2, __out) \ 13c698e2adSLouis Peens do { \ 14c698e2adSLouis Peens typeof(__match1) _match1 = (__match1); \ 15c698e2adSLouis Peens typeof(__match2) _match2 = (__match2); \ 16c698e2adSLouis Peens bool *_out = (__out); \ 17c698e2adSLouis Peens int i, size = sizeof(*(_match1).key); \ 18c698e2adSLouis Peens char *k1, *m1, *k2, *m2; \ 19c698e2adSLouis Peens *_out = false; \ 20c698e2adSLouis Peens k1 = (char *)_match1.key; \ 21c698e2adSLouis Peens m1 = (char *)_match1.mask; \ 22c698e2adSLouis Peens k2 = (char *)_match2.key; \ 23c698e2adSLouis Peens m2 = (char *)_match2.mask; \ 24c698e2adSLouis Peens for (i = 0; i < size; i++) \ 25c698e2adSLouis Peens if ((k1[i] & m1[i] & m2[i]) ^ \ 26c698e2adSLouis Peens (k2[i] & m1[i] & m2[i])) { \ 27c698e2adSLouis Peens *_out = true; \ 28c698e2adSLouis Peens break; \ 29c698e2adSLouis Peens } \ 30c698e2adSLouis Peens } while (0) \ 31c698e2adSLouis Peens 32e236e484SLouis Peens extern const struct rhashtable_params nfp_zone_table_params; 33fa81d6d2SLouis Peens extern const struct rhashtable_params nfp_ct_map_params; 34f7ae12e2SLouis Peens extern const struct rhashtable_params nfp_tc_ct_merge_params; 35b5e30c61SLouis Peens extern const struct rhashtable_params nfp_nft_ct_merge_params; 36e236e484SLouis Peens 37e236e484SLouis Peens /** 38e236e484SLouis Peens * struct nfp_fl_ct_zone_entry - Zone entry containing conntrack flow information 39e236e484SLouis Peens * @zone: The zone number, used as lookup key in hashtable 40e236e484SLouis Peens * @hash_node: Used by the hashtable 41e236e484SLouis Peens * @priv: Pointer to nfp_flower_priv data 42e236e484SLouis Peens * @nft: Pointer to nf_flowtable for this zone 43072c089cSLouis Peens * 44072c089cSLouis Peens * @pre_ct_list: The pre_ct_list of nfp_fl_ct_flow_entry entries 45072c089cSLouis Peens * @pre_ct_count: Keep count of the number of pre_ct entries 46072c089cSLouis Peens * 47072c089cSLouis Peens * @post_ct_list: The post_ct_list of nfp_fl_ct_flow_entry entries 48072c089cSLouis Peens * @post_ct_count: Keep count of the number of post_ct entries 49f7ae12e2SLouis Peens * 50f7ae12e2SLouis Peens * @tc_merge_tb: The table of merged tc flows 51f7ae12e2SLouis Peens * @tc_merge_count: Keep count of the number of merged tc entries 5295255017SLouis Peens * 5395255017SLouis Peens * @nft_flows_list: The list of nft relatednfp_fl_ct_flow_entry entries 5495255017SLouis Peens * @nft_flows_count: Keep count of the number of nft_flow entries 55b5e30c61SLouis Peens * 56b5e30c61SLouis Peens * @nft_merge_tb: The table of merged tc+nft flows 57b5e30c61SLouis Peens * @nft_merge_count: Keep count of the number of merged tc+nft entries 58e236e484SLouis Peens */ 59e236e484SLouis Peens struct nfp_fl_ct_zone_entry { 60e236e484SLouis Peens u16 zone; 61e236e484SLouis Peens struct rhash_head hash_node; 62e236e484SLouis Peens 63e236e484SLouis Peens struct nfp_flower_priv *priv; 64e236e484SLouis Peens struct nf_flowtable *nft; 65072c089cSLouis Peens 66072c089cSLouis Peens struct list_head pre_ct_list; 67072c089cSLouis Peens unsigned int pre_ct_count; 68072c089cSLouis Peens 69072c089cSLouis Peens struct list_head post_ct_list; 70072c089cSLouis Peens unsigned int post_ct_count; 71f7ae12e2SLouis Peens 72f7ae12e2SLouis Peens struct rhashtable tc_merge_tb; 73f7ae12e2SLouis Peens unsigned int tc_merge_count; 7495255017SLouis Peens 7595255017SLouis Peens struct list_head nft_flows_list; 7695255017SLouis Peens unsigned int nft_flows_count; 77b5e30c61SLouis Peens 78b5e30c61SLouis Peens struct rhashtable nft_merge_tb; 79b5e30c61SLouis Peens unsigned int nft_merge_count; 80072c089cSLouis Peens }; 81072c089cSLouis Peens 82072c089cSLouis Peens enum ct_entry_type { 83072c089cSLouis Peens CT_TYPE_PRE_CT, 84072c089cSLouis Peens CT_TYPE_NFT, 85072c089cSLouis Peens CT_TYPE_POST_CT, 8671e88cfbSLouis Peens _CT_TYPE_MAX, 8771e88cfbSLouis Peens }; 8871e88cfbSLouis Peens 89*a87ceb3dSWentao Jia #define NFP_MAX_RECIRC_CT_ZONES 4 90*a87ceb3dSWentao Jia #define NFP_MAX_ENTRY_RULES (NFP_MAX_RECIRC_CT_ZONES * 2 + 1) 91*a87ceb3dSWentao Jia 9271e88cfbSLouis Peens enum nfp_nfp_layer_name { 9371e88cfbSLouis Peens FLOW_PAY_META_TCI = 0, 9471e88cfbSLouis Peens FLOW_PAY_INPORT, 9571e88cfbSLouis Peens FLOW_PAY_EXT_META, 9671e88cfbSLouis Peens FLOW_PAY_MAC_MPLS, 9771e88cfbSLouis Peens FLOW_PAY_L4, 9871e88cfbSLouis Peens FLOW_PAY_IPV4, 9971e88cfbSLouis Peens FLOW_PAY_IPV6, 10071e88cfbSLouis Peens FLOW_PAY_CT, 10171e88cfbSLouis Peens FLOW_PAY_GRE, 10271e88cfbSLouis Peens FLOW_PAY_QINQ, 10371e88cfbSLouis Peens FLOW_PAY_UDP_TUN, 10471e88cfbSLouis Peens FLOW_PAY_GENEVE_OPT, 10571e88cfbSLouis Peens 10671e88cfbSLouis Peens _FLOW_PAY_LAYERS_MAX 107072c089cSLouis Peens }; 108072c089cSLouis Peens 1095cee92c6SHui Zhou /* NFP flow entry flags. */ 1105cee92c6SHui Zhou #define NFP_FL_ACTION_DO_NAT BIT(0) 1115cee92c6SHui Zhou #define NFP_FL_ACTION_DO_MANGLE BIT(1) 1125cee92c6SHui Zhou 113072c089cSLouis Peens /** 114072c089cSLouis Peens * struct nfp_fl_ct_flow_entry - Flow entry containing conntrack flow information 115072c089cSLouis Peens * @cookie: Flow cookie, same as original TC flow, used as key 116072c089cSLouis Peens * @list_node: Used by the list 117072c089cSLouis Peens * @chain_index: Chain index of the original flow 1183e44d199SWentao Jia * @goto_chain_index: goto chain index of the flow 119072c089cSLouis Peens * @netdev: netdev structure. 120072c089cSLouis Peens * @zt: Reference to the zone table this belongs to 121072c089cSLouis Peens * @children: List of tc_merge flows this flow forms part of 122072c089cSLouis Peens * @rule: Reference to the original TC flow rule 123072c089cSLouis Peens * @stats: Used to cache stats for updating 124*a87ceb3dSWentao Jia * @prev_m_entries: Array of all previous nft_tc_merge entries 125*a87ceb3dSWentao Jia * @num_prev_m_entries: The number of all previous nft_tc_merge entries 126072c089cSLouis Peens * @tun_offset: Used to indicate tunnel action offset in action list 1275cee92c6SHui Zhou * @flags: Used to indicate flow flag like NAT which used by merge. 128*a87ceb3dSWentao Jia * @type: Type of ct-entry from enum ct_entry_type 129072c089cSLouis Peens */ 130072c089cSLouis Peens struct nfp_fl_ct_flow_entry { 131072c089cSLouis Peens unsigned long cookie; 132072c089cSLouis Peens struct list_head list_node; 133072c089cSLouis Peens u32 chain_index; 1343e44d199SWentao Jia u32 goto_chain_index; 135072c089cSLouis Peens struct net_device *netdev; 136072c089cSLouis Peens struct nfp_fl_ct_zone_entry *zt; 137072c089cSLouis Peens struct list_head children; 138072c089cSLouis Peens struct flow_rule *rule; 139072c089cSLouis Peens struct flow_stats stats; 140*a87ceb3dSWentao Jia struct nfp_fl_nft_tc_merge *prev_m_entries[NFP_MAX_RECIRC_CT_ZONES - 1]; 141*a87ceb3dSWentao Jia u8 num_prev_m_entries; 142072c089cSLouis Peens u8 tun_offset; // Set to NFP_FL_CT_NO_TUN if no tun 1435cee92c6SHui Zhou u8 flags; 144*a87ceb3dSWentao Jia u8 type; 145e236e484SLouis Peens }; 146e236e484SLouis Peens 147fa81d6d2SLouis Peens /** 148f7ae12e2SLouis Peens * struct nfp_fl_ct_tc_merge - Merge of two flows from tc 149f7ae12e2SLouis Peens * @cookie: Flow cookie, combination of pre and post ct cookies 150f7ae12e2SLouis Peens * @hash_node: Used by the hashtable 151f7ae12e2SLouis Peens * @pre_ct_list: This entry is part of a pre_ct_list 152f7ae12e2SLouis Peens * @post_ct_list: This entry is part of a post_ct_list 153f7ae12e2SLouis Peens * @zt: Reference to the zone table this belongs to 154f7ae12e2SLouis Peens * @pre_ct_parent: The pre_ct_parent 155f7ae12e2SLouis Peens * @post_ct_parent: The post_ct_parent 156f7ae12e2SLouis Peens * @children: List of nft merged entries 157f7ae12e2SLouis Peens */ 158f7ae12e2SLouis Peens struct nfp_fl_ct_tc_merge { 159f7ae12e2SLouis Peens unsigned long cookie[2]; 160f7ae12e2SLouis Peens struct rhash_head hash_node; 161f7ae12e2SLouis Peens struct list_head pre_ct_list; 162f7ae12e2SLouis Peens struct list_head post_ct_list; 163f7ae12e2SLouis Peens struct nfp_fl_ct_zone_entry *zt; 164f7ae12e2SLouis Peens struct nfp_fl_ct_flow_entry *pre_ct_parent; 165f7ae12e2SLouis Peens struct nfp_fl_ct_flow_entry *post_ct_parent; 166f7ae12e2SLouis Peens struct list_head children; 167f7ae12e2SLouis Peens }; 168f7ae12e2SLouis Peens 169f7ae12e2SLouis Peens /** 170b5e30c61SLouis Peens * struct nfp_fl_nft_tc_merge - Merge of tc_merge flows with nft flow 171b5e30c61SLouis Peens * @netdev: Ingress netdev name 172b5e30c61SLouis Peens * @cookie: Flow cookie, combination of tc_merge and nft cookies 173b5e30c61SLouis Peens * @hash_node: Used by the hashtable 174b5e30c61SLouis Peens * @zt: Reference to the zone table this belongs to 175b5e30c61SLouis Peens * @nft_flow_list: This entry is part of a nft_flows_list 176b5e30c61SLouis Peens * @tc_merge_list: This entry is part of a ct_merge_list 177b5e30c61SLouis Peens * @tc_m_parent: The tc_merge parent 178b5e30c61SLouis Peens * @nft_parent: The nft_entry parent 179b5e30c61SLouis Peens * @tc_flower_cookie: The cookie of the flow offloaded to the nfp 180b5e30c61SLouis Peens * @flow_pay: Reference to the offloaded flow struct 181*a87ceb3dSWentao Jia * @next_pre_ct_entry: Reference to the next ct zone pre ct entry 182b5e30c61SLouis Peens */ 183b5e30c61SLouis Peens struct nfp_fl_nft_tc_merge { 184b5e30c61SLouis Peens struct net_device *netdev; 185b5e30c61SLouis Peens unsigned long cookie[3]; 186b5e30c61SLouis Peens struct rhash_head hash_node; 187b5e30c61SLouis Peens struct nfp_fl_ct_zone_entry *zt; 188b5e30c61SLouis Peens struct list_head nft_flow_list; 189b5e30c61SLouis Peens struct list_head tc_merge_list; 190b5e30c61SLouis Peens struct nfp_fl_ct_tc_merge *tc_m_parent; 191b5e30c61SLouis Peens struct nfp_fl_ct_flow_entry *nft_parent; 192b5e30c61SLouis Peens unsigned long tc_flower_cookie; 193b5e30c61SLouis Peens struct nfp_fl_payload *flow_pay; 194*a87ceb3dSWentao Jia struct nfp_fl_ct_flow_entry *next_pre_ct_entry; 195b5e30c61SLouis Peens }; 196b5e30c61SLouis Peens 197b5e30c61SLouis Peens /** 198fa81d6d2SLouis Peens * struct nfp_fl_ct_map_entry - Map between flow cookie and specific ct_flow 199fa81d6d2SLouis Peens * @cookie: Flow cookie, same as original TC flow, used as key 200fa81d6d2SLouis Peens * @hash_node: Used by the hashtable 201fa81d6d2SLouis Peens * @ct_entry: Pointer to corresponding ct_entry 202fa81d6d2SLouis Peens */ 203fa81d6d2SLouis Peens struct nfp_fl_ct_map_entry { 204fa81d6d2SLouis Peens unsigned long cookie; 205fa81d6d2SLouis Peens struct rhash_head hash_node; 206fa81d6d2SLouis Peens struct nfp_fl_ct_flow_entry *ct_entry; 207fa81d6d2SLouis Peens }; 208fa81d6d2SLouis Peens 209c8b034fbSLouis Peens bool is_pre_ct_flow(struct flow_cls_offload *flow); 210c8b034fbSLouis Peens bool is_post_ct_flow(struct flow_cls_offload *flow); 211c8b034fbSLouis Peens 212c8b034fbSLouis Peens /** 213c8b034fbSLouis Peens * nfp_fl_ct_handle_pre_ct() - Handles -trk conntrack rules 214c8b034fbSLouis Peens * @priv: Pointer to app priv 215c8b034fbSLouis Peens * @netdev: netdev structure. 216c8b034fbSLouis Peens * @flow: TC flower classifier offload structure. 217c8b034fbSLouis Peens * @extack: Extack pointer for errors 218*a87ceb3dSWentao Jia * @m_entry:previous nfp_fl_nft_tc_merge entry 219c8b034fbSLouis Peens * 220c8b034fbSLouis Peens * Adds a new entry to the relevant zone table and tries to 221c8b034fbSLouis Peens * merge with other +trk+est entries and offload if possible. 222c8b034fbSLouis Peens * 223c8b034fbSLouis Peens * Return: negative value on error, 0 if configured successfully. 224c8b034fbSLouis Peens */ 225c8b034fbSLouis Peens int nfp_fl_ct_handle_pre_ct(struct nfp_flower_priv *priv, 226c8b034fbSLouis Peens struct net_device *netdev, 227c8b034fbSLouis Peens struct flow_cls_offload *flow, 228*a87ceb3dSWentao Jia struct netlink_ext_ack *extack, 229*a87ceb3dSWentao Jia struct nfp_fl_nft_tc_merge *m_entry); 230c8b034fbSLouis Peens /** 231c8b034fbSLouis Peens * nfp_fl_ct_handle_post_ct() - Handles +trk+est conntrack rules 232c8b034fbSLouis Peens * @priv: Pointer to app priv 233c8b034fbSLouis Peens * @netdev: netdev structure. 234c8b034fbSLouis Peens * @flow: TC flower classifier offload structure. 235c8b034fbSLouis Peens * @extack: Extack pointer for errors 236c8b034fbSLouis Peens * 237c8b034fbSLouis Peens * Adds a new entry to the relevant zone table and tries to 238c8b034fbSLouis Peens * merge with other -trk entries and offload if possible. 239c8b034fbSLouis Peens * 240c8b034fbSLouis Peens * Return: negative value on error, 0 if configured successfully. 241c8b034fbSLouis Peens */ 242c8b034fbSLouis Peens int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv, 243c8b034fbSLouis Peens struct net_device *netdev, 244c8b034fbSLouis Peens struct flow_cls_offload *flow, 245c8b034fbSLouis Peens struct netlink_ext_ack *extack); 246c8b034fbSLouis Peens 247072c089cSLouis Peens /** 248*a87ceb3dSWentao Jia * nfp_fl_create_new_pre_ct() - create next ct_zone -trk conntrack rules 249*a87ceb3dSWentao Jia * @m_entry:previous nfp_fl_nft_tc_merge entry 250*a87ceb3dSWentao Jia * 251*a87ceb3dSWentao Jia * Create a new pre_ct entry from previous nfp_fl_nft_tc_merge entry 252*a87ceb3dSWentao Jia * to the next relevant zone table. Try to merge with other +trk+est 253*a87ceb3dSWentao Jia * entries and offload if possible. The created new pre_ct entry is 254*a87ceb3dSWentao Jia * linked to the previous nfp_fl_nft_tc_merge entry. 255*a87ceb3dSWentao Jia * 256*a87ceb3dSWentao Jia * Return: negative value on error, 0 if configured successfully. 257*a87ceb3dSWentao Jia */ 258*a87ceb3dSWentao Jia int nfp_fl_create_new_pre_ct(struct nfp_fl_nft_tc_merge *m_entry); 259*a87ceb3dSWentao Jia 260*a87ceb3dSWentao Jia /** 261072c089cSLouis Peens * nfp_fl_ct_clean_flow_entry() - Free a nfp_fl_ct_flow_entry 262072c089cSLouis Peens * @entry: Flow entry to cleanup 263072c089cSLouis Peens */ 264072c089cSLouis Peens void nfp_fl_ct_clean_flow_entry(struct nfp_fl_ct_flow_entry *entry); 265d33d24a7SLouis Peens 266d33d24a7SLouis Peens /** 267d33d24a7SLouis Peens * nfp_fl_ct_del_flow() - Handle flow_del callbacks for conntrack 268d33d24a7SLouis Peens * @ct_map_ent: ct map entry for the flow that needs deleting 269d33d24a7SLouis Peens */ 270d33d24a7SLouis Peens int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent); 27162268e78SLouis Peens 27262268e78SLouis Peens /** 27362268e78SLouis Peens * nfp_fl_ct_handle_nft_flow() - Handle flower flow callbacks for nft table 27462268e78SLouis Peens * @type: Type provided by callback 27562268e78SLouis Peens * @type_data: Callback data 27662268e78SLouis Peens * @cb_priv: Pointer to data provided when registering the callback, in this 27762268e78SLouis Peens * case it's the zone table. 27862268e78SLouis Peens */ 27962268e78SLouis Peens int nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data, 28062268e78SLouis Peens void *cb_priv); 28140c10bd9SLouis Peens 28240c10bd9SLouis Peens /** 28340c10bd9SLouis Peens * nfp_fl_ct_stats() - Handle flower stats callbacks for ct flows 28440c10bd9SLouis Peens * @flow: TC flower classifier offload structure. 28540c10bd9SLouis Peens * @ct_map_ent: ct map entry for the flow that needs deleting 28640c10bd9SLouis Peens */ 28740c10bd9SLouis Peens int nfp_fl_ct_stats(struct flow_cls_offload *flow, 28840c10bd9SLouis Peens struct nfp_fl_ct_map_entry *ct_map_ent); 289c8b034fbSLouis Peens #endif 290