NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
flow_skeleton.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #include <stdlib.h>
27 
28 #include <doca_log.h>
29 #include <doca_error.h>
30 
31 #include "flow_skeleton.h"
32 
33 DOCA_LOG_REGISTER(FLOW_SKELETON);
34 
35 #define DEFAULT_QUEUE_DEPTH 128 /* DOCA Flow default queue depth */
36 #define DEFAULT_TIMEOUT_US 10000 /* Timeout for processing pipe entries */
37 #define QUOTA_TIME 20 /* max handling aging time in ms */
38 
39 struct skeleton_ctx {
40  uint32_t queue_depth; /* DOCA Flow queue depth */
41  struct flow_skeleton_cfg skeleton_cfg; /* pointer to skeleton config */
42  uint32_t **queue_state; /* array to monitor the queues state */
43  uint32_t *queue_counter; /* array to count how many entries processed */
44  struct flow_skeleton_entry *entries; /* array of flow skeleton entries */
45  void **program_ctx; /* application context from main loop */
46 };
47 
48 static struct skeleton_ctx skeleton_ctx;
49 static volatile bool force_quit;
50 
51 /*
52  * Entry processing callback
53  *
54  * @entry [in]: entry pointer
55  * @pipe_queue [in]: queue identifier
56  * @status [in]: DOCA Flow entry status
57  * @op [in]: DOCA Flow entry operation
58  * @user_ctx [out]: user context
59  */
60 static void process_callback(struct doca_flow_pipe_entry *entry,
61  uint16_t pipe_queue,
62  enum doca_flow_entry_status status,
63  enum doca_flow_entry_op op,
64  void *user_ctx)
65 {
67 
68  if (op == DOCA_FLOW_ENTRY_OP_ADD) {
69  /* call application callback */
71  skeleton_ctx.skeleton_cfg.add_cb(entry, pipe_queue, status, user_ctx, skeleton_ctx.program_ctx);
72  if (status != DOCA_FLOW_ENTRY_STATUS_SUCCESS) {
73  DOCA_LOG_ERR("Failed to add entry");
74  /* if status is not success - the skeleton will remove the entry */
76  if (result != DOCA_SUCCESS)
77  DOCA_LOG_ERR("Failed to remove entry: %s", doca_error_get_descr(result));
78  } else
79  skeleton_ctx.queue_counter[pipe_queue]++;
80  } else if (op == DOCA_FLOW_ENTRY_OP_DEL) {
81  /* call application callback */
84  pipe_queue,
85  status,
86  user_ctx,
87  skeleton_ctx.program_ctx[pipe_queue]);
88  if (status != DOCA_FLOW_ENTRY_STATUS_SUCCESS) {
89  /* if status is not success - notify the application about a failure */
90  DOCA_LOG_ERR("Failed to remove entry");
93  } else
94  skeleton_ctx.queue_counter[pipe_queue]++;
95  } else if (op == DOCA_FLOW_ENTRY_OP_AGED) {
96  struct flow_skeleton_aging_op aging_op = {0};
97 
99  if (aging_op.to_remove) {
101  if (result != DOCA_SUCCESS)
102  DOCA_LOG_ERR("Failed to remove entry: %s", doca_error_get_descr(result));
103  }
104  }
105 }
106 
107 doca_error_t flow_skeleton_init(struct doca_flow_cfg *flow_cfg, struct flow_skeleton_cfg *skeleton_cfg)
108 {
109  uint32_t i;
111 
112  memcpy(&skeleton_ctx.skeleton_cfg, skeleton_cfg, sizeof(struct flow_skeleton_cfg));
113  skeleton_ctx.queue_depth = skeleton_cfg->queue_depth == 0 ? DEFAULT_QUEUE_DEPTH : skeleton_cfg->queue_depth;
114 
115  if (skeleton_cfg->entries_acquisition_cb == NULL) {
116  DOCA_LOG_ERR("Entries acquisition callback must be provided");
118  }
119 
120  if (skeleton_cfg->handle_aging && skeleton_cfg->aging_cb == NULL) {
121  DOCA_LOG_ERR("Aging callback must be provided when enable handle aging");
123  }
124 
125  if (skeleton_cfg->nb_entries > skeleton_ctx.queue_depth / 2) {
126  DOCA_LOG_ERR("Queue depth should be at least twice larger than nb_entries");
128  }
129 
131  (struct flow_skeleton_entry *)calloc(skeleton_cfg->nb_entries, sizeof(struct flow_skeleton_entry));
132  if (skeleton_ctx.entries == NULL) {
133  DOCA_LOG_ERR("Failed to allocate memory");
134  return DOCA_ERROR_NO_MEMORY;
135  }
136  skeleton_ctx.program_ctx = (void *)calloc(skeleton_cfg->nb_queues, sizeof(void *));
137  if (skeleton_ctx.program_ctx == NULL) {
138  DOCA_LOG_ERR("Failed to allocate memory");
140  goto free_entries;
141  }
142  skeleton_ctx.queue_counter = (uint32_t *)calloc(skeleton_cfg->nb_queues, sizeof(uint32_t));
144  DOCA_LOG_ERR("Failed to allocate memory");
146  goto free_program_ctx;
147  }
148  skeleton_ctx.queue_state = (uint32_t **)calloc(skeleton_cfg->nb_ports, sizeof(uint32_t *));
149  if (skeleton_ctx.program_ctx == NULL) {
150  DOCA_LOG_ERR("Failed to allocate memory");
152  goto free_queue_counter;
153  }
154  for (i = 0; i < skeleton_cfg->nb_ports; i++) {
155  skeleton_ctx.queue_state[i] = (uint32_t *)calloc(skeleton_cfg->nb_queues, sizeof(uint32_t));
156  if (skeleton_ctx.program_ctx == NULL) {
157  uint32_t j;
158 
159  DOCA_LOG_ERR("Failed to allocate memory");
160  for (j = 0; j < i; j++)
161  free(skeleton_ctx.queue_state[j]);
163  goto free_queue_state;
164  }
165  }
166 
167  result = doca_flow_cfg_create(&flow_cfg);
168  if (result != DOCA_SUCCESS) {
169  DOCA_LOG_ERR("Failed to create doca_flow_cfg: %s", doca_error_get_descr(result));
170  goto free_queue_state_raw;
171  }
172 
173  result = doca_flow_cfg_set_pipe_queues(flow_cfg, skeleton_cfg->nb_queues);
174  if (result != DOCA_SUCCESS) {
175  DOCA_LOG_ERR("Failed to set doca_flow_cfg pipe_queues: %s", doca_error_get_descr(result));
176  goto destroy_flow_cfg;
177  }
178 
179  result = doca_flow_cfg_set_queue_depth(flow_cfg, skeleton_cfg->queue_depth);
180  if (result != DOCA_SUCCESS) {
181  DOCA_LOG_ERR("Failed to set doca_flow_cfg queue_depth: %s", doca_error_get_descr(result));
182  goto destroy_flow_cfg;
183  }
184 
186  if (result != DOCA_SUCCESS) {
187  DOCA_LOG_ERR("Failed to set doca_flow_cfg cb_entry_process: %s", doca_error_get_descr(result));
188  goto destroy_flow_cfg;
189  }
190 
191  result = doca_flow_init(flow_cfg);
192  if (result != DOCA_SUCCESS) {
193  DOCA_LOG_ERR("Failed to init DOCA Flow: %s", doca_error_get_descr(result));
195  goto destroy_flow_cfg;
196  }
197 
198  result = doca_flow_cfg_destroy(flow_cfg);
199  if (result != DOCA_SUCCESS) {
200  DOCA_LOG_ERR("Failed to destroy doca_flow_cfg: %s", doca_error_get_descr(result));
201  goto free_queue_state_raw;
202  }
203 
204  force_quit = false;
205  return DOCA_SUCCESS;
206 
207 destroy_flow_cfg:
208  doca_flow_cfg_destroy(flow_cfg);
209 free_queue_state_raw:
210  for (i = 0; i < skeleton_cfg->nb_ports; i++)
211  free(skeleton_ctx.queue_state[i]);
212 free_queue_state:
214 free_queue_counter:
216 free_program_ctx:
218 free_entries:
219  free(skeleton_ctx.entries);
220  return result;
221 }
222 
224 {
225  uint32_t i;
226 
227  if (skeleton_ctx.entries != NULL)
228  free(skeleton_ctx.entries);
229 
232 
235 
236  if (skeleton_ctx.queue_state != NULL) {
237  for (i = 0; i < skeleton_ctx.skeleton_cfg.nb_ports; i++) {
238  if (skeleton_ctx.queue_state[i] != NULL)
239  free(skeleton_ctx.queue_state[i]);
240  }
242  }
244 }
245 
246 /*
247  * Add entry based on the given flow_skeleton_entry struct
248  *
249  * @pipe_queue [in]: queue identifier
250  * @flag [in]: DOCA_FLOW_WAIT_FOR_BATCH / DOCA_FLOW_NO_WAIT
251  * @entry [in]: application input information for adding the entry
252  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
253  */
254 static doca_error_t add_entry(uint16_t pipe_queue, uint32_t flag, struct flow_skeleton_entry *entry)
255 {
257 
258  switch (entry->ctx.type) {
260  result = doca_flow_pipe_add_entry(pipe_queue,
261  entry->ctx.pipe,
262  entry->ctx.match,
263  entry->ctx.actions,
264  entry->ctx.monitor,
265  entry->ctx.fwd,
266  flag,
267  entry->ctx.usr_ctx,
268  entry->ctx.entry);
269  break;
272  entry->ctx.priority,
273  entry->ctx.pipe,
274  entry->ctx.match,
275  entry->ctx.match_mask,
276  NULL,
277  entry->ctx.actions,
278  entry->ctx.actions_mask,
279  entry->ctx.action_descs,
280  entry->ctx.monitor,
281  entry->ctx.fwd,
282  entry->ctx.usr_ctx,
283  entry->ctx.entry);
284  break;
285  case DOCA_FLOW_PIPE_LPM:
287  entry->ctx.pipe,
288  entry->ctx.match,
289  entry->ctx.match_mask,
290  entry->ctx.actions,
291  entry->ctx.monitor,
292  entry->ctx.fwd,
293  flag,
294  entry->ctx.usr_ctx,
295  entry->ctx.entry);
296  break;
297  case DOCA_FLOW_PIPE_ACL:
299  entry->ctx.pipe,
300  entry->ctx.match,
301  entry->ctx.match_mask,
302  entry->ctx.priority,
303  entry->ctx.fwd,
304  flag,
305  entry->ctx.usr_ctx,
306  entry->ctx.entry);
307  break;
310  entry->ctx.pipe,
311  entry->ctx.idx,
312  entry->ctx.ordered_list,
313  entry->ctx.fwd,
314  flag,
315  entry->ctx.usr_ctx,
316  entry->ctx.entry);
317  break;
318  case DOCA_FLOW_PIPE_HASH:
320  entry->ctx.pipe,
321  entry->ctx.idx,
322  entry->ctx.actions,
323  entry->ctx.monitor,
324  entry->ctx.fwd,
325  flag,
326  entry->ctx.usr_ctx,
327  entry->ctx.entry);
328  break;
329  default:
330  DOCA_LOG_ERR("Unsupported pipe type");
332  }
333  return result;
334 }
335 
336 /*
337  * Add a batch of entries and process
338  *
339  * @params [in]: main loop params
340  * @nb_entries [in]: number of entries in the batch
341  * @port_id [in]: port ID of the entries
342  */
343 static void add_batch_entries(struct main_loop_params *params, uint32_t nb_entries, int port_id)
344 {
345  uint32_t flags;
346  uint32_t i;
348 
349  /* Add all the entries with DOCA_FLOW_WAIT_FOR_BATCH flag */
350  flags = DOCA_FLOW_WAIT_FOR_BATCH;
351  for (i = 0; i < nb_entries - 1; i++) {
353  result = add_entry(params->pipe_queue, flags, &skeleton_ctx.entries[i]);
356  flags,
358  else {
359  DOCA_LOG_ERR("DOCA Flow op [%d] is not supported", skeleton_ctx.entries[i].ctx.op);
361  }
362  if (result != DOCA_SUCCESS)
363  DOCA_LOG_ERR("Failed to add/remove entry in index [%d]: %s", i, doca_error_get_descr(result));
364  else
365  skeleton_ctx.queue_state[port_id][params->pipe_queue]++;
366  }
367 
368  /* Add last entry with DOCA_FLOW_NO_WAIT */
369  flags = DOCA_FLOW_NO_WAIT;
371  result = add_entry(params->pipe_queue, flags, &skeleton_ctx.entries[nb_entries - 1]);
374  flags,
376  else {
377  DOCA_LOG_ERR("DOCA Flow op [%d] is not supported", skeleton_ctx.entries[nb_entries - 1].ctx.op);
379  }
380  if (result != DOCA_SUCCESS)
381  DOCA_LOG_ERR("Failed to add/remove entry in index [%d]: %s",
382  nb_entries - 1,
384  else
385  skeleton_ctx.queue_state[port_id][params->pipe_queue]++;
386 
387  result = doca_flow_entries_process(params->ports[port_id], params->pipe_queue, 0, nb_entries);
388  if (result != DOCA_SUCCESS)
389  DOCA_LOG_ERR("DOCA Flow entries process failed %s", doca_error_get_descr(result));
390 
392 }
393 
395 {
396  struct main_loop_params *params = (struct main_loop_params *)main_loop_params;
397  uint32_t nb_entries;
398  int port_id;
400 
401  skeleton_ctx.program_ctx[params->pipe_queue] = params->program_ctx;
402 
403  if (params->initialization) {
404  for (port_id = 0; port_id < params->nb_ports; port_id++) {
406  /* Get array of entries to add or remove */
408  break;
410  port_id,
411  params->program_ctx,
412  &nb_entries);
413  if (nb_entries == 0)
414  continue;
415  add_batch_entries(params, nb_entries, port_id);
416  }
417  }
418 
419  while (!force_quit) {
420  for (port_id = 0; port_id < params->nb_ports; port_id++) {
422  /* Get array of entries to add or remove */
424  port_id,
425  params->program_ctx,
426  &nb_entries);
427  if (nb_entries == 0)
428  continue;
429  if (skeleton_ctx.queue_state[port_id][params->pipe_queue] + nb_entries >=
431  DOCA_LOG_WARN("Queue %d on port %d is full", params->pipe_queue, port_id);
432  result = doca_flow_entries_process(params->ports[port_id],
433  params->pipe_queue,
434  0,
435  nb_entries);
436  if (result != DOCA_SUCCESS)
437  DOCA_LOG_ERR("DOCA Flow entries process failed %s",
439  }
440  add_batch_entries(params, nb_entries, port_id);
442  doca_flow_aging_handle(params->ports[port_id], params->pipe_queue, QUOTA_TIME, 0);
443  }
444  }
445 
446  /* empty the queue before exit */
447  for (port_id = 0; port_id < params->nb_ports; port_id++) {
448  while (skeleton_ctx.queue_state[port_id][params->pipe_queue] > 0) {
450  result = doca_flow_entries_process(params->ports[port_id],
451  params->pipe_queue,
453  skeleton_ctx.queue_state[port_id][params->pipe_queue]);
454  if (result != DOCA_SUCCESS) {
455  DOCA_LOG_ERR("DOCA Flow entries process failed %s", doca_error_get_descr(result));
456  break;
457  }
458  skeleton_ctx.queue_state[port_id][params->pipe_queue] -=
460  }
461  }
462 }
463 
465 {
466  force_quit = true;
467 }
#define NULL
Definition: __stddef_null.h:26
int32_t result
static int nb_entries
static struct doca_flow_pipe_entry * entry[MAX_ENTRIES]
doca_error_t flow_skeleton_init(struct doca_flow_cfg *flow_cfg, struct flow_skeleton_cfg *skeleton_cfg)
static doca_error_t add_entry(uint16_t pipe_queue, uint32_t flag, struct flow_skeleton_entry *entry)
void flow_skeleton_main_loop(void *main_loop_params)
#define DEFAULT_TIMEOUT_US
Definition: flow_skeleton.c:36
#define QUOTA_TIME
Definition: flow_skeleton.c:37
void flow_skeleton_destroy(void)
DOCA_LOG_REGISTER(FLOW_SKELETON)
static void add_batch_entries(struct main_loop_params *params, uint32_t nb_entries, int port_id)
static void process_callback(struct doca_flow_pipe_entry *entry, uint16_t pipe_queue, enum doca_flow_entry_status status, enum doca_flow_entry_op op, void *user_ctx)
Definition: flow_skeleton.c:60
#define DEFAULT_QUEUE_DEPTH
Definition: flow_skeleton.c:35
void flow_skeleton_notify_exit(void)
static volatile bool force_quit
Definition: flow_skeleton.c:49
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_ERROR_INVALID_VALUE
Definition: doca_error.h:44
@ DOCA_SUCCESS
Definition: doca_error.h:38
@ DOCA_ERROR_NO_MEMORY
Definition: doca_error.h:45
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_ordered_list_add_entry(uint16_t pipe_queue, struct doca_flow_pipe *pipe, uint32_t idx, const struct doca_flow_ordered_list *ordered_list, const struct doca_flow_fwd *fwd, enum doca_flow_flags_type flags, void *user_ctx, struct doca_flow_pipe_entry **entry)
DOCA_STABLE doca_error_t doca_flow_entries_process(struct doca_flow_port *port, uint16_t pipe_queue, uint64_t timeout, uint32_t max_processed_entries)
Process entries in queue.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_control_add_entry(uint16_t pipe_queue, uint32_t priority, struct doca_flow_pipe *pipe, const struct doca_flow_match *match, const struct doca_flow_match *match_mask, const struct doca_flow_match_condition *condition, const struct doca_flow_actions *actions, const struct doca_flow_actions *actions_mask, const struct doca_flow_action_descs *action_descs, const struct doca_flow_monitor *monitor, const struct doca_flow_fwd *fwd, void *usr_ctx, struct doca_flow_pipe_entry **entry)
Add one new entry to a control pipe.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_acl_add_entry(uint16_t pipe_queue, struct doca_flow_pipe *pipe, const struct doca_flow_match *match, const struct doca_flow_match *match_mask, const uint32_t priority, const struct doca_flow_fwd *fwd, const enum doca_flow_flags_type flag, void *usr_ctx, struct doca_flow_pipe_entry **entry)
Add one new entry to a acl pipe.
doca_flow_entry_op
doca flow entry operation
Definition: doca_flow.h:146
DOCA_STABLE doca_error_t doca_flow_cfg_set_cb_entry_process(struct doca_flow_cfg *cfg, doca_flow_entry_process_cb cb)
Set callback for entry create/destroy.
DOCA_STABLE doca_error_t doca_flow_cfg_set_queue_depth(struct doca_flow_cfg *cfg, uint32_t queue_depth)
Set number of pre-configured queue_size.
DOCA_STABLE doca_error_t doca_flow_cfg_create(struct doca_flow_cfg **cfg)
Create DOCA Flow configuration struct.
DOCA_EXPERIMENTAL doca_error_t doca_flow_init(struct doca_flow_cfg *cfg)
Initialize the doca flow.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_lpm_add_entry(uint16_t pipe_queue, struct doca_flow_pipe *pipe, const struct doca_flow_match *match, const struct doca_flow_match *match_mask, const struct doca_flow_actions *actions, const struct doca_flow_monitor *monitor, const struct doca_flow_fwd *fwd, const enum doca_flow_flags_type flag, void *usr_ctx, struct doca_flow_pipe_entry **entry)
Add one new entry to a lpm pipe.
DOCA_STABLE int doca_flow_aging_handle(struct doca_flow_port *port, uint16_t queue, uint64_t quota, uint64_t max_entries)
Handle aging of entries.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_add_entry(uint16_t pipe_queue, struct doca_flow_pipe *pipe, const struct doca_flow_match *match, const struct doca_flow_actions *actions, const struct doca_flow_monitor *monitor, const struct doca_flow_fwd *fwd, uint32_t flags, void *usr_ctx, struct doca_flow_pipe_entry **entry)
Add one new entry to a pipe.
DOCA_STABLE doca_error_t doca_flow_pipe_remove_entry(uint16_t pipe_queue, uint32_t flags, struct doca_flow_pipe_entry *entry)
Free one pipe entry.
doca_flow_entry_status
doca flow entry status
Definition: doca_flow.h:160
DOCA_STABLE void doca_flow_destroy(void)
Destroy the doca flow.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_hash_add_entry(uint16_t pipe_queue, struct doca_flow_pipe *pipe, uint32_t entry_index, const struct doca_flow_actions *actions, const struct doca_flow_monitor *monitor, const struct doca_flow_fwd *fwd, const enum doca_flow_flags_type flags, void *usr_ctx, struct doca_flow_pipe_entry **entry)
Add one new entry to an hash pipe.
DOCA_STABLE doca_error_t doca_flow_cfg_set_pipe_queues(struct doca_flow_cfg *cfg, uint16_t pipe_queues)
Set pipe queues.
DOCA_STABLE doca_error_t doca_flow_cfg_destroy(struct doca_flow_cfg *cfg)
Destroy DOCA Flow configuration struct.
@ DOCA_FLOW_ENTRY_OP_ADD
Definition: doca_flow.h:147
@ DOCA_FLOW_ENTRY_OP_AGED
Definition: doca_flow.h:153
@ DOCA_FLOW_ENTRY_OP_DEL
Definition: doca_flow.h:149
@ DOCA_FLOW_PIPE_CONTROL
Definition: doca_flow.h:223
@ DOCA_FLOW_PIPE_BASIC
Definition: doca_flow.h:221
@ DOCA_FLOW_PIPE_ACL
Definition: doca_flow.h:229
@ DOCA_FLOW_PIPE_HASH
Definition: doca_flow.h:233
@ DOCA_FLOW_PIPE_ORDERED_LIST
Definition: doca_flow.h:231
@ DOCA_FLOW_PIPE_LPM
Definition: doca_flow.h:225
@ DOCA_FLOW_NO_WAIT
Definition: doca_flow.h:115
@ DOCA_FLOW_WAIT_FOR_BATCH
Definition: doca_flow.h:117
@ DOCA_FLOW_ENTRY_STATUS_SUCCESS
Definition: doca_flow.h:163
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
#define DOCA_LOG_WARN(format,...)
Generates a WARNING application log message.
Definition: doca_log.h:476
flow_skeleton_aging_cb aging_cb
flow_skeleton_entries_acquisition_cb entries_acquisition_cb
flow_skeleton_failure_cb failure_cb
flow_skeleton_process_cb add_cb
flow_skeleton_process_cb remove_cb
flow_skeleton_initialize_cb init_cb
struct doca_flow_pipe_entry ** entry
Definition: flow_skeleton.h:50
enum doca_flow_entry_op op
Definition: flow_skeleton.h:36
Definition: flow_skeleton.h:63
struct flow_skeleton_entry_ctx ctx
Definition: flow_skeleton.h:64
struct doca_flow_port * ports[]
uint32_t ** queue_state
Definition: flow_skeleton.c:42
struct flow_skeleton_cfg skeleton_cfg
Definition: flow_skeleton.c:41
struct flow_skeleton_entry * entries
Definition: flow_skeleton.c:44
uint32_t queue_depth
Definition: flow_skeleton.c:40
uint32_t * queue_counter
Definition: flow_skeleton.c:43
void ** program_ctx
Definition: flow_skeleton.c:45