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