NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
ipsec_ctx.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 #include <time.h>
26 
27 #include <rte_ethdev.h>
28 
29 #include <doca_log.h>
30 #include <doca_dpdk.h>
31 #include <doca_ctx.h>
32 #include <doca_pe.h>
33 
34 #include <samples/common.h>
35 
36 #include "ipsec_ctx.h"
37 #include "flow_common.h"
38 
39 DOCA_LOG_REGISTER(IPSEC_SECURITY_GW::ipsec_ctx);
40 
41 #define SLEEP_IN_NANOS (10 * 1000) /* Sample the task every 10 microseconds */
42 
44 {
45  int ret;
46  uint16_t proxy_port_id;
47 
48  /* get the port ID which has the privilege to control the switch ("proxy port") */
49  ret = rte_flow_pick_transfer_proxy(port_id, &proxy_port_id, NULL);
50  if (ret < 0) {
51  DOCA_LOG_ERR("Failed getting proxy port: %s", strerror(-ret));
52  return DOCA_ERROR_DRIVER;
53  }
54 
55  if (proxy_port_id == port_id)
56  *idx = SECURED_IDX;
57  else
58  *idx = UNSECURED_IDX;
59 
60  return DOCA_SUCCESS;
61 }
62 
63 /*
64  * Compare between the input interface name and the device name
65  *
66  * @dev_info [in]: device info
67  * @iface_name [in]: input interface name
68  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
69  */
70 static doca_error_t compare_device_name(struct doca_devinfo *dev_info, const char *iface_name)
71 {
72  char buf[DOCA_DEVINFO_IFACE_NAME_SIZE] = {};
73  char val_copy[DOCA_DEVINFO_IFACE_NAME_SIZE] = {};
75 
76  if (strlen(iface_name) >= DOCA_DEVINFO_IFACE_NAME_SIZE)
78 
79  memcpy(val_copy, iface_name, strlen(iface_name));
80 
82  if (result != DOCA_SUCCESS) {
83  DOCA_LOG_ERR("Failed to get device name: %s", doca_error_get_descr(result));
84  return result;
85  }
86 
87  if (memcmp(buf, val_copy, DOCA_DEVINFO_IFACE_NAME_SIZE) == 0)
88  return DOCA_SUCCESS;
89 
91 }
92 
93 /*
94  * Compare between the input PCI address and the device address
95  *
96  * @dev_info [in]: device info
97  * @pci_addr [in]: PCI address
98  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
99  */
100 static doca_error_t compare_device_pci_addr(struct doca_devinfo *dev_info, const char *pci_addr)
101 {
102  uint8_t is_addr_equal = 0;
104 
105  result = doca_devinfo_is_equal_pci_addr(dev_info, pci_addr, &is_addr_equal);
106  if (result != DOCA_SUCCESS) {
107  DOCA_LOG_ERR("Failed to compare device PCI address: %s", doca_error_get_descr(result));
108  return result;
109  }
110 
111  if (is_addr_equal)
112  return DOCA_SUCCESS;
113 
115 }
116 
118  int port_id,
119  struct doca_dev **connected_dev,
120  int *idx)
121 {
122  struct doca_devinfo *dev_info;
124  static bool is_secured_set, is_unsecured_set;
125 
126  result = doca_dpdk_port_as_dev(port_id, connected_dev);
127  if (result != DOCA_SUCCESS) {
128  DOCA_LOG_ERR("Failed to find DOCA device associated with port ID %d: %s",
129  port_id,
131  return result;
132  }
133 
134  dev_info = doca_dev_as_devinfo(*connected_dev);
135  if (dev_info == NULL) {
136  DOCA_LOG_ERR("Failed to find DOCA device associated with port ID %d", port_id);
138  }
139 
140  if (!is_secured_set && app_cfg->objects.secured_dev.open_by_pci) {
141  if (compare_device_pci_addr(dev_info, app_cfg->objects.secured_dev.pci_addr) == DOCA_SUCCESS) {
142  *idx = SECURED_IDX;
143  is_secured_set = true;
144  return DOCA_SUCCESS;
145  }
146  } else if (!is_secured_set && app_cfg->objects.secured_dev.open_by_name) {
147  if (compare_device_name(dev_info, app_cfg->objects.secured_dev.iface_name) == DOCA_SUCCESS) {
148  *idx = SECURED_IDX;
149  is_secured_set = true;
150  return DOCA_SUCCESS;
151  }
152  }
153  if (!is_unsecured_set && app_cfg->objects.unsecured_dev.open_by_pci) {
154  if (compare_device_pci_addr(dev_info, app_cfg->objects.unsecured_dev.pci_addr) == DOCA_SUCCESS) {
155  *idx = UNSECURED_IDX;
156  is_unsecured_set = true;
157  return DOCA_SUCCESS;
158  }
159  } else if (!is_unsecured_set && app_cfg->objects.unsecured_dev.open_by_name) {
160  if (compare_device_name(dev_info, app_cfg->objects.unsecured_dev.iface_name) == DOCA_SUCCESS) {
161  *idx = UNSECURED_IDX;
162  is_unsecured_set = true;
163  return DOCA_SUCCESS;
164  }
165  }
166 
168 }
169 
171 {
173  doca_error_t tmp_result;
174 
175  tmp_result = doca_dev_close(app_cfg->objects.secured_dev.doca_dev);
176  if (tmp_result != DOCA_SUCCESS) {
177  DOCA_LOG_ERR("Failed to destroy secured DOCA dev: %s", doca_error_get_descr(tmp_result));
178  DOCA_ERROR_PROPAGATE(result, tmp_result);
179  }
180 
181  if (app_cfg->flow_mode == IPSEC_SECURITY_GW_VNF) {
182  tmp_result = doca_dev_close(app_cfg->objects.unsecured_dev.doca_dev);
183  if (tmp_result != DOCA_SUCCESS) {
184  DOCA_LOG_ERR("Failed to destroy unsecured DOCA dev: %s", doca_error_get_descr(tmp_result));
185  DOCA_ERROR_PROPAGATE(result, tmp_result);
186  }
187  }
188  return result;
189 }
190 
191 /*
192  * Open DOCA device by interface name or PCI address based on the application input
193  *
194  * @info [in]: ipsec_security_gw_dev_info struct
195  * @func [in]: pointer to a function that checks if the device have some task capabilities
196  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
197  */
199 {
201 
202  if (info->open_by_pci) {
203  result = open_doca_device_with_pci(info->pci_addr, func, &info->doca_dev);
204  if (result != DOCA_SUCCESS) {
205  DOCA_LOG_ERR("Failed to open DOCA device: %s", doca_error_get_descr(result));
206  return result;
207  }
208  } else {
210  strlen(info->iface_name),
211  func,
212  &info->doca_dev);
213  if (result != DOCA_SUCCESS) {
214  DOCA_LOG_ERR("Failed to open DOCA device: %s", doca_error_get_descr(result));
215  return result;
216  }
217  }
218  return DOCA_SUCCESS;
219 }
220 
222 {
224 
225  result = open_doca_device(&app_cfg->objects.secured_dev, NULL);
226  if (result != DOCA_SUCCESS) {
227  DOCA_LOG_ERR("Failed to open DOCA device for the secured port: %s", doca_error_get_descr(result));
228  return result;
229  }
230  if (app_cfg->flow_mode == IPSEC_SECURITY_GW_VNF) {
231  result = open_doca_device(&app_cfg->objects.unsecured_dev, NULL);
232  if (result != DOCA_SUCCESS) {
233  DOCA_LOG_ERR("Failed to open DOCA device for the unsecured port: %s",
235  goto close_secured;
236  }
237  /* probe the opened doca devices with 'dv_flow_en=2' for HWS mode */
238  result = doca_dpdk_port_probe(app_cfg->objects.secured_dev.doca_dev, "dv_flow_en=2,dv_xmeta_en=4");
239  if (result != DOCA_SUCCESS) {
240  DOCA_LOG_ERR("Failed to probe dpdk port for secured port: %s", doca_error_get_descr(result));
241  goto close_unsecured;
242  }
243 
244  result = doca_dpdk_port_probe(app_cfg->objects.unsecured_dev.doca_dev, "dv_flow_en=2,dv_xmeta_en=4");
245  if (result != DOCA_SUCCESS) {
246  DOCA_LOG_ERR("Failed to probe dpdk port for unsecured port: %s", doca_error_get_descr(result));
247  goto close_unsecured;
248  }
249  } else {
251  app_cfg->objects.secured_dev.doca_dev,
252  "dv_flow_en=2,dv_xmeta_en=4,fdb_def_rule_en=0,vport_match=1,repr_matching_en=0,representor=pf[0-1]");
253  if (result != DOCA_SUCCESS) {
254  DOCA_LOG_ERR("Failed to probe dpdk port for secured port: %s", doca_error_get_descr(result));
255  goto close_secured;
256  }
257  }
258 
259  return DOCA_SUCCESS;
260 close_unsecured:
261  doca_dev_close(app_cfg->objects.unsecured_dev.doca_dev);
262 close_secured:
263  doca_dev_close(app_cfg->objects.secured_dev.doca_dev);
264  return result;
265 }
#define NULL
Definition: __stddef_null.h:26
int32_t result
#define SECURED_IDX
Definition: flow_common.h:40
#define UNSECURED_IDX
Definition: flow_common.h:41
doca_error_t open_doca_device_with_iface_name(const uint8_t *value, size_t val_size, tasks_check func, struct doca_dev **retval)
Definition: common.c:136
static doca_error_t open_doca_device_with_pci(const char *pcie_value, struct doca_dev **retval)
Definition: device.c:43
struct rte_eth_dev_info dev_info
Definition: device.c:32
static struct app_gpu_cfg app_cfg
DOCA_STABLE doca_error_t doca_devinfo_is_equal_pci_addr(const struct doca_devinfo *devinfo, const char *pci_addr_str, uint8_t *is_equal)
Check if a PCI address belongs to a DOCA devinfo.
#define DOCA_DEVINFO_IFACE_NAME_SIZE
Buffer size to hold network interface name. Including a null terminator.
Definition: doca_dev.h:305
DOCA_STABLE struct doca_devinfo * doca_dev_as_devinfo(const struct doca_dev *dev)
Get local device info from device. This should be useful when wanting to query information about devi...
DOCA_STABLE doca_error_t doca_devinfo_get_iface_name(const struct doca_devinfo *devinfo, char *iface_name, uint32_t size)
Get the name of the ethernet interface of a DOCA devinfo.
DOCA_STABLE doca_error_t doca_dev_close(struct doca_dev *dev)
Destroy allocated local device instance.
DOCA_EXPERIMENTAL doca_error_t doca_dpdk_port_probe(struct doca_dev *dev, const char *devargs)
Attach a DPDK port specified by DOCA device.
DOCA_EXPERIMENTAL doca_error_t doca_dpdk_port_as_dev(uint16_t port_id, struct doca_dev **dev)
Return the DOCA device associated with a DPDK port.
#define DOCA_ERROR_PROPAGATE(r, t)
Save the first encountered doca_error_t.
Definition: doca_error.h:83
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_INITIALIZATION
Definition: doca_error.h:46
@ DOCA_SUCCESS
Definition: doca_error.h:38
@ DOCA_ERROR_DRIVER
Definition: doca_error.h:59
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
static doca_error_t compare_device_name(struct doca_devinfo *dev_info, const char *iface_name)
Definition: ipsec_ctx.c:70
doca_error_t ipsec_security_gw_init_devices(struct ipsec_security_gw_config *app_cfg)
Definition: ipsec_ctx.c:221
DOCA_LOG_REGISTER(IPSEC_SECURITY_GW::ipsec_ctx)
static doca_error_t compare_device_pci_addr(struct doca_devinfo *dev_info, const char *pci_addr)
Definition: ipsec_ctx.c:100
doca_error_t find_port_action_type_vnf(const struct ipsec_security_gw_config *app_cfg, int port_id, struct doca_dev **connected_dev, int *idx)
Definition: ipsec_ctx.c:117
doca_error_t find_port_action_type_switch(int port_id, int *idx)
Definition: ipsec_ctx.c:43
static doca_error_t open_doca_device(struct ipsec_security_gw_dev_info *info, tasks_check func)
Definition: ipsec_ctx.c:198
doca_error_t ipsec_security_gw_close_devices(const struct ipsec_security_gw_config *app_cfg)
Definition: ipsec_ctx.c:170
@ IPSEC_SECURITY_GW_VNF
Definition: ipsec_ctx.h:187
doca_error_t(* tasks_check)(struct doca_devinfo *)
Definition: common.h:42
struct doca_dev * doca_dev
Definition: ipsec_ctx.h:219
char pci_addr[DOCA_DEVINFO_PCI_ADDR_SIZE]
Definition: ipsec_ctx.h:215
char iface_name[DOCA_DEVINFO_IFACE_NAME_SIZE]
Definition: ipsec_ctx.h:216