NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
flow.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023-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 <arpa/inet.h>
27 #include <rte_ethdev.h>
28 #include <doca_flow.h>
29 
30 #include "common.h"
32 
33 DOCA_LOG_REGISTER(GPU_PACKET_PROCESSING_FLOW);
34 
35 static uint64_t default_flow_timeout_usec;
36 
37 struct doca_flow_port *init_doca_flow(uint16_t port_id, uint8_t rxq_num)
38 {
40  struct doca_flow_port_cfg *port_cfg;
41  struct doca_flow_port *df_port;
42  struct doca_flow_cfg *rxq_flow_cfg;
43  int ret = 0;
44  struct rte_eth_dev_info dev_info = {0};
45  struct rte_eth_conf eth_conf = {
46  .rxmode =
47  {
48  .mtu = 2048, /* Not really used, just to initialize DPDK */
49  },
50  .txmode =
51  {
52  .offloads = RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
53  RTE_ETH_TX_OFFLOAD_TCP_CKSUM,
54  },
55  };
56  struct rte_mempool *mp = NULL;
57  struct rte_eth_txconf tx_conf;
58  struct rte_flow_error error;
59 
60  /*
61  * DPDK should be initialized and started before DOCA Flow.
62  * DPDK doesn't start the device without, at least, one DPDK Rx queue.
63  * DOCA Flow needs to specify in advance how many Rx queues will be used by the app.
64  *
65  * Following lines of code can be considered the minimum WAR for this issue.
66  */
67 
68  ret = rte_eth_dev_info_get(port_id, &dev_info);
69  if (ret) {
70  DOCA_LOG_ERR("Failed rte_eth_dev_info_get with: %s", rte_strerror(-ret));
71  return NULL;
72  }
73 
74  ret = rte_eth_dev_configure(port_id, rxq_num, rxq_num, &eth_conf);
75  if (ret) {
76  DOCA_LOG_ERR("Failed rte_eth_dev_configure with: %s", rte_strerror(-ret));
77  return NULL;
78  }
79 
80  mp = rte_pktmbuf_pool_create("TEST", 8192, 0, 0, MAX_PKT_SIZE, rte_eth_dev_socket_id(port_id));
81  if (mp == NULL) {
82  DOCA_LOG_ERR("Failed rte_pktmbuf_pool_create with: %s", rte_strerror(-ret));
83  return NULL;
84  }
85 
86  tx_conf = dev_info.default_txconf;
87  tx_conf.offloads |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | RTE_ETH_TX_OFFLOAD_UDP_CKSUM | RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
88 
89  for (int idx = 0; idx < rxq_num; idx++) {
90  ret = rte_eth_rx_queue_setup(port_id, idx, 2048, rte_eth_dev_socket_id(port_id), NULL, mp);
91  if (ret) {
92  DOCA_LOG_ERR("Failed rte_eth_rx_queue_setup with: %s", rte_strerror(-ret));
93  return NULL;
94  }
95 
96  ret = rte_eth_tx_queue_setup(port_id, idx, 2048, rte_eth_dev_socket_id(port_id), &tx_conf);
97  if (ret) {
98  DOCA_LOG_ERR("Failed rte_eth_tx_queue_setup with: %s", rte_strerror(-ret));
99  return NULL;
100  }
101  }
102 
103  ret = rte_flow_isolate(port_id, 1, &error);
104  if (ret) {
105  DOCA_LOG_ERR("Failed rte_flow_isolate with: %s", error.message);
106  return NULL;
107  }
108 
109  ret = rte_eth_dev_start(port_id);
110  if (ret) {
111  DOCA_LOG_ERR("Failed rte_eth_dev_start with: %s", rte_strerror(-ret));
112  return NULL;
113  }
114 
115  /* Initialize doca flow framework */
116  ret = doca_flow_cfg_create(&rxq_flow_cfg);
117  if (ret != DOCA_SUCCESS) {
118  DOCA_LOG_ERR("Failed to create doca_flow_cfg: %s", doca_error_get_descr(ret));
119  return NULL;
120  }
121  ret = doca_flow_cfg_set_pipe_queues(rxq_flow_cfg, rxq_num);
122  if (ret != DOCA_SUCCESS) {
123  DOCA_LOG_ERR("Failed to set doca_flow_cfg pipe_queues: %s", doca_error_get_descr(ret));
124  doca_flow_cfg_destroy(rxq_flow_cfg);
125  return NULL;
126  }
127  /*
128  * HWS: Hardware steering
129  * Isolated: don't create RSS rule for DPDK created RX queues
130  */
131  ret = doca_flow_cfg_set_mode_args(rxq_flow_cfg, "vnf,hws,isolated");
132  if (ret != DOCA_SUCCESS) {
133  DOCA_LOG_ERR("Failed to set doca_flow_cfg mode_args: %s", doca_error_get_descr(ret));
134  doca_flow_cfg_destroy(rxq_flow_cfg);
135  return NULL;
136  }
137  ret = doca_flow_cfg_set_nr_counters(rxq_flow_cfg, FLOW_NB_COUNTERS);
138  if (ret != DOCA_SUCCESS) {
139  DOCA_LOG_ERR("Failed to set doca_flow_cfg nr_counters: %s", doca_error_get_descr(ret));
140  doca_flow_cfg_destroy(rxq_flow_cfg);
141  return NULL;
142  }
143  ret = doca_flow_init(rxq_flow_cfg);
144  if (ret != DOCA_SUCCESS) {
145  DOCA_LOG_ERR("Failed to init doca flow with: %s", doca_error_get_descr(ret));
146  doca_flow_cfg_destroy(rxq_flow_cfg);
147  return NULL;
148  }
149  doca_flow_cfg_destroy(rxq_flow_cfg);
150 
151  /* Start doca flow port */
152  result = doca_flow_port_cfg_create(&port_cfg);
153  if (result != DOCA_SUCCESS) {
154  DOCA_LOG_ERR("Failed to create doca_flow_port_cfg: %s", doca_error_get_descr(result));
155  return NULL;
156  }
157  result = doca_flow_port_cfg_set_port_id(port_cfg, port_id);
158  if (result != DOCA_SUCCESS) {
159  DOCA_LOG_ERR("Failed to set doca_flow_port_cfg port_id: %s", doca_error_get_descr(result));
160  doca_flow_port_cfg_destroy(port_cfg);
161  return NULL;
162  }
163  result = doca_flow_port_start(port_cfg, &df_port);
164  if (result != DOCA_SUCCESS) {
165  DOCA_LOG_ERR("Failed to start doca flow port with: %s", doca_error_get_descr(result));
166  doca_flow_port_cfg_destroy(port_cfg);
167  return NULL;
168  }
169  doca_flow_port_cfg_destroy(port_cfg);
170 
172 
173  return df_port;
174 }
175 
176 doca_error_t create_udp_pipe(struct rxq_udp_queues *udp_queues, struct doca_flow_port *port)
177 {
179  struct doca_flow_match match = {0};
180  struct doca_flow_fwd fwd = {0};
181  struct doca_flow_fwd miss_fwd = {0};
182  struct doca_flow_pipe_cfg *pipe_cfg;
183  struct doca_flow_pipe_entry *entry;
184  uint16_t flow_queue_id;
185  uint16_t rss_queues[MAX_QUEUES];
186  struct doca_flow_monitor monitor = {
188  };
189  const char *pipe_name = "GPU_RXQ_UDP_PIPE";
190 
191  if (udp_queues == NULL || port == NULL || udp_queues->numq > MAX_QUEUES)
193 
196 
197  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
198  if (result != DOCA_SUCCESS) {
199  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
200  return result;
201  }
202 
203  result = doca_flow_pipe_cfg_set_name(pipe_cfg, pipe_name);
204  if (result != DOCA_SUCCESS) {
205  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg name: %s", doca_error_get_descr(result));
206  goto destroy_pipe_cfg;
207  }
209  if (result != DOCA_SUCCESS) {
210  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg type: %s", doca_error_get_descr(result));
211  goto destroy_pipe_cfg;
212  }
213  result = doca_flow_pipe_cfg_set_is_root(pipe_cfg, false);
214  if (result != DOCA_SUCCESS) {
215  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg is_root: %s", doca_error_get_descr(result));
216  goto destroy_pipe_cfg;
217  }
218  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
219  if (result != DOCA_SUCCESS) {
220  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
221  goto destroy_pipe_cfg;
222  }
224  if (result != DOCA_SUCCESS) {
225  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
226  goto destroy_pipe_cfg;
227  }
228 
229  for (int idx = 0; idx < udp_queues->numq; idx++) {
231  rss_queues[idx] = flow_queue_id;
232  }
233 
239 
240  miss_fwd.type = DOCA_FLOW_FWD_DROP;
241 
242  result = doca_flow_pipe_create(pipe_cfg, &fwd, &miss_fwd, &(udp_queues->rxq_pipe));
243  if (result != DOCA_SUCCESS) {
244  DOCA_LOG_ERR("RxQ pipe creation failed with: %s", doca_error_get_descr(result));
245  goto destroy_pipe_cfg;
246  }
247 
248  doca_flow_pipe_cfg_destroy(pipe_cfg);
249 
250  /* Add HW offload */
253  &match,
254  NULL,
255  NULL,
256  NULL,
258  NULL,
259  &entry);
260  if (result != DOCA_SUCCESS) {
261  DOCA_LOG_ERR("RxQ pipe entry creation failed with: %s", doca_error_get_descr(result));
262  return result;
263  }
264 
266  if (result != DOCA_SUCCESS) {
267  DOCA_LOG_ERR("RxQ pipe entry process failed with: %s", doca_error_get_descr(result));
268  return result;
269  }
270 
271  DOCA_LOG_DBG("Created Pipe %s", pipe_name);
272 
273  return DOCA_SUCCESS;
274 
276  doca_flow_pipe_cfg_destroy(pipe_cfg);
277  return result;
278 }
279 
280 doca_error_t create_tcp_cpu_pipe(struct rxq_tcp_queues *tcp_queues, struct doca_flow_port *port)
281 {
283  uint16_t rss_queues[MAX_QUEUES];
284  struct doca_flow_match match = {0};
285 
286  /*
287  * Setup the TCP pipe 'rxq_pipe_cpu' which forwards unrecognized flows and
288  * TCP SYN/ACK/FIN flags to the CPU - in other words, any TCP packets not
289  * recognized by the GPU TCP pipe.
290  */
291 
292  if (tcp_queues == NULL || port == NULL)
294 
295  /* Init TCP session table */
296  tcp_session_table = rte_hash_create(&tcp_session_ht_params);
297 
300 
301  for (int idx = 0; idx < tcp_queues->numq_cpu_rss; idx++)
302  rss_queues[idx] = idx;
303 
304  struct doca_flow_fwd fwd = {
307  .rss =
308  {
309  .outer_flags = DOCA_FLOW_RSS_IPV4 | DOCA_FLOW_RSS_TCP,
310  .queues_array = rss_queues,
311  .nr_queues = tcp_queues->numq_cpu_rss,
312  },
313  };
314 
315  struct doca_flow_fwd miss_fwd = {
317  };
318 
319  struct doca_flow_monitor monitor = {
321  };
322 
323  struct doca_flow_pipe_cfg *pipe_cfg;
324  const char *pipe_name = "CPU_RXQ_TCP_PIPE";
325 
326  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
327  if (result != DOCA_SUCCESS) {
328  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
329  return result;
330  }
331 
332  result = doca_flow_pipe_cfg_set_name(pipe_cfg, pipe_name);
333  if (result != DOCA_SUCCESS) {
334  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg name: %s", doca_error_get_descr(result));
335  goto destroy_pipe_cfg;
336  }
338  if (result != DOCA_SUCCESS) {
339  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg type: %s", doca_error_get_descr(result));
340  goto destroy_pipe_cfg;
341  }
342  result = doca_flow_pipe_cfg_set_is_root(pipe_cfg, false);
343  if (result != DOCA_SUCCESS) {
344  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg is_root: %s", doca_error_get_descr(result));
345  goto destroy_pipe_cfg;
346  }
347  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
348  if (result != DOCA_SUCCESS) {
349  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
350  goto destroy_pipe_cfg;
351  }
353  if (result != DOCA_SUCCESS) {
354  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
355  goto destroy_pipe_cfg;
356  }
357 
358  result = doca_flow_pipe_create(pipe_cfg, &fwd, &miss_fwd, &tcp_queues->rxq_pipe_cpu);
359  if (result != DOCA_SUCCESS) {
360  DOCA_LOG_ERR("RxQ pipe creation failed with: %s", doca_error_get_descr(result));
361  goto destroy_pipe_cfg;
362  }
363 
364  doca_flow_pipe_cfg_destroy(pipe_cfg);
365 
368  NULL,
369  NULL,
370  NULL,
371  NULL,
373  NULL,
375  if (result != DOCA_SUCCESS) {
376  DOCA_LOG_ERR("RxQ pipe entry creation failed with: %s", doca_error_get_descr(result));
377  return result;
378  }
379 
381  if (result != DOCA_SUCCESS) {
382  DOCA_LOG_ERR("RxQ pipe entry process failed with: %s", doca_error_get_descr(result));
383  return result;
384  }
385 
386  DOCA_LOG_DBG("Created Pipe %s", pipe_name);
387 
388  return DOCA_SUCCESS;
389 
391  doca_flow_pipe_cfg_destroy(pipe_cfg);
392  return result;
393 }
394 
396  struct doca_flow_port *port,
397  bool connection_based_flows)
398 {
399  uint16_t flow_queue_id;
400  uint16_t rss_queues[MAX_QUEUES];
402  struct doca_flow_pipe_entry *dummy_entry = NULL;
403 
404  /* The GPU TCP pipe should only forward known flows to the GPU. Others will be dropped */
405 
406  if (tcp_queues == NULL || port == NULL || tcp_queues->numq > MAX_QUEUES)
408 
409  struct doca_flow_match match = {
410  .outer =
411  {
413  .ip4.next_proto = IPPROTO_TCP,
414  },
415  };
416 
417  if (connection_based_flows) {
418  match.outer.ip4.src_ip = 0xffffffff;
419  match.outer.ip4.dst_ip = 0xffffffff;
420  match.outer.tcp.l4_port.src_port = 0xffff;
421  match.outer.tcp.l4_port.dst_port = 0xffff;
423  };
424 
425  for (int idx = 0; idx < tcp_queues->numq; idx++) {
427  rss_queues[idx] = flow_queue_id;
428  }
429 
430  struct doca_flow_fwd fwd = {
433  .rss =
434  {
435  .outer_flags = DOCA_FLOW_RSS_IPV4 | DOCA_FLOW_RSS_TCP,
436  .queues_array = rss_queues,
437  .nr_queues = tcp_queues->numq,
438  },
439  };
440 
441  struct doca_flow_fwd miss_fwd = {
443  };
444 
445  struct doca_flow_monitor monitor = {
447  };
448 
449  struct doca_flow_pipe_cfg *pipe_cfg;
450  const char *pipe_name = "GPU_RXQ_TCP_PIPE";
451 
452  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
453  if (result != DOCA_SUCCESS) {
454  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
455  return result;
456  }
457 
458  result = doca_flow_pipe_cfg_set_name(pipe_cfg, pipe_name);
459  if (result != DOCA_SUCCESS) {
460  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg name: %s", doca_error_get_descr(result));
461  goto destroy_pipe_cfg;
462  }
464  if (result != DOCA_SUCCESS) {
465  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg type: %s", doca_error_get_descr(result));
466  goto destroy_pipe_cfg;
467  }
468  result = doca_flow_pipe_cfg_set_is_root(pipe_cfg, false);
469  if (result != DOCA_SUCCESS) {
470  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg is_root: %s", doca_error_get_descr(result));
471  goto destroy_pipe_cfg;
472  }
473  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
474  if (result != DOCA_SUCCESS) {
475  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
476  goto destroy_pipe_cfg;
477  }
479  if (result != DOCA_SUCCESS) {
480  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
481  goto destroy_pipe_cfg;
482  }
483 
484  result = doca_flow_pipe_create(pipe_cfg, &fwd, &miss_fwd, &tcp_queues->rxq_pipe_gpu);
485  if (result != DOCA_SUCCESS) {
486  DOCA_LOG_ERR("RxQ pipe creation failed with: %s", doca_error_get_descr(result));
487  goto destroy_pipe_cfg;
488  }
489 
490  doca_flow_pipe_cfg_destroy(pipe_cfg);
491 
492  if (!connection_based_flows) {
493  // For the non-connection-based configuration, create a dummy flow entry which will enable
494  // any TCP packets to be forwarded.
497  NULL,
498  NULL,
499  NULL,
500  NULL,
501  0,
502  NULL,
503  &dummy_entry);
504  if (result != DOCA_SUCCESS) {
505  DOCA_LOG_ERR("RxQ pipe-entry creation failed with: %s", doca_error_get_descr(result));
506  DOCA_GPUNETIO_VOLATILE(force_quit) = true;
507  return result;
508  }
509 
511  if (result != DOCA_SUCCESS) {
512  DOCA_LOG_ERR("RxQ pipe entry process failed with: %s", doca_error_get_descr(result));
513  return result;
514  }
515  }
516 
517  DOCA_LOG_DBG("Created Pipe %s", pipe_name);
518 
519  return DOCA_SUCCESS;
520 
522  doca_flow_pipe_cfg_destroy(pipe_cfg);
523  return result;
524 }
525 
526 doca_error_t create_icmp_gpu_pipe(struct rxq_icmp_queues *icmp_queues, struct doca_flow_port *port)
527 {
529  struct doca_flow_match match = {0};
530  struct doca_flow_fwd fwd = {0};
531  struct doca_flow_fwd miss_fwd = {0};
532  struct doca_flow_pipe_cfg *pipe_cfg;
533  struct doca_flow_pipe_entry *entry;
534  uint16_t flow_queue_id;
535  uint16_t rss_queues[MAX_QUEUES];
536  struct doca_flow_monitor monitor = {
538  };
539  const char *pipe_name = "GPU_RXQ_ICMP_PIPE";
540 
541  if (icmp_queues == NULL || port == NULL || icmp_queues->numq > MAX_QUEUES)
543 
546 
547  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
548  if (result != DOCA_SUCCESS) {
549  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
550  return result;
551  }
552 
553  result = doca_flow_pipe_cfg_set_name(pipe_cfg, pipe_name);
554  if (result != DOCA_SUCCESS) {
555  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg name: %s", doca_error_get_descr(result));
556  goto destroy_pipe_cfg;
557  }
559  if (result != DOCA_SUCCESS) {
560  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg type: %s", doca_error_get_descr(result));
561  goto destroy_pipe_cfg;
562  }
563  result = doca_flow_pipe_cfg_set_is_root(pipe_cfg, false);
564  if (result != DOCA_SUCCESS) {
565  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg is_root: %s", doca_error_get_descr(result));
566  goto destroy_pipe_cfg;
567  }
568 
569  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
570  if (result != DOCA_SUCCESS) {
571  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
572  goto destroy_pipe_cfg;
573  }
574 
576  if (result != DOCA_SUCCESS) {
577  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
578  goto destroy_pipe_cfg;
579  }
580 
581  for (int idx = 0; idx < icmp_queues->numq; idx++) {
583  rss_queues[idx] = flow_queue_id;
584  }
585 
591 
592  miss_fwd.type = DOCA_FLOW_FWD_DROP;
593 
594  result = doca_flow_pipe_create(pipe_cfg, &fwd, &miss_fwd, &(icmp_queues->rxq_pipe));
595  if (result != DOCA_SUCCESS) {
596  DOCA_LOG_ERR("RxQ pipe creation failed with: %s", doca_error_get_descr(result));
597  goto destroy_pipe_cfg;
598  }
599 
600  doca_flow_pipe_cfg_destroy(pipe_cfg);
601 
602  /* Add HW offload */
605  &match,
606  NULL,
607  NULL,
608  NULL,
610  NULL,
611  &entry);
612  if (result != DOCA_SUCCESS) {
613  DOCA_LOG_ERR("RxQ pipe entry creation failed with: %s", doca_error_get_descr(result));
614  return result;
615  }
616 
618  if (result != DOCA_SUCCESS) {
619  DOCA_LOG_ERR("RxQ pipe entry process failed with: %s", doca_error_get_descr(result));
620  return result;
621  }
622 
623  DOCA_LOG_DBG("Created Pipe %s", pipe_name);
624 
625  return DOCA_SUCCESS;
626 
628  doca_flow_pipe_cfg_destroy(pipe_cfg);
629  return result;
630 }
631 
633  struct rxq_tcp_queues *tcp_queues,
635  struct doca_flow_port *port)
636 {
637  uint32_t priority_high = 1;
638  uint32_t priority_low = 3;
640  struct doca_flow_monitor monitor = {
642  };
643 
644  if (udp_queues == NULL || tcp_queues == NULL || port == NULL)
646 
647  struct doca_flow_pipe_cfg *pipe_cfg;
648  const char *pipe_name = "ROOT_PIPE";
649 
650  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
651  if (result != DOCA_SUCCESS) {
652  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
653  return result;
654  }
655 
656  result = doca_flow_pipe_cfg_set_name(pipe_cfg, pipe_name);
657  if (result != DOCA_SUCCESS) {
658  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg name: %s", doca_error_get_descr(result));
659  doca_flow_pipe_cfg_destroy(pipe_cfg);
660  return result;
661  }
663  if (result != DOCA_SUCCESS) {
664  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg type: %s", doca_error_get_descr(result));
665  doca_flow_pipe_cfg_destroy(pipe_cfg);
666  return result;
667  }
668  result = doca_flow_pipe_cfg_set_is_root(pipe_cfg, true);
669  if (result != DOCA_SUCCESS) {
670  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg is_root: %s", doca_error_get_descr(result));
671  doca_flow_pipe_cfg_destroy(pipe_cfg);
672  return result;
673  }
675  if (result != DOCA_SUCCESS) {
676  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
677  doca_flow_pipe_cfg_destroy(pipe_cfg);
678  return result;
679  }
680 
682  if (result != DOCA_SUCCESS) {
683  DOCA_LOG_ERR("Root pipe creation failed with: %s", doca_error_get_descr(result));
684  doca_flow_pipe_cfg_destroy(pipe_cfg);
685  return result;
686  }
687  doca_flow_pipe_cfg_destroy(pipe_cfg);
688 
689  struct doca_flow_match udp_match = {
691  .outer.l3_type = DOCA_FLOW_L3_TYPE_IP4,
692  .outer.ip4.next_proto = IPPROTO_UDP,
693  };
694 
695  struct doca_flow_fwd udp_fwd = {
697  .next_pipe = udp_queues->rxq_pipe,
698  };
699 
701  0,
703  &udp_match,
704  NULL,
705  NULL,
706  NULL,
707  NULL,
708  NULL,
709  NULL,
710  &udp_fwd,
711  NULL,
713  if (result != DOCA_SUCCESS) {
714  DOCA_LOG_ERR("Root pipe UDP entry creation failed with: %s", doca_error_get_descr(result));
715  return result;
716  }
717 
718  if (icmp_queues->rxq_pipe) {
719  struct doca_flow_match icmp_match_gpu = {
721  .outer.l3_type = DOCA_FLOW_L3_TYPE_IP4,
722  .outer.ip4.next_proto = IPPROTO_ICMP,
723  };
724 
725  struct doca_flow_fwd icmp_fwd_gpu = {
727  .next_pipe = icmp_queues->rxq_pipe,
728  };
729 
731  priority_low,
733  &icmp_match_gpu,
734  NULL,
735  NULL,
736  NULL,
737  NULL,
738  NULL,
739  NULL,
740  &icmp_fwd_gpu,
741  NULL,
743  if (result != DOCA_SUCCESS) {
744  DOCA_LOG_ERR("Root pipe ICMP entry creation failed with: %s", doca_error_get_descr(result));
745  return result;
746  }
747  }
748 
749  if (tcp_queues->rxq_pipe_gpu) {
750  struct doca_flow_match tcp_match_gpu = {
752  .outer.l3_type = DOCA_FLOW_L3_TYPE_IP4,
753  .outer.ip4.next_proto = IPPROTO_TCP,
754  };
755 
756  struct doca_flow_fwd tcp_fwd_gpu = {
758  .next_pipe = tcp_queues->rxq_pipe_gpu,
759  };
760 
762  priority_low,
764  &tcp_match_gpu,
765  NULL,
766  NULL,
767  NULL,
768  NULL,
769  NULL,
770  NULL,
771  &tcp_fwd_gpu,
772  NULL,
774  if (result != DOCA_SUCCESS) {
775  DOCA_LOG_ERR("Root pipe TCP GPU entry creation failed with: %s", doca_error_get_descr(result));
776  return result;
777  }
778  }
779 
780  if (tcp_queues->rxq_pipe_cpu) {
781  struct doca_flow_match tcp_match_cpu = {
783  .outer.l3_type = DOCA_FLOW_L3_TYPE_IP4,
784  .outer.ip4.next_proto = IPPROTO_TCP,
785  .outer.l4_type_ext = DOCA_FLOW_L4_TYPE_EXT_TCP,
786  };
787 
788  struct doca_flow_fwd tcp_fwd_cpu = {
790  .next_pipe = tcp_queues->rxq_pipe_cpu,
791  };
792 
793  uint8_t individual_tcp_flags[] = {
797  };
798 
799  /* Note: not strictly necessary */
800  struct doca_flow_match tcp_match_cpu_mask = {
801  .outer.eth.type = 0xFFFF,
802  .outer.ip4.next_proto = 0xFF,
803  };
804 
805  for (int i = 0; i < 3; i++) {
806  tcp_match_cpu.outer.tcp.flags = individual_tcp_flags[i];
807  tcp_match_cpu_mask.outer.tcp.flags = individual_tcp_flags[i];
809  priority_high,
811  &tcp_match_cpu,
812  &tcp_match_cpu_mask,
813  NULL,
814  NULL,
815  NULL,
816  NULL,
817  NULL,
818  &tcp_fwd_cpu,
819  NULL,
821  if (result != DOCA_SUCCESS) {
822  DOCA_LOG_ERR("Root pipe TCP CPU %d entry creation failed with: %s",
823  i,
825  return result;
826  }
827  }
828  }
829 
831  if (result != DOCA_SUCCESS) {
832  DOCA_LOG_ERR("Root pipe entry process failed with: %s", doca_error_get_descr(result));
833  return result;
834  }
835 
836  DOCA_LOG_DBG("Created Pipe %s", pipe_name);
837 
838  return DOCA_SUCCESS;
839 }
840 
841 doca_error_t enable_tcp_gpu_offload(struct doca_flow_port *port,
842  uint16_t queue_id,
843  struct doca_flow_pipe *gpu_rss_pipe,
844  struct tcp_session_entry *session_entry)
845 {
847  char src_addr[INET_ADDRSTRLEN];
848  char dst_addr[INET_ADDRSTRLEN];
849 
850  struct doca_flow_match match = {
851  .outer =
852  {
854  .l4_type_ext = DOCA_FLOW_L4_TYPE_EXT_TCP,
855  .tcp.flags = 0,
856  .ip4.src_ip = session_entry->key.src_addr,
857  .ip4.dst_ip = session_entry->key.dst_addr,
858  .tcp.l4_port.src_port = session_entry->key.src_port,
859  .tcp.l4_port.dst_port = session_entry->key.dst_port,
860  },
861  };
862 
864  gpu_rss_pipe,
865  &match,
866  NULL,
867  NULL,
868  NULL,
870  NULL,
871  &session_entry->flow);
872  if (result != DOCA_SUCCESS) {
873  inet_ntop(AF_INET, &session_entry->key.src_addr, src_addr, INET_ADDRSTRLEN);
874  inet_ntop(AF_INET, &session_entry->key.dst_addr, dst_addr, INET_ADDRSTRLEN);
875  DOCA_LOG_ERR("Failed to create TCP offload session; error = %s, session = %s:%d>%s:%d",
877  src_addr,
878  htons(session_entry->key.src_port),
879  dst_addr,
880  htons(session_entry->key.dst_port));
881  return result;
882  }
883 
884  inet_ntop(AF_INET, &session_entry->key.src_addr, src_addr, INET_ADDRSTRLEN);
885  inet_ntop(AF_INET, &session_entry->key.dst_addr, dst_addr, INET_ADDRSTRLEN);
886  DOCA_LOG_INFO("Created TCP offload session %s:%d>%s:%d",
887  src_addr,
888  htons(session_entry->key.src_port),
889  dst_addr,
890  htons(session_entry->key.dst_port));
891 
893  if (result != DOCA_SUCCESS) {
894  DOCA_LOG_ERR("RxQ pipe entry process failed with: %s", doca_error_get_descr(result));
895  return result;
896  }
897 
898  return DOCA_SUCCESS;
899 }
900 
901 doca_error_t disable_tcp_gpu_offload(struct doca_flow_port *port,
902  uint16_t queue_id,
903  struct tcp_session_entry *session_entry)
904 {
906  char src_addr[INET_ADDRSTRLEN];
907  char dst_addr[INET_ADDRSTRLEN];
908 
909  /*
910  * Because those flows tend to be extremely short-lived,
911  * process the queue once more to ensure the newly created
912  * flows have been able to reach a deletable state.
913  */
915  if (result != DOCA_SUCCESS) {
916  DOCA_LOG_ERR("RxQ pipe entry process failed with: %s", doca_error_get_descr(result));
917  return result;
918  }
919 
921 
922  if (result != DOCA_SUCCESS) {
923  inet_ntop(AF_INET, &session_entry->key.src_addr, src_addr, INET_ADDRSTRLEN);
924  inet_ntop(AF_INET, &session_entry->key.dst_addr, dst_addr, INET_ADDRSTRLEN);
925  DOCA_LOG_ERR("Failed to destroy TCP offload session; error = %s, session = %s:%d>%s:%d",
927  src_addr,
928  htons(session_entry->key.src_port),
929  dst_addr,
930  htons(session_entry->key.dst_port));
931  } else {
932  inet_ntop(AF_INET, &session_entry->key.src_addr, src_addr, INET_ADDRSTRLEN);
933  inet_ntop(AF_INET, &session_entry->key.dst_addr, dst_addr, INET_ADDRSTRLEN);
934  DOCA_LOG_INFO("Destroyed TCP offload session %s:%d>%s:%d",
935  src_addr,
936  htons(session_entry->key.src_port),
937  dst_addr,
938  htons(session_entry->key.dst_port));
939  }
940 
941  return result;
942 }
943 
944 doca_error_t destroy_flow_queue(struct doca_flow_port *port_df,
946  struct rxq_udp_queues *udp_queues,
947  struct rxq_tcp_queues *tcp_queues,
948  bool http_server,
950 {
951  doca_flow_port_stop(port_df);
953 
957 
958  return DOCA_SUCCESS;
959 }
#define NULL
Definition: __stddef_null.h:26
int32_t result
doca_error_t destroy_tcp_queues(struct rxq_tcp_queues *tcp_queues, bool http_server, struct txq_http_queues *http_queues)
Definition: tcp_queues.c:485
doca_error_t destroy_icmp_queues(struct rxq_icmp_queues *icmp_queues)
Definition: icmp_queues.c:291
doca_error_t destroy_udp_queues(struct rxq_udp_queues *udp_queues)
Definition: udp_queues.c:271
#define MAX_QUEUES
Definition: defines.h:62
#define FLOW_NB_COUNTERS
Definition: defines.h:86
#define MAX_PKT_SIZE
Definition: defines.h:65
struct rte_eth_conf eth_conf
Definition: device.c:33
struct rte_mempool * mp
Definition: device.c:34
struct rte_eth_dev_info dev_info
Definition: device.c:32
doca_error_t enable_tcp_gpu_offload(struct doca_flow_port *port, uint16_t queue_id, struct doca_flow_pipe *gpu_rss_pipe, struct tcp_session_entry *session_entry)
Definition: flow.c:841
struct doca_flow_port * init_doca_flow(uint16_t port_id, uint8_t rxq_num)
Definition: flow.c:37
doca_error_t destroy_flow_queue(struct doca_flow_port *port_df, struct rxq_icmp_queues *icmp_queues, struct rxq_udp_queues *udp_queues, struct rxq_tcp_queues *tcp_queues, bool http_server, struct txq_http_queues *http_queues)
Definition: flow.c:944
doca_error_t create_tcp_gpu_pipe(struct rxq_tcp_queues *tcp_queues, struct doca_flow_port *port, bool connection_based_flows)
Definition: flow.c:395
DOCA_LOG_REGISTER(GPU_PACKET_PROCESSING_FLOW)
doca_error_t create_root_pipe(struct rxq_udp_queues *udp_queues, struct rxq_tcp_queues *tcp_queues, struct rxq_icmp_queues *icmp_queues, struct doca_flow_port *port)
Definition: flow.c:632
static uint64_t default_flow_timeout_usec
Definition: flow.c:35
doca_error_t disable_tcp_gpu_offload(struct doca_flow_port *port, uint16_t queue_id, struct tcp_session_entry *session_entry)
Definition: flow.c:901
doca_error_t create_tcp_cpu_pipe(struct rxq_tcp_queues *tcp_queues, struct doca_flow_port *port)
Definition: flow.c:280
doca_error_t create_icmp_gpu_pipe(struct rxq_icmp_queues *icmp_queues, struct doca_flow_port *port)
Definition: flow.c:526
doca_error_t create_udp_pipe(struct rxq_udp_queues *udp_queues, struct doca_flow_port *port)
Definition: flow.c:176
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_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]
static volatile bool force_quit
Definition: flow_skeleton.c:49
static struct rxq_icmp_queues icmp_queues
static struct doca_flow_port * df_port
static struct rxq_tcp_queues tcp_queues
static struct rxq_udp_queues udp_queues
static struct txq_http_queues http_queues
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_ERROR_INVALID_VALUE
Definition: doca_error.h:44
@ DOCA_SUCCESS
Definition: doca_error.h:38
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_get_flow_queue_id(struct doca_eth_rxq *eth_rxq, uint16_t *flow_queue_id)
Get the DPDK queue ID of the doca_eth receive queue. can only be called after calling doca_ctx_start(...
#define DOCA_FLOW_ETHER_TYPE_IPV4
Definition: doca_flow_net.h:57
@ 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_cfg_set_mode_args(struct doca_flow_cfg *cfg, const char *mode_args)
Set DOCA mode args.
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_STABLE doca_error_t doca_flow_pipe_cfg_set_name(struct doca_flow_pipe_cfg *cfg, const char *name)
Set pipe's name.
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_port_start(const struct doca_flow_port_cfg *cfg, struct doca_flow_port **port)
Start a doca port.
DOCA_STABLE doca_error_t doca_flow_pipe_cfg_set_is_root(struct doca_flow_pipe_cfg *cfg, bool is_root)
Set if pipe is root or not.
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_STABLE doca_error_t doca_flow_cfg_create(struct doca_flow_cfg **cfg)
Create DOCA Flow configuration struct.
DOCA_STABLE doca_error_t doca_flow_pipe_cfg_set_type(struct doca_flow_pipe_cfg *cfg, enum doca_flow_pipe_type type)
Set pipe's type.
DOCA_EXPERIMENTAL doca_error_t doca_flow_init(struct doca_flow_cfg *cfg)
Initialize the doca flow.
DOCA_STABLE doca_error_t doca_flow_cfg_set_nr_counters(struct doca_flow_cfg *cfg, uint32_t nr_counters)
Set number of counters to configure.
DOCA_STABLE doca_error_t doca_flow_port_stop(struct doca_flow_port *port)
Stop a doca port.
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 doca_error_t doca_flow_pipe_remove_entry(uint16_t pipe_queue, uint32_t flags, struct doca_flow_pipe_entry *entry)
Free one pipe entry.
DOCA_STABLE void doca_flow_destroy(void)
Destroy the doca flow.
DOCA_EXPERIMENTAL doca_error_t doca_flow_port_cfg_set_port_id(struct doca_flow_port_cfg *cfg, uint16_t port_id)
Set the logical port ID.
DOCA_STABLE doca_error_t doca_flow_port_cfg_create(struct doca_flow_port_cfg **cfg)
Create DOCA Flow port configuration struct.
DOCA_STABLE doca_error_t doca_flow_port_cfg_destroy(struct doca_flow_port_cfg *cfg)
Destroy DOCA Flow port configuration struct.
DOCA_STABLE doca_error_t doca_flow_cfg_set_pipe_queues(struct doca_flow_cfg *cfg, uint16_t pipe_queues)
Set pipe queues.
DOCA_STABLE doca_error_t doca_flow_cfg_destroy(struct doca_flow_cfg *cfg)
Destroy DOCA Flow configuration struct.
@ DOCA_FLOW_RSS_TCP
Definition: doca_flow.h:770
@ DOCA_FLOW_RSS_IPV4
Definition: doca_flow.h:764
@ DOCA_FLOW_RSS_UDP
Definition: doca_flow.h:768
@ 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_NO_WAIT
Definition: doca_flow.h:115
@ DOCA_FLOW_MATCH_TCP_FLAG_FIN
Definition: doca_flow.h:403
@ DOCA_FLOW_MATCH_TCP_FLAG_RST
Definition: doca_flow.h:407
@ DOCA_FLOW_MATCH_TCP_FLAG_SYN
Definition: doca_flow.h:405
@ DOCA_FLOW_RESOURCE_TYPE_NON_SHARED
Definition: doca_flow.h:615
@ DOCA_FLOW_FWD_PIPE
Definition: doca_flow.h:746
@ DOCA_FLOW_FWD_DROP
Definition: doca_flow.h:748
@ DOCA_FLOW_FWD_RSS
Definition: doca_flow.h:742
@ DOCA_FLOW_L4_META_UDP
Definition: doca_flow.h:310
@ DOCA_FLOW_L4_META_ICMP
Definition: doca_flow.h:312
@ 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
uint16_t queue_id
Definition: ip_frag_dp.c:1
uint32_t src_addr
Definition: packets.h:8
uint32_t dst_addr
Definition: packets.h:9
forwarding configuration
Definition: doca_flow.h:779
enum doca_flow_fwd_type type
Definition: doca_flow.h:780
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_l4_type_ext l4_type_ext
Definition: doca_flow.h:454
struct doca_flow_header_eth eth
Definition: doca_flow.h:440
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 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
uint16_t numq
Definition: common.h:103
struct doca_flow_pipe * rxq_pipe
Definition: common.h:112
struct doca_eth_rxq * eth_rxq_cpu[MAX_QUEUES]
Definition: common.h:105
uint16_t numq
Definition: common.h:47
uint16_t numq_cpu_rss
Definition: common.h:48
struct doca_flow_pipe_entry * cpu_rss_entry
Definition: common.h:61
struct doca_flow_pipe * rxq_pipe_cpu
Definition: common.h:60
struct doca_flow_pipe * rxq_pipe_gpu
Definition: common.h:59
struct doca_eth_rxq * eth_rxq_cpu[MAX_QUEUES]
Definition: common.h:52
struct doca_eth_rxq * eth_rxq_cpu[MAX_QUEUES]
Definition: common.h:79
struct doca_flow_pipe * root_pipe
Definition: common.h:87
uint16_t numq
Definition: common.h:77
struct doca_flow_pipe * rxq_pipe
Definition: common.h:86
struct doca_flow_pipe_entry * root_udp_entry
Definition: common.h:88
struct doca_flow_pipe_entry * root_tcp_entry_cpu[3]
Definition: common.h:90
struct doca_flow_pipe_entry * root_tcp_entry_gpu
Definition: common.h:89
struct doca_flow_pipe_entry * root_icmp_entry_gpu
Definition: common.h:91
struct doca_flow_pipe_entry * flow
struct tcp_session_key key
struct rte_hash * tcp_session_table
struct rte_hash_parameters tcp_session_ht_params