Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ /* Copyright (C) 2021 Corigine, Inc. */ #ifndef __NFP_FLOWER_CONNTRACK_H__ #define __NFP_FLOWER_CONNTRACK_H__ 1 #include <net/netfilter/nf_flow_table.h> #include "main.h" #define NFP_FL_CT_NO_TUN 0xff #define COMPARE_UNMASKED_FIELDS(__match1, __match2, __out) \ do { \ typeof(__match1) _match1 = (__match1); \ typeof(__match2) _match2 = (__match2); \ bool *_out = (__out); \ int i, size = sizeof(*(_match1).key); \ char *k1, *m1, *k2, *m2; \ *_out = false; \ k1 = (char *)_match1.key; \ m1 = (char *)_match1.mask; \ k2 = (char *)_match2.key; \ m2 = (char *)_match2.mask; \ for (i = 0; i < size; i++) \ if ((k1[i] & m1[i] & m2[i]) ^ \ (k2[i] & m1[i] & m2[i])) { \ *_out = true; \ break; \ } \ } while (0) \ extern const struct rhashtable_params nfp_zone_table_params; extern const struct rhashtable_params nfp_ct_map_params; extern const struct rhashtable_params nfp_tc_ct_merge_params; extern const struct rhashtable_params nfp_nft_ct_merge_params; /** * struct nfp_fl_ct_zone_entry - Zone entry containing conntrack flow information * @zone: The zone number, used as lookup key in hashtable * @hash_node: Used by the hashtable * @priv: Pointer to nfp_flower_priv data * @nft: Pointer to nf_flowtable for this zone * * @pre_ct_list: The pre_ct_list of nfp_fl_ct_flow_entry entries * @pre_ct_count: Keep count of the number of pre_ct entries * * @post_ct_list: The post_ct_list of nfp_fl_ct_flow_entry entries * @post_ct_count: Keep count of the number of post_ct entries * * @tc_merge_tb: The table of merged tc flows * @tc_merge_count: Keep count of the number of merged tc entries * * @nft_flows_list: The list of nft relatednfp_fl_ct_flow_entry entries * @nft_flows_count: Keep count of the number of nft_flow entries * * @nft_merge_tb: The table of merged tc+nft flows * @nft_merge_count: Keep count of the number of merged tc+nft entries */ struct nfp_fl_ct_zone_entry { u16 zone; struct rhash_head hash_node; struct nfp_flower_priv *priv; struct nf_flowtable *nft; struct list_head pre_ct_list; unsigned int pre_ct_count; struct list_head post_ct_list; unsigned int post_ct_count; struct rhashtable tc_merge_tb; unsigned int tc_merge_count; struct list_head nft_flows_list; unsigned int nft_flows_count; struct rhashtable nft_merge_tb; unsigned int nft_merge_count; }; enum ct_entry_type { CT_TYPE_PRE_CT, CT_TYPE_NFT, CT_TYPE_POST_CT, _CT_TYPE_MAX, }; #define NFP_MAX_RECIRC_CT_ZONES 4 #define NFP_MAX_ENTRY_RULES (NFP_MAX_RECIRC_CT_ZONES * 2 + 1) enum nfp_nfp_layer_name { FLOW_PAY_META_TCI = 0, FLOW_PAY_INPORT, FLOW_PAY_EXT_META, FLOW_PAY_MAC_MPLS, FLOW_PAY_L4, FLOW_PAY_IPV4, FLOW_PAY_IPV6, FLOW_PAY_CT, FLOW_PAY_GRE, FLOW_PAY_QINQ, FLOW_PAY_UDP_TUN, FLOW_PAY_GENEVE_OPT, _FLOW_PAY_LAYERS_MAX }; /* NFP flow entry flags. */ #define NFP_FL_ACTION_DO_NAT BIT(0) #define NFP_FL_ACTION_DO_MANGLE BIT(1) /** * struct nfp_fl_ct_flow_entry - Flow entry containing conntrack flow information * @cookie: Flow cookie, same as original TC flow, used as key * @list_node: Used by the list * @chain_index: Chain index of the original flow * @goto_chain_index: goto chain index of the flow * @netdev: netdev structure. * @zt: Reference to the zone table this belongs to * @children: List of tc_merge flows this flow forms part of * @rule: Reference to the original TC flow rule * @stats: Used to cache stats for updating * @prev_m_entries: Array of all previous nft_tc_merge entries * @num_prev_m_entries: The number of all previous nft_tc_merge entries * @tun_offset: Used to indicate tunnel action offset in action list * @flags: Used to indicate flow flag like NAT which used by merge. * @type: Type of ct-entry from enum ct_entry_type */ struct nfp_fl_ct_flow_entry { unsigned long cookie; struct list_head list_node; u32 chain_index; u32 goto_chain_index; struct net_device *netdev; struct nfp_fl_ct_zone_entry *zt; struct list_head children; struct flow_rule *rule; struct flow_stats stats; struct nfp_fl_nft_tc_merge *prev_m_entries[NFP_MAX_RECIRC_CT_ZONES - 1]; u8 num_prev_m_entries; u8 tun_offset; // Set to NFP_FL_CT_NO_TUN if no tun u8 flags; u8 type; }; /** * struct nfp_fl_ct_tc_merge - Merge of two flows from tc * @cookie: Flow cookie, combination of pre and post ct cookies * @hash_node: Used by the hashtable * @pre_ct_list: This entry is part of a pre_ct_list * @post_ct_list: This entry is part of a post_ct_list * @zt: Reference to the zone table this belongs to * @pre_ct_parent: The pre_ct_parent * @post_ct_parent: The post_ct_parent * @children: List of nft merged entries */ struct nfp_fl_ct_tc_merge { unsigned long cookie[2]; struct rhash_head hash_node; struct list_head pre_ct_list; struct list_head post_ct_list; struct nfp_fl_ct_zone_entry *zt; struct nfp_fl_ct_flow_entry *pre_ct_parent; struct nfp_fl_ct_flow_entry *post_ct_parent; struct list_head children; }; /** * struct nfp_fl_nft_tc_merge - Merge of tc_merge flows with nft flow * @netdev: Ingress netdev name * @cookie: Flow cookie, combination of tc_merge and nft cookies * @hash_node: Used by the hashtable * @zt: Reference to the zone table this belongs to * @nft_flow_list: This entry is part of a nft_flows_list * @tc_merge_list: This entry is part of a ct_merge_list * @tc_m_parent: The tc_merge parent * @nft_parent: The nft_entry parent * @tc_flower_cookie: The cookie of the flow offloaded to the nfp * @flow_pay: Reference to the offloaded flow struct * @next_pre_ct_entry: Reference to the next ct zone pre ct entry */ struct nfp_fl_nft_tc_merge { struct net_device *netdev; unsigned long cookie[3]; struct rhash_head hash_node; struct nfp_fl_ct_zone_entry *zt; struct list_head nft_flow_list; struct list_head tc_merge_list; struct nfp_fl_ct_tc_merge *tc_m_parent; struct nfp_fl_ct_flow_entry *nft_parent; unsigned long tc_flower_cookie; struct nfp_fl_payload *flow_pay; struct nfp_fl_ct_flow_entry *next_pre_ct_entry; }; /** * struct nfp_fl_ct_map_entry - Map between flow cookie and specific ct_flow * @cookie: Flow cookie, same as original TC flow, used as key * @hash_node: Used by the hashtable * @ct_entry: Pointer to corresponding ct_entry */ struct nfp_fl_ct_map_entry { unsigned long cookie; struct rhash_head hash_node; struct nfp_fl_ct_flow_entry *ct_entry; }; bool is_pre_ct_flow(struct flow_cls_offload *flow); bool is_post_ct_flow(struct flow_cls_offload *flow); /** * nfp_fl_ct_handle_pre_ct() - Handles -trk conntrack rules * @priv: Pointer to app priv * @netdev: netdev structure. * @flow: TC flower classifier offload structure. * @extack: Extack pointer for errors * @m_entry:previous nfp_fl_nft_tc_merge entry * * Adds a new entry to the relevant zone table and tries to * merge with other +trk+est entries and offload if possible. * * Return: negative value on error, 0 if configured successfully. */ int nfp_fl_ct_handle_pre_ct(struct nfp_flower_priv *priv, struct net_device *netdev, struct flow_cls_offload *flow, struct netlink_ext_ack *extack, struct nfp_fl_nft_tc_merge *m_entry); /** * nfp_fl_ct_handle_post_ct() - Handles +trk+est conntrack rules * @priv: Pointer to app priv * @netdev: netdev structure. * @flow: TC flower classifier offload structure. * @extack: Extack pointer for errors * * Adds a new entry to the relevant zone table and tries to * merge with other -trk entries and offload if possible. * * Return: negative value on error, 0 if configured successfully. */ int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv, struct net_device *netdev, struct flow_cls_offload *flow, struct netlink_ext_ack *extack); /** * nfp_fl_create_new_pre_ct() - create next ct_zone -trk conntrack rules * @m_entry:previous nfp_fl_nft_tc_merge entry * * Create a new pre_ct entry from previous nfp_fl_nft_tc_merge entry * to the next relevant zone table. Try to merge with other +trk+est * entries and offload if possible. The created new pre_ct entry is * linked to the previous nfp_fl_nft_tc_merge entry. * * Return: negative value on error, 0 if configured successfully. */ int nfp_fl_create_new_pre_ct(struct nfp_fl_nft_tc_merge *m_entry); /** * nfp_fl_ct_clean_flow_entry() - Free a nfp_fl_ct_flow_entry * @entry: Flow entry to cleanup */ void nfp_fl_ct_clean_flow_entry(struct nfp_fl_ct_flow_entry *entry); /** * nfp_fl_ct_del_flow() - Handle flow_del callbacks for conntrack * @ct_map_ent: ct map entry for the flow that needs deleting */ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent); /** * nfp_fl_ct_handle_nft_flow() - Handle flower flow callbacks for nft table * @type: Type provided by callback * @type_data: Callback data * @cb_priv: Pointer to data provided when registering the callback, in this * case it's the zone table. */ int nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data, void *cb_priv); /** * nfp_fl_ct_stats() - Handle flower stats callbacks for ct flows * @flow: TC flower classifier offload structure. * @ct_map_ent: ct map entry for the flow that needs deleting */ int nfp_fl_ct_stats(struct flow_cls_offload *flow, struct nfp_fl_ct_map_entry *ct_map_ent); #endif |