NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
flow_ct_2_ports_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 <unistd.h>
27 
28 #include <rte_ethdev.h>
29 
30 #include <doca_log.h>
31 #include <doca_flow.h>
32 #include <doca_flow_ct.h>
33 
34 #include "flow_ct_common.h"
35 #include "flow_common.h"
36 
37 #define PACKET_BURST 128
38 
39 DOCA_LOG_REGISTER(FLOW_CT_2_PORTS);
40 
41 /*
42  * Create RSS pipe
43  *
44  * @port [in]: Pipe port
45  * @status [in]: User context for adding entry
46  * @pipe [out]: Created pipe pointer
47  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
48  */
49 static doca_error_t create_rss_pipe(struct doca_flow_port *port,
50  struct entries_status *status,
51  struct doca_flow_pipe **pipe)
52 {
53  struct doca_flow_match match;
54  struct doca_flow_pipe_cfg *cfg;
55  struct doca_flow_fwd fwd;
56  uint16_t rss_queues[1];
58 
59  memset(&match, 0, sizeof(match));
60  memset(&fwd, 0, sizeof(fwd));
61 
63  if (result != DOCA_SUCCESS) {
64  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
65  return result;
66  }
67 
68  result = set_flow_pipe_cfg(cfg, "RSS_PIPE", DOCA_FLOW_PIPE_BASIC, false);
69  if (result != DOCA_SUCCESS) {
70  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
71  goto destroy_pipe_cfg;
72  }
74  if (result != DOCA_SUCCESS) {
75  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
76  goto destroy_pipe_cfg;
77  }
78 
79  /* RSS queue - send matched traffic to queue 0 */
80  rss_queues[0] = 0;
85  fwd.rss.nr_queues = 1;
86 
88  if (result != DOCA_SUCCESS) {
89  DOCA_LOG_ERR("Failed to create RSS pipe: %s", doca_error_get_descr(result));
90  goto destroy_pipe_cfg;
91  }
93 
94  /* Match on any packet */
95  result = doca_flow_pipe_add_entry(0, *pipe, &match, NULL, NULL, &fwd, 0, status, NULL);
96  if (result != DOCA_SUCCESS) {
97  DOCA_LOG_ERR("Failed to add RSS pipe entry: %s", doca_error_get_descr(result));
98  return result;
99  }
100 
102  if (result != DOCA_SUCCESS)
103  DOCA_LOG_ERR("Failed to process RSS entry: %s", doca_error_get_descr(result));
104 
105  return result;
106 
109  return result;
110 }
111 
112 /*
113  * Create CT pipe
114  *
115  * @port [in]: Pipe port
116  * @fwd_pipe [in]: Forward pipe pointer
117  * @fwd_miss_pipe [in]: Forward miss pipe pointer
118  * @pipe [out]: Created pipe pointer
119  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
120  */
121 static doca_error_t create_ct_pipe(struct doca_flow_port *port,
122  struct doca_flow_pipe *fwd_pipe,
123  struct doca_flow_pipe *fwd_miss_pipe,
124  struct doca_flow_pipe **pipe)
125 {
126  struct doca_flow_match match;
127  struct doca_flow_match mask;
128  struct doca_flow_pipe_cfg *cfg;
129  struct doca_flow_fwd fwd;
130  struct doca_flow_fwd fwd_miss;
132 
133  memset(&match, 0, sizeof(match));
134  memset(&mask, 0, sizeof(mask));
135  memset(&fwd, 0, sizeof(fwd));
136  memset(&fwd_miss, 0, sizeof(fwd));
137 
139  if (result != DOCA_SUCCESS) {
140  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
141  return result;
142  }
143 
144  result = set_flow_pipe_cfg(cfg, "CT_PIPE", DOCA_FLOW_PIPE_CT, false);
145  if (result != DOCA_SUCCESS) {
146  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
147  goto destroy_pipe_cfg;
148  }
149  result = doca_flow_pipe_cfg_set_match(cfg, &match, &mask);
150  if (result != DOCA_SUCCESS) {
151  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
152  goto destroy_pipe_cfg;
153  }
154 
156  fwd.next_pipe = fwd_pipe;
157 
159  fwd_miss.next_pipe = fwd_miss_pipe;
160 
162  if (result != DOCA_SUCCESS)
163  DOCA_LOG_ERR("Failed to add CT pipe: %s", doca_error_get_descr(result));
166  return result;
167 }
168 
169 /*
170  * Create VxLAN encapsulation pipe
171  *
172  * @port [in]: Pipe port
173  * @status [in]: User context for adding entry
174  * @pipe [out]: Created pipe pointer
175  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
176  */
177 static doca_error_t create_hairpin_pipe(struct doca_flow_port *port,
178  struct entries_status *status,
179  struct doca_flow_pipe **pipe)
180 {
181  struct doca_flow_match match;
182  struct doca_flow_actions actions;
183  struct doca_flow_actions *actions_list[] = {&actions};
184  struct doca_flow_fwd fwd;
185  struct doca_flow_pipe_cfg *pipe_cfg;
187  uint16_t queue = 2;
188 
189  memset(&match, 0, sizeof(match));
190  memset(&actions, 0, sizeof(actions));
191  memset(&fwd, 0, sizeof(fwd));
192 
193  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
194  if (result != DOCA_SUCCESS) {
195  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
196  return result;
197  }
198 
199  result = set_flow_pipe_cfg(pipe_cfg, "HAIRPIN_PIPE", DOCA_FLOW_PIPE_BASIC, false);
200  if (result != DOCA_SUCCESS) {
201  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
202  goto destroy_pipe_cfg;
203  }
204  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
205  if (result != DOCA_SUCCESS) {
206  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
207  goto destroy_pipe_cfg;
208  }
209  result = doca_flow_pipe_cfg_set_actions(pipe_cfg, actions_list, NULL, NULL, 1);
210  if (result != DOCA_SUCCESS) {
211  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg actions: %s", doca_error_get_descr(result));
212  goto destroy_pipe_cfg;
213  }
214 
217  fwd.rss.nr_queues = 1;
218  fwd.rss.queues_array = &queue;
220 
221  result = doca_flow_pipe_create(pipe_cfg, &fwd, NULL, pipe);
222  if (result != DOCA_SUCCESS) {
223  DOCA_LOG_ERR("Failed to create VxLAN Encap pipe: %s", doca_error_get_descr(result));
224  goto destroy_pipe_cfg;
225  }
226  doca_flow_pipe_cfg_destroy(pipe_cfg);
227 
228  memset(&actions, 0, sizeof(actions));
229 
230  result = doca_flow_pipe_add_entry(0, *pipe, &match, &actions, NULL, NULL, 0, status, NULL);
231  if (result != DOCA_SUCCESS) {
232  DOCA_LOG_ERR("Failed to add VxLAN Encap pipe entry: %s", doca_error_get_descr(result));
233  return result;
234  }
235 
237  if (result != DOCA_SUCCESS)
238  DOCA_LOG_ERR("Failed to process UDP entry: %s", doca_error_get_descr(result));
239 
240  return result;
241 
243  doca_flow_pipe_cfg_destroy(pipe_cfg);
244  return result;
245 }
246 
247 /*
248  * Create pipe to count packets based on 5 tuple match
249  *
250  * @port [in]: Pipe port
251  * @fwd_pipe [in]: Next pipe pointer
252  * @status [in]: User context for adding entry
253  * @pipe [out]: Created pipe pointer
254  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
255  */
256 static doca_error_t create_count_pipe(struct doca_flow_port *port,
257  struct doca_flow_pipe *fwd_pipe,
258  struct entries_status *status,
259  struct doca_flow_pipe **pipe)
260 {
261  struct doca_flow_match match;
262  struct doca_flow_monitor monitor;
263  struct doca_flow_fwd fwd;
264  struct doca_flow_fwd fwd_miss;
265  struct doca_flow_pipe_cfg *pipe_cfg;
267 
268  memset(&match, 0, sizeof(match));
269  memset(&monitor, 0, sizeof(monitor));
270  memset(&fwd, 0, sizeof(fwd));
271  memset(&fwd_miss, 0, sizeof(fwd_miss));
272 
274 
275  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
276  if (result != DOCA_SUCCESS) {
277  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
278  return result;
279  }
280 
281  result = set_flow_pipe_cfg(pipe_cfg, "COUNT_PIPE", DOCA_FLOW_PIPE_BASIC, false);
282  if (result != DOCA_SUCCESS) {
283  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
284  goto destroy_pipe_cfg;
285  }
286  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
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  }
292  if (result != DOCA_SUCCESS) {
293  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg monitor: %s", doca_error_get_descr(result));
294  goto destroy_pipe_cfg;
295  }
296 
298  fwd.next_pipe = fwd_pipe;
299 
301  fwd_miss.next_pipe = fwd_pipe;
302 
303  result = doca_flow_pipe_create(pipe_cfg, &fwd, &fwd_miss, pipe);
304  if (result != DOCA_SUCCESS) {
305  DOCA_LOG_ERR("Failed to create count pipe: %s", doca_error_get_descr(result));
306  goto destroy_pipe_cfg;
307  }
308  doca_flow_pipe_cfg_destroy(pipe_cfg);
309 
310  result = doca_flow_pipe_add_entry(0, *pipe, &match, NULL, NULL, NULL, 0, status, NULL);
311  if (result != DOCA_SUCCESS) {
312  DOCA_LOG_ERR("Failed to add count pipe entry: %s", doca_error_get_descr(result));
313  return result;
314  }
315 
317  if (result != DOCA_SUCCESS)
318  DOCA_LOG_ERR("Failed to process count entry: %s", doca_error_get_descr(result));
319 
320  return result;
321 
323  doca_flow_pipe_cfg_destroy(pipe_cfg);
324  return result;
325 }
326 
327 /*
328  * Parse UDP packet to update CT tables
329  *
330  * @packet [in]: Packet to parse
331  * @match_o [out]: Origin match struct to fill
332  * @match_r [out]: Reply match struct to fill
333  */
334 static void parse_packet(struct rte_mbuf *packet,
335  struct doca_flow_ct_match *match_o,
336  struct doca_flow_ct_match *match_r)
337 {
338  uint8_t *l4_hdr;
339  struct rte_ipv4_hdr *ipv4_hdr;
340  const struct rte_udp_hdr *udp_hdr;
341 
342  ipv4_hdr = rte_pktmbuf_mtod_offset(packet, struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));
343 
344  match_o->ipv4.src_ip = ipv4_hdr->src_addr;
345  match_o->ipv4.dst_ip = ipv4_hdr->dst_addr;
346  match_r->ipv4.src_ip = match_o->ipv4.dst_ip;
347  match_r->ipv4.dst_ip = match_o->ipv4.src_ip;
348 
349  l4_hdr = (typeof(l4_hdr))ipv4_hdr + rte_ipv4_hdr_len(ipv4_hdr);
350  udp_hdr = (typeof(udp_hdr))l4_hdr;
351 
352  match_o->ipv4.l4_port.src_port = udp_hdr->src_port;
353  match_o->ipv4.l4_port.dst_port = udp_hdr->dst_port;
354  match_r->ipv4.l4_port.src_port = match_o->ipv4.l4_port.dst_port;
355  match_r->ipv4.l4_port.dst_port = match_o->ipv4.l4_port.src_port;
356 
359 }
360 
361 /*
362  * Dequeue packets from DPDK queues, parse and update CT tables with new connection 5 tuple
363  *
364  * @port [in]: Port to which an entry should be inserted
365  * @port_id [in]: Port id to which packet can be received
366  * @ct_queue [in]: DOCA Flow CT queue number
367  * @ct_pipe [in]: Pipe of CT
368  * @ct_status [in]: User context for adding CT entry
369  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
370  */
371 static doca_error_t process_packets(struct doca_flow_port *port,
372  uint16_t port_id,
373  uint16_t ct_queue,
374  struct doca_flow_pipe *ct_pipe,
375  struct entries_status *ct_status)
376 {
377  struct rte_mbuf *packets[PACKET_BURST];
378  struct doca_flow_ct_match match_o;
379  struct doca_flow_ct_match match_r;
380  struct doca_flow_pipe_entry *entry;
381  uint32_t flags;
383  int i, entries, nb_packets = 0;
384  bool conn_found = false;
385 
386  memset(&match_o, 0, sizeof(match_o));
387  memset(&match_r, 0, sizeof(match_r));
388 
389  DOCA_LOG_INFO("Listening on port %u, please send UDP packet with DIP 1.1.1.1", port_id);
390  do {
391  nb_packets = rte_eth_rx_burst(port_id, 0, packets, PACKET_BURST);
392  } while (nb_packets == 0);
393 
394  DOCA_LOG_INFO("%d packets received", nb_packets);
395 
396  entries = 0;
397  DOCA_LOG_INFO("Sample received %d packets on port %d", nb_packets, port_id);
398  for (i = 0; i < PACKET_BURST && i < nb_packets; i++) {
399  parse_packet(packets[i], &match_o, &match_r);
402  /* Allocate CT entry */
404  ct_pipe,
405  flags,
406  &match_o,
407  packets[i]->hash.rss,
408  &match_r,
409  packets[i]->hash.rss,
410  &entry,
411  &conn_found);
412  if (result != DOCA_SUCCESS) {
413  DOCA_LOG_ERR("Failed to prepare CT entry\n");
414  return result;
415  }
416 
417  if (!conn_found) {
420  result = doca_flow_ct_add_entry(ct_queue,
421  ct_pipe,
422  flags,
423  &match_o,
424  &match_r,
425  NULL,
426  NULL,
427  0,
428  0,
429  0,
430  ct_status,
431  entry);
432  if (result != DOCA_SUCCESS) {
433  DOCA_LOG_ERR("Failed to add CT pipe an entry: %s", doca_error_get_descr(result));
434  return result;
435  }
436  entries++;
437  }
438  }
439 
440  DOCA_LOG_INFO("%d CT connections created", nb_packets);
441 
442  while (ct_status->nb_processed != entries) {
443  result = doca_flow_ct_entries_process(port, ct_queue, 0, 0, NULL);
444  if (result != DOCA_SUCCESS) {
445  DOCA_LOG_ERR("Failed to process Flow CT entries: %s", doca_error_get_descr(result));
446  return result;
447  }
448 
449  if (ct_status->failure) {
450  DOCA_LOG_ERR("Flow CT entries process returned with a failure");
451  return DOCA_ERROR_BAD_STATE;
452  }
453  }
454 
455  DOCA_LOG_INFO("%d CT connections processed\n", ct_status->nb_processed);
456 
457  return DOCA_SUCCESS;
458 }
459 
460 /*
461  * flow_ct_2_ports
462  *
463  * @nb_queues [in]: number of queues the sample will use
464  * @dev_arr [in]: Flow CT devices
465  * @nb_ports [in]: number of ports the sample will use
466  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise.
467  */
468 doca_error_t flow_ct_2_ports(uint16_t nb_queues, struct doca_dev *dev_arr[], int nb_ports)
469 {
470  const int nb_entries = 6;
471  struct flow_resources resource;
472  uint32_t nr_shared_resources[SHARED_RESOURCE_NUM_VALUES] = {0};
473  struct doca_flow_pipe *rss_pipes[nb_ports];
474  struct doca_flow_pipe *hairpin_pipes[nb_ports];
475  struct doca_flow_pipe *count_pipes[nb_ports];
476  struct doca_flow_pipe *ct_pipes[nb_ports];
477  struct doca_flow_pipe *udp_pipes[nb_ports];
478  struct doca_flow_port *ports[nb_ports];
479  uint32_t actions_mem_size[nb_ports];
480  struct doca_flow_meta o_zone_mask, o_modify_mask, r_zone_mask, r_modify_mask;
481  struct entries_status ctrl_status, ct_status;
482  uint32_t ct_flags, nb_arm_queues = 1, nb_ctrl_queues = 1, nb_user_actions = 0, nb_ipv4_sessions = 1024,
483  nb_ipv6_sessions = 0; /* On BF2 should always be 0 */
484  uint16_t ct_queue = nb_queues;
486  int i;
487 
488  memset(&resource, 0, sizeof(resource));
489  memset(rss_pipes, 0, sizeof(struct doca_flow_pipe *) * nb_ports);
490  memset(hairpin_pipes, 0, sizeof(struct doca_flow_pipe *) * nb_ports);
491  memset(count_pipes, 0, sizeof(struct doca_flow_pipe *) * nb_ports);
492  memset(ct_pipes, 0, sizeof(struct doca_flow_pipe *) * nb_ports);
493  memset(udp_pipes, 0, sizeof(struct doca_flow_pipe *) * nb_ports);
494 
495  resource.nr_counters = 1;
496 
497  result = init_doca_flow(nb_queues, "switch,hws", &resource, nr_shared_resources);
498  if (result != DOCA_SUCCESS) {
499  DOCA_LOG_ERR("Failed to init DOCA Flow: %s", doca_error_get_descr(result));
500  return result;
501  }
502 
503  /* Dont use zone masking */
504  memset(&o_zone_mask, 0, sizeof(o_zone_mask));
505  memset(&o_modify_mask, 0, sizeof(o_modify_mask));
506  memset(&r_zone_mask, 0, sizeof(r_zone_mask));
507  memset(&r_modify_mask, 0, sizeof(r_modify_mask));
508 
510  result = init_doca_flow_ct(ct_flags,
511  nb_arm_queues,
512  nb_ctrl_queues,
513  nb_user_actions,
514  NULL,
515  nb_ipv4_sessions,
516  nb_ipv6_sessions,
518  false,
519  &o_zone_mask,
520  &o_modify_mask,
521  false,
522  &r_zone_mask,
523  &r_modify_mask);
524  if (result != DOCA_SUCCESS) {
526  return result;
527  }
528 
529  memset(ports, 0, sizeof(struct doca_dev *) * nb_ports);
532  if (result != DOCA_SUCCESS) {
533  DOCA_LOG_ERR("Failed to init DOCA ports: %s", doca_error_get_descr(result));
536  return result;
537  }
538 
539  for (i = 0; i < nb_ports; i++) {
540  memset(&ctrl_status, 0, sizeof(ctrl_status));
541 
542  result = create_rss_pipe(ports[i], &ctrl_status, &rss_pipes[i]);
543  if (result != DOCA_SUCCESS)
544  goto cleanup;
545 
546  result = create_hairpin_pipe(ports[i], &ctrl_status, &hairpin_pipes[i]);
547  if (result != DOCA_SUCCESS)
548  goto cleanup;
549 
550  result = create_count_pipe(ports[i], rss_pipes[i], &ctrl_status, &count_pipes[i]);
551  if (result != DOCA_SUCCESS)
552  goto cleanup;
553 
554  result = create_ct_pipe(ports[i], hairpin_pipes[i], count_pipes[i], &ct_pipes[i]);
555  if (result != DOCA_SUCCESS)
556  goto cleanup;
557 
559  true,
560  false,
562  ct_pipes[i],
563  &ctrl_status,
564  &udp_pipes[i]);
565  if (result != DOCA_SUCCESS)
566  goto cleanup;
567 
568  if (ctrl_status.nb_processed != nb_entries || ctrl_status.failure) {
569  DOCA_LOG_ERR("Failed to process control path entries");
571  goto cleanup;
572  }
573  }
574 
575  DOCA_LOG_INFO("Please send same UDP packets to see the CT entries being created\n");
576  for (i = 0; i < nb_ports; i++) {
577  memset(&ct_status, 0, sizeof(ct_status));
578  result = process_packets(ports[i], i, ct_queue, ct_pipes[i], &ct_status);
579  if (result != DOCA_SUCCESS)
580  goto cleanup;
581  }
582 
583  sleep(3);
584 
585 cleanup:
586  for (i = 0; i < nb_ports; i++) {
587  if (udp_pipes[i] != NULL)
588  doca_flow_pipe_destroy(udp_pipes[i]);
589  if (ct_pipes[i] != NULL)
590  doca_flow_pipe_destroy(ct_pipes[i]);
591  if (hairpin_pipes[i] != NULL)
592  doca_flow_pipe_destroy(hairpin_pipes[i]);
593  if (count_pipes[i] != NULL)
594  doca_flow_pipe_destroy(count_pipes[i]);
595  if (rss_pipes[i] != NULL)
596  doca_flow_pipe_destroy(rss_pipes[i]);
597  }
599  return result;
600 }
#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 void cleanup(struct cache_invalidate_sample_state *state)
DOCA_LOG_REGISTER(FLOW_CT_2_PORTS)
static doca_error_t create_count_pipe(struct doca_flow_port *port, struct doca_flow_pipe *fwd_pipe, struct entries_status *status, struct doca_flow_pipe **pipe)
#define PACKET_BURST
static doca_error_t process_packets(struct doca_flow_port *port, uint16_t port_id, uint16_t ct_queue, struct doca_flow_pipe *ct_pipe, struct entries_status *ct_status)
static doca_error_t create_ct_pipe(struct doca_flow_port *port, struct doca_flow_pipe *fwd_pipe, struct doca_flow_pipe *fwd_miss_pipe, struct doca_flow_pipe **pipe)
doca_error_t flow_ct_2_ports(uint16_t nb_queues, struct doca_dev *dev_arr[], int nb_ports)
static doca_error_t create_rss_pipe(struct doca_flow_port *port, struct entries_status *status, struct doca_flow_pipe **pipe)
static void parse_packet(struct rte_mbuf *packet, struct doca_flow_ct_match *match_o, struct doca_flow_ct_match *match_r)
static doca_error_t create_hairpin_pipe(struct doca_flow_port *port, struct entries_status *status, struct doca_flow_pipe **pipe)
doca_error_t init_doca_flow_ct(uint32_t flags, uint32_t nb_arm_queues, uint32_t nb_ctrl_queues, uint32_t nb_user_actions, doca_flow_ct_entry_finalize_cb entry_finalize_cb, uint32_t nb_ipv4_sessions, uint32_t nb_ipv6_sessions, uint32_t dup_filter_sz, bool o_match_inner, struct doca_flow_meta *o_zone_mask, struct doca_flow_meta *o_modify_mask, bool r_match_inner, struct doca_flow_meta *r_zone_mask, struct doca_flow_meta *r_modify_mask)
doca_error_t create_ct_root_pipe(struct doca_flow_port *port, bool is_ipv4, bool is_ipv6, enum doca_flow_l4_meta l4_type, struct doca_flow_pipe *fwd_pipe, struct entries_status *status, struct doca_flow_pipe **pipe)
void cleanup_procedure(struct doca_flow_pipe *ct_pipe, int nb_ports, struct doca_flow_port *ports[])
#define DUP_FILTER_CONN_NUM
static int nb_entries
static doca_error_t destroy_pipe_cfg(struct doca_flow_pipe_cfg *cfg)
static struct doca_flow_pipe_entry * entries[NB_ENTRIES]
static struct doca_flow_fwd fwd_miss
Definition: flow_parser.c:110
static uint16_t * rss_queues
Definition: flow_parser.c:114
static struct doca_flow_actions actions
Definition: flow_parser.c:107
static struct doca_flow_monitor monitor
Definition: flow_parser.c:108
static struct doca_flow_fwd fwd
Definition: flow_parser.c:109
static struct doca_flow_pipe_entry * entry[MAX_ENTRIES]
#define DEFAULT_TIMEOUT_US
Definition: flow_skeleton.c:36
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_EXPERIMENTAL doca_error_t doca_flow_ct_entries_process(struct doca_flow_port *port, uint16_t pipe_queue, uint32_t min_room, uint32_t max_processed_entries, uint32_t *queue_room)
Process CT entries in queue.
DOCA_EXPERIMENTAL doca_error_t doca_flow_ct_add_entry(uint16_t queue, struct doca_flow_pipe *pipe, uint32_t flags, struct doca_flow_ct_match *match_origin, struct doca_flow_ct_match *match_reply, const struct doca_flow_ct_actions *actions_origin, const struct doca_flow_ct_actions *actions_reply, uint32_t fwd_handle_origin, uint32_t fwd_handle_reply, uint32_t timeout_s, void *usr_ctx, struct doca_flow_pipe_entry *entry)
Add new entry to doca flow CT pipe.
DOCA_EXPERIMENTAL void doca_flow_ct_destroy(void)
Destroy the doca flow ct.
DOCA_EXPERIMENTAL doca_error_t doca_flow_ct_entry_prepare(uint16_t queue, struct doca_flow_pipe *pipe, uint32_t flags, struct doca_flow_ct_match *match_origin, uint32_t hash_origin, struct doca_flow_ct_match *match_reply, uint32_t hash_reply, struct doca_flow_pipe_entry **entry, bool *conn_found)
Lookup recent CT entry and create on miss.
@ DOCA_FLOW_CT_ENTRY_FLAGS_DIR_ORIGIN
Definition: doca_flow_ct.h:667
@ DOCA_FLOW_CT_ENTRY_FLAGS_NO_WAIT
Definition: doca_flow_ct.h:665
@ DOCA_FLOW_CT_ENTRY_FLAGS_DIR_REPLY
Definition: doca_flow_ct.h:669
@ DOCA_FLOW_CT_ENTRY_FLAGS_ALLOC_ON_MISS
Definition: doca_flow_ct.h:683
@ DOCA_FLOW_CT_ENTRY_FLAGS_DUP_FILTER_REPLY
Definition: doca_flow_ct.h:687
@ DOCA_FLOW_CT_ENTRY_FLAGS_DUP_FILTER_ORIGIN
Definition: doca_flow_ct.h:685
@ DOCA_FLOW_CT_FLAG_NO_COUNTER
Definition: doca_flow_ct.h:60
@ DOCA_FLOW_CT_FLAG_NO_AGING
Definition: doca_flow_ct.h:58
#define DOCA_FLOW_PROTO_UDP
Definition: doca_flow_net.h:42
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_STABLE void doca_flow_pipe_destroy(struct doca_flow_pipe *pipe)
Destroy one 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_FLOW_RSS_IPV4
Definition: doca_flow.h:764
@ DOCA_FLOW_RSS_UDP
Definition: doca_flow.h:768
@ DOCA_FLOW_PIPE_CT
Definition: doca_flow.h:227
@ DOCA_FLOW_PIPE_BASIC
Definition: doca_flow.h:221
@ DOCA_FLOW_RESOURCE_TYPE_NON_SHARED
Definition: doca_flow.h:615
@ DOCA_FLOW_FWD_PIPE
Definition: doca_flow.h:746
@ DOCA_FLOW_FWD_RSS
Definition: doca_flow.h:742
@ DOCA_FLOW_L4_META_UDP
Definition: doca_flow.h:310
#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
const struct ip_frag_config * cfg
Definition: ip_frag_dp.c:0
struct tcp_hdr l4_hdr
Definition: packets.h:2
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
struct doca_flow_header_l4_port l4_port
Definition: doca_flow_ct.h:623
doca_be32_t src_ip
Definition: doca_flow_ct.h:625
doca_be32_t dst_ip
Definition: doca_flow_ct.h:627
doca flow CT match pattern
Definition: doca_flow_ct.h:654
struct doca_flow_ct_match4 ipv4
Definition: doca_flow_ct.h:656
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
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
doca flow matcher information
Definition: doca_flow.h:491
doca flow meta data
Definition: doca_flow.h:358
doca monitor action configuration
Definition: doca_flow.h:968
enum doca_flow_resource_type counter_type
Definition: doca_flow.h:988
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
uint32_t src_addr
Definition: packets.h:75
uint32_t dst_addr
Definition: packets.h:76
uint16_t dst_port
Definition: packets.h:99
uint16_t src_port
Definition: packets.h:98
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