NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
psp_gw_params.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024-2025 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 <ctype.h>
27 #include <net/if.h>
28 #include <sys/ioctl.h>
29 
30 #include <fstream>
31 #include <functional>
32 #include <sstream>
33 
34 #include <json-c/json.h>
35 
36 #include <rte_hash_crc.h>
37 
38 #include <doca_argp.h>
39 #include <doca_dev.h>
40 #include <doca_log.h>
41 
42 #include <psp_gw_config.h>
43 #include <psp_gw_params.h>
44 #include <psp_gw_utils.h>
45 
46 DOCA_LOG_REGISTER(PSP_Gateway_Params);
47 
48 doca_flow_ip_addr interface_vf_addr; /* The VF's interface IPv4 address extracted via "--vf-name" param */
49 
50 /* JSON parsing callback */
51 using psp_parse_json_object_cb = std::function<doca_error_t(json_object *, psp_gw_app_config *, std::vector<void *> &)>;
52 
53 /* JSON handler struct */
55  const std::string key; /* JSON key */
56  psp_parse_json_object_cb parser_cb; /* JSON parsing callback */
57  bool required; /* Is the field required? */
58  bool found; /* Has the field been found - internal use */
59  std::vector<void *> params; /* Additional parameters to pass to the callback */
60  /* Constructor */
61  psp_json_field_handler(const std::string &key,
63  bool required,
64  std::vector<void *> params = {})
65  : key(key),
68  found(false),
69  params(std::move(params))
70  {
71  }
72 };
73 
74 /* JSON handler vector */
75 using psp_json_field_handlers = std::vector<psp_json_field_handler>;
76 
77 /*
78  * Create Hash table for IPv6 addresses
79  *
80  * @app_config [in/out]: application configuration struct
81  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
82  */
84 {
85  struct rte_hash_parameters table_params = {0};
86 
87  table_params.name = "IPv6 table";
88  table_params.entries = app_config->max_tunnels;
89  table_params.key_len = sizeof(uint32_t) * 4;
90  table_params.hash_func = rte_hash_crc;
91  table_params.hash_func_init_val = 0;
92 
93  app_config->ip6_table = rte_hash_create(&table_params);
94  if (app_config->ip6_table == NULL)
95  return DOCA_ERROR_DRIVER;
96 
97  return DOCA_SUCCESS;
98 }
99 
107 static doca_error_t handle_pci_addr_param(void *param, void *config)
108 {
109  auto *app_config = (struct psp_gw_app_config *)config;
110  const char *pci_addr = (const char *)param;
111 
112  int pci_addr_len = strlen(pci_addr);
113  if (pci_addr_len + 1 != DOCA_DEVINFO_PCI_ADDR_SIZE && pci_addr_len + 1 != DOCA_DEVINFO_PCI_BDF_SIZE) {
114  DOCA_LOG_ERR("Expected PCI addr in DDDD:BB:DD.F or BB:DD.F formats, instead received: %s", pci_addr);
116  }
117 
118  app_config->pf_pcie_addr = pci_addr;
119  for (char &c : app_config->pf_pcie_addr) {
120  c = tolower(c);
121  }
122 
123  DOCA_LOG_INFO("Using %s for PF PCIe Addr", app_config->pf_pcie_addr.c_str());
124  return DOCA_SUCCESS;
125 }
126 
134 static doca_error_t handle_repr_param(void *param, void *config)
135 {
136  auto *app_config = (struct psp_gw_app_config *)config;
137 
138  app_config->pf_repr_indices = (char *)param;
139 
140  DOCA_LOG_INFO("Device representor list: %s", app_config->pf_repr_indices.c_str());
141  return DOCA_SUCCESS;
142 }
143 
151 static doca_error_t handle_core_mask_param(void *param, void *config)
152 {
153  auto *app_config = (struct psp_gw_app_config *)config;
154 
155  app_config->core_mask = (char *)param;
156 
157  DOCA_LOG_INFO("RTE EAL core-mask: %s", app_config->core_mask.c_str());
158  return DOCA_SUCCESS;
159 }
160 
168 static doca_error_t handle_decap_dmac_param(void *param, void *config)
169 {
170  auto *app_config = (struct psp_gw_app_config *)config;
171  char *mac_addr = (char *)param;
172 
173  if (!is_empty_mac_addr(app_config->dcap_dmac)) {
174  DOCA_LOG_ERR("Cannot specify both --decap-dmac and --vf-name");
176  }
177 
178  if (rte_ether_unformat_addr(mac_addr, &app_config->dcap_dmac) != 0) {
179  DOCA_LOG_ERR("Malformed MAC addr: %s", mac_addr);
181  }
182 
183  DOCA_LOG_INFO("Decap dmac: %s", mac_addr);
184  return DOCA_SUCCESS;
185 }
186 
194 static doca_error_t handle_nexthop_dmac_param(void *param, void *config)
195 {
196  auto *app_config = (struct psp_gw_app_config *)config;
197  char *mac_addr = (char *)param;
198 
199  if (rte_ether_unformat_addr(mac_addr, &app_config->nexthop_dmac) != 0) {
200  DOCA_LOG_ERR("Malformed MAC addr: %s", mac_addr);
202  }
203 
204  app_config->nexthop_enable = true;
205 
206  DOCA_LOG_INFO("Next-Hop dmac: %s", mac_addr);
207  return DOCA_SUCCESS;
208 }
209 
217 static doca_error_t parse_subnet_mask(std::string &ip, uint32_t &mask_len)
218 {
219  mask_len = 32;
220  size_t slash = ip.find('/');
221  if (slash == std::string::npos) {
222  return DOCA_SUCCESS;
223  }
224 
225  std::string mask_len_str = ip.substr(slash + 1);
226  mask_len = std::atoi(mask_len_str.c_str());
227 
228  if (mask_len == 0 || mask_len > 32) {
229  DOCA_LOG_ERR("Invalid IP addr mask string found: %s", ip.c_str());
231  }
232 
233  ip = ip.substr(0, slash);
234 
235  if (mask_len < 32) {
236  // adjust the IP address to zero out the unmasked bits;
237  // i.e. 1.2.3.4/24 -> 1.2.3.0
238  doca_flow_ip_addr ip_parsed;
239  if (parse_ip_addr(ip, DOCA_FLOW_L3_TYPE_IP4, &ip_parsed) != DOCA_SUCCESS) {
240  DOCA_LOG_ERR("Failed to parse IP addr: %s", ip.c_str());
242  }
243 
244  uint32_t ip_native = RTE_BE32(ip_parsed.ipv4_addr);
245  uint32_t mask = (1 << (32 - mask_len)) - 1;
246  ip_native &= ~mask;
247  ip = ipv4_to_string(RTE_BE32(ip_native));
248  }
249 
250  return DOCA_SUCCESS;
251 }
252 
260 static doca_error_t handle_vc_param(void *param, void *config)
261 {
262  auto *app_config = (struct psp_gw_app_config *)config;
263  bool *bool_param = (bool *)param;
264  app_config->net_config.vc_enabled = *bool_param;
265  DOCA_LOG_INFO("PSP VCs %s", *bool_param ? "Enabled" : "Disabled");
266  return DOCA_SUCCESS;
267 }
268 
276 static doca_error_t handle_ingress_acl_param(void *param, void *config)
277 {
278  auto *app_config = (struct psp_gw_app_config *)config;
279  bool *bool_param = (bool *)param;
280  app_config->disable_ingress_acl = *bool_param;
281  DOCA_LOG_INFO("Ingress ACLs %s", *bool_param ? "Disabled" : "Enabled");
282  return DOCA_SUCCESS;
283 }
284 
292 static doca_error_t handle_sample_param(void *param, void *config)
293 {
294  auto *app_config = (struct psp_gw_app_config *)config;
295  int32_t *int_param = (int32_t *)param;
296  app_config->log2_sample_rate = (uint16_t)*int_param;
297  DOCA_LOG_INFO("The log2_sample_rate is set to %d", app_config->log2_sample_rate);
298  return DOCA_SUCCESS;
299 }
300 
308 static doca_error_t handle_static_tunnels_param(void *param, void *config)
309 {
310  auto *app_config = (struct psp_gw_app_config *)config;
311  app_config->create_tunnels_at_startup = (bool *)param;
312 
313  DOCA_LOG_INFO("Create PSP tunnels at startup: %s",
314  app_config->create_tunnels_at_startup ? "Enabled" : "Disabled");
315 
316  return DOCA_SUCCESS;
317 }
318 
326 static doca_error_t handle_max_tunnels_param(void *param, void *config)
327 {
328  auto *app_config = (struct psp_gw_app_config *)config;
329  int *int_param = (int *)param;
330  if (*int_param < 1) {
331  DOCA_LOG_ERR(
332  "The maximal number of tunnel (max-tunnels) must be greater than zero, instead received: %d",
333  *int_param);
335  }
336 
337  app_config->max_tunnels = *int_param;
338  DOCA_LOG_INFO("Configured max-tunnels = %d", app_config->max_tunnels);
339 
340  return DOCA_SUCCESS;
341 }
342 
353 static doca_error_t handle_psp_crypt_offset_param(void *param, void *config)
354 {
355  auto *app_config = (struct psp_gw_app_config *)config;
356  int *int_param = (int *)param;
357  if (*int_param < 0 || 0x3f < *int_param) {
358  DOCA_LOG_ERR("PSP crypt-offset must be a 6-bit non-negative integer, instead received: %d", *int_param);
360  }
361 
362  app_config->net_config.crypt_offset = *int_param;
363  DOCA_LOG_INFO("Configured PSP crypt_offset = %d", app_config->net_config.crypt_offset);
364 
365  return DOCA_SUCCESS;
366 }
367 
375 static doca_error_t handle_psp_version_param(void *param, void *config)
376 {
377  auto *app_config = (struct psp_gw_app_config *)config;
378  int *int_param = (int *)param;
379  if (!SUPPORTED_PSP_VERSIONS.count(*int_param)) {
380  DOCA_LOG_ERR("Unsupported PSP version: %d", *int_param);
382  }
383 
384  app_config->net_config.default_psp_proto_ver = *int_param;
385  DOCA_LOG_INFO("Configured PSP version = %d", app_config->net_config.default_psp_proto_ver);
386 
387  return DOCA_SUCCESS;
388 }
389 
397 static doca_error_t handle_debug_keys_param(void *param, void *config)
398 {
399  auto *app_config = (struct psp_gw_app_config *)config;
400  bool *bool_param = (bool *)param;
401  app_config->debug_keys = *bool_param;
402  if (*bool_param) {
403  DOCA_LOG_INFO("NOTE: debug_keys is enabled; crypto keys will be written to logs.");
404  }
405  return DOCA_SUCCESS;
406 }
407 
417 static doca_error_t handle_vf_name_param(void *param, void *config)
418 {
419  auto *app_config = (struct psp_gw_app_config *)config;
420  std::string vf_iface_name = (const char *)param;
421 
422  if (!is_empty_mac_addr(app_config->dcap_dmac)) {
423  DOCA_LOG_ERR("Cannot specify both --vf-name and --decap-dmac");
425  }
426 
427  if (app_config->inner == DOCA_FLOW_L3_TYPE_IP6) {
428  DOCA_LOG_ERR("Cannot specify both --vf-name and --inner ipv6");
430  }
431 
432  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
433  if (sockfd < 0) {
434  DOCA_LOG_ERR("Failed to open socket");
435  return DOCA_ERROR_IO_FAILED;
436  }
437 
438  struct ifreq ifr = {};
439  strncpy(ifr.ifr_name, vf_iface_name.c_str(), IFNAMSIZ - 1);
440 
441  if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) {
442  DOCA_LOG_ERR("Failed ioctl(sockfd, SIOCGIFADDR, &ifr)");
443  close(sockfd);
444  return DOCA_ERROR_IO_FAILED;
445  }
446 
447  rte_be32_t vf_ip_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
449  interface_vf_addr.ipv4_addr = vf_ip_addr;
450 
451  if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
452  DOCA_LOG_ERR("Failed ioctl(sockfd, SIOCGIFHWADDR, &ifr)");
453  close(sockfd);
454  return DOCA_ERROR_IO_FAILED;
455  }
456 
457  app_config->dcap_dmac = *(rte_ether_addr *)ifr.ifr_hwaddr.sa_data;
458  close(sockfd);
459 
460  DOCA_LOG_INFO("For VF device %s, detected IP addr %s, MAC addr %s",
461  vf_iface_name.c_str(),
463  mac_to_string(app_config->dcap_dmac).c_str());
464 
465  return DOCA_SUCCESS;
466 }
467 
475 static doca_error_t handle_stats_print_param(void *param, void *config)
476 {
477  auto *app_config = (struct psp_gw_app_config *)config;
478  bool *bool_param = (bool *)param;
479  app_config->print_stats = *bool_param;
480  DOCA_LOG_INFO("Stats %s", *bool_param ? "Enabled" : "Disabled");
481  return DOCA_SUCCESS;
482 }
483 
489 static void get_supported_perf_types(std::string &supported_types)
490 {
491  bool first = true;
492  for (const auto &type : PSP_PERF_MAP) {
493  supported_types += (first ? "" : ", ") + type.first;
494  first = false;
495  }
496 }
497 
505 static doca_error_t handle_perf_print_param(void *param, void *config)
506 {
507  auto *app_config = (struct psp_gw_app_config *)config;
508 
509  std::string perf_types = (const char *)param;
510  std::istringstream perf_types_stream(perf_types);
511  for (std::string perf_type; std::getline(perf_types_stream, perf_type, ',');) {
512  if (PSP_PERF_MAP.count(perf_type) == 0) {
513  std::string supported_types;
514  get_supported_perf_types(supported_types);
515  DOCA_LOG_ERR("Unsupported perf type: %s, supported types are: %s",
516  perf_type.c_str(),
517  supported_types.c_str());
519  }
520  app_config->print_perf_flags |= PSP_PERF_MAP.at(perf_type);
521  }
522  DOCA_LOG_INFO("Enabled perf print for %s", perf_types.c_str());
523  return DOCA_SUCCESS;
524 }
525 
533 static doca_error_t handle_show_rss_rx_packets_param(void *param, void *config)
534 {
535  auto *app_config = (struct psp_gw_app_config *)config;
536  bool *bool_param = (bool *)param;
537  app_config->show_rss_rx_packets = *bool_param;
538  if (*bool_param) {
540  "NOTE: show_rss_rx_packets is enabled; rx packets received to RSS will be written to logs");
541  }
542  return DOCA_SUCCESS;
543 }
544 
552 static doca_error_t handle_maintain_order_param(void *param, void *config)
553 {
554  auto *app_config = (struct psp_gw_app_config *)config;
555  bool *bool_param = (bool *)param;
556  app_config->maintain_order = *bool_param;
557  if (*bool_param) {
558  DOCA_LOG_INFO("The original order of the packets will be maintained");
559  }
560  return DOCA_SUCCESS;
561 }
562 
570 static doca_error_t handle_outer_param(void *param, void *config)
571 {
572  auto *app_config = (struct psp_gw_app_config *)config;
573  std::string outer_type = (const char *)param;
574 
575  if (outer_type == "ipv4") {
577  } else if (outer_type == "ipv6") {
579  } else {
580  DOCA_LOG_ERR("Unsupported outer type: %s, supported types are: ipv4, ipv6", outer_type.c_str());
582  }
583 
584  DOCA_LOG_INFO("Outer type: %s", outer_type.c_str());
585  return DOCA_SUCCESS;
586 }
587 
595 static doca_error_t handle_inner_param(void *param, void *config)
596 {
597  auto *app_config = (struct psp_gw_app_config *)config;
598  std::string inner_type = (const char *)param;
599 
600  if (inner_type == "ipv4") {
602  } else if (inner_type == "ipv6") {
604  DOCA_LOG_ERR("Cannot specify both --inner ipv6 and --vf-name");
606  }
608  } else {
609  DOCA_LOG_ERR("Unsupported inner type: %s, supported types are: ipv4, ipv6", inner_type.c_str());
611  }
612 
613  DOCA_LOG_INFO("Inner type: %s", inner_type.c_str());
614  return DOCA_SUCCESS;
615 }
616 
624 static doca_error_t handle_mode_param(void *param, void *config)
625 {
626  auto *app_config = (struct psp_gw_app_config *)config;
627  std::string mode = (const char *)param;
628 
629  if (mode == "tunnel") {
631  } else if (mode == "transport") {
633  } else {
634  DOCA_LOG_ERR("Unsupported mode: %s, supported modes are: tunnel, transport", mode.c_str());
636  }
637 
638  DOCA_LOG_INFO("Mode: %s", mode.c_str());
639  return DOCA_SUCCESS;
640 }
641 
649 static doca_error_t handle_config_file_param(void *param, void *config)
650 {
651  auto *app_config = (struct psp_gw_app_config *)config;
652  std::string json_path = (char *)param;
653 
654  if (json_path.length() >= MAX_FILE_NAME) {
655  DOCA_LOG_ERR("JSON file name is too long - MAX=%d", MAX_FILE_NAME - 1);
657  }
658  if (access(json_path.c_str(), F_OK) == -1) {
659  DOCA_LOG_ERR("JSON file was not found: %s", json_path.c_str());
660  return DOCA_ERROR_NOT_FOUND;
661  }
662  app_config->json_path = json_path;
663  DOCA_LOG_INFO("Using JSON file: %s", app_config->json_path.c_str());
664  return DOCA_SUCCESS;
665 }
666 
667 /* --------------------- JSON Parsing --------------------- */
668 
676 static doca_error_t json_object_ver_get_string(json_object *json_obj, std::string &value)
677 {
678  if (!json_object_is_type(json_obj, json_type_string)) {
679  DOCA_LOG_ERR("Invalid JSON object type: %d, expected string", json_object_get_type(json_obj));
681  }
682  value = json_object_get_string(json_obj);
683  return DOCA_SUCCESS;
684 }
685 
695 static doca_error_t json_object_ver_array_length(json_object *json_obj, int &length)
696 {
697  if (!json_object_is_type(json_obj, json_type_array)) {
698  DOCA_LOG_ERR("Invalid JSON object type: %d, expected array", json_object_get_type(json_obj));
700  }
701  length = json_object_array_length(json_obj);
702  return DOCA_SUCCESS;
703 }
704 
714  json_object *json_obj,
716 {
718 
719  /* verify object is a JSON object */
720  if (!json_object_is_type(json_obj, json_type_object)) {
721  DOCA_LOG_ERR("Invalid JSON object type: %d, expected object", json_object_get_type(json_obj));
723  }
724 
725  /* Note that json parser will randomly erase duplicate keys, so this is up to the user to ensure */
726  json_object_object_foreach(json_obj, key, val)
727  {
728  bool found = false;
729  for (auto &handler : handlers) {
730  if (strcmp(key, handler.key.c_str()) == 0) {
731  result = handler.parser_cb(val, app_config, handler.params);
732  if (result != DOCA_SUCCESS) {
733  return result;
734  }
735  found = true;
736  handler.found = true;
737  break;
738  }
739  }
740  if (!found) {
741  DOCA_LOG_ERR("Invalid key in JSON file: %s", key);
743  }
744  }
745 
746  /* verify all required keys were found */
747  for (auto &handler : handlers) {
748  if (handler.required && !handler.found) {
749  DOCA_LOG_ERR("Missing required key in JSON file: %s", handler.key.c_str());
751  }
752  }
753 
754  return DOCA_SUCCESS;
755 }
756 
765 static doca_error_t parse_local_grpc_address(json_object *json_obj_local_addr,
767  std::vector<void *> &params)
768 {
769  (void)params;
770  doca_error_t result = json_object_ver_get_string(json_obj_local_addr, app_config->local_svc_addr);
771  if (result != DOCA_SUCCESS) {
772  DOCA_LOG_ERR("Invalid local-grpc-address, expected string");
773  return result;
774  }
775  std::string server = app_config->local_svc_addr;
776 
777  /* verify legal format: address:port or address*/
778  size_t sep = app_config->local_svc_addr.find(':');
779  if (sep != 0 && sep != std::string::npos) {
780  std::string port = server.substr(sep + 1);
781  server = server.substr(0, sep);
782  if (port.empty()) {
783  DOCA_LOG_ERR("Invalid port in local-grpc-address: %s", server.c_str());
785  }
786  if (port.find_first_not_of("0123456789") != std::string::npos) {
787  DOCA_LOG_ERR("Invalid port in local-grpc-address: %s", port.c_str());
789  }
790  int port_num = std::stoi(port);
791  if (port_num < 0 || 65535 < port_num) {
792  DOCA_LOG_ERR("Invalid port in local-grpc-address: %s", port.c_str());
794  }
795  }
796 
797  DOCA_LOG_DBG("Local gRPC address: %s", app_config->local_svc_addr.c_str());
798 
799  return DOCA_SUCCESS;
800 }
801 
810 static doca_error_t parse_json_config(json_object *json_obj_config,
812  std::vector<void *> &params)
813 {
814  (void)params;
815  psp_json_field_handlers handlers = {
816  {"local-grpc-address", parse_local_grpc_address, false},
817  };
818  doca_error_t result = handle_json_level_fields(handlers, json_obj_config, app_config);
819  if (result != DOCA_SUCCESS) {
820  DOCA_LOG_ERR("Failed to parse JSON config");
821  return result;
822  }
823 
824  return DOCA_SUCCESS;
825 }
826 
835 static doca_error_t parse_remote_grpc_address(json_object *json_obj_remote_addr,
837  std::vector<void *> &params)
838 {
839  (void)app_config;
840  struct psp_gw_peer *peer = (struct psp_gw_peer *)params[0];
841 
842  doca_error_t result = json_object_ver_get_string(json_obj_remote_addr, peer->svc_addr);
843  if (result != DOCA_SUCCESS) {
844  DOCA_LOG_ERR("Invalid remote-grpc-address, expected string");
845  return result;
846  }
847 
848  DOCA_LOG_DBG("Remote gRPC address: %s", peer->svc_addr.c_str());
849 
850  return DOCA_SUCCESS;
851 }
852 
861 static doca_error_t parse_local_vip(json_object *json_obj_local_vip,
863  std::vector<void *> &params)
864 {
865  doca_flow_ip_addr *local_vip = (doca_flow_ip_addr *)params[0];
866  std::string local_vip_str;
867  doca_error_t result = json_object_ver_get_string(json_obj_local_vip, local_vip_str);
868  if (result != DOCA_SUCCESS) {
869  DOCA_LOG_ERR("Invalid local-vip, expected string");
870  return result;
871  }
872 
873  if (parse_ip_addr(local_vip_str, app_config->inner, local_vip) != DOCA_SUCCESS) {
874  DOCA_LOG_ERR("Invalid local VIP addr: %s", local_vip_str.c_str());
876  }
877  DOCA_LOG_DBG("Local VIP: %s", local_vip_str.c_str());
878 
879  return DOCA_SUCCESS;
880 }
881 
890 static doca_error_t parse_remote_vips(json_object *json_obj_remote_vips,
892  std::vector<void *> &params)
893 {
894  (void)app_config;
895 
896  std::vector<ip_pair> *vip_pairs = (std::vector<ip_pair> *)params[0];
897  doca_flow_ip_addr *local_vip = (doca_flow_ip_addr *)params[1];
898  if (local_vip->type == DOCA_FLOW_L3_TYPE_NONE) {
899  DOCA_LOG_ERR("Local VIP not set - must specify 'local-vip' or '--vf-name'");
901  }
902  int nb_remote_vips;
903  uint32_t n_peers;
904  doca_error_t result = json_object_ver_array_length(json_obj_remote_vips, nb_remote_vips);
905  if (result != DOCA_SUCCESS) {
906  DOCA_LOG_ERR("Invalid remote-vips, expected array");
907  return result;
908  }
909  if (nb_remote_vips == 0) {
910  DOCA_LOG_ERR("No remote vips found in JSON file");
912  }
913 
914  for (int i = 0; i < nb_remote_vips; i++) {
915  json_object *json_obj_vip = json_object_array_get_idx(json_obj_remote_vips, i);
916  std::string vip_str;
917  doca_error_t result = json_object_ver_get_string(json_obj_vip, vip_str);
918  if (result != DOCA_SUCCESS) {
919  DOCA_LOG_ERR("Invalid remote-vip, expected string");
920  return result;
921  }
922 
923  uint32_t mask_len = 0;
924  doca_flow_ip_addr remote_vip;
925  if (app_config->inner == DOCA_FLOW_L3_TYPE_IP4) {
926  result = parse_subnet_mask(vip_str, mask_len);
927  if (result != DOCA_SUCCESS) {
928  return result;
929  }
930  if (mask_len < 16) {
931  DOCA_LOG_ERR("Remote VIP subnet mask length < 16 not supported; found %d", mask_len);
933  }
934  }
935  if (parse_ip_addr(vip_str, app_config->inner, &remote_vip) != DOCA_SUCCESS) {
936  DOCA_LOG_ERR("Invalid remote VIP addr: %s", vip_str.c_str());
938  }
939 
940  if (remote_vip.type == DOCA_FLOW_L3_TYPE_IP6) {
941  int ret = rte_hash_lookup(app_config->ip6_table, (void *)remote_vip.ipv6_addr);
942  if (ret < 0) {
943  ret = rte_hash_add_key(app_config->ip6_table, remote_vip.ipv6_addr);
944  if (ret < 0) {
945  DOCA_LOG_ERR("Failed to add address to hash table");
946  return DOCA_ERROR_DRIVER;
947  }
948  }
949  }
950 
951  if (mask_len != 0)
952  n_peers = 1 << (32 - mask_len); // note mask_len is between 16 and 32
953  else
954  n_peers = 1;
955  for (uint32_t i = 0; i < n_peers; i++) {
956  std::string peer_virt_ip;
957  if (i < 16) {
958  peer_virt_ip = ip_to_string(remote_vip);
959  DOCA_LOG_DBG("Added remote vip %d: %s", (int)vip_pairs->size(), peer_virt_ip.c_str());
960  } else if (i == 16) {
961  DOCA_LOG_DBG("And more peers... (%d)", n_peers);
962  } // else, silent
963 
964  // check if the vip pair does not already exist in app_config->net_config.peers
965  struct ip_pair vip_pair = {*local_vip, remote_vip};
966  auto peer = lookup_vip_pair(&app_config->net_config.peers, vip_pair);
967  if (peer != nullptr) {
968  std::string local_vip_str = ip_to_string(*local_vip);
969  DOCA_LOG_ERR("Duplicate VIP pair found in JSON file: (%s -> %s)",
970  local_vip_str.c_str(),
971  peer_virt_ip.c_str());
973  }
974  vip_pairs->push_back(vip_pair);
975  remote_vip.ipv4_addr = RTE_BE32(RTE_BE32(remote_vip.ipv4_addr) + 1); // Increment only ipv4
976  // case, for ipv6 always
977  // n_peers
978  // == 1
979  }
980  }
981 
982  return DOCA_SUCCESS;
983 }
984 
993 static doca_error_t parse_sessions(json_object *json_obj_sessions,
995  std::vector<void *> &params)
996 {
997  struct psp_gw_peer *peer = (struct psp_gw_peer *)params[0];
998  int nb_sessions;
999  doca_error_t result = json_object_ver_array_length(json_obj_sessions, nb_sessions);
1000  if (result != DOCA_SUCCESS) {
1001  DOCA_LOG_ERR("Invalid sessions, expected array");
1002  return result;
1003  }
1004  if (nb_sessions == 0) {
1005  DOCA_LOG_ERR("No sessions found in JSON file for peer %s", peer->svc_addr.c_str());
1006  return DOCA_ERROR_INVALID_VALUE;
1007  }
1008 
1009  if ((uint32_t)nb_sessions > PSP_MAX_SESSIONS) {
1010  DOCA_LOG_ERR("Too many sessions in JSON file for peer %s: %d, max allowed: %d",
1011  peer->svc_addr.c_str(),
1012  nb_sessions,
1014  return DOCA_ERROR_INVALID_VALUE;
1015  }
1016 
1017  for (int i = 0; i < nb_sessions; i++) {
1018  DOCA_LOG_DBG("Session %d for peer %s :", i, peer->svc_addr.c_str());
1019 
1020  json_object *json_obj_session = json_object_array_get_idx(json_obj_sessions, i);
1021  doca_flow_ip_addr local_vip_addr = {};
1022  copy_ip_addr(interface_vf_addr, local_vip_addr); // set default
1023 
1024  psp_json_field_handlers handlers = {
1025  {"local-vip", parse_local_vip, false, {(void *)&local_vip_addr}},
1026  {"remote-vips", parse_remote_vips, true, {(void *)&peer->vip_pairs, (void *)&local_vip_addr}},
1027  };
1028 
1029  doca_error_t result = handle_json_level_fields(handlers, json_obj_session, app_config);
1030  if (result != DOCA_SUCCESS) {
1031  return result;
1032  }
1033 
1034  if (peer->vip_pairs.empty()) {
1035  DOCA_LOG_ERR("No remote vips found in JSON file for peer: %s", peer->svc_addr.c_str());
1036  return DOCA_ERROR_INVALID_VALUE;
1037  }
1038  }
1039 
1040  return DOCA_SUCCESS;
1041 }
1042 
1051 static doca_error_t parse_json_peers(json_object *json_obj_peers,
1053  std::vector<void *> &params)
1054 {
1055  (void)params;
1056  int nb_peers;
1057  doca_error_t result = json_object_ver_array_length(json_obj_peers, nb_peers);
1058  if (result != DOCA_SUCCESS) {
1059  DOCA_LOG_ERR("Invalid peers, expected array");
1060  return result;
1061  }
1062 
1063  if (nb_peers == 0) {
1064  DOCA_LOG_WARN("No peers found in JSON file");
1065  return DOCA_SUCCESS;
1066  }
1067 
1068  if ((uint32_t)nb_peers > PSP_MAX_PEERS) {
1069  DOCA_LOG_ERR("Too many peers in JSON file: %d, max allowed: %d", nb_peers, PSP_MAX_PEERS);
1070  return DOCA_ERROR_INVALID_VALUE;
1071  }
1072 
1073  for (int i = 0; i < nb_peers; i++) {
1074  DOCA_LOG_DBG("Peer %d :", i);
1075  json_object *json_obj_peer = json_object_array_get_idx(json_obj_peers, i);
1076  struct psp_gw_peer peer = {};
1077 
1078  psp_json_field_handlers handlers = {
1079  {"remote-grpc-address", parse_remote_grpc_address, true, {(void *)&peer}},
1080  {"sessions", parse_sessions, true, {(void *)&peer}},
1081  };
1082 
1083  doca_error_t result = handle_json_level_fields(handlers, json_obj_peer, app_config);
1084  if (result != DOCA_SUCCESS) {
1085  return result;
1086  }
1087 
1088  app_config->net_config.peers.push_back(peer);
1089  }
1090 
1091  return DOCA_SUCCESS;
1092 }
1093 
1095 {
1097 
1098  std::ifstream in{app_config->json_path};
1099  if (!in.good()) {
1100  DOCA_LOG_ERR("Failed to open JSON file");
1101  return DOCA_ERROR_NOT_FOUND;
1102  }
1103 
1105  if (result != DOCA_SUCCESS)
1106  return result;
1107 
1108  // Read the entire file into a string
1109  std::string json_content((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
1110 
1111  // Close the file
1112  in.close();
1113 
1114  enum json_tokener_error json_err = json_tokener_success;
1115  json_object *parsed_json = json_tokener_parse_verbose(json_content.c_str(), &json_err);
1116  if (parsed_json == nullptr || json_err != json_tokener_success) {
1117  DOCA_LOG_ERR("Failed to parse JSON file(: %s)", json_tokener_error_desc(json_err));
1118  return DOCA_ERROR_INVALID_VALUE;
1119  }
1120 
1121  psp_json_field_handlers handlers = {
1122  {"config", parse_json_config, true},
1123  {"peers", parse_json_peers, true},
1124  };
1125 
1126  result = handle_json_level_fields(handlers, parsed_json, app_config);
1127  if (result != DOCA_SUCCESS) {
1128  DOCA_LOG_ERR("Failed to parse JSON file");
1129  json_object_put(parsed_json);
1130  return result;
1131  }
1132 
1133  if (is_empty_mac_addr(app_config->dcap_dmac)) {
1134  DOCA_LOG_ERR("REQUIRED: One of (--vf-name) or (--decap-dmac) to set the MAC address for decap");
1135  json_object_put(parsed_json);
1136  return DOCA_ERROR_INVALID_VALUE;
1137  }
1138  json_object_put(parsed_json);
1139  DOCA_LOG_DBG("Successfully parsed JSON file");
1140 
1141  return DOCA_SUCCESS;
1142 }
1143 
1156 static doca_error_t psp_gw_register_single_param(const char *short_name,
1157  const char *long_name,
1158  const char *description,
1160  enum doca_argp_type arg_type,
1161  bool required,
1162  bool accept_multiple)
1163 {
1164  struct doca_argp_param *param = NULL;
1166  if (result != DOCA_SUCCESS) {
1167  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
1168  return result;
1169  }
1170  if (short_name)
1171  doca_argp_param_set_short_name(param, short_name);
1172  if (long_name)
1173  doca_argp_param_set_long_name(param, long_name);
1174  if (description)
1176  if (cb)
1177  doca_argp_param_set_callback(param, cb);
1178  if (required)
1180  if (accept_multiple)
1182 
1183  doca_argp_param_set_type(param, arg_type);
1185  if (result != DOCA_SUCCESS) {
1186  DOCA_LOG_ERR("Failed to register program param %s: %s",
1187  long_name ? long_name : short_name,
1189  return result;
1190  }
1191 
1192  return DOCA_SUCCESS;
1193 }
1194 
1201 {
1203 
1205  "pci-addr",
1206  "PCI BDF of the device in BB:DD.F format (required)",
1209  true,
1210  false);
1211  if (result != DOCA_SUCCESS)
1212  return result;
1213 
1215  "repr",
1216  "Device representor list in vf[x-y]pf[x-y] format (required)",
1219  true,
1220  false);
1221  if (result != DOCA_SUCCESS)
1222  return result;
1223 
1225  "core-mask",
1226  "EAL Core Mask",
1229  false,
1230  false);
1231  if (result != DOCA_SUCCESS)
1232  return result;
1233 
1235  "decap-dmac",
1236  "mac_dst addr of the decapped packets",
1239  false,
1240  false);
1241  if (result != DOCA_SUCCESS)
1242  return result;
1243 
1245  "vf-name",
1246  "Name of the virtual function device / unsecured port",
1249  false,
1250  false);
1251  if (result != DOCA_SUCCESS)
1252  return result;
1253 
1255  "nexthop-dmac",
1256  "next-hop mac_dst addr of the encapped packets",
1259  false,
1260  false);
1261  if (result != DOCA_SUCCESS)
1262  return result;
1263 
1265  "cookie",
1266  "Enable use of PSP virtualization cookies",
1269  false,
1270  false);
1271  if (result != DOCA_SUCCESS)
1272  return result;
1273 
1275  "disable-ingress-acl",
1276  "Allows any ingress packet that successfully decrypts",
1279  false,
1280  false);
1281  if (result != DOCA_SUCCESS)
1282  return result;
1283 
1285  "sample-rate",
1286  "Sets the log2 sample rate: 0: disabled, 1: 50%, ... 16: 1.5e-3%",
1289  false,
1290  false);
1291  if (result != DOCA_SUCCESS)
1292  return result;
1293 
1295  "max-tunnels",
1296  "Specify the max number of PSP tunnels",
1299  false,
1300  false);
1301  if (result != DOCA_SUCCESS)
1302  return result;
1303 
1305  "crypt-offset",
1306  "Specify the PSP crypt offset",
1309  false,
1310  false);
1311  if (result != DOCA_SUCCESS)
1312  return result;
1313 
1315  "psp-version",
1316  "Specify the PSP version for outgoing connections (0 or 1)",
1319  false,
1320  false);
1321  if (result != DOCA_SUCCESS)
1322  return result;
1323 
1325  "static-tunnels",
1326  "Create tunnels at startup",
1329  false,
1330  false);
1331  if (result != DOCA_SUCCESS)
1332  return result;
1333 
1335  "debug-keys",
1336  "Enable debug keys",
1339  false,
1340  false);
1341  if (result != DOCA_SUCCESS)
1342  return result;
1343 
1345  "stat-print",
1346  "Enable printing statistics",
1349  false,
1350  false);
1351  if (result != DOCA_SUCCESS)
1352  return result;
1353 
1355  "perf-print",
1356  "Enable printing performance metrics (key-gen, insertion, all)",
1359  false,
1360  false);
1361  if (result != DOCA_SUCCESS)
1362  return result;
1363 
1365  "show-rss-rx-packets",
1366  "Show RSS rx packets",
1369  false,
1370  false);
1371  if (result != DOCA_SUCCESS)
1372  return result;
1373 
1375  "outer-ip-type",
1376  "outer IP type",
1379  false,
1380  false);
1381  if (result != DOCA_SUCCESS)
1382  return result;
1383 
1385  "inner-ip-type",
1386  "inner IP type",
1389  false,
1390  false);
1391  if (result != DOCA_SUCCESS)
1392  return result;
1393 
1395  "config",
1396  "Path to the JSON file with application configuration",
1399  true,
1400  false);
1401  if (result != DOCA_SUCCESS)
1402  return result;
1403 
1405  "maintain-order",
1406  "maintain original packet ordering",
1409  false,
1410  false);
1411  if (result != DOCA_SUCCESS)
1412  return result;
1413 
1415  "mode",
1416  "tunnel or transport mode",
1419  false,
1420  false);
1421 
1422  return result;
1423 }
1424 
1426 {
1428 
1429  // Init ARGP interface and start parsing cmdline/json arguments
1431  if (result != DOCA_SUCCESS) {
1432  DOCA_LOG_ERR("Failed to init ARGP resources: %s", doca_error_get_descr(result));
1433  return result;
1434  }
1435 
1437  if (result != DOCA_SUCCESS) {
1438  DOCA_LOG_ERR("Failed to register ARGP parameters: %s", doca_error_get_descr(result));
1439  return result;
1440  }
1441 
1442  result = doca_argp_start(argc, argv);
1443  if (result != DOCA_SUCCESS) {
1444  DOCA_LOG_ERR("Failed to parse application input: %s", doca_error_get_descr(result));
1446  return result;
1447  }
1448 
1449  return DOCA_SUCCESS;
1450 }
#define NULL
Definition: __stddef_null.h:26
int32_t result
#define MAX_FILE_NAME
DOCA_EXPERIMENTAL void doca_argp_param_set_description(struct doca_argp_param *param, const char *description)
Set the description of the program param, used during program usage.
DOCA_EXPERIMENTAL void doca_argp_param_set_long_name(struct doca_argp_param *param, const char *name)
Set the long name of the program param.
doca_argp_type
Flag input type.
Definition: doca_argp.h:54
DOCA_EXPERIMENTAL doca_error_t doca_argp_start(int argc, char **argv)
Parse incoming arguments (cmd line/json).
DOCA_EXPERIMENTAL doca_error_t doca_argp_init(const char *program_name, void *program_config)
Initialize the parser interface.
doca_error_t(* doca_argp_param_cb_t)(void *, void *)
Flag callback function type.
Definition: doca_argp.h:37
DOCA_EXPERIMENTAL void doca_argp_param_set_callback(struct doca_argp_param *param, doca_argp_param_cb_t callback)
Set the callback function of the program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_mandatory(struct doca_argp_param *param)
Mark the program param as mandatory.
DOCA_EXPERIMENTAL doca_error_t doca_argp_param_create(struct doca_argp_param **param)
Create new program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_type(struct doca_argp_param *param, enum doca_argp_type type)
Set the type of the param arguments.
DOCA_EXPERIMENTAL void doca_argp_param_set_short_name(struct doca_argp_param *param, const char *name)
Set the short name of the program param.
DOCA_EXPERIMENTAL doca_error_t doca_argp_destroy(void)
ARG Parser destroy.
DOCA_EXPERIMENTAL doca_error_t doca_argp_register_param(struct doca_argp_param *input_param)
Register a program flag.
DOCA_EXPERIMENTAL void doca_argp_param_set_multiplicity(struct doca_argp_param *param)
Mark the program param as supporting multiple appearances.
@ DOCA_ARGP_TYPE_STRING
Definition: doca_argp.h:56
@ DOCA_ARGP_TYPE_BOOLEAN
Definition: doca_argp.h:58
@ DOCA_ARGP_TYPE_INT
Definition: doca_argp.h:57
#define DOCA_DEVINFO_PCI_BDF_SIZE
Buffer size to hold PCI BDF format: "XX:XX.X". Including a null terminator.
Definition: doca_dev.h:317
#define DOCA_DEVINFO_PCI_ADDR_SIZE
Buffer size to hold PCI BDF format: "XXXX:XX:XX.X". Including a null terminator.
Definition: doca_dev.h:313
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_ERROR_NOT_FOUND
Definition: doca_error.h:54
@ DOCA_ERROR_IO_FAILED
Definition: doca_error.h:55
@ DOCA_SUCCESS
Definition: doca_error.h:38
@ DOCA_ERROR_DRIVER
Definition: doca_error.h:59
@ DOCA_FLOW_L3_TYPE_IP6
@ DOCA_FLOW_L3_TYPE_IP4
@ DOCA_FLOW_L3_TYPE_NONE
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
#define DOCA_LOG_WARN(format,...)
Generates a WARNING application log message.
Definition: doca_log.h:476
#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
type value
type description
uint8_t type
Definition: packets.h:0
static const uint32_t PSP_MAX_SESSIONS
Definition: psp_gw_config.h:64
static const std::map< std::string, uint16_t > PSP_PERF_MAP
Definition: psp_gw_config.h:71
const std::set< uint32_t > SUPPORTED_PSP_VERSIONS
Definition: psp_gw_config.h:45
static const uint32_t PSP_MAX_PEERS
Definition: psp_gw_config.h:63
@ PSP_GW_MODE_TUNNEL
Definition: psp_gw_config.h:87
@ PSP_GW_MODE_TRANSPORT
Definition: psp_gw_config.h:88
rte_ipv6_hdr ip
Definition: psp_gw_flows.cpp:4
static doca_error_t psp_gw_register_params(void)
Registers command-line arguments to the application.
DOCA_LOG_REGISTER(PSP_Gateway_Params)
doca_flow_ip_addr interface_vf_addr
static doca_error_t handle_nexthop_dmac_param(void *param, void *config)
Configures the next-hop dst-mac to apply on encap.
static void get_supported_perf_types(std::string &supported_types)
Returns supported perf types as a string.
static doca_error_t handle_psp_version_param(void *param, void *config)
Configures the PSP version to use for outgoing connections.
static doca_error_t handle_config_file_param(void *param, void *config)
Configures the JSON config file path.
static doca_error_t handle_sample_param(void *param, void *config)
Configures the sampling rate of packets.
static doca_error_t handle_perf_print_param(void *param, void *config)
Indicates what performance printing should be enabled.
static doca_error_t parse_json_peers(json_object *json_obj_peers, psp_gw_app_config *app_config, std::vector< void * > &params)
Parses the peers.
static doca_error_t handle_mode_param(void *param, void *config)
Handle the mode param.
static doca_error_t handle_debug_keys_param(void *param, void *config)
Indicates the application should log all encryption keys.
static doca_error_t handle_outer_param(void *param, void *config)
Handle outer IP type param.
static doca_error_t handle_json_level_fields(psp_json_field_handlers &handlers, json_object *json_obj, psp_gw_app_config *app_config)
Handles a JSON object with all of its keys.
static doca_error_t parse_subnet_mask(std::string &ip, uint32_t &mask_len)
Parses a host string with optional subnet mask suffix (i.e. /24).
static doca_error_t handle_pci_addr_param(void *param, void *config)
Configures the dst-mac to apply on decap.
static doca_error_t handle_inner_param(void *param, void *config)
Handle inner IP type param.
static doca_error_t parse_json_config(json_object *json_obj_config, psp_gw_app_config *app_config, std::vector< void * > &params)
Parses the remote gRPC address.
static doca_error_t handle_show_rss_rx_packets_param(void *param, void *config)
Indicates the application should log all received packets to RSS.
static doca_error_t handle_vf_name_param(void *param, void *config)
Indicates the name of the netdev used as the unsecured port.
static doca_error_t json_object_ver_array_length(json_object *json_obj, int &length)
Verifies and extracts the array length from the json object.
static doca_error_t handle_maintain_order_param(void *param, void *config)
Indicates if the application should maintain the order of original packets.
static doca_error_t parse_local_grpc_address(json_object *json_obj_local_addr, psp_gw_app_config *app_config, std::vector< void * > &params)
Parse the local gRPC address.
static doca_error_t handle_stats_print_param(void *param, void *config)
Indicates whether statistics should be printed.
static doca_error_t handle_static_tunnels_param(void *param, void *config)
Indicates the application should create all PSP tunnels at startup.
static doca_error_t parse_local_vip(json_object *json_obj_local_vip, psp_gw_app_config *app_config, std::vector< void * > &params)
Parses the local VIP.
static doca_error_t json_object_ver_get_string(json_object *json_obj, std::string &value)
Verifies and extracts the string from the json object.
static doca_error_t parse_remote_vips(json_object *json_obj_remote_vips, psp_gw_app_config *app_config, std::vector< void * > &params)
Parses the remote VIPs.
static doca_error_t handle_core_mask_param(void *param, void *config)
Configures the DPDK eal_init core mask parameter.
static doca_error_t psp_gw_register_single_param(const char *short_name, const char *long_name, const char *description, doca_argp_param_cb_t cb, enum doca_argp_type arg_type, bool required, bool accept_multiple)
Utility function to create a single argp parameter.
doca_error_t psp_gw_parse_config_file(psp_gw_app_config *app_config)
Parses the configuration JSON file that was passed to the application.
static doca_error_t handle_psp_crypt_offset_param(void *param, void *config)
Configures the PSP crypt-offset.
static doca_error_t handle_repr_param(void *param, void *config)
Configures the device representors parameter.
static doca_error_t create_ip6_table(psp_gw_app_config *app_config)
std::vector< psp_json_field_handler > psp_json_field_handlers
static doca_error_t handle_ingress_acl_param(void *param, void *config)
Indicates the application should skip ACL checks on ingress.
doca_error_t psp_gw_argp_exec(int &argc, char *argv[], psp_gw_app_config *app_config)
Parses command-line arguments to the application.
static doca_error_t parse_sessions(json_object *json_obj_sessions, psp_gw_app_config *app_config, std::vector< void * > &params)
Parses the sessions.
static doca_error_t handle_vc_param(void *param, void *config)
Indicates the application should include the VC in the PSP tunnel header.
std::function< doca_error_t(json_object *, psp_gw_app_config *, std::vector< void * > &)> psp_parse_json_object_cb
static doca_error_t handle_max_tunnels_param(void *param, void *config)
Configures the max number of tunnels to be supported.
static doca_error_t parse_remote_grpc_address(json_object *json_obj_remote_addr, psp_gw_app_config *app_config, std::vector< void * > &params)
Parses the remote gRPC address.
static doca_error_t handle_decap_dmac_param(void *param, void *config)
Configures the dst-mac to apply on decap.
doca_error_t parse_ip_addr(const std::string &ip_str, doca_flow_l3_type enforce_l3_type, struct doca_flow_ip_addr *ip_addr)
Parse an IP address string into a DOCA Flow IP address struct.
std::string ipv4_to_string(rte_be32_t ipv4_addr)
Converts an IPv4 address to a C++ string.
psp_gw_peer * lookup_vip_pair(std::vector< psp_gw_peer > *peers, ip_pair &vip_pair)
Search for a peer in a vector of peers that holds the same IP pair.
bool is_empty_mac_addr(const rte_ether_addr &addr)
Tests whether a MAC address has been set (is non-zero)
std::string mac_to_string(const rte_ether_addr &mac_addr)
Converts a MAC/ethernet address to a C++ string.
void copy_ip_addr(const struct doca_flow_ip_addr &src, struct doca_flow_ip_addr &dst)
Copy an IP address struct.
std::string ip_to_string(const struct doca_flow_ip_addr &ip_addr)
Converts a DOCA Flow IP address struct to a C++ string.
doca flow ip address
doca_be32_t ipv4_addr
doca_be32_t ipv6_addr[4]
enum doca_flow_l3_type type
describes the configuration of the PSP networking service on the local host.
enum psp_gw_mode mode
std::string json_path
Describes a peer which is capable of exchanging traffic flows over a PSP tunnel.
Definition: psp_gw_config.h:98
std::string svc_addr
std::vector< ip_pair > vip_pairs
psp_parse_json_object_cb parser_cb
const std::string key
std::vector< void * > params
psp_json_field_handler(const std::string &key, psp_parse_json_object_cb parser_cb, bool required, std::vector< void * > params={})