NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
flow_switch_rss_sample.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 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 <rte_byteorder.h>
30 #include <rte_ethdev.h>
31 #include <rte_mempool.h>
32 #include <rte_mbuf.h>
33 #include <rte_net.h>
34 
35 #include <doca_log.h>
36 #include <doca_flow.h>
37 #include <doca_dev.h>
38 
39 #include "flow_common.h"
40 #include "flow_switch_common.h"
41 
42 DOCA_LOG_REGISTER(FLOW_SWITCH_SWITCH_RSS);
43 
49 };
50 
52  SWITCH_RSS_BASIC_PIPE_CONST_RSS, /* Constant RSS fwd in pipe */
53  SWITCH_RSS_BASIC_PIPE_DYN_RSS, /* Dynamic RSS fwd in entry */
54  SWITCH_RSS_BASIC_PIPE_SHARED_RSS, /* null fwd with shared RSS in entry */
56 };
57 
62 };
63 
70 };
71 
73  SWITCH_RSS_PIPE_DIR_N2H, /* Network to host direction pipe */
74  SWITCH_RSS_PIPE_DIR_BI, /* Bi-direction pipe */
76 };
77 
78 #define NB_EGRESS_ENTRIES (SWITCH_RSS_BASIC_PIPE_MAX + SWITCH_RSS_CONTROL_MAX)
79 
80 #define NB_INGRESS_ENTRIES INGRESS_ROOT_TO_MAX
81 
82 #define NB_VPORT_ENTRIES INGRESS_TO_PORT_MAX
83 
84 #define NB_TOTAL_ENTRIES \
85  (1 + NB_INGRESS_ENTRIES + NB_EGRESS_ENTRIES + NB_VPORT_ENTRIES + \
86  (SWITCH_RSS_BASIC_PIPE_MAX + SWITCH_RSS_CONTROL_MAX) * SWITCH_RSS_PIPE_DIR_MAX)
87 
88 #define MAX_PKTS 16
89 
90 #define WAIT_SECS 15
91 
92 static struct doca_flow_pipe *pipe_egress;
93 static struct doca_flow_pipe *pipe_ingress;
94 static struct doca_flow_pipe *pipe_vport;
95 static struct doca_flow_pipe *pipe_rss;
96 
98 static struct doca_flow_pipe *pipe_control_switch_rss[SWITCH_RSS_PIPE_DIR_MAX];
99 
102 static struct doca_flow_pipe_entry *rss_entry;
103 
105  {
106  0,
107  1,
108  2,
109  },
110  {
111  3,
112  4,
113  5,
114  },
115 };
117  {
118  6,
119  7,
120  },
121  {
122  8,
123  9,
124  },
125 };
126 
127 #define MAX_RSS_QUEUE 10
128 
129 /* array for storing created egress entries */
130 static struct doca_flow_pipe_entry *egress_entries[NB_EGRESS_ENTRIES];
131 
132 /* array for storing created ingress entries */
133 static struct doca_flow_pipe_entry *ingress_entries[NB_INGRESS_ENTRIES];
134 
135 /* array for storing created ingress entries */
136 static struct doca_flow_pipe_entry *vport_entries[NB_VPORT_ENTRIES];
137 
138 /*
139  * Handle received traffic and check the pkt_meta value added by internal pipe.
140  *
141  * @port_id [in]: proxy port id
142  * @nb_queues [in]: number of queues the sample has
143  */
144 static void handle_rx_tx_pkts(uint32_t port_id, uint16_t nb_queues)
145 {
146  int rc;
147  uint32_t queue_id;
148  uint32_t secs = WAIT_SECS;
149  uint32_t nb_rx;
150  uint32_t i;
151  uint32_t sw_packet_type;
152  struct rte_mbuf *mbufs[MAX_PKTS];
153 
154  rc = rte_flow_dynf_metadata_register();
155  if (unlikely(rc)) {
156  DOCA_LOG_ERR("Enable metadata failed");
157  return;
158  }
159 
160  while (secs--) {
161  sleep(1);
162  for (queue_id = 0; queue_id < nb_queues; queue_id++) {
163  nb_rx = rte_eth_rx_burst(port_id, queue_id, mbufs, MAX_PKTS);
164  for (i = 0; i < nb_rx; i++) {
165  sw_packet_type = rte_net_get_ptype(mbufs[i], NULL, RTE_PTYPE_ALL_MASK);
166  if (mbufs[i]->ol_flags & RTE_MBUF_F_RX_FDIR_ID)
167  DOCA_LOG_INFO("The pkt meta:0x%x, src_q:%d, type:0x%x",
168  mbufs[i]->hash.fdir.hi,
169  queue_id,
170  sw_packet_type);
171  else
172  DOCA_LOG_INFO("The pkt src_q:%d, type: 0x%x\n", queue_id, sw_packet_type);
173  rte_pktmbuf_free(mbufs[i]);
174  }
175  }
176  }
177 }
178 
179 /*
180  * Create DOCA Flow pipe with 5 tuple match, and forward RSS
181  *
182  * @port [in]: port of the pipe
183  * @pipe [out]: created pipe pointer
184  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
185  */
186 static doca_error_t create_rss_pipe(struct doca_flow_port *port, struct doca_flow_pipe **pipe)
187 {
188  struct doca_flow_match match;
189  struct doca_flow_monitor monitor;
190  struct doca_flow_fwd fwd;
191  struct doca_flow_pipe_cfg *pipe_cfg;
192  uint16_t rss_queues[1];
194 
195  memset(&match, 0, sizeof(match));
196  memset(&fwd, 0, sizeof(fwd));
197  memset(&monitor, 0, sizeof(monitor));
198 
200 
201  /* L3 match */
203 
204  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
205  if (result != DOCA_SUCCESS) {
206  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
207  return result;
208  }
209 
210  result = set_flow_pipe_cfg(pipe_cfg, "RSS_META_PIPE", DOCA_FLOW_PIPE_BASIC, false);
211  if (result != DOCA_SUCCESS) {
212  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
213  goto destroy_pipe_cfg;
214  }
215  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
216  if (result != DOCA_SUCCESS) {
217  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
218  goto destroy_pipe_cfg;
219  }
221  if (result != DOCA_SUCCESS) {
222  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
223  goto destroy_pipe_cfg;
224  }
225 
226  /* RSS queue - send matched traffic to queue 0 */
227  rss_queues[0] = 0;
232  fwd.rss.nr_queues = 1;
233 
234  result = doca_flow_pipe_create(pipe_cfg, &fwd, NULL, pipe);
236  doca_flow_pipe_cfg_destroy(pipe_cfg);
237  return result;
238 }
239 
240 /*
241  * Add DOCA Flow pipe entry with example 5 tuple
242  *
243  * @pipe [in]: pipe of the entry
244  * @status [in]: user context for adding entry
245  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
246  */
247 static doca_error_t add_rss_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status)
248 {
249  struct doca_flow_match match;
250  struct doca_flow_actions actions;
252 
253  memset(&match, 0, sizeof(match));
254  memset(&actions, 0, sizeof(actions));
255 
256  actions.action_idx = 0;
257 
258  result = doca_flow_pipe_add_entry(0, pipe, &match, &actions, NULL, NULL, 0, status, &rss_entry);
259  if (result != DOCA_SUCCESS)
260  return result;
261 
262  return DOCA_SUCCESS;
263 }
264 
265 /*
266  * Create DOCA Flow control pipe
267  *
268  * @port [in]: port of the pipe
269  * @dir [in]: pipe direction
270  * @pipe [out]: created pipe pointer
271  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
272  */
273 static doca_error_t create_switch_rss_control_pipe(struct doca_flow_port *port,
274  enum switch_rss_pipe_dir_type dir,
275  struct doca_flow_pipe **pipe)
276 {
277  struct doca_flow_pipe_cfg *pipe_cfg;
279 
280  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
281  if (result != DOCA_SUCCESS) {
282  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
283  return result;
284  }
285 
286  result = set_flow_pipe_cfg(pipe_cfg, "CONTROL_PIPE", DOCA_FLOW_PIPE_CONTROL, false);
287  if (result != DOCA_SUCCESS) {
288  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
289  goto destroy_pipe_cfg;
290  }
291 
292  if (dir == SWITCH_RSS_PIPE_DIR_N2H) {
294  if (result != DOCA_SUCCESS) {
295  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg domain: %s", doca_error_get_descr(result));
296  goto destroy_pipe_cfg;
297  }
298  } else {
300  if (result != DOCA_SUCCESS) {
301  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg domain: %s", doca_error_get_descr(result));
302  goto destroy_pipe_cfg;
303  }
304  }
305 
306  result = doca_flow_pipe_create(pipe_cfg, NULL, NULL, pipe);
308  doca_flow_pipe_cfg_destroy(pipe_cfg);
309  return result;
310 }
311 
312 /*
313  * Create DOCA Flow pipe with 5 tuple match, and forward RSS
314  *
315  * @port [in]: port of the pipe
316  * @dir [in]: pipe direction
317  * @type [in]: pipe type
318  * @pipe [out]: created pipe pointer
319  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
320  */
321 static doca_error_t create_switch_rss_pipe(struct doca_flow_port *port,
322  enum switch_rss_pipe_dir_type dir,
324  struct doca_flow_pipe **pipe)
325 {
326  struct doca_flow_match match;
327  struct doca_flow_monitor monitor;
328  struct doca_flow_fwd fwd;
329  struct doca_flow_fwd *pfwd = &fwd;
330  struct doca_flow_pipe_cfg *pipe_cfg;
331  uint16_t rss_queues[1];
333 
334  memset(&match, 0, sizeof(match));
335  memset(&fwd, 0, sizeof(fwd));
336  memset(&monitor, 0, sizeof(monitor));
337 
340  match.outer.ip4.dst_ip = 0xffffffff;
341 
343 
344  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
345  if (result != DOCA_SUCCESS) {
346  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
347  return result;
348  }
349 
350  result = set_flow_pipe_cfg(pipe_cfg, "RSS_META_PIPE", DOCA_FLOW_PIPE_BASIC, false);
351  if (result != DOCA_SUCCESS) {
352  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
353  goto destroy_pipe_cfg;
354  }
355  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
356  if (result != DOCA_SUCCESS) {
357  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
358  goto destroy_pipe_cfg;
359  }
361  if (result != DOCA_SUCCESS) {
362  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
363  goto destroy_pipe_cfg;
364  }
365 
366  if (dir == SWITCH_RSS_PIPE_DIR_N2H) {
368  if (result != DOCA_SUCCESS) {
369  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg domain: %s", doca_error_get_descr(result));
370  goto destroy_pipe_cfg;
371  }
372  } else {
374  if (result != DOCA_SUCCESS) {
375  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg domain: %s", doca_error_get_descr(result));
376  goto destroy_pipe_cfg;
377  }
378  }
379 
382  } else if (type == SWITCH_RSS_BASIC_PIPE_DYN_RSS) {
385  fwd.rss.nr_queues = UINT32_MAX;
386  } else {
387  /* RSS queue - send matched traffic to queue 0 */
388  rss_queues[0] = basic_queue_map[dir][type];
393  fwd.rss.nr_queues = 1;
394  }
395 
396  result = doca_flow_pipe_create(pipe_cfg, pfwd, NULL, pipe);
398  doca_flow_pipe_cfg_destroy(pipe_cfg);
399  return result;
400 }
401 
402 /*
403  * Create DOCA Flow pipe with 5 tuple match on the switch port.
404  * Matched traffic will be forwarded to the port defined per entry.
405  * Unmatched traffic will be dropped.
406  *
407  * @sw_port [in]: switch port
408  * @pipe [out]: created pipe pointer
409  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
410  */
411 static doca_error_t create_switch_egress_pipe(struct doca_flow_port *sw_port, struct doca_flow_pipe **pipe)
412 {
413  struct doca_flow_match match;
414  struct doca_flow_monitor monitor;
415  struct doca_flow_fwd fwd;
416  struct doca_flow_pipe_cfg *pipe_cfg;
418 
419  memset(&match, 0, sizeof(match));
420  memset(&monitor, 0, sizeof(monitor));
421  memset(&fwd, 0, sizeof(fwd));
422 
425 
426  /* Source, destination IP addresses and source, destination TCP ports are defined per entry */
427  match.outer.ip4.src_ip = 0xffffffff;
428 
430 
432 
433  result = doca_flow_pipe_cfg_create(&pipe_cfg, sw_port);
434  if (result != DOCA_SUCCESS) {
435  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
436  return result;
437  }
438 
439  result = set_flow_pipe_cfg(pipe_cfg, "SWITCH_PIPE", DOCA_FLOW_PIPE_BASIC, true);
440  if (result != DOCA_SUCCESS) {
441  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
442  goto destroy_pipe_cfg;
443  }
445  if (result != DOCA_SUCCESS) {
446  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg nr_entries: %s", doca_error_get_descr(result));
447  goto destroy_pipe_cfg;
448  }
450  if (result != DOCA_SUCCESS) {
451  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg domain: %s", doca_error_get_descr(result));
452  goto destroy_pipe_cfg;
453  }
454  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
455  if (result != DOCA_SUCCESS) {
456  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
457  goto destroy_pipe_cfg;
458  }
460  if (result != DOCA_SUCCESS) {
461  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
462  goto destroy_pipe_cfg;
463  }
464 
465  result = doca_flow_pipe_create(pipe_cfg, &fwd, NULL, pipe);
467  doca_flow_pipe_cfg_destroy(pipe_cfg);
468  return result;
469 }
470 
471 /*
472  * Create DOCA Flow pipe with 5 tuple match on the switch port.
473  * Matched traffic will be forwarded to the port defined per entry.
474  * Unmatched traffic will be dropped.
475  *
476  * @sw_port [in]: switch port
477  * @pipe [out]: created pipe pointer
478  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
479  */
480 static doca_error_t create_switch_ingress_pipe(struct doca_flow_port *sw_port, struct doca_flow_pipe **pipe)
481 {
482  struct doca_flow_match match;
483  struct doca_flow_monitor monitor;
484  struct doca_flow_fwd fwd;
485  struct doca_flow_pipe_cfg *pipe_cfg;
487 
488  memset(&match, 0, sizeof(match));
489  memset(&monitor, 0, sizeof(monitor));
490  memset(&fwd, 0, sizeof(fwd));
491 
494 
495  /* Source, destination IP addresses and source, destination TCP ports are defined per entry */
496  match.outer.ip4.src_ip = 0xffffffff;
497 
498  /* Port ID to forward to is defined per entry */
500  fwd.next_pipe = NULL;
501 
503 
504  result = doca_flow_pipe_cfg_create(&pipe_cfg, sw_port);
505  if (result != DOCA_SUCCESS) {
506  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
507  return result;
508  }
509 
510  result = set_flow_pipe_cfg(pipe_cfg, "SWITCH_PIPE", DOCA_FLOW_PIPE_BASIC, true);
511  if (result != DOCA_SUCCESS) {
512  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
513  goto destroy_pipe_cfg;
514  }
516  if (result != DOCA_SUCCESS) {
517  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg nr_entries: %s", doca_error_get_descr(result));
518  goto destroy_pipe_cfg;
519  }
521  if (result != DOCA_SUCCESS) {
522  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg domain: %s", doca_error_get_descr(result));
523  goto destroy_pipe_cfg;
524  }
525  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
526  if (result != DOCA_SUCCESS) {
527  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
528  goto destroy_pipe_cfg;
529  }
531  if (result != DOCA_SUCCESS) {
532  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
533  goto destroy_pipe_cfg;
534  }
535 
536  result = doca_flow_pipe_create(pipe_cfg, &fwd, NULL, pipe);
538  doca_flow_pipe_cfg_destroy(pipe_cfg);
539  return result;
540 }
541 
542 /*
543  * Create DOCA Flow pipe with 5 tuple match on the switch port.
544  * Matched traffic will be forwarded to the port defined per entry.
545  * Unmatched traffic will be dropped.
546  *
547  * @sw_port [in]: switch port
548  * @pipe [out]: created pipe pointer
549  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
550  */
551 static doca_error_t create_switch_vport_pipe(struct doca_flow_port *sw_port, struct doca_flow_pipe **pipe)
552 {
553  struct doca_flow_match match;
554  struct doca_flow_monitor monitor;
555  struct doca_flow_fwd fwd;
556  struct doca_flow_pipe_cfg *pipe_cfg;
558 
559  memset(&match, 0, sizeof(match));
560  memset(&monitor, 0, sizeof(monitor));
561  memset(&fwd, 0, sizeof(fwd));
562  memset(&pipe_cfg, 0, sizeof(pipe_cfg));
563 
566 
567  /* Source IP addresses and source TCP ports are defined per entry */
568  match.outer.ip4.dst_ip = 0xffffffff;
569 
570  /* Port ID to forward to is defined per entry */
572  fwd.port_id = 0xffff;
573 
575 
576  result = doca_flow_pipe_cfg_create(&pipe_cfg, sw_port);
577  if (result != DOCA_SUCCESS) {
578  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
579  return result;
580  }
581 
582  result = set_flow_pipe_cfg(pipe_cfg, "SWITCH_VPORT_PIPE", DOCA_FLOW_PIPE_BASIC, false);
583  if (result != DOCA_SUCCESS) {
584  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
585  goto destroy_pipe_cfg;
586  }
588  if (result != DOCA_SUCCESS) {
589  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg nr_entries: %s", doca_error_get_descr(result));
590  goto destroy_pipe_cfg;
591  }
593  if (result != DOCA_SUCCESS) {
594  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg domain: %s", doca_error_get_descr(result));
595  goto destroy_pipe_cfg;
596  }
597  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
598  if (result != DOCA_SUCCESS) {
599  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
600  goto destroy_pipe_cfg;
601  }
603  if (result != DOCA_SUCCESS) {
604  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
605  goto destroy_pipe_cfg;
606  }
607 
608  result = doca_flow_pipe_create(pipe_cfg, &fwd, NULL, pipe);
610  doca_flow_pipe_cfg_destroy(pipe_cfg);
611  return result;
612 }
613 
614 /*
615  * Add DOCA Flow pipe entry to the pipe
616  *
617  * @pipe [in]: pipe of the entry
618  * @status [in]: user context for adding entry
619  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
620  */
621 static doca_error_t add_switch_egress_pipe_entries(struct doca_flow_pipe *pipe, struct entries_status *status)
622 {
623  struct doca_flow_match match;
624  struct doca_flow_fwd fwd;
627  int entry_index = 0;
628  doca_be32_t src_ip_addr;
629 
630  memset(&fwd, 0, sizeof(fwd));
631  memset(&match, 0, sizeof(match));
634 
635  for (entry_index = 0; entry_index < NB_EGRESS_ENTRIES; entry_index++) {
636  src_ip_addr = BE_IPV4_ADDR(1, 2, 3, 4 + INGRESS_ROOT_TO_CONTROL + entry_index);
637  match.outer.ip4.src_ip = src_ip_addr;
638 
640  if (entry_index < SWITCH_RSS_BASIC_PIPE_MAX)
642  else if (entry_index < INGRESS_ROOT_TO_CONTROL)
644 
646  pipe,
647  &match,
648  NULL,
649  NULL,
650  &fwd,
651  flags,
652  status,
653  &egress_entries[entry_index]);
654 
655  if (result != DOCA_SUCCESS) {
656  DOCA_LOG_ERR("Failed to add pipe entry %d: %s", entry_index, doca_error_get_descr(result));
657  return result;
658  }
659  }
660 
661  return DOCA_SUCCESS;
662 }
663 
664 /*
665  * Add DOCA Flow pipe entry to the pipe
666  *
667  * @pipe [in]: pipe of the entry
668  * @status [in]: user context for adding entry
669  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
670  */
671 static doca_error_t add_switch_ingress_pipe_entries(struct doca_flow_pipe *pipe, struct entries_status *status)
672 {
673  struct doca_flow_match match;
674  struct doca_flow_fwd fwd;
677  int entry_index = 0;
678  doca_be32_t src_ip_addr;
679 
680  memset(&fwd, 0, sizeof(fwd));
681  memset(&match, 0, sizeof(match));
682 
685 
686  for (entry_index = 0; entry_index < NB_INGRESS_ENTRIES; entry_index++) {
687  src_ip_addr = BE_IPV4_ADDR(1, 2, 3, 4 + entry_index);
688  match.outer.ip4.src_ip = src_ip_addr;
689 
691  if (entry_index < INGRESS_ROOT_TO_BASIC)
693  else if (entry_index < INGRESS_ROOT_TO_CONTROL)
695  else if (entry_index < INGRESS_ROOT_TO_EGRESS)
697  else if (entry_index < INGRESS_ROOT_TO_VPORT)
700  pipe,
701  &match,
702  NULL,
703  NULL,
704  &fwd,
705  flags,
706  status,
707  &ingress_entries[entry_index]);
708 
709  if (result != DOCA_SUCCESS) {
710  DOCA_LOG_ERR("Failed to add pipe entry %d: %s", entry_index, doca_error_get_descr(result));
711  return result;
712  }
713  }
714 
715  return DOCA_SUCCESS;
716 }
717 
718 /*
719  * Add DOCA Flow pipe entry to the pipe
720  *
721  * @pipe [in]: pipe of the entry
722  * @status [in]: user context for adding entry
723  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
724  */
725 static doca_error_t add_switch_vport_pipe_entries(struct doca_flow_pipe *pipe, struct entries_status *status)
726 {
727  struct doca_flow_match match;
728  struct doca_flow_fwd fwd;
731  int entry_index = 0;
732  doca_be32_t dst_ip_addr;
733 
734  memset(&fwd, 0, sizeof(fwd));
735  memset(&match, 0, sizeof(match));
738 
739  for (entry_index = 0; entry_index < NB_VPORT_ENTRIES; entry_index++) {
740  dst_ip_addr = BE_IPV4_ADDR(8, 8, 8, 8 + entry_index);
741 
742  match.outer.ip4.dst_ip = dst_ip_addr;
743 
745  /* First port as wire to wire, second wire to VF */
746  fwd.port_id = entry_index;
747 
749  pipe,
750  &match,
751  NULL,
752  NULL,
753  &fwd,
754  flags,
755  status,
756  &vport_entries[entry_index]);
757 
758  if (result != DOCA_SUCCESS) {
759  DOCA_LOG_ERR("Failed to add pipe entry: %s", doca_error_get_descr(result));
760  return result;
761  }
762  }
763 
764  return DOCA_SUCCESS;
765 }
766 
767 /*
768  * Create DOCA Flow SWITCH RSS pipes match on the switch port.
769  * Matched traffic will be forwarded to the RSS queue defined per entry.
770  * Unmatched traffic will be dropped.
771  *
772  * @port [in]: switch port
773  * @dir [in]: pipe direction
774  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
775  */
776 static int create_switch_rss_pipes(struct doca_flow_port *port, enum switch_rss_pipe_dir_type dir)
777 {
779  int i;
780 
782  if (result != DOCA_SUCCESS) {
783  DOCA_LOG_ERR("Failed to create %d control pipe: %s", dir, doca_error_get_descr(result));
784  return result;
785  }
786 
787  for (i = 0; i < SWITCH_RSS_BASIC_PIPE_MAX; i++) {
788  result = create_switch_rss_pipe(port, dir, i, &pipe_basic_switch_rss[dir][i]);
789  if (result != DOCA_SUCCESS) {
790  DOCA_LOG_ERR("Failed to create %d basic pipe %d: %s", dir, i, doca_error_get_descr(result));
791  return result;
792  }
793  }
794 
795  return DOCA_SUCCESS;
796 }
797 
798 /*
799  * Add DOCA Flow RSS pipe entry to the pipe
800  *
801  * @dir [in]: pipe direction
802  * @status [in]: user context for adding entry
803  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
804  */
806 {
807  struct doca_flow_match match;
808  struct doca_flow_fwd fwd;
809  struct doca_flow_fwd *efwd = &fwd;
810  enum doca_flow_flags_type flags = 0; // DOCA_FLOW_WAIT_FOR_BATCH;
812  int entry_index = 0;
813  doca_be32_t dst_ip_addr;
814  uint16_t rss_queues[1];
815  struct doca_flow_monitor monitor;
816 
817  memset(&match, 0, sizeof(match));
820 
821  for (entry_index = 0; entry_index < SWITCH_RSS_BASIC_PIPE_MAX; entry_index++) {
822  dst_ip_addr = BE_IPV4_ADDR(8, 8, 8, 8);
823  match.outer.ip4.dst_ip = dst_ip_addr;
824 
825  memset(&fwd, 0, sizeof(fwd));
826  if (entry_index == SWITCH_RSS_BASIC_PIPE_SHARED_RSS) {
829  fwd.shared_rss_id = basic_queue_map[dir][entry_index];
830  } else {
831  rss_queues[0] = basic_queue_map[dir][entry_index];
836  fwd.rss.nr_queues = 1;
837  }
838 
840  pipe_basic_switch_rss[dir][entry_index],
841  &match,
842  NULL,
843  NULL,
844  efwd,
845  flags,
846  status,
847  &entry_basic_switch_rss[dir][entry_index]);
848 
849  if (result != DOCA_SUCCESS) {
850  DOCA_LOG_ERR("Failed to add pipe %d entry: %s", entry_index, doca_error_get_descr(result));
851  return result;
852  }
853  }
854 
855  for (entry_index = 0; entry_index < SWITCH_RSS_CONTROL_MAX; entry_index++) {
856  dst_ip_addr = BE_IPV4_ADDR(8, 8, 8, 8 + entry_index);
857  match.outer.ip4.dst_ip = dst_ip_addr;
858 
859  memset(&fwd, 0, sizeof(fwd));
860  memset(&monitor, 0, sizeof(monitor));
862  if (entry_index == SWITCH_RSS_CONTROL_IMM_RSS) {
863  /* RSS queue - send matched traffic to queue 0 */
864  rss_queues[0] = control_queue_map[dir][entry_index];
869  fwd.rss.nr_queues = 1;
870  } else if (entry_index == SWITCH_RSS_CONTROL_SHARED_RSS) {
873  fwd.shared_rss_id = control_queue_map[dir][entry_index];
874  }
876  entry_index,
878  &match,
879  NULL,
880  NULL,
881  NULL,
882  NULL,
883  NULL,
884  &monitor,
885  efwd,
886  status,
887  &entry_control_switch_rss[dir][entry_index]);
888  if (result != DOCA_SUCCESS) {
889  DOCA_LOG_ERR("Failed to add pipe entry: %s", doca_error_get_descr(result));
890  return result;
891  }
892  }
893 
894  return DOCA_SUCCESS;
895 }
896 
897 /*
898  * Run flow_switch_rss sample
899  *
900  * @nb_queues [in]: number of queues the sample will use
901  * @nb_ports [in]: number of ports the sample will use
902  * @ctx [in]: flow switch context the sample will use
903  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
904  */
906 {
907  struct flow_resources resource = {0};
908  uint32_t nr_shared_resources[SHARED_RESOURCE_NUM_VALUES] = {0};
909  struct doca_flow_port *ports[nb_ports];
910  struct doca_dev *dev_arr[nb_ports];
911  uint32_t actions_mem_size[nb_ports];
912  struct doca_flow_resource_query query_stats;
913  struct entries_status status;
915  int entry_idx;
916  uint32_t shared_rss_ids;
917  struct doca_flow_shared_resource_cfg cfg = {0};
918  struct doca_flow_resource_rss_cfg rss_cfg = {0};
919  struct doca_dev *doca_dev = ctx->doca_dev[0];
920  const char *start_str;
921  bool is_expert = ctx->is_expert;
922  int i;
923  uint16_t queues[1];
924 
925  memset(&status, 0, sizeof(status));
926  nr_shared_resources[DOCA_FLOW_SHARED_RESOURCE_RSS] = 10;
927  resource.nr_counters = 2 * NB_TOTAL_ENTRIES; /* counter per entry */
928  /* Use isolated mode as we will create the RSS pipe later */
929  if (is_expert)
930  start_str = "switch,hws,isolated,hairpinq_num=4,expert";
931  else
932  start_str = "switch,hws,isolated,hairpinq_num=4";
933  result = init_doca_flow(nb_queues, start_str, &resource, nr_shared_resources);
934  if (result != DOCA_SUCCESS) {
935  DOCA_LOG_ERR("Failed to init DOCA Flow: %s", doca_error_get_descr(result));
936  return result;
937  }
938 
939  /* Doca_dev is opened for proxy_port only */
940  memset(dev_arr, 0, sizeof(struct doca_dev *) * nb_ports);
941  dev_arr[0] = doca_dev;
943  result = init_doca_flow_ports(nb_ports, ports, false /* is_hairpin */, dev_arr, actions_mem_size);
944  if (result != DOCA_SUCCESS) {
945  DOCA_LOG_ERR("Failed to init DOCA ports: %s", doca_error_get_descr(result));
947  return result;
948  }
949 
951  rss_cfg.nr_queues = 1;
952  rss_cfg.queues_array = queues;
953  cfg.rss_cfg = rss_cfg;
954  /* config shared rss with dest */
955  for (i = 0; i < MAX_RSS_QUEUE; i++) {
956  queues[0] = i;
957  shared_rss_ids = i;
959  if (result != DOCA_SUCCESS) {
960  DOCA_LOG_ERR("Failed to cfg shared rss %d", i);
963  return result;
964  }
965  /* bind shared rss to port */
967  if (result != DOCA_SUCCESS) {
968  DOCA_LOG_ERR("Failed to bind shared rss %d to port", i);
971  return result;
972  }
973  }
974 
975  /* Create rss pipe and entry */
977  if (result != DOCA_SUCCESS) {
978  DOCA_LOG_ERR("Failed to create rss pipe: %s", doca_error_get_descr(result));
981  return result;
982  }
983 
984  result = add_rss_pipe_entry(pipe_rss, &status);
985  if (result != DOCA_SUCCESS) {
986  DOCA_LOG_ERR("Failed to add entry: %s", doca_error_get_descr(result));
989  return result;
990  }
991 
992  /* Create Newtowrk to host rss pipes */
994  if (result != DOCA_SUCCESS) {
995  DOCA_LOG_ERR("Failed to create rx rss pipe: %s", doca_error_get_descr(result));
998  return result;
999  }
1000 
1002  if (result != DOCA_SUCCESS) {
1003  DOCA_LOG_ERR("Failed to add rx entry: %s", doca_error_get_descr(result));
1006  return result;
1007  }
1008 
1009  /* Create bi-direction rss pipe */
1011  if (result != DOCA_SUCCESS) {
1012  DOCA_LOG_ERR("Failed to create unified rss pipe: %s", doca_error_get_descr(result));
1015  return result;
1016  }
1017 
1019  if (result != DOCA_SUCCESS) {
1020  DOCA_LOG_ERR("Failed to add unified entry: %s", doca_error_get_descr(result));
1023  return result;
1024  }
1025 
1026  /* Create egress pipe and entries */
1028  if (result != DOCA_SUCCESS) {
1029  DOCA_LOG_ERR("Failed to create egress pipe: %s", doca_error_get_descr(result));
1032  return result;
1033  }
1034 
1036  if (result != DOCA_SUCCESS) {
1037  DOCA_LOG_ERR("Failed to add egress_entries to the pipe: %s", doca_error_get_descr(result));
1040  return result;
1041  }
1042 
1043  /* Create vport pipe and entries */
1045  if (result != DOCA_SUCCESS) {
1046  DOCA_LOG_ERR("Failed to create vport pipe: %s", doca_error_get_descr(result));
1049  return result;
1050  }
1051 
1053  if (result != DOCA_SUCCESS) {
1054  DOCA_LOG_ERR("Failed to add vport_entries to the pipe: %s", doca_error_get_descr(result));
1057  return result;
1058  }
1059 
1060  /* Create ingress pipe and entries */
1062  if (result != DOCA_SUCCESS) {
1063  DOCA_LOG_ERR("Failed to create ingress pipe: %s", doca_error_get_descr(result));
1066  return result;
1067  }
1068 
1070  if (result != DOCA_SUCCESS) {
1071  DOCA_LOG_ERR("Failed to add ingress_entries to the pipe: %s", doca_error_get_descr(result));
1074  return result;
1075  }
1076 
1077  result =
1079  if (result != DOCA_SUCCESS) {
1080  DOCA_LOG_ERR("Failed to process egress_entries: %s", doca_error_get_descr(result));
1083  return result;
1084  }
1085 
1086  if (status.nb_processed != NB_TOTAL_ENTRIES || status.failure) {
1087  DOCA_LOG_ERR("Failed to process all entries %d", status.nb_processed);
1090  return DOCA_ERROR_BAD_STATE;
1091  }
1092 
1093  DOCA_LOG_INFO("Wait few seconds for packets to arrive");
1094 
1095  handle_rx_tx_pkts(0, nb_queues);
1096 
1097  /* dump egress entries counters */
1100  if (result != DOCA_SUCCESS) {
1101  DOCA_LOG_ERR("Failed to query entry: %s", doca_error_get_descr(result));
1104  return result;
1105  }
1106  DOCA_LOG_INFO("Egress Entry in index: %d", entry_idx);
1107  DOCA_LOG_INFO("Total bytes: %ld", query_stats.counter.total_bytes);
1108  DOCA_LOG_INFO("Total packets: %ld", query_stats.counter.total_pkts);
1109  }
1110 
1111  for (entry_idx = 0; entry_idx < NB_VPORT_ENTRIES; entry_idx++) {
1113  if (result != DOCA_SUCCESS) {
1114  DOCA_LOG_ERR("Failed to query vport pipe entry: %s", doca_error_get_descr(result));
1117  return result;
1118  }
1119  DOCA_LOG_INFO("Vport Entry in index: %d", entry_idx);
1120  DOCA_LOG_INFO("Total bytes: %ld", query_stats.counter.total_bytes);
1121  DOCA_LOG_INFO("Total packets: %ld", query_stats.counter.total_pkts);
1122  }
1123 
1126  if (result != DOCA_SUCCESS) {
1127  DOCA_LOG_ERR("Failed to query entry: %s", doca_error_get_descr(result));
1130  return result;
1131  }
1132  DOCA_LOG_INFO("Ingress Entry in index: %d", entry_idx);
1133  DOCA_LOG_INFO("Total bytes: %ld", query_stats.counter.total_bytes);
1134  DOCA_LOG_INFO("Total packets: %ld", query_stats.counter.total_pkts);
1135  }
1136 
1139  &query_stats);
1140  if (result != DOCA_SUCCESS) {
1141  DOCA_LOG_ERR("Failed to query entry: %s", doca_error_get_descr(result));
1144  return result;
1145  }
1146  DOCA_LOG_INFO("Rx Basic PIPE Entry in index: %d", entry_idx);
1147  DOCA_LOG_INFO("Total bytes: %ld", query_stats.counter.total_bytes);
1148  DOCA_LOG_INFO("Total packets: %ld", query_stats.counter.total_pkts);
1149  }
1150 
1153  &query_stats);
1154  if (result != DOCA_SUCCESS) {
1155  DOCA_LOG_ERR("Failed to query entry: %s", doca_error_get_descr(result));
1158  return result;
1159  }
1160  DOCA_LOG_INFO("Unified Basic PIPE Entry in index: %d", entry_idx);
1161  DOCA_LOG_INFO("Total bytes: %ld", query_stats.counter.total_bytes);
1162  DOCA_LOG_INFO("Total packets: %ld", query_stats.counter.total_pkts);
1163  }
1164 
1167  &query_stats);
1168  if (result != DOCA_SUCCESS) {
1169  DOCA_LOG_ERR("Failed to query entry: %s", doca_error_get_descr(result));
1172  return result;
1173  }
1174  DOCA_LOG_INFO("Rx Control PIPE Entry in index: %d", entry_idx);
1175  DOCA_LOG_INFO("Total bytes: %ld", query_stats.counter.total_bytes);
1176  DOCA_LOG_INFO("Total packets: %ld", query_stats.counter.total_pkts);
1177  }
1178 
1181  &query_stats);
1182  if (result != DOCA_SUCCESS) {
1183  DOCA_LOG_ERR("Failed to query entry: %s", doca_error_get_descr(result));
1186  return result;
1187  }
1188  DOCA_LOG_INFO("Unified Control PIPE Entry in index: %d", entry_idx);
1189  DOCA_LOG_INFO("Total bytes: %ld", query_stats.counter.total_bytes);
1190  DOCA_LOG_INFO("Total packets: %ld", query_stats.counter.total_pkts);
1191  }
1192 
1194  if (result != DOCA_SUCCESS) {
1195  DOCA_LOG_ERR("Failed to query entry: %s", doca_error_get_descr(result));
1198  return result;
1199  }
1200  DOCA_LOG_INFO("Miss RSS Entry");
1201  DOCA_LOG_INFO("Total bytes: %ld", query_stats.counter.total_bytes);
1202  DOCA_LOG_INFO("Total packets: %ld", query_stats.counter.total_pkts);
1203 
1206  return result;
1207 }
#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
#define unlikely(x)
Definition: utils.h:42
static doca_error_t destroy_pipe_cfg(struct doca_flow_pipe_cfg *cfg)
static uint16_t * rss_queues
Definition: flow_parser.c:114
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
#define DEFAULT_TIMEOUT_US
Definition: flow_skeleton.c:36
static uint8_t entry_idx
static doca_error_t add_switch_vport_pipe_entries(struct doca_flow_pipe *pipe, struct entries_status *status)
static struct doca_flow_pipe_entry * egress_entries[NB_EGRESS_ENTRIES]
static struct doca_flow_pipe * pipe_rss
static struct doca_flow_pipe * pipe_egress
static doca_error_t add_rss_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status)
#define MAX_PKTS
static doca_error_t create_switch_rss_control_pipe(struct doca_flow_port *port, enum switch_rss_pipe_dir_type dir, struct doca_flow_pipe **pipe)
static doca_error_t create_switch_rss_pipe(struct doca_flow_port *port, enum switch_rss_pipe_dir_type dir, enum switch_rss_basic_pipe_type type, struct doca_flow_pipe **pipe)
static struct doca_flow_pipe * pipe_control_switch_rss[SWITCH_RSS_PIPE_DIR_MAX]
static struct doca_flow_pipe * pipe_vport
static doca_error_t create_switch_vport_pipe(struct doca_flow_port *sw_port, struct doca_flow_pipe **pipe)
static doca_error_t create_switch_egress_pipe(struct doca_flow_port *sw_port, struct doca_flow_pipe **pipe)
static doca_error_t create_switch_ingress_pipe(struct doca_flow_port *sw_port, struct doca_flow_pipe **pipe)
static int add_switch_rss_pipe_entries(enum switch_rss_pipe_dir_type dir, struct entries_status *status)
#define NB_TOTAL_ENTRIES
static struct doca_flow_pipe * pipe_basic_switch_rss[SWITCH_RSS_PIPE_DIR_MAX][SWITCH_RSS_BASIC_PIPE_MAX]
static struct doca_flow_pipe_entry * entry_basic_switch_rss[SWITCH_RSS_PIPE_DIR_MAX][SWITCH_RSS_BASIC_PIPE_MAX]
static uint16_t control_queue_map[SWITCH_RSS_PIPE_DIR_MAX][SWITCH_RSS_CONTROL_MAX]
#define NB_VPORT_ENTRIES
#define NB_EGRESS_ENTRIES
ingress_vport_entry_type
@ INGRESS_TO_PORT_MAX
@ INGRESS_TO_PORT0
@ INGRESS_TO_PORT1
@ INGRESS_TO_PORT2
static struct doca_flow_pipe_entry * vport_entries[NB_VPORT_ENTRIES]
static doca_error_t add_switch_ingress_pipe_entries(struct doca_flow_pipe *pipe, struct entries_status *status)
#define NB_INGRESS_ENTRIES
#define WAIT_SECS
static doca_error_t create_rss_pipe(struct doca_flow_port *port, struct doca_flow_pipe **pipe)
ingress_root_entry_type
@ INGRESS_ROOT_TO_EGRESS
@ INGRESS_ROOT_TO_MAX
@ INGRESS_ROOT_TO_CONTROL
@ INGRESS_ROOT_TO_BASIC
@ INGRESS_ROOT_TO_VPORT
static struct doca_flow_pipe_entry * entry_control_switch_rss[SWITCH_RSS_PIPE_DIR_MAX][SWITCH_RSS_CONTROL_MAX]
#define MAX_RSS_QUEUE
static int create_switch_rss_pipes(struct doca_flow_port *port, enum switch_rss_pipe_dir_type dir)
static doca_error_t add_switch_egress_pipe_entries(struct doca_flow_pipe *pipe, struct entries_status *status)
static struct doca_flow_pipe * pipe_ingress
switch_rss_control_entry_type
@ SWITCH_RSS_CONTROL_SHARED_RSS
@ SWITCH_RSS_CONTROL_IMM_RSS
@ SWITCH_RSS_CONTROL_MAX
DOCA_LOG_REGISTER(FLOW_SWITCH_SWITCH_RSS)
static void handle_rx_tx_pkts(uint32_t port_id, uint16_t nb_queues)
static uint16_t basic_queue_map[SWITCH_RSS_PIPE_DIR_MAX][SWITCH_RSS_BASIC_PIPE_MAX]
switch_rss_pipe_dir_type
@ SWITCH_RSS_PIPE_DIR_N2H
@ SWITCH_RSS_PIPE_DIR_MAX
@ SWITCH_RSS_PIPE_DIR_BI
static struct doca_flow_pipe_entry * rss_entry
static struct doca_flow_pipe_entry * ingress_entries[NB_INGRESS_ENTRIES]
doca_error_t flow_switch_rss(int nb_queues, int nb_ports, struct flow_switch_ctx *ctx)
switch_rss_basic_pipe_type
@ SWITCH_RSS_BASIC_PIPE_CONST_RSS
@ SWITCH_RSS_BASIC_PIPE_MAX
@ SWITCH_RSS_BASIC_PIPE_SHARED_RSS
@ SWITCH_RSS_BASIC_PIPE_DYN_RSS
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
@ 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_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_STABLE doca_error_t doca_flow_shared_resources_bind(enum doca_flow_shared_resource_type type, uint32_t *res_array, uint32_t res_array_len, void *bindable_obj)
Binds a bulk of shared resources to a bindable object.
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_flow_flags_type
doca flow flags type
Definition: doca_flow.h:114
DOCA_EXPERIMENTAL doca_error_t doca_flow_shared_resource_set_cfg(enum doca_flow_shared_resource_type type, uint32_t id, struct doca_flow_shared_resource_cfg *cfg)
Configure a single shared resource.
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_EXPERIMENTAL doca_error_t doca_flow_pipe_cfg_set_dir_info(struct doca_flow_pipe_cfg *cfg, enum doca_flow_direction_info dir_info)
Set pipe's Direction info.
DOCA_STABLE struct doca_flow_port * doca_flow_port_switch_get(const struct doca_flow_port *port)
Get doca flow switch port.
DOCA_STABLE doca_error_t doca_flow_pipe_cfg_set_domain(struct doca_flow_pipe_cfg *cfg, enum doca_flow_pipe_domain domain)
Set pipe's domain.
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_RSS_TCP
Definition: doca_flow.h:770
@ DOCA_FLOW_RSS_IPV4
Definition: doca_flow.h:764
@ DOCA_FLOW_SHARED_RESOURCE_RSS
Definition: doca_flow.h:97
@ DOCA_FLOW_DIRECTION_NETWORK_TO_HOST
Definition: doca_flow.h:1094
@ 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_WAIT_FOR_BATCH
Definition: doca_flow.h:117
@ DOCA_FLOW_RESOURCE_TYPE_SHARED
Definition: doca_flow.h:614
@ 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_RSS
Definition: doca_flow.h:742
@ DOCA_FLOW_PIPE_DOMAIN_EGRESS
Definition: doca_flow.h:245
@ DOCA_FLOW_PIPE_DOMAIN_DEFAULT
Definition: doca_flow.h:241
#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
const struct ip_frag_config * cfg
Definition: ip_frag_dp.c:0
uint16_t queue_id
Definition: ip_frag_dp.c:1
uint8_t type
Definition: packets.h:0
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
doca flow actions information
Definition: doca_flow.h:684
uint8_t action_idx
Definition: doca_flow.h:685
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
uint32_t shared_rss_id
Definition: doca_flow.h:789
enum doca_flow_resource_type rss_type
Definition: doca_flow.h:784
struct doca_flow_resource_rss_cfg rss
Definition: doca_flow.h:787
struct doca_flow_header_ip4 ip4
Definition: doca_flow.h:449
enum doca_flow_l3_type l3_type
Definition: doca_flow.h:446
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
flow resource query
Definition: doca_flow.h:1101
struct doca_flow_resource_query::@115::@117 counter
doca flow rss resource configuration
Definition: doca_flow.h:180
doca flow shared resource configuration
Definition: doca_flow.h:953
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