NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
flow_lpm_em_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 <string.h>
27 #include <unistd.h>
28 
29 #include <doca_log.h>
30 #include <doca_flow.h>
31 #include <doca_bitfield.h>
32 
33 #include "flow_common.h"
34 
35 DOCA_LOG_REGISTER(FLOW_LPM_EM);
36 
37 #define NB_ACTION_DESC (1)
38 #define TEST_LPM_EM_TAG 1
39 #define META_U32_BIT_OFFSET(idx) (offsetof(struct doca_flow_meta, u32[(idx)]) << 3)
40 
41 /*
42  * Create DOCA Flow pipe with match on header types to fwd to main pipe with it's own logic.
43  * Miss fwd is a drop action.
44  *
45  * @port [in]: port of the pipe
46  * @drop_pipe [in]: pipe to forward the traffic that didn't hit the pipe rules
47  * @pipe [out]: created pipe pointer
48  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
49  */
50 static doca_error_t create_classifier_pipe(struct doca_flow_port *port,
51  struct doca_flow_pipe *main_pipe,
52  struct doca_flow_pipe **pipe)
53 {
54  struct doca_flow_match match;
56  struct doca_flow_fwd fwd;
57  struct doca_flow_fwd fwd_miss;
58  struct doca_flow_pipe_cfg *pipe_cfg;
60 
61  memset(&match, 0, sizeof(match));
62  memset(&monitor, 0, sizeof(monitor));
63  memset(&fwd, 0, sizeof(fwd));
64  memset(&fwd_miss, 0, sizeof(fwd_miss));
65 
66  /* Match on header types */
69  /* Match on tunnel type being VXLAN */
73 
75 
76  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
77  if (result != DOCA_SUCCESS) {
78  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
79  return result;
80  }
81 
82  result = set_flow_pipe_cfg(pipe_cfg, "CLASSIFIER_PIPE", DOCA_FLOW_PIPE_BASIC, true);
83  if (result != DOCA_SUCCESS) {
84  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
85  goto destroy_pipe_cfg;
86  }
87  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
88  if (result != DOCA_SUCCESS) {
89  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
90  goto destroy_pipe_cfg;
91  }
93  if (result != DOCA_SUCCESS) {
94  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
95  goto destroy_pipe_cfg;
96  }
97 
99  fwd.next_pipe = main_pipe;
100 
102 
103  result = doca_flow_pipe_create(pipe_cfg, &fwd, &fwd_miss, pipe);
105  doca_flow_pipe_cfg_destroy(pipe_cfg);
106  return result;
107 }
108 
109 /*
110  * Add DOCA Flow pipe entry to the classifier pipe
111  *
112  * @pipe [in]: pipe of the entry
113  * @status [in]: user context for adding entry
114  * @entry [out]: created entry pointer
115  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
116  */
117 static doca_error_t add_classifier_pipe_entry(struct doca_flow_pipe *pipe,
118  struct entries_status *status,
119  struct doca_flow_pipe_entry **entry)
120 {
121  struct doca_flow_match match;
122 
123  /*
124  * All fields are not changeable, thus we need to add only 1 entry, all values will be
125  * inherited from the pipe creation
126  */
127  memset(&match, 0, sizeof(match));
128 
129  return doca_flow_pipe_add_entry(0, pipe, &match, NULL, NULL, NULL, 0, status, entry);
130 }
131 
132 /*
133  * Create DOCA Flow basic pipe that gets vlan from the packet, sets the value vlan to the register 1
134  *
135  * @port [in]: port of the pipe
136  * @next_pipe [in]: lpm pipe to forward the matched traffic
137  * @pipe [out]: created pipe pointer
138  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
139  */
140 static doca_error_t create_main_pipe(struct doca_flow_port *port,
141  struct doca_flow_pipe *next_pipe,
142  struct doca_flow_pipe **pipe)
143 {
144  struct doca_flow_match match;
145  struct doca_flow_monitor counter;
146  struct doca_flow_actions actions;
147  struct doca_flow_actions *actions_arr[NB_ACTIONS_ARR];
148  struct doca_flow_fwd fwd;
149  struct doca_flow_fwd fwd_miss;
150  struct doca_flow_pipe_cfg *pipe_cfg;
151  struct doca_flow_action_descs descs;
152  struct doca_flow_action_descs *descs_arr[NB_ACTIONS_ARR];
153  struct doca_flow_action_desc desc_array[NB_ACTION_DESC] = {0};
155 
156  memset(&match, 0, sizeof(match));
157  memset(&counter, 0, sizeof(counter));
158  memset(&actions, 0, sizeof(actions));
159  memset(&fwd, 0, sizeof(fwd));
160  memset(&fwd_miss, 0, sizeof(fwd_miss));
161  memset(&descs, 0, sizeof(descs));
162 
164 
165  actions_arr[0] = &actions;
166  descs_arr[0] = &descs;
167  descs.nb_action_desc = 1;
168  descs.desc_array = desc_array;
169 
171 
172  /* forwarding traffic to next pipe */
174  fwd.next_pipe = next_pipe;
175 
176  desc_array[0].type = DOCA_FLOW_ACTION_COPY;
177  desc_array[0].field_op.src.field_string = "outer.eth_vlan0.tci";
178  desc_array[0].field_op.src.bit_offset = 0;
179  desc_array[0].field_op.dst.field_string = "meta.data";
180  desc_array[0].field_op.dst.bit_offset = META_U32_BIT_OFFSET(TEST_LPM_EM_TAG);
181  desc_array[0].field_op.width = 8;
182 
183  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
184  if (result != DOCA_SUCCESS) {
185  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
186  return result;
187  }
188 
189  result = set_flow_pipe_cfg(pipe_cfg, "MAIN_PIPE_COPY_TO_META", DOCA_FLOW_PIPE_BASIC, false);
190  if (result != DOCA_SUCCESS) {
191  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
192  goto destroy_pipe_cfg;
193  }
194 
195  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
196  if (result != DOCA_SUCCESS) {
197  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
198  goto destroy_pipe_cfg;
199  }
200 
201  result = doca_flow_pipe_cfg_set_monitor(pipe_cfg, &counter);
202  if (result != DOCA_SUCCESS) {
203  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
204  goto destroy_pipe_cfg;
205  }
206 
207  result = doca_flow_pipe_cfg_set_actions(pipe_cfg, actions_arr, NULL, descs_arr, NB_ACTIONS_ARR);
208  if (result != DOCA_SUCCESS) {
209  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg actions: %s", doca_error_get_descr(result));
210  goto destroy_pipe_cfg;
211  }
212 
213  result = doca_flow_pipe_create(pipe_cfg, &fwd, &fwd_miss, pipe);
214 
216  doca_flow_pipe_cfg_destroy(pipe_cfg);
217  return result;
218 }
219 
220 /*
221  * Add DOCA Flow pipe entry to the basic pipe that forwards ipv4 traffic to lpm pipe
222  *
223  * @pipe [in]: pipe of the entry
224  * @status [in]: user context for adding entry
225  * @entry [out]: result of entry addition
226  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
227  */
228 static doca_error_t add_main_pipe_entry(struct doca_flow_pipe *pipe,
229  struct entries_status *status,
230  struct doca_flow_pipe_entry **entry)
231 {
232  struct doca_flow_match match;
233 
234  memset(&match, 0, sizeof(match));
235 
236  return doca_flow_pipe_add_entry(0, pipe, &match, NULL, NULL, NULL, DOCA_FLOW_NO_WAIT, status, entry);
237 }
238 
239 /*
240  * Add DOCA Flow LPM pipe which performs LPM logic for IPv4 src address and exact-match logic on
241  * meta.u32[1], match_mask.tun.vxlan_tun_id and match_mask.inner.eth.dst_mac.
242  * Only these fields are available for exact-match logic.
243  * To enable the exact-match logic, set any of these fields to full mask.
244  *
245  *
246  * @port [in]: port of the pipe
247  * @pipe [out]: created pipe pointer
248  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
249  */
250 static doca_error_t create_lpm_pipe(struct doca_flow_port *port, struct doca_flow_pipe **pipe)
251 {
252  struct doca_flow_match match, match_mask;
253  struct doca_flow_actions actions, *actions_arr[NB_ACTIONS_ARR];
254  struct doca_flow_pipe_cfg *pipe_cfg;
256  struct doca_flow_monitor counter;
258 
259  memset(&match, 0, sizeof(match));
260  memset(&match_mask, 0, sizeof(match_mask));
261  memset(&actions, 0, sizeof(actions));
262  memset(&counter, 0, sizeof(counter));
263 
265  match.outer.ip4.src_ip = UINT32_MAX;
266 
267  match_mask.meta.u32[1] = UINT32_MAX;
269  match_mask.tun.vxlan_tun_id = UINT32_MAX;
270  memset(match_mask.inner.eth.dst_mac, UINT8_MAX, sizeof(match_mask.inner.eth.dst_mac));
271 
272  actions_arr[0] = &actions;
273 
274  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
275  if (result != DOCA_SUCCESS) {
276  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
277  return result;
278  }
279 
280  result = set_flow_pipe_cfg(pipe_cfg, "LPM_EM_PIPE", DOCA_FLOW_PIPE_LPM, false);
281  if (result != DOCA_SUCCESS) {
282  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
283  goto destroy_pipe_cfg;
284  }
285 
286  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, &match_mask);
287  if (result != DOCA_SUCCESS) {
288  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
289  goto destroy_pipe_cfg;
290  }
291 
292  result = doca_flow_pipe_cfg_set_actions(pipe_cfg, actions_arr, NULL, NULL, NB_ACTIONS_ARR);
293  if (result != DOCA_SUCCESS) {
294  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg actions: %s", doca_error_get_descr(result));
295  goto destroy_pipe_cfg;
296  }
297 
299  result = doca_flow_pipe_cfg_set_monitor(pipe_cfg, &counter);
300  if (result != DOCA_SUCCESS) {
301  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg counter: %s", doca_error_get_descr(result));
302  goto destroy_pipe_cfg;
303  }
304 
305  result = doca_flow_pipe_create(pipe_cfg, &fwd, NULL, pipe);
307  doca_flow_pipe_cfg_destroy(pipe_cfg);
308  return result;
309 }
310 
311 /*
312  * Add DOCA Flow pipe entry to the LPM pipe.
313  *
314  * @pipe [in]: pipe of the entry
315  * @port_id [in]: port ID of the entry
316  * @src_ip_addr [in]: src ip address
317  * @src_ip_addr_mask [in]: src ip mask
318  * @exact_match_meta [in]: value for exact match logic on meta
319  * @exact_match_vni [in]: value for exact match logic on vni
320  * @exact_match_inner_dmac [in]: pointer to value for exact match logic on inner destination mac
321  * @flag [in]: Flow entry will be pushed to hw immediately or not. enum doca_flow_flags_type.
322  * flag DOCA_FLOW_WAIT_FOR_BATCH is using for collecting entries by LPM module
323  * flag DOCA_FLOW_NO_WAIT is using for adding the entry and starting building and offloading
324  * @status [in]: user context for adding entry
325  * @entry [out]: created entry pointer.
326  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
327  */
328 static doca_error_t add_lpm_one_entry(struct doca_flow_pipe *pipe,
329  uint16_t port_id,
330  doca_be32_t src_ip_addr,
331  doca_be32_t src_ip_addr_mask,
332  uint32_t exact_match_meta,
333  uint32_t exact_match_vni,
334  uint8_t *exact_match_inner_dmac,
335  const enum doca_flow_flags_type flag,
336  struct entries_status *status,
337  struct doca_flow_pipe_entry **entry)
338 {
339  struct doca_flow_match match = {0};
340  struct doca_flow_match match_mask = {0};
341  struct doca_flow_fwd fwd = {0};
342  doca_error_t rc;
343 
344  match.outer.ip4.src_ip = src_ip_addr;
345  match.meta.u32[1] = exact_match_meta;
346  match.tun.vxlan_tun_id = exact_match_vni;
347  memcpy(match.inner.eth.dst_mac, exact_match_inner_dmac, sizeof(match.inner.eth.dst_mac));
348 
349  match_mask.outer.ip4.src_ip = src_ip_addr_mask;
350 
351  if (port_id == UINT16_MAX)
353  else {
355  fwd.port_id = port_id ^ 1;
356  }
357 
358  rc = doca_flow_pipe_lpm_add_entry(0, pipe, &match, &match_mask, NULL, NULL, &fwd, flag, status, entry);
359  if (rc != DOCA_SUCCESS) {
360  DOCA_LOG_ERR("Failed to add lpm pipe entry: %s", doca_error_get_descr(rc));
361  return rc;
362  }
363  return rc;
364 }
365 
366 /*
367  * Add DOCA Flow pipe entries to the LPM pipe.
368  * one entry with full mask and one with 16 bits mask for vlan 1 and vlan 2
369  * and one default entry for each vlan
370  *
371  * @pipe [in]: pipe of the entry
372  * @port_id [in]: port ID of the entry
373  * @status [in]: user context for adding entry
374  * @entries [out]: created entry pointers.
375  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
376  */
377 static doca_error_t add_lpm_pipe_entries(struct doca_flow_pipe *pipe,
378  uint16_t port_id,
379  struct entries_status *status,
380  struct doca_flow_pipe_entry **entries)
381 {
382  doca_error_t rc;
383  uint8_t inner_dmac[6] = {0};
384 
385  /* add default entry with 0 bits mask and fwd drop */
386  rc = add_lpm_one_entry(pipe,
387  UINT16_MAX, /* indicates forward drop */
388  BE_IPV4_ADDR(0, 0, 0, 0),
389  RTE_BE32(0x00000000),
390  0, /* does not make a difference for a default entry */
391  0,
392  inner_dmac,
394  status,
395  &entries[0]);
396  if (rc != DOCA_SUCCESS)
397  return rc;
398 
399  /* add entry with full mask and fwd port */
400  memset(inner_dmac, 1, sizeof(inner_dmac));
401  rc = add_lpm_one_entry(pipe,
402  port_id,
403  BE_IPV4_ADDR(1, 2, 3, 4),
404  RTE_BE32(0xffffffff),
405  DOCA_HTOBE32(1),
406  DOCA_HTOBE32(0xabcde1),
407  inner_dmac,
409  status,
410  &entries[1]);
411  if (rc != DOCA_SUCCESS)
412  return rc;
413 
414  memset(inner_dmac, 2, sizeof(inner_dmac));
415  rc = add_lpm_one_entry(pipe,
416  port_id,
417  BE_IPV4_ADDR(1, 2, 3, 4),
418  RTE_BE32(0xffffffff),
419  DOCA_HTOBE32(2),
420  DOCA_HTOBE32(0xabcde2),
421  inner_dmac,
423  status,
424  &entries[2]);
425  if (rc != DOCA_SUCCESS)
426  return rc;
427 
428  /* add entry with full mask, but exact-match 3 to fwd drop */
429  memset(inner_dmac, 3, sizeof(inner_dmac));
430  rc = add_lpm_one_entry(pipe,
431  UINT16_MAX,
432  BE_IPV4_ADDR(1, 2, 3, 4),
433  RTE_BE32(0xffffffff),
434  DOCA_HTOBE32(3),
435  DOCA_HTOBE32(0xabcde3),
436  inner_dmac,
438  status,
439  &entries[3]);
440  if (rc != DOCA_SUCCESS)
441  return rc;
442 
443  /* add entry with 16 bit mask, exact-match 3 and fwd port */
444  rc = add_lpm_one_entry(pipe,
445  port_id,
446  BE_IPV4_ADDR(1, 2, 0, 0),
447  RTE_BE32(0xffff0000),
448  DOCA_HTOBE32(3),
449  DOCA_HTOBE32(0xabcde3),
450  inner_dmac,
452  status,
453  &entries[4]);
454  if (rc != DOCA_SUCCESS)
455  return rc;
456 
457  return DOCA_SUCCESS;
458 }
459 
460 /*
461  * Run flow_lpm_em sample
462  *
463  * @nb_queues [in]: number of queues the sample will use
464  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
465  */
466 doca_error_t flow_lpm_em(int nb_queues)
467 {
468  const int nb_ports = 2;
469  /*
470  * Total numbe of entries - 7.
471  * - 1 entry for classifier pipe
472  * - 1 entry for main pipe
473  * - 5 entries for LPM EM pipe
474  */
475  const int num_of_entries = 7;
476  const int classifier_entry_idx = 0;
477  const int main_entry_idx = 1;
478  const int lpm_entries_idx = 2;
479  struct flow_resources resource = {.nr_counters = 64};
480  struct doca_dev *dev_arr[nb_ports];
481  uint32_t actions_mem_size[nb_ports];
482  uint32_t nr_shared_resources[SHARED_RESOURCE_NUM_VALUES] = {0};
483  struct doca_flow_port *ports[nb_ports];
484  struct doca_flow_pipe *classifier_pipe;
485  struct doca_flow_pipe *main_pipe;
486  struct doca_flow_pipe *lpm_pipe;
487  struct entries_status status;
488  struct doca_flow_pipe_entry *entries[nb_ports][num_of_entries];
491  int port_id, lpm_entry_id;
492 
493  result = init_doca_flow(nb_queues, "vnf,hws", &resource, nr_shared_resources);
494  if (result != DOCA_SUCCESS) {
495  DOCA_LOG_ERR("Failed to init DOCA Flow: %s", doca_error_get_descr(result));
496  return result;
497  }
498 
499  memset(dev_arr, 0, sizeof(struct doca_dev *) * nb_ports);
500  ARRAY_INIT(actions_mem_size, ACTIONS_MEM_SIZE(nb_queues, num_of_entries));
502  if (result != DOCA_SUCCESS) {
503  DOCA_LOG_ERR("Failed to init DOCA ports: %s", doca_error_get_descr(result));
505  return result;
506  }
507 
508  for (port_id = 0; port_id < nb_ports; port_id++) {
509  memset(&status, 0, sizeof(status));
510 
511  result = create_lpm_pipe(ports[port_id], &lpm_pipe);
512  if (result != DOCA_SUCCESS) {
513  DOCA_LOG_ERR("Failed to create pipe: %s", doca_error_get_descr(result));
516  return result;
517  }
518 
519  result = add_lpm_pipe_entries(lpm_pipe, port_id, &status, &entries[port_id][lpm_entries_idx]);
520  if (result != DOCA_SUCCESS) {
523  return result;
524  }
525 
526  result = create_main_pipe(ports[port_id], lpm_pipe, &main_pipe);
527  if (result != DOCA_SUCCESS) {
528  DOCA_LOG_ERR("Failed to create main pipe: %s", doca_error_get_descr(result));
531  return result;
532  }
533 
534  result = add_main_pipe_entry(main_pipe, &status, &entries[port_id][main_entry_idx]);
535  if (result != DOCA_SUCCESS) {
536  DOCA_LOG_ERR("Failed to add entry: %s", doca_error_get_descr(result));
539  return result;
540  }
541 
542  result = create_classifier_pipe(ports[port_id], main_pipe, &classifier_pipe);
543  if (result != DOCA_SUCCESS) {
544  DOCA_LOG_ERR("Failed to create classifier pipe: %s", doca_error_get_descr(result));
547  return result;
548  }
549 
550  result = add_classifier_pipe_entry(classifier_pipe, &status, &entries[port_id][classifier_entry_idx]);
551  if (result != DOCA_SUCCESS) {
552  DOCA_LOG_ERR("Failed to add entry: %s", doca_error_get_descr(result));
555  return result;
556  }
557 
558  result = doca_flow_entries_process(ports[port_id], 0, DEFAULT_TIMEOUT_US, num_of_entries);
559  if (result != DOCA_SUCCESS) {
560  DOCA_LOG_ERR("Failed to process entries: %s", doca_error_get_descr(result));
563  return result;
564  }
565 
566  if (status.nb_processed != num_of_entries || status.failure) {
567  DOCA_LOG_ERR("Failed to process entries");
570  return DOCA_ERROR_BAD_STATE;
571  }
572  }
573  DOCA_LOG_INFO("Wait few seconds for packets to arrive");
574  sleep(10);
575  DOCA_LOG_INFO("===================================================");
576 
577  for (port_id = 0; port_id < nb_ports; port_id++) {
578  DOCA_LOG_INFO("Port %d:", port_id);
579  result = doca_flow_resource_query_entry(entries[port_id][classifier_entry_idx], &stats);
580  if (result != DOCA_SUCCESS) {
581  DOCA_LOG_ERR("Port %d failed to query classifier pipe entry: %s",
582  port_id,
584  return result;
585  }
586  DOCA_LOG_INFO("\tClassifier pipe: %lu packets", stats.counter.total_pkts);
587  DOCA_LOG_INFO("--------------");
588 
589  result = doca_flow_resource_query_entry(entries[port_id][main_entry_idx], &stats);
590  if (result != DOCA_SUCCESS) {
591  DOCA_LOG_ERR("Port %d failed to query main pipe entry: %s",
592  port_id,
594  return result;
595  }
596  DOCA_LOG_INFO("\tMain pipe: %lu packets", stats.counter.total_pkts);
597  DOCA_LOG_INFO("--------------");
598 
599  DOCA_LOG_INFO("LPM with EM pipe:");
600  for (lpm_entry_id = lpm_entries_idx; lpm_entry_id < num_of_entries; lpm_entry_id++) {
601  result = doca_flow_resource_query_entry(entries[port_id][lpm_entry_id], &stats);
602  if (result != DOCA_SUCCESS) {
603  DOCA_LOG_ERR("Port %d failed to query LPM entry %d: %s",
604  port_id,
605  lpm_entry_id - 1,
607  return result;
608  }
609 
610  DOCA_LOG_INFO("\tEntry %d received %lu packets", lpm_entry_id - 1, stats.counter.total_pkts);
611  }
612  DOCA_LOG_INFO("===================================================");
613  }
614 
617  return DOCA_SUCCESS;
618 }
#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 struct eth_l2_fwd_stats stats
static doca_error_t destroy_pipe_cfg(struct doca_flow_pipe_cfg *cfg)
static struct doca_flow_pipe_entry * entries[NB_ENTRIES]
static doca_error_t add_lpm_one_entry(struct doca_flow_pipe *pipe, uint16_t port_id, doca_be32_t src_ip_addr, doca_be32_t src_ip_addr_mask, uint32_t exact_match_meta, uint32_t exact_match_vni, uint8_t *exact_match_inner_dmac, const enum doca_flow_flags_type flag, struct entries_status *status, struct doca_flow_pipe_entry **entry)
static doca_error_t add_lpm_pipe_entries(struct doca_flow_pipe *pipe, uint16_t port_id, struct entries_status *status, struct doca_flow_pipe_entry **entries)
doca_error_t flow_lpm_em(int nb_queues)
DOCA_LOG_REGISTER(FLOW_LPM_EM)
static doca_error_t add_main_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status, struct doca_flow_pipe_entry **entry)
static doca_error_t add_classifier_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status, struct doca_flow_pipe_entry **entry)
static doca_error_t create_main_pipe(struct doca_flow_port *port, struct doca_flow_pipe *next_pipe, struct doca_flow_pipe **pipe)
#define TEST_LPM_EM_TAG
static doca_error_t create_classifier_pipe(struct doca_flow_port *port, struct doca_flow_pipe *main_pipe, struct doca_flow_pipe **pipe)
#define META_U32_BIT_OFFSET(idx)
#define NB_ACTION_DESC
static doca_error_t create_lpm_pipe(struct doca_flow_port *port, struct doca_flow_pipe **pipe)
static struct doca_flow_fwd fwd_miss
Definition: flow_parser.c:110
static struct doca_flow_actions actions
Definition: flow_parser.c:107
#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_match match_mask
Definition: flow_parser.c:106
static struct doca_flow_pipe_entry * entry[MAX_ENTRIES]
#define DEFAULT_TIMEOUT_US
Definition: flow_skeleton.c:36
#define DOCA_HTOBE32(_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_ERROR_BAD_STATE
Definition: doca_error.h:56
@ DOCA_SUCCESS
Definition: doca_error.h:38
#define DOCA_FLOW_VXLAN_DEFAULT_PORT
Definition: doca_flow_net.h:49
@ DOCA_FLOW_L4_TYPE_EXT_UDP
@ DOCA_FLOW_L3_TYPE_IP4
@ DOCA_FLOW_TUN_VXLAN
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_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_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_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_flow_flags_type
doca flow flags type
Definition: doca_flow.h:114
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_EXPERIMENTAL doca_error_t doca_flow_pipe_cfg_set_actions(struct doca_flow_pipe_cfg *cfg, struct doca_flow_actions *const *actions, struct doca_flow_actions *const *actions_masks, struct doca_flow_action_descs *const *action_descs, size_t nr_actions)
Set pipe's actions, actions mask and actions descriptor.
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_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_BASIC
Definition: doca_flow.h:221
@ DOCA_FLOW_PIPE_LPM
Definition: doca_flow.h:225
@ DOCA_FLOW_L3_META_IPV4
Definition: doca_flow.h:296
@ DOCA_FLOW_NO_WAIT
Definition: doca_flow.h:115
@ DOCA_FLOW_WAIT_FOR_BATCH
Definition: doca_flow.h:117
@ DOCA_FLOW_ACTION_COPY
Definition: doca_flow.h:1012
@ 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_FWD_CHANGEABLE
Definition: doca_flow.h:756
@ DOCA_FLOW_FWD_DROP
Definition: doca_flow.h:748
@ DOCA_FLOW_L4_META_UDP
Definition: doca_flow.h:310
@ DOCA_FLOW_L2_META_SINGLE_VLAN
Definition: doca_flow.h:284
#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
uint32_t doca_be32_t
Definition: doca_types.h:121
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 NB_ACTIONS_ARR
Definition: flow_common.h:58
#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
action description
Definition: doca_flow.h:1019
enum doca_flow_action_type type
Definition: doca_flow.h:1020
struct doca_flow_action_desc::@108::@110 field_op
action descriptor array
Definition: doca_flow.h:1033
struct doca_flow_action_desc * desc_array
Definition: doca_flow.h:1036
doca flow actions information
Definition: doca_flow.h:684
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
uint8_t dst_mac[DOCA_FLOW_ETHER_ADDR_LEN]
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
struct doca_flow_header_eth eth
Definition: doca_flow.h:440
struct doca_flow_header_udp udp
Definition: doca_flow.h:459
enum doca_flow_l3_type l3_type
Definition: doca_flow.h:446
struct doca_flow_header_l4_port l4_port
doca flow matcher information
Definition: doca_flow.h:491
struct doca_flow_header_format inner
Definition: doca_flow.h:502
struct doca_flow_parser_meta parser_meta
Definition: doca_flow.h:496
struct doca_flow_header_format outer
Definition: doca_flow.h:498
struct doca_flow_tun tun
Definition: doca_flow.h:500
struct doca_flow_meta meta
Definition: doca_flow.h:494
doca_be32_t u32[DOCA_FLOW_META_SCRATCH_PAD_MAX]
Definition: doca_flow.h:360
doca monitor action configuration
Definition: doca_flow.h:968
enum doca_flow_resource_type counter_type
Definition: doca_flow.h:988
enum doca_flow_l2_meta outer_l2_type
Definition: doca_flow.h:381
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
flow resource query
Definition: doca_flow.h:1101
enum doca_flow_tun_type type
doca_be32_t vxlan_tun_id
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