xref: /dpdk/lib/table/rte_swx_table.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4 #ifndef __INCLUDE_RTE_SWX_TABLE_H__
5 #define __INCLUDE_RTE_SWX_TABLE_H__
6 
7 /**
8  * @file
9  * RTE SWX Table
10  *
11  * Table interface.
12  */
13 
14 #include <stdint.h>
15 
16 #include <rte_os.h>
17 
18 #include "rte_swx_hash_func.h"
19 
20 /** Match type. */
21 enum rte_swx_table_match_type {
22 	/** Wildcard Match (WM). */
23 	RTE_SWX_TABLE_MATCH_WILDCARD,
24 
25 	/** Longest Prefix Match (LPM). */
26 	RTE_SWX_TABLE_MATCH_LPM,
27 
28 	/** Exact Match (EM). */
29 	RTE_SWX_TABLE_MATCH_EXACT,
30 };
31 
32 /** Table creation parameters. */
33 struct rte_swx_table_params {
34 	/** Table match type. */
35 	enum rte_swx_table_match_type match_type;
36 
37 	/** Key size in bytes. */
38 	uint32_t key_size;
39 
40 	/** Offset of the first byte of the key within the key buffer. */
41 	uint32_t key_offset;
42 
43 	/** Mask of *key_size* bytes logically laid over the bytes at positions
44 	 * *key_offset* .. (*key_offset* + *key_size* - 1) of the key buffer in
45 	 * order to specify which bits from the key buffer are part of the key
46 	 * and which ones are not. A bit value of 1 in the *key_mask0* means the
47 	 * respective bit in the key buffer is part of the key, while a bit
48 	 * value of 0 means the opposite. A NULL value means that all the bits
49 	 * are part of the key, i.e. the *key_mask0* is an all-ones mask.
50 	 */
51 	uint8_t *key_mask0;
52 
53 	/** Maximum size (in bytes) of the action data. The data stored in the
54 	 * table for each entry is equal to *action_data_size* plus 8 bytes,
55 	 * which are used to store the action ID.
56 	 */
57 	uint32_t action_data_size;
58 
59 	/** Hash function. Ignored when not needed by the table implementation.
60 	 * When needed but set to NULL, the table implementation will select the
61 	 * hash function to use.
62 	 */
63 	rte_swx_hash_func_t hash_func;
64 
65 	/** Maximum number of keys to be stored in the table together with their
66 	 * associated data.
67 	 */
68 	uint32_t n_keys_max;
69 };
70 
71 /** Table entry. */
72 struct rte_swx_table_entry {
73 	/** Used to facilitate the membership of this table entry to a
74 	 * linked list.
75 	 */
76 	RTE_TAILQ_ENTRY(rte_swx_table_entry) node;
77 
78 	/** Key value for the current entry. Array of *key_size* bytes or NULL
79 	 * if the *key_size* for the current table is 0.
80 	 */
81 	uint8_t *key;
82 
83 	/** Key mask for the current entry. Array of *key_size* bytes that is
84 	 * logically and'ed with *key_mask0* of the current table. A NULL value
85 	 * means that all the key bits already enabled by *key_mask0* are part
86 	 * of the key of the current entry.
87 	 */
88 	uint8_t *key_mask;
89 
90 	/** Placeholder for a possible compressed version of the *key* and
91 	 * *key_mask* of the current entry. Typically a hash signature, its main
92 	 * purpose is to the linked list search operation. Should be ignored by
93 	 * the API functions below.
94 	 */
95 	uint64_t key_signature;
96 
97 	/** Key priority for the current entry. Useful for wildcard match (as
98 	 * match rules are commonly overlapping with other rules), ignored for
99 	 * exact match (as match rules never overlap, hence all rules have the
100 	 * same match priority) and for LPM (match priority is driven by the
101 	 * prefix length, with non-overlapping prefixes essentially having the
102 	 * same match priority). Value 0 indicates the highest match priority.
103 	 */
104 	uint32_t key_priority;
105 
106 	/** Action ID for the current entry. */
107 	uint64_t action_id;
108 
109 	/** Action data for the current entry. Considering S as the action data
110 	 * size of the *action_id* action, which must be less than or equal to
111 	 * the table *action_data_size*, the *action_data* field must point to
112 	 * an array of S bytes when S is non-zero. The *action_data* field is
113 	 * ignored when S is zero.
114 	 */
115 	uint8_t *action_data;
116 };
117 
118 /** List of table entries. */
119 RTE_TAILQ_HEAD(rte_swx_table_entry_list, rte_swx_table_entry);
120 
121 /**
122  * Table memory footprint get
123  *
124  * @param[in] params
125  *   Table create parameters.
126  * @param[in] entries
127  *   Table entries.
128  * @param[in] args
129  *   Any additional table create arguments. It may be NULL.
130  * @return
131  *   Table memory footprint in bytes, if successful, or zero, on error.
132  */
133 typedef uint64_t
134 (*rte_swx_table_footprint_get_t)(struct rte_swx_table_params *params,
135 				 struct rte_swx_table_entry_list *entries,
136 				 const char *args);
137 
138 /**
139  * Table mailbox size get
140  *
141  * The mailbox is used to store the context of a lookup operation that is in
142  * progress and it is passed as a parameter to the lookup operation. This allows
143  * for multiple concurrent lookup operations into the same table.
144  *
145  * @return
146  *   Table memory footprint in bytes, on success, or zero, on error.
147  */
148 typedef uint64_t
149 (*rte_swx_table_mailbox_size_get_t)(void);
150 
151 /**
152  * Table create
153  *
154  * @param[in] params
155  *   Table creation parameters.
156  * @param[in] entries
157  *   Entries to be added to the table at creation time.
158  * @param[in] args
159  *   Any additional table create arguments. It may be NULL.
160  * @param[in] numa_node
161  *   Non-Uniform Memory Access (NUMA) node.
162  * @return
163  *   Table handle, on success, or NULL, on error.
164  */
165 typedef void *
166 (*rte_swx_table_create_t)(struct rte_swx_table_params *params,
167 			  struct rte_swx_table_entry_list *entries,
168 			  const char *args,
169 			  int numa_node);
170 
171 /**
172  * Table entry add
173  *
174  * @param[in] table
175  *   Table handle.
176  * @param[in] entry
177  *   Entry to be added to the table.
178  * @return
179  *   0 on success or the following error codes otherwise:
180  *   -EINVAL: Invalid table handle, entry or entry field;
181  *   -ENOSPC: Table full.
182  */
183 typedef int
184 (*rte_swx_table_add_t)(void *table,
185 		       struct rte_swx_table_entry *entry);
186 
187 /**
188  * Table entry delete
189  *
190  * @param[in] table
191  *   Table handle.
192  * @param[in] entry
193  *   Entry to be deleted from the table. The entry *action_id* and *action_data*
194  *   fields are ignored.
195  * @return
196  *   0 on success or the following error codes otherwise:
197  *   -EINVAL: Invalid table handle, entry or entry field;
198  *   -ENOSPC: Table full.
199  */
200 typedef int
201 (*rte_swx_table_delete_t)(void *table,
202 			  struct rte_swx_table_entry *entry);
203 
204 /**
205  * Table lookup
206  *
207  * The table lookup operation searches a given key in the table and upon its
208  * completion it returns an indication of whether the key is found in the table
209  * (lookup hit) or not (lookup miss). In case of lookup hit, the action_id and
210  * the action_data associated with the key are also returned.
211  *
212  * Multiple invocations of this function may be required in order to complete a
213  * single table lookup operation for a given table and a given lookup key. The
214  * completion of the table lookup operation is flagged by a return value of 1;
215  * in case of a return value of 0, the function must be invoked again with
216  * exactly the same arguments.
217  *
218  * The mailbox argument is used to store the context of an on-going table lookup
219  * operation. The mailbox mechanism allows for multiple concurrent table lookup
220  * operations into the same table.
221  *
222  * The typical reason an implementation may choose to split the table lookup
223  * operation into multiple steps is to hide the latency of the inherent memory
224  * read operations: before a read operation with the source data likely not in
225  * the CPU cache, the source data prefetch is issued and the table lookup
226  * operation is postponed in favor of some other unrelated work, which the CPU
227  * executes in parallel with the source data being fetched into the CPU cache;
228  * later on, the table lookup operation is resumed, this time with the source
229  * data likely to be read from the CPU cache with no CPU pipeline stall, which
230  * significantly improves the table lookup performance.
231  *
232  * The table entry consists of the action ID and the action data. Each table
233  * entry is unique, although different table entries can have identical content,
234  * i.e. same values for the action ID and the action data. The table entry ID is
235  * also returned by the table lookup operation. It can be used to index into an
236  * external array of resources such as counters, registers or meters to identify
237  * the resource directly associated with the current table entry with no need to
238  * store the corresponding index into the table entry. The index of the external
239  * resource is thus auto-generated instead of being stored in the table entry.
240  *
241  * @param[in] table
242  *   Table handle.
243  * @param[in] mailbox
244  *   Mailbox for the current table lookup operation.
245  * @param[in] key
246  *   Lookup key. Its size mult be equal to the table *key_size*. If the latter
247  *   is zero, then the lookup key must be NULL.
248  * @param[out] action_id
249  *   ID of the action associated with the *key*. Must point to a valid 64-bit
250  *   variable. Only valid when the function returns 1 and *hit* is set to true.
251  * @param[out] action_data
252  *   Action data for the *action_id* action. Must point to a valid array of
253  *   table *action_data_size* bytes. Only valid when the function returns 1 and
254  *   *hit* is set to true.
255  * @param[out] entry_id
256  *   Table entry unique ID. Must point to a valid 32-bit variable. Only valid
257  *   when the function returns 1 and *hit* is set to true.
258  * @param[out] hit
259  *   Only valid when the function returns 1. Set to non-zero (true) on table
260  *   lookup hit and to zero (false) on table lookup miss.
261  * @return
262  *   0 when the table lookup operation is not yet completed, and 1 when the
263  *   table lookup operation is completed. No other return values are allowed.
264  */
265 typedef int
266 (*rte_swx_table_lookup_t)(void *table,
267 			  void *mailbox,
268 			  uint8_t **key,
269 			  uint64_t *action_id,
270 			  uint8_t **action_data,
271 			  size_t *entry_id,
272 			  int *hit);
273 
274 /**
275  * Table free
276  *
277  * @param[in] table
278  *   Table handle.
279  */
280 typedef void
281 (*rte_swx_table_free_t)(void *table);
282 
283 /** Table operations.  */
284 struct rte_swx_table_ops {
285 	/** Table memory footprint get. Set to NULL when not supported. */
286 	rte_swx_table_footprint_get_t footprint_get;
287 
288 	/** Table mailbox size get. When NULL, the mailbox size is 0. */
289 	rte_swx_table_mailbox_size_get_t mailbox_size_get;
290 
291 	/** Table create. Must be non-NULL. */
292 	rte_swx_table_create_t create;
293 
294 	/** Incremental table entry add. Set to NULL when not supported, in
295 	 * which case the existing table has to be destroyed and a new table
296 	 * built from scratch with the new entry included.
297 	 */
298 	rte_swx_table_add_t add;
299 
300 	/** Incremental table entry delete. Set to NULL when not supported, in
301 	 * which case the existing table has to be destroyed and a new table
302 	 * built from scratch with the entry excluded.
303 	 */
304 	rte_swx_table_delete_t del;
305 
306 	/** Table lookup. Must be non-NULL. */
307 	rte_swx_table_lookup_t lkp;
308 
309 	/** Table free. Must be non-NULL. */
310 	rte_swx_table_free_t free;
311 };
312 
313 #endif
314