NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
flow_loopback_sample.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #include <string.h>
27 #include <unistd.h>
28 #include <stdint.h>
29 #include <signal.h>
30 
31 #include <rte_ethdev.h>
32 
33 #include <doca_log.h>
34 #include <doca_flow.h>
35 #include <doca_bitfield.h>
36 
37 #include "flow_common.h"
38 
39 DOCA_LOG_REGISTER(FLOW_LOOPBACK);
40 
41 #define PACKET_BURST 128 /* The number of packets in the rx queue */
42 
43 static bool force_quit = false;
44 
45 /*
46  * Signal handler
47  *
48  * @signum [in]: The signal received to handle
49  */
50 static void signal_handler(int signum)
51 {
52  if (signum == SIGINT || signum == SIGTERM) {
53  DOCA_LOG_INFO("Signal %d received, preparing to exit", signum);
54  force_quit = true;
55  }
56 }
57 
58 /*
59  * Dequeue packets from DPDK queues
60  *
61  * @ingress_port [in]: port id for dequeue packets
62  */
63 static void process_packets(int ingress_port)
64 {
65  struct rte_mbuf *packets[PACKET_BURST];
66  int queue_index = 0;
67  int nb_packets;
68  int i;
69 
70  nb_packets = rte_eth_rx_burst(ingress_port, queue_index, packets, PACKET_BURST);
71 
72  /* Print received packets' meta data */
73  for (i = 0; i < nb_packets; i++) {
74  if (rte_flow_dynf_metadata_avail())
75  DOCA_LOG_INFO("Packet received with meta data %d", *RTE_FLOW_DYNF_METADATA(packets[i]));
76  }
77  rte_eth_tx_burst(ingress_port, queue_index, packets, PACKET_BURST);
78 }
79 
80 /*
81  * Create DOCA Flow pipe where the match is on changeable TCP over IPv4 source and destination
82  * addresses (IP and port), forward is RSS, and the forward miss is to another pipe.
83  *
84  * @port [in]: port of the pipe
85  * @miss_pipe [in]: the next pipe to use in case of a miss.
86  * @pipe [out]: created pipe pointer
87  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
88  */
89 static doca_error_t create_rss_tcp_ip_pipe(struct doca_flow_port *port,
90  struct doca_flow_pipe *miss_pipe,
91  struct doca_flow_pipe **pipe)
92 {
93  struct doca_flow_match match;
94  struct doca_flow_actions actions, *actions_arr[NB_ACTIONS_ARR];
95  struct doca_flow_fwd fwd;
96  struct doca_flow_fwd fwd_miss;
97  struct doca_flow_pipe_cfg *pipe_cfg;
98  uint16_t rss_queues[1];
100 
101  memset(&match, 0, sizeof(match));
102  memset(&actions, 0, sizeof(actions));
103  memset(&fwd, 0, sizeof(fwd));
104  memset(&fwd_miss, 0, sizeof(fwd_miss));
105 
106  /* changeable TCP over IPv4 source and destination addresses */
109 
111  match.outer.ip4.src_ip = 0xffffffff;
112  match.outer.ip4.dst_ip = 0xffffffff;
114  match.outer.tcp.l4_port.src_port = 0xffff;
115  match.outer.tcp.l4_port.dst_port = 0xffff;
116 
117  actions_arr[0] = &actions;
118 
119  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
120  if (result != DOCA_SUCCESS) {
121  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
122  return result;
123  }
124 
125  result = set_flow_pipe_cfg(pipe_cfg, "RSS_TCP_IPv4_PIPE", DOCA_FLOW_PIPE_BASIC, true);
126  if (result != DOCA_SUCCESS) {
127  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
128  goto destroy_pipe_cfg;
129  }
130  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
131  if (result != DOCA_SUCCESS) {
132  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
133  goto destroy_pipe_cfg;
134  }
135  result = doca_flow_pipe_cfg_set_actions(pipe_cfg, actions_arr, NULL, NULL, NB_ACTIONS_ARR);
136  if (result != DOCA_SUCCESS) {
137  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg actions: %s", doca_error_get_descr(result));
138  goto destroy_pipe_cfg;
139  }
140 
141  /* RSS queue - send matched traffic to queue 0 */
142  rss_queues[0] = 0;
147  fwd.rss.nr_queues = 1;
148 
149  /* In case of a miss, forward the packet to the next pipe */
151  fwd_miss.next_pipe = miss_pipe;
152 
153  result = doca_flow_pipe_create(pipe_cfg, &fwd, &fwd_miss, pipe);
155  doca_flow_pipe_cfg_destroy(pipe_cfg);
156  return result;
157 }
158 
159 /*
160  * Add DOCA Flow pipe entry to the "RSS TCP over IPv4" pipe
161  *
162  * @pipe [in]: a pointer to the pipe to add the entry to
163  * @status [in]: user context for adding entry
164  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
165  */
166 static doca_error_t add_rss_tcp_ip_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status)
167 {
168  struct doca_flow_match match;
169  struct doca_flow_actions actions;
170  struct doca_flow_pipe_entry *entry;
172 
173  /* TCPoTPv4 source and destination addresses */
174  doca_be32_t dst_ip_addr = BE_IPV4_ADDR(8, 8, 8, 8);
175  doca_be32_t src_ip_addr = BE_IPV4_ADDR(1, 2, 3, 4);
176  doca_be16_t dst_port = rte_cpu_to_be_16(80);
177  doca_be16_t src_port = rte_cpu_to_be_16(1234);
178 
179  memset(&match, 0, sizeof(match));
180  memset(&actions, 0, sizeof(actions));
181 
182  match.outer.ip4.dst_ip = dst_ip_addr;
183  match.outer.ip4.src_ip = src_ip_addr;
186 
187  result = doca_flow_pipe_add_entry(0, pipe, &match, &actions, NULL, NULL, 0, status, &entry);
188  if (result != DOCA_SUCCESS)
189  return result;
190 
191  return DOCA_SUCCESS;
192 }
193 
194 /*
195  * Create DOCA Flow pipe where it matches UDP over IPv4 traffic
196  * with changeable source and destination IPv4 addresses.
197  * The actions of the pipe is only setting a changeable metadata, forward is RSS and forward miss is drop.
198  *
199  * @port [in]: port of the pipe
200  * @pipe [out]: created pipe pointer
201  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
202  */
203 static doca_error_t create_rss_udp_ip_pipe(struct doca_flow_port *port, struct doca_flow_pipe **pipe)
204 {
205  struct doca_flow_match match;
206  struct doca_flow_actions actions, *actions_arr[NB_ACTIONS_ARR];
207  struct doca_flow_fwd fwd;
208  struct doca_flow_fwd fwd_miss;
209  struct doca_flow_pipe_cfg *pipe_cfg;
210  uint16_t rss_queues[1];
212 
213  memset(&match, 0, sizeof(match));
214  memset(&actions, 0, sizeof(actions));
215  memset(&fwd, 0, sizeof(fwd));
216  memset(&fwd_miss, 0, sizeof(fwd_miss));
217 
218  /* set mask value */
219  actions.meta.pkt_meta = UINT32_MAX;
220  actions_arr[0] = &actions;
221 
222  /* changeable IPv4 source and destination addresses */
224 
226  match.outer.ip4.src_ip = 0xffffffff;
227  match.outer.ip4.dst_ip = 0xffffffff;
228 
229  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
230  if (result != DOCA_SUCCESS) {
231  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
232  return result;
233  }
234 
235  result = set_flow_pipe_cfg(pipe_cfg, "RSS_UDP_IP_PIPE", DOCA_FLOW_PIPE_BASIC, false);
236  if (result != DOCA_SUCCESS) {
237  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
238  goto destroy_pipe_cfg;
239  }
240  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
241  if (result != DOCA_SUCCESS) {
242  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
243  goto destroy_pipe_cfg;
244  }
245  result = doca_flow_pipe_cfg_set_actions(pipe_cfg, actions_arr, NULL, NULL, NB_ACTIONS_ARR);
246  if (result != DOCA_SUCCESS) {
247  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg actions: %s", doca_error_get_descr(result));
248  goto destroy_pipe_cfg;
249  }
250 
251  /* RSS queue - send matched traffic to queue 0 */
252  rss_queues[0] = 0;
257  fwd.rss.nr_queues = 1;
258 
259  /* In case of a miss match, drop the packet */
261 
262  result = doca_flow_pipe_create(pipe_cfg, &fwd, &fwd_miss, pipe);
264  doca_flow_pipe_cfg_destroy(pipe_cfg);
265  return result;
266 }
267 
268 /*
269  * Add DOCA Flow pipe entry to the "RSS UDP over IPv4" pipe
270  *
271  * @pipe [in]: a pointer to the pipe to add the entry to
272  * @status [in]: user context for adding entry
273  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
274  */
275 static doca_error_t add_rss_rss_udp_ip_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status)
276 {
277  struct doca_flow_match match;
278  struct doca_flow_actions actions;
279  struct doca_flow_pipe_entry *entry;
281 
282  memset(&match, 0, sizeof(match));
283  memset(&actions, 0, sizeof(actions));
284 
285  /* IPv4 source and destination addresses */
286  match.outer.ip4.dst_ip = BE_IPV4_ADDR(81, 81, 81, 81);
287  match.outer.ip4.src_ip = BE_IPV4_ADDR(11, 21, 31, 41);
288 
289  /* set meta value */
291 
292  result = doca_flow_pipe_add_entry(0, pipe, &match, &actions, NULL, NULL, 0, status, &entry);
293  if (result != DOCA_SUCCESS)
294  return result;
295 
296  return DOCA_SUCCESS;
297 }
298 
299 /*
300  * Create DOCA Flow "loopback" pipe.
301  * The "loopback" pipe is created on egress domain, and it
302  * matches changeable TCP over IPv4 source and destination addresses (IP and port).
303  * It also does changeable VXLAN encapsulation.
304  *
305  * @port [in]: port of the pipe
306  * @port_id [in]: the port identifier to re-inject the packet to
307  * @pipe [out]: created pipe pointer
308  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
309  */
310 static doca_error_t create_loopback_pipe(struct doca_flow_port *port, uint16_t port_id, struct doca_flow_pipe **pipe)
311 {
312  struct doca_flow_match match;
313  struct doca_flow_actions actions, *actions_arr[NB_ACTIONS_ARR];
314 
315  struct doca_flow_fwd fwd;
316  struct doca_flow_fwd fwd_miss;
317  struct doca_flow_pipe_cfg *pipe_cfg;
319 
320  memset(&match, 0, sizeof(match));
321  memset(&actions, 0, sizeof(actions));
322  memset(&fwd, 0, sizeof(fwd));
323  memset(&fwd_miss, 0, sizeof(fwd_miss));
324 
325  /* changeable TCP over IPv4 source and destination addresses */
328 
330  match.outer.ip4.src_ip = 0xffffffff;
331  match.outer.ip4.dst_ip = 0xffffffff;
333  match.outer.tcp.l4_port.src_port = 0xffff;
334  match.outer.tcp.l4_port.dst_port = 0xffff;
335 
336  /* build basic outer VXLAN encap data */
338  actions.encap_cfg.is_l2 = true;
339  SET_MAC_ADDR(actions.encap_cfg.encap.outer.eth.src_mac, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
340  SET_MAC_ADDR(actions.encap_cfg.encap.outer.eth.dst_mac, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
342  actions.encap_cfg.encap.outer.ip4.src_ip = 0xffffffff;
343  actions.encap_cfg.encap.outer.ip4.dst_ip = 0xffffffff;
348  actions.encap_cfg.encap.tun.vxlan_tun_id = 0xffffffff;
349  actions_arr[0] = &actions;
350 
351  result = doca_flow_pipe_cfg_create(&pipe_cfg, port);
352  if (result != DOCA_SUCCESS) {
353  DOCA_LOG_ERR("Failed to create doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
354  return result;
355  }
356 
357  result = set_flow_pipe_cfg(pipe_cfg, "LOOPBACK_PIPE", DOCA_FLOW_PIPE_BASIC, true);
358  if (result != DOCA_SUCCESS) {
359  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg: %s", doca_error_get_descr(result));
360  goto destroy_pipe_cfg;
361  }
363  if (result != DOCA_SUCCESS) {
364  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg domain: %s", doca_error_get_descr(result));
365  goto destroy_pipe_cfg;
366  }
367  result = doca_flow_pipe_cfg_set_match(pipe_cfg, &match, NULL);
368  if (result != DOCA_SUCCESS) {
369  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg match: %s", doca_error_get_descr(result));
370  goto destroy_pipe_cfg;
371  }
372  result = doca_flow_pipe_cfg_set_actions(pipe_cfg, actions_arr, NULL, NULL, NB_ACTIONS_ARR);
373  if (result != DOCA_SUCCESS) {
374  DOCA_LOG_ERR("Failed to set doca_flow_pipe_cfg actions: %s", doca_error_get_descr(result));
375  goto destroy_pipe_cfg;
376  }
377 
379  fwd.port_id = port_id;
380 
381  /* In cade of a miss, drop the packet */
383 
384  result = doca_flow_pipe_create(pipe_cfg, &fwd, &fwd_miss, pipe);
386  doca_flow_pipe_cfg_destroy(pipe_cfg);
387  return result;
388 }
389 
390 /*
391  * Add DOCA Flow pipe entry to the "loopback" pipe
392  * Note that upon encapsulation the
393  * destination MAC address is the same mac address of the port
394  * the packet arrived to (needed for the "loopback" or "packet re-injection").
395  *
396  * @pipe [in]: pipe of the entry
397  * @status [in]: user context for adding entry
398  * @dst_mac [in]: MAC address used for the encapsulation
399  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
400  */
401 static doca_error_t add_loopback_pipe_entry(struct doca_flow_pipe *pipe,
402  struct entries_status *status,
403  uint8_t dst_mac[6])
404 {
405  struct doca_flow_match match;
406  struct doca_flow_actions actions;
407  struct doca_flow_pipe_entry *entry;
409 
410  doca_be32_t encap_dst_ip_addr = BE_IPV4_ADDR(81, 81, 81, 81);
411  doca_be32_t encap_src_ip_addr = BE_IPV4_ADDR(11, 21, 31, 41);
412  uint8_t encap_ttl = 17;
413  doca_be32_t encap_vxlan_tun_id = DOCA_HTOBE32(0xadadad);
414  uint8_t src_mac[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
415 
416  doca_be32_t dst_ip_addr = BE_IPV4_ADDR(8, 8, 8, 8);
417  doca_be32_t src_ip_addr = BE_IPV4_ADDR(1, 2, 3, 4);
418  doca_be16_t dst_port = rte_cpu_to_be_16(80);
419  doca_be16_t src_port = rte_cpu_to_be_16(1234);
420 
421  memset(&match, 0, sizeof(match));
422  memset(&actions, 0, sizeof(actions));
423 
424  match.outer.ip4.dst_ip = dst_ip_addr;
425  match.outer.ip4.src_ip = src_ip_addr;
428 
430  src_mac[0],
431  src_mac[1],
432  src_mac[2],
433  src_mac[3],
434  src_mac[4],
435  src_mac[5]);
437  dst_mac[0],
438  dst_mac[1],
439  dst_mac[2],
440  dst_mac[3],
441  dst_mac[4],
442  dst_mac[5]);
444  actions.encap_cfg.encap.outer.ip4.src_ip = encap_src_ip_addr;
445  actions.encap_cfg.encap.outer.ip4.dst_ip = encap_dst_ip_addr;
446  actions.encap_cfg.encap.outer.ip4.ttl = encap_ttl;
448  actions.encap_cfg.encap.tun.vxlan_tun_id = encap_vxlan_tun_id;
449 
450  result = doca_flow_pipe_add_entry(0, pipe, &match, &actions, NULL, NULL, 0, status, &entry);
451  if (result != DOCA_SUCCESS)
452  return result;
453 
454  return DOCA_SUCCESS;
455 }
456 
457 static int populate_macs(const int nb_ports, uint8_t mac_addresses[2][6])
458 {
459  struct doca_devinfo **list = NULL;
460  uint32_t list_size = 0;
461  int port_id;
462  int i, j;
463  int ret;
464 
465  for (i = 0; i < 2; i++)
466  for (j = 0; j < 6; j++)
467  if (mac_addresses[i][j])
468  return 0;
469 
470  ret = doca_devinfo_create_list(&list, &list_size);
471  if (ret != DOCA_SUCCESS) {
472  DOCA_LOG_ERR("Failed to create devinfo list");
473  return ret;
474  }
475 
476  if ((const int)list_size < nb_ports) {
477  DOCA_LOG_ERR("Failed to create devinfo list");
478  goto out;
479  }
480 
481  for (port_id = 0; port_id < nb_ports; port_id++) {
482  ret = doca_devinfo_get_mac_addr(list[port_id], mac_addresses[port_id], 6);
483  if (ret != DOCA_SUCCESS) {
484  DOCA_LOG_ERR("Failed to get mac address");
485  goto out;
486  }
487  }
488 
489 out:
491  return ret;
492 }
493 
494 /*
495  * Run flow_loopback sample
496  *
497  * @nb_queues [in]: number of queues the sample will use
498  * @mac_addresses [in]: MAC addresses of each port used for encapsulation
499  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
500  */
501 doca_error_t flow_loopback(int nb_queues, uint8_t mac_addresses[2][6])
502 {
503  const int nb_ports = 2;
504  struct flow_resources resource = {0};
505  uint32_t nr_shared_resources[SHARED_RESOURCE_NUM_VALUES] = {0};
506  struct doca_flow_port *ports[nb_ports];
507  struct doca_dev *dev_arr[nb_ports];
508  uint32_t actions_mem_size[nb_ports];
509  struct doca_flow_pipe *pipe, *miss_pipe;
510  struct entries_status status;
511  int num_of_entries = 3;
513  int port_id;
514 
515  result = populate_macs(nb_ports, mac_addresses);
516  if (result)
517  return result;
518 
519  result = init_doca_flow(nb_queues, "vnf,hws", &resource, nr_shared_resources);
520  if (result != DOCA_SUCCESS) {
521  DOCA_LOG_ERR("Failed to init DOCA Flow: %s", doca_error_get_descr(result));
522  return -1;
523  }
524 
525  memset(dev_arr, 0, sizeof(struct doca_dev *) * nb_ports);
526  ARRAY_INIT(actions_mem_size, ACTIONS_MEM_SIZE(nb_queues, num_of_entries));
528  if (result != DOCA_SUCCESS) {
529  DOCA_LOG_ERR("Failed to init DOCA ports: %s", doca_error_get_descr(result));
531  return result;
532  }
533 
534  for (port_id = 0; port_id < nb_ports; port_id++) {
535  memset(&status, 0, sizeof(status));
536  result = create_rss_udp_ip_pipe(ports[port_id], &pipe);
537  if (result != DOCA_SUCCESS) {
538  DOCA_LOG_ERR("Failed to create pipe: %s", doca_error_get_descr(result));
541  return result;
542  }
543 
544  result = add_rss_rss_udp_ip_pipe_entry(pipe, &status);
545  if (result != DOCA_SUCCESS) {
546  DOCA_LOG_ERR("Failed to add entry: %s", doca_error_get_descr(result));
549  return result;
550  }
551  miss_pipe = pipe;
552 
553  result = create_rss_tcp_ip_pipe(ports[port_id], miss_pipe, &pipe);
554  if (result != DOCA_SUCCESS) {
555  DOCA_LOG_ERR("Failed to create pipe: %s", doca_error_get_descr(result));
558  return result;
559  }
560 
561  result = add_rss_tcp_ip_pipe_entry(pipe, &status);
562  if (result != DOCA_SUCCESS) {
563  DOCA_LOG_ERR("Failed to add entry: %s", doca_error_get_descr(result));
566  return result;
567  }
568 
569  result = create_loopback_pipe(ports[port_id], port_id, &pipe);
570  if (result != DOCA_SUCCESS) {
571  DOCA_LOG_ERR("Failed to create pipe: %s", doca_error_get_descr(result));
574  return result;
575  }
576 
577  result = add_loopback_pipe_entry(pipe, &status, mac_addresses[port_id]);
578  if (result != DOCA_SUCCESS) {
579  DOCA_LOG_ERR("Failed to add entry: %s", doca_error_get_descr(result));
582  return result;
583  }
584 
585  result = doca_flow_entries_process(ports[port_id], 0, DEFAULT_TIMEOUT_US, num_of_entries);
586  if (result != DOCA_SUCCESS) {
587  DOCA_LOG_ERR("Failed to process entries: %s", doca_error_get_descr(result));
590  return result;
591  }
592 
593  if (status.nb_processed != num_of_entries || status.failure) {
594  DOCA_LOG_ERR("Failed to process entries");
597  return DOCA_ERROR_BAD_STATE;
598  }
599  }
600 
601  signal(SIGINT, signal_handler);
602  signal(SIGTERM, signal_handler);
603 
604  DOCA_LOG_INFO("Wait for packets to arrive");
605  while (!force_quit) {
606  for (port_id = 0; port_id < nb_ports; port_id++)
607  process_packets(port_id);
608  }
609 
612  return result;
613 }
#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 SET_MAC_ADDR(addr, a, b, c, d, e, f)
Definition: flow_common.h:60
static doca_error_t destroy_pipe_cfg(struct doca_flow_pipe_cfg *cfg)
static doca_error_t create_loopback_pipe(struct doca_flow_port *port, uint16_t port_id, struct doca_flow_pipe **pipe)
static void process_packets(int ingress_port)
#define PACKET_BURST
static int populate_macs(const int nb_ports, uint8_t mac_addresses[2][6])
static doca_error_t create_rss_tcp_ip_pipe(struct doca_flow_port *port, struct doca_flow_pipe *miss_pipe, struct doca_flow_pipe **pipe)
static bool force_quit
static doca_error_t add_rss_rss_udp_ip_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status)
static doca_error_t create_rss_udp_ip_pipe(struct doca_flow_port *port, struct doca_flow_pipe **pipe)
DOCA_LOG_REGISTER(FLOW_LOOPBACK)
static doca_error_t add_rss_tcp_ip_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status)
static void signal_handler(int signum)
static doca_error_t add_loopback_pipe_entry(struct doca_flow_pipe *pipe, struct entries_status *status, uint8_t dst_mac[6])
doca_error_t flow_loopback(int nb_queues, uint8_t mac_addresses[2][6])
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
#define BE_IPV4_ADDR(a, b, c, d)
Definition: flow_parser.c:64
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
#define DOCA_HTOBE32(_x)
DOCA_STABLE doca_error_t doca_devinfo_create_list(struct doca_devinfo ***dev_list, uint32_t *nb_devs)
Creates list of all available local devices.
DOCA_STABLE doca_error_t doca_devinfo_destroy_list(struct doca_devinfo **dev_list)
Destroy list of local device info structures.
DOCA_STABLE doca_error_t doca_devinfo_get_mac_addr(const struct doca_devinfo *devinfo, uint8_t *mac_addr, uint32_t size)
Get the MAC address of a DOCA devinfo.
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_ERROR_BAD_STATE
Definition: doca_error.h:56
@ DOCA_SUCCESS
Definition: doca_error.h:38
#define DOCA_FLOW_VXLAN_DEFAULT_PORT
Definition: doca_flow_net.h:49
@ DOCA_FLOW_L4_TYPE_EXT_TCP
@ DOCA_FLOW_L4_TYPE_EXT_UDP
@ DOCA_FLOW_L3_TYPE_IP4
@ DOCA_FLOW_TUN_VXLAN
DOCA_STABLE doca_error_t doca_flow_pipe_cfg_destroy(struct doca_flow_pipe_cfg *cfg)
Destroy DOCA Flow pipe configuration struct.
DOCA_STABLE doca_error_t doca_flow_pipe_cfg_create(struct doca_flow_pipe_cfg **cfg, struct doca_flow_port *port)
Create DOCA Flow pipe configuration struct.
DOCA_STABLE doca_error_t doca_flow_entries_process(struct doca_flow_port *port, uint16_t pipe_queue, uint64_t timeout, uint32_t max_processed_entries)
Process entries in queue.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_cfg_set_match(struct doca_flow_pipe_cfg *cfg, const struct doca_flow_match *match, const struct doca_flow_match *match_mask)
Set pipe's match and match mask.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_create(const struct doca_flow_pipe_cfg *cfg, const struct doca_flow_fwd *fwd, const struct doca_flow_fwd *fwd_miss, struct doca_flow_pipe **pipe)
Create one new pipe.
DOCA_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_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_domain(struct doca_flow_pipe_cfg *cfg, enum doca_flow_pipe_domain domain)
Set pipe's domain.
@ 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_BASIC
Definition: doca_flow.h:221
@ DOCA_FLOW_L3_META_IPV4
Definition: doca_flow.h:296
@ 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_DROP
Definition: doca_flow.h:748
@ DOCA_FLOW_FWD_RSS
Definition: doca_flow.h:742
@ DOCA_FLOW_L4_META_TCP
Definition: doca_flow.h:308
@ DOCA_FLOW_PIPE_DOMAIN_EGRESS
Definition: doca_flow.h:245
#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
uint16_t doca_be16_t
Declare DOCA endianity types.
Definition: doca_types.h:120
uint16_t src_port
Definition: packets.h:0
uint16_t dst_port
Definition: packets.h:1
doca_error_t stop_doca_flow_ports(int nb_ports, struct doca_flow_port *ports[])
Definition: flow_common.c:240
doca_error_t init_doca_flow_ports(int nb_ports, struct doca_flow_port *ports[], bool is_hairpin, struct doca_dev *dev_arr[], uint32_t actions_mem_size[])
Definition: flow_common.c:296
doca_error_t set_flow_pipe_cfg(struct doca_flow_pipe_cfg *cfg, const char *name, enum doca_flow_pipe_type type, bool is_root)
Definition: flow_common.c:305
#define NB_ACTIONS_ARR
Definition: flow_common.h:58
#define SHARED_RESOURCE_NUM_VALUES
Definition: flow_common.h:59
#define ACTIONS_MEM_SIZE(nr_queues, entries)
Definition: flow_common.h:66
#define ARRAY_INIT(array, val)
Definition: flow_common.h:71
doca flow actions information
Definition: doca_flow.h:684
struct doca_flow_resource_encap_cfg encap_cfg
Definition: doca_flow.h:710
enum doca_flow_resource_type encap_type
Definition: doca_flow.h:707
struct doca_flow_meta meta
Definition: doca_flow.h:699
struct doca_flow_tun tun
Definition: doca_flow.h:569
struct doca_flow_header_format outer
Definition: doca_flow.h:567
forwarding configuration
Definition: doca_flow.h:779
struct doca_flow_pipe * next_pipe
Definition: doca_flow.h:800
uint16_t port_id
Definition: doca_flow.h:795
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
uint8_t dst_mac[DOCA_FLOW_ETHER_ADDR_LEN]
uint8_t src_mac[DOCA_FLOW_ETHER_ADDR_LEN]
struct doca_flow_header_ip4 ip4
Definition: doca_flow.h:449
enum doca_flow_l4_type_ext l4_type_ext
Definition: doca_flow.h:454
struct doca_flow_header_eth eth
Definition: doca_flow.h:440
struct doca_flow_header_udp udp
Definition: doca_flow.h:459
enum doca_flow_l3_type l3_type
Definition: doca_flow.h:446
struct doca_flow_header_tcp tcp
Definition: doca_flow.h:461
struct doca_flow_header_l4_port l4_port
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_be32_t pkt_meta
Definition: doca_flow.h:359
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
struct doca_flow_encap_action encap
Definition: doca_flow.h:663
enum doca_flow_tun_type type
doca_be32_t vxlan_tun_id
user context struct that will be used in entries process callback
Definition: flow_common.h:78
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