NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
flow_sampling_sample.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 <stdint.h>
27 #include <string.h>
28 #include <unistd.h>
29 
30 #include <rte_ethdev.h>
31 
32 #include <doca_log.h>
33 #include <doca_flow.h>
34 #include <doca_bitfield.h>
35 
36 #include "doca_error.h"
37 #include "flow_common.h"
38 #include "flow_switch_common.h"
39 
40 DOCA_LOG_REGISTER(FLOW_SAMPLING);
41 
42 /* The number of bits in random field */
43 #define RANDOM_WIDTH 16
44 
45 /* The number of numbers in random field range */
46 #define RANDOM_TOTAL_RANGE (1 << RANDOM_WIDTH)
47 
48 /* Get the percentage according to part and total */
49 #define GET_PERCENTAGE(part, total) (((double)part / (double)total) * 100)
50 
51 /* The number of seconds app waits for traffic to come */
52 #define WAITING_TIME 15
53 
54 /*
55  * Create DOCA Flow pipe with changeable 5 tuple match as root
56  *
57  * @port [in]: port of the pipe
58  * @next_pipe [in]: next pipe pointer
59  * @pipe [out]: created pipe pointer
60  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
61  */
62 static doca_error_t create_root_pipe(struct doca_flow_port *port,
63  struct doca_flow_pipe *next_pipe,
64  struct doca_flow_pipe **pipe)
65 {
66  struct doca_flow_match match;
68  struct doca_flow_fwd fwd;
69  struct doca_flow_pipe_cfg *pipe_cfg;
71 
72  memset(&match, 0, sizeof(match));
73  memset(&monitor, 0, sizeof(monitor));
74  memset(&fwd, 0, sizeof(fwd));
75 
76  /* 5 tuple match */
81  match.outer.ip4.src_ip = 0xffffffff;
82  match.outer.ip4.dst_ip = 0xffffffff;
83  match.outer.tcp.l4_port.src_port = 0xffff;
84  match.outer.tcp.l4_port.dst_port = 0xffff;
85 
86  /* Add counter to see how many packet arrived before sampling */
88 
89  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
90  if (result != DOCA_SUCCESS) {
91  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
92  return result;
93  }
94 
95  result = set_flow_pipe_cfg(pipe_cfg, "ROOT_PIPE", DOCA_FLOW_PIPE_BASIC, true);
96  if (result != DOCA_SUCCESS) {
97  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
98  goto destroy_pipe_cfg;
99  }
101  if (result != DOCA_SUCCESS) {
102  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg nr_entries: %s", doca_error_get_descr(result));
103  goto destroy_pipe_cfg;
104  }
105  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
106  if (result != DOCA_SUCCESS) {
107  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
108  goto destroy_pipe_cfg;
109  }
111  if (result != DOCA_SUCCESS) {
112  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
113  goto destroy_pipe_cfg;
114  }
115 
117  fwd.next_pipe = next_pipe;
118 
119  result = doca_flow_pipe_create(pipe_cfg, &fwd, NULL, pipe);
121  doca_flow_pipe_cfg_destroy(pipe_cfg);
122  return result;
123 }
124 
125 /*
126  * Add DOCA Flow pipe entry to the root pipe that forwards the traffic to specific random pipe.
127  *
128  * @pipe [in]: pipe of the entries.
129  * @status [in]: user context for adding entry.
130  * @entry [out]: created entry pointer.
131  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
132  */
133 static doca_error_t add_root_pipe_entry(struct doca_flow_pipe *pipe,
134  struct entries_status *status,
135  struct doca_flow_pipe_entry **entry)
136 {
137  struct doca_flow_match match;
138 
139  memset(&match, 0, sizeof(match));
140 
141  match.outer.ip4.dst_ip = BE_IPV4_ADDR(8, 8, 8, 8);
142  match.outer.ip4.src_ip = BE_IPV4_ADDR(1, 1, 1, 1);
143  match.outer.tcp.l4_port.dst_port = rte_cpu_to_be_16(80);
144  match.outer.tcp.l4_port.src_port = rte_cpu_to_be_16(1234);
145 
146  DOCA_LOG_DBG("Adding root pipe entry matching of: "
147  "IPv4(src='1.1.1.1',dst='8.8.8.8') and TCP(src_port=1234,dst_port=80)");
148 
149  return doca_flow_pipe_add_entry(0, pipe, &match, NULL, NULL, NULL, 0, status, entry);
150 }
151 
152 /*
153  * Calculate the random value used to achieve given certain percentage.
154  *
155  * @percentage [in]: the certain percentage user wish to get in sampling.
156  * @return: value to use in match.parser_meta.random field for getting this percentage along with
157  * "parser_meta.random.value" string in condition argument.
158  */
159 static uint16_t get_random_value(double percentage)
160 {
161  uint16_t random_value;
162  double temp;
163 
164  temp = (percentage / 100) * RANDOM_TOTAL_RANGE;
165  random_value = (uint16_t)temp;
166  temp = GET_PERCENTAGE(random_value, RANDOM_TOTAL_RANGE);
167 
168  DOCA_LOG_DBG("Using random value 0x%04x for sampling %g%% of traffic (%g%% requested)",
169  random_value,
170  temp,
171  percentage);
172 
173  return random_value;
174 }
175 
176 /*
177  * Add DOCA Flow pipe for sampling according to random value
178  *
179  * @port [in]: port of the pipe
180  * @pipe [out]: created pipe pointer
181  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
182  */
183 static doca_error_t create_random_sampling_pipe(struct doca_flow_port *port, struct doca_flow_pipe **pipe)
184 {
185  struct doca_flow_pipe_cfg *pipe_cfg;
187 
188  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
189  if (result != DOCA_SUCCESS) {
190  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
191  return result;
192  }
193 
194  result = set_flow_pipe_cfg(pipe_cfg, "SAMPLING_PIPE", DOCA_FLOW_PIPE_CONTROL, false);
195  if (result != DOCA_SUCCESS) {
196  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
197  goto destroy_pipe_cfg;
198  }
199 
200  result = doca_flow_pipe_create(pipe_cfg, NULL, NULL, pipe);
202  doca_flow_pipe_cfg_destroy(pipe_cfg);
203  return result;
204 }
205 
206 /*
207  * Add DOCA Flow pipe entry to the random sampling pipe.
208  *
209  * @pipe [in]: pipe of the entries
210  * @status [in]: user context for adding entry
211  * @percentage [in]: the certain percentage user wish to get in sampling
212  * @entry [out]: created entry pointer.
213  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
214  */
215 static doca_error_t add_random_sampling_pipe_entry(struct doca_flow_pipe *pipe,
216  struct entries_status *status,
217  double percentage,
218  struct doca_flow_pipe_entry **entry)
219 {
220  struct doca_flow_match match;
221  struct doca_flow_match_condition condition;
222  struct doca_flow_monitor monitor;
223  struct doca_flow_fwd fwd;
224 
225  memset(&match, 0, sizeof(match));
226  memset(&condition, 0, sizeof(condition));
227  memset(&monitor, 0, sizeof(monitor));
228  memset(&fwd, 0, sizeof(fwd));
229 
230  condition.operation = DOCA_FLOW_COMPARE_LT;
231  /* Argument field is random */
232  condition.field_op.a.field_string = "parser_meta.random.value";
233  condition.field_op.a.bit_offset = 0;
234  /* Base is immediate value, so the string should be NULL and value is taken from match structure */
235  condition.field_op.b.field_string = NULL;
236  condition.field_op.b.bit_offset = 0;
237  condition.field_op.width = RANDOM_WIDTH;
238 
239  /*
240  * The immediate value to compare with random field is provided in the match structure.
241  * Match mask structure is not relevant here since it is masked in argument using offset + width.
242  */
243  match.parser_meta.random = DOCA_HTOBE16(get_random_value(percentage));
244 
245  /* Add counter to see how many packet are sampled */
247 
249  fwd.port_id = 1;
250 
251  return doca_flow_pipe_control_add_entry(0 /* queue */,
252  0 /* priority */,
253  pipe,
254  &match,
255  NULL /* match_mask */,
256  &condition,
257  NULL /* actions */,
258  NULL /* actions_mask */,
259  NULL /* action_descs */,
260  &monitor,
261  &fwd,
262  status,
263  entry);
264 }
265 
266 /*
267  * Get results about certain percentage sampling.
268  *
269  * @root_entry [in]: entry sent packets to sampling.
270  * @random_entry [in]: entry samples certain percentage of traffic.
271  * @requested_percentage [in]: the certain percentage user wished to get in sampling.
272  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
273  */
274 static doca_error_t random_sampling_results(struct doca_flow_pipe_entry *root_entry,
275  struct doca_flow_pipe_entry *random_entry,
276  double requested_percentage)
277 {
278  struct doca_flow_resource_query root_query_stats;
279  struct doca_flow_resource_query random_query_stats;
280  double actuall_percentage;
281  uint32_t total_packets;
282  uint32_t nb_sampled_packets;
284 
285  result = doca_flow_resource_query_entry(root_entry, &root_query_stats);
286  if (result != DOCA_SUCCESS) {
287  DOCA_LOG_ERR("Failed to query root entry: %s", doca_error_get_descr(result));
288  return result;
289  }
290 
291  total_packets = root_query_stats.counter.total_pkts;
292  if (total_packets == 0)
293  return DOCA_SUCCESS;
294 
295  result = doca_flow_resource_query_entry(random_entry, &random_query_stats);
296  if (result != DOCA_SUCCESS) {
297  DOCA_LOG_ERR("Failed to query random entry: %s", doca_error_get_descr(result));
298  return result;
299  }
300 
301  nb_sampled_packets = random_query_stats.counter.total_pkts;
302  actuall_percentage = GET_PERCENTAGE(nb_sampled_packets, total_packets);
303 
304  DOCA_LOG_INFO("Sampling result information (%g%% is requested):", requested_percentage);
305  DOCA_LOG_INFO("This pipeline samples %u packets which is %g%% of the traffic (%u/%u)",
306  nb_sampled_packets,
307  actuall_percentage,
308  nb_sampled_packets,
309  total_packets);
310 
311  return DOCA_SUCCESS;
312 }
313 
314 /*
315  * Run flow_sampling sample.
316  *
317  * This sample tests the sampling certain percentage of traffic.
318  *
319  * @nb_queues [in]: number of queues the sample will use
320  * @ctx [in]: flow switch context the sample will use
321  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
322  */
324 {
325  int nb_ports = 2;
326  struct flow_resources resource = {0};
327  uint32_t nr_shared_resources[SHARED_RESOURCE_NUM_VALUES] = {0};
328  struct doca_flow_port *ports[nb_ports];
329  struct doca_flow_port *switch_port;
330  struct doca_dev *dev_arr[nb_ports];
331  uint32_t actions_mem_size[nb_ports];
332  struct doca_flow_pipe *root_pipe;
333  struct doca_flow_pipe *sampling_pipe;
334  struct doca_flow_pipe_entry *root_entry;
335  struct doca_flow_pipe_entry *random_entry;
336  struct entries_status status;
337  double requested_percentage = 35;
338  uint32_t num_of_entries = 2;
340 
341  memset(&status, 0, sizeof(status));
342  resource.nr_counters = num_of_entries;
343 
344  result = init_doca_flow(nb_queues, "switch,hws", &resource, nr_shared_resources);
345  if (result != DOCA_SUCCESS) {
346  DOCA_LOG_ERR("Failed to init DOCA Flow: %s", doca_error_get_descr(result));
347  return result;
348  }
349 
350  memset(dev_arr, 0, sizeof(struct doca_dev *) * nb_ports);
351  dev_arr[0] = ctx->doca_dev[0];
352  ARRAY_INIT(actions_mem_size, ACTIONS_MEM_SIZE(nb_queues, num_of_entries));
354  if (result != DOCA_SUCCESS) {
355  DOCA_LOG_ERR("Failed to init DOCA ports: %s", doca_error_get_descr(result));
357  return result;
358  }
359 
360  switch_port = doca_flow_port_switch_get(NULL);
361 
362  result = create_random_sampling_pipe(switch_port, &sampling_pipe);
363  if (result != DOCA_SUCCESS) {
364  DOCA_LOG_ERR("Failed to create random sampling pipe: %s", doca_error_get_descr(result));
367  return result;
368  }
369 
370  result = add_random_sampling_pipe_entry(sampling_pipe, &status, requested_percentage, &random_entry);
371  if (result != DOCA_SUCCESS) {
372  DOCA_LOG_ERR("Failed to add random sampling pipe entry: %s", doca_error_get_descr(result));
375  return result;
376  }
377 
378  result = create_root_pipe(switch_port, sampling_pipe, &root_pipe);
379  if (result != DOCA_SUCCESS) {
380  DOCA_LOG_ERR("Failed to create root pipe: %s", doca_error_get_descr(result));
383  return result;
384  }
385 
386  result = add_root_pipe_entry(root_pipe, &status, &root_entry);
387  if (result != DOCA_SUCCESS) {
388  DOCA_LOG_ERR("Failed to add root pipe entry: %s", doca_error_get_descr(result));
391  return result;
392  }
393 
394  result = flow_process_entries(switch_port, &status, num_of_entries);
395  if (result != DOCA_SUCCESS) {
396  DOCA_LOG_ERR("Failed to process entries: %s", doca_error_get_descr(result));
399  return result;
400  }
401 
402  DOCA_LOG_INFO("Wait %u seconds for packets to arrive", WAITING_TIME);
403  sleep(WAITING_TIME);
404 
405  /* Show the results for sampling */
406  result = random_sampling_results(root_entry, random_entry, requested_percentage);
407  if (result != DOCA_SUCCESS) {
408  DOCA_LOG_ERR("Failed to show sampling results: %s", doca_error_get_descr(result));
411  return result;
412  }
413 
416  return result;
417 }
#define NULL
Definition: __stddef_null.h:26
int32_t result
struct doca_flow_port * init_doca_flow(uint16_t port_id, uint8_t rxq_num)
Definition: flow.c:37
static doca_error_t destroy_pipe_cfg(struct doca_flow_pipe_cfg *cfg)
#define BE_IPV4_ADDR(a, b, c, d)
Definition: flow_parser.c:64
static struct doca_flow_monitor monitor
Definition: flow_parser.c:108
static struct doca_flow_fwd fwd
Definition: flow_parser.c:109
static struct doca_flow_pipe_entry * entry[MAX_ENTRIES]
#define RANDOM_TOTAL_RANGE
static doca_error_t create_random_sampling_pipe(struct doca_flow_port *port, struct doca_flow_pipe **pipe)
static doca_error_t add_root_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status, struct doca_flow_pipe_entry **entry)
static doca_error_t random_sampling_results(struct doca_flow_pipe_entry *root_entry, struct doca_flow_pipe_entry *random_entry, double requested_percentage)
#define GET_PERCENTAGE(part, total)
static doca_error_t add_random_sampling_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status, double percentage, struct doca_flow_pipe_entry **entry)
doca_error_t flow_sampling(int nb_queues, struct flow_switch_ctx *ctx)
static doca_error_t create_root_pipe(struct doca_flow_port *port, struct doca_flow_pipe *next_pipe, struct doca_flow_pipe **pipe)
#define WAITING_TIME
static uint16_t get_random_value(double percentage)
DOCA_LOG_REGISTER(FLOW_SAMPLING)
#define RANDOM_WIDTH
#define DOCA_HTOBE16(_x)
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_SUCCESS
Definition: doca_error.h:38
@ DOCA_FLOW_L4_TYPE_EXT_TCP
@ DOCA_FLOW_L3_TYPE_IP4
DOCA_STABLE doca_error_t doca_flow_pipe_cfg_destroy(struct doca_flow_pipe_cfg *cfg)
Destroy DOCA Flow pipe configuration struct.
DOCA_STABLE doca_error_t doca_flow_pipe_cfg_create(struct doca_flow_pipe_cfg **cfg, struct doca_flow_port *port)
Create DOCA Flow pipe configuration struct.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_cfg_set_match(struct doca_flow_pipe_cfg *cfg, const struct doca_flow_match *match, const struct doca_flow_match *match_mask)
Set pipe's match and match mask.
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_create(const struct doca_flow_pipe_cfg *cfg, const struct doca_flow_fwd *fwd, const struct doca_flow_fwd *fwd_miss, struct doca_flow_pipe **pipe)
Create one new pipe.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_cfg_set_monitor(struct doca_flow_pipe_cfg *cfg, const struct doca_flow_monitor *monitor)
Set pipe's monitor.
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 void doca_flow_destroy(void)
Destroy the doca flow.
DOCA_STABLE doca_error_t doca_flow_pipe_cfg_set_nr_entries(struct doca_flow_pipe_cfg *cfg, uint32_t nr_entries)
Set pipe's maximum number of flow rules.
DOCA_STABLE struct doca_flow_port * doca_flow_port_switch_get(const struct doca_flow_port *port)
Get doca flow switch port.
DOCA_EXPERIMENTAL doca_error_t doca_flow_resource_query_entry(struct doca_flow_pipe_entry *entry, struct doca_flow_resource_query *query_stats)
Extract information about specific entry.
@ DOCA_FLOW_PIPE_CONTROL
Definition: doca_flow.h:223
@ DOCA_FLOW_PIPE_BASIC
Definition: doca_flow.h:221
@ DOCA_FLOW_L3_META_IPV4
Definition: doca_flow.h:296
@ DOCA_FLOW_COMPARE_LT
Definition: doca_flow.h:514
@ DOCA_FLOW_RESOURCE_TYPE_NON_SHARED
Definition: doca_flow.h:615
@ DOCA_FLOW_FWD_PORT
Definition: doca_flow.h:744
@ DOCA_FLOW_FWD_PIPE
Definition: doca_flow.h:746
@ DOCA_FLOW_L4_META_TCP
Definition: doca_flow.h:308
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
Definition: doca_log.h:486
#define DOCA_LOG_DBG(format,...)
Generates a DEBUG application log message.
Definition: doca_log.h:496
doca_error_t flow_process_entries(struct doca_flow_port *port, struct entries_status *status, uint32_t nr_entries)
Definition: flow_common.c:338
doca_error_t stop_doca_flow_ports(int nb_ports, struct doca_flow_port *ports[])
Definition: flow_common.c:240
doca_error_t init_doca_flow_ports(int nb_ports, struct doca_flow_port *ports[], bool is_hairpin, struct doca_dev *dev_arr[], uint32_t actions_mem_size[])
Definition: flow_common.c:296
doca_error_t set_flow_pipe_cfg(struct doca_flow_pipe_cfg *cfg, const char *name, enum doca_flow_pipe_type type, bool is_root)
Definition: flow_common.c:305
#define SHARED_RESOURCE_NUM_VALUES
Definition: flow_common.h:59
#define ACTIONS_MEM_SIZE(nr_queues, entries)
Definition: flow_common.h:66
#define ARRAY_INIT(array, val)
Definition: flow_common.h:71
forwarding configuration
Definition: doca_flow.h:779
struct doca_flow_pipe * next_pipe
Definition: doca_flow.h:800
struct doca_flow_pipe * pipe
Definition: doca_flow.h:806
uint16_t port_id
Definition: doca_flow.h:795
enum doca_flow_fwd_type type
Definition: doca_flow.h:780
struct doca_flow_header_ip4 ip4
Definition: doca_flow.h:449
enum doca_flow_l4_type_ext l4_type_ext
Definition: doca_flow.h:454
enum doca_flow_l3_type l3_type
Definition: doca_flow.h:446
struct doca_flow_header_tcp tcp
Definition: doca_flow.h:461
struct doca_flow_header_l4_port l4_port
doca flow match condition information
Definition: doca_flow.h:548
enum doca_flow_compare_op operation
Definition: doca_flow.h:549
struct doca_flow_match_condition::@68::@70 field_op
doca flow matcher information
Definition: doca_flow.h:491
struct doca_flow_parser_meta parser_meta
Definition: doca_flow.h:496
struct doca_flow_header_format outer
Definition: doca_flow.h:498
doca monitor action configuration
Definition: doca_flow.h:968
enum doca_flow_resource_type counter_type
Definition: doca_flow.h:988
enum doca_flow_l3_meta outer_l3_type
Definition: doca_flow.h:382
enum doca_flow_l4_meta outer_l4_type
Definition: doca_flow.h:383
doca_be16_t random
Definition: doca_flow.h:376
flow resource query
Definition: doca_flow.h:1101
struct doca_flow_resource_query::@115::@117 counter
user context struct that will be used in entries process callback
Definition: flow_common.h:78
uint32_t nr_counters
Definition: flow_common.h:96
static int nb_ports
Definition: switch_core.c:44
static uint32_t actions_mem_size[FLOW_SWITCH_PORTS_MAX]
Definition: switch_core.c:43
static struct doca_flow_port * ports[FLOW_SWITCH_PORTS_MAX]
Definition: switch_core.c:42
struct upf_accel_ctx * ctx