Modified Secuirty gateway application to support load/unload
esp-ah ddp package on i40e NIC from ipsec-secgw application.

Signed-off-by: Praveen Shetty <praveen.she...@intel.com>
---
 examples/ipsec-secgw/ipsec-secgw.c |  67 +++++++++++-
 examples/ipsec-secgw/ipsec.c       | 158 +++++++++++++++++++++++++++++
 examples/ipsec-secgw/ipsec.h       |   6 +-
 3 files changed, 228 insertions(+), 3 deletions(-)

diff --git a/examples/ipsec-secgw/ipsec-secgw.c 
b/examples/ipsec-secgw/ipsec-secgw.c
index 4799bc90c..214b8a625 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -198,7 +198,10 @@ struct app_sa_prm app_sa_prm = {
                        .cache_sz = SA_CACHE_SZ
                };
 static const char *cfgfile;
-
+static const char *ddp_file;
+static const char *ddp_bkp_file;
+static uint16_t fdir_portid;
+static int16_t ddp_unload_flag;
 struct lcore_rx_queue {
        uint16_t port_id;
        uint8_t queue_id;
@@ -1286,6 +1289,8 @@ print_usage(const char *prgname)
                " [-e]"
                " [-a]"
                " [-c]"
+               " [-L (portid,ddp_file_path,ddp_backup_file_path)]"
+               " [-U (portid,ddp_backup_file_path)]"
                " -f CONFIG_FILE"
                " --config (port,queue,lcore)[,(port,queue,lcore)]"
                " [--single-sa SAIDX]"
@@ -1307,6 +1312,8 @@ print_usage(const char *prgname)
                "  -a enables SA SQN atomic behaviour\n"
                "  -c specifies inbound SAD cache size,\n"
                "     zero value disables the cache (default value: 128)\n"
+               "  -L To load ddp profile on NIC\n"
+               "  -U To unload ddp profile from NIC\n"
                "  -f CONFIG_FILE: Configuration file\n"
                "  --config (port,queue,lcore): Rx queue configuration\n"
                "  --single-sa SAIDX: Use single SA index for outbound 
traffic,\n"
@@ -1379,6 +1386,33 @@ parse_decimal(const char *str)
        return num;
 }
 
+static int32_t
+parse_ddp_load_args(char *str)
+{
+       int16_t num_args = 0;
+       char *file_fld[3];
+       num_args = rte_strsplit(str, strlen(str), file_fld, 3, ',');
+       if (num_args != 3)
+               return -1;
+       fdir_portid = atoi(file_fld[0]);
+       ddp_file = file_fld[1];
+       ddp_bkp_file = file_fld[2];
+       return 0;
+}
+
+static int32_t
+parse_ddp_unload_args(char *str)
+{
+       int16_t num_args = 0;
+       char *file_fld[2];
+       num_args = rte_strsplit(str, strlen(str), file_fld, 2, ',');
+       if (num_args != 2)
+               return -1;
+       fdir_portid = atoi(file_fld[0]);
+       ddp_bkp_file = file_fld[1];
+       return 0;
+}
+
 static int32_t
 parse_config(const char *q_arg)
 {
@@ -1459,7 +1493,7 @@ parse_args(int32_t argc, char **argv)
 
        argvopt = argv;
 
-       while ((opt = getopt_long(argc, argvopt, "aelp:Pu:f:j:w:c:",
+       while ((opt = getopt_long(argc, argvopt, "aelp:Pu:L:U:f:j:w:c:",
                                lgopts, &option_index)) != EOF) {
 
                switch (opt) {
@@ -1483,6 +1517,25 @@ parse_args(int32_t argc, char **argv)
                                return -1;
                        }
                        break;
+               case 'L':
+                       printf("Loading ddp package selected\n");
+                       ret = parse_ddp_load_args(optarg);
+                       if (ret < 0) {
+                               printf("Invalid ddp load args: %s\n", optarg);
+                               print_usage(prgname);
+                               return -1;
+                       }
+                       break;
+               case 'U':
+                       printf("Unloading ddp package selected\n");
+                       ret = parse_ddp_unload_args(optarg);
+                       if (ret < 0) {
+                               printf("Invalid ddp unload args: %s\n", optarg);
+                               print_usage(prgname);
+                               return -1;
+                       }
+                       ddp_unload_flag = 1;
+                       break;
                case 'f':
                        if (f_present == 1) {
                                printf("\"-f\" option present more than "
@@ -2505,6 +2558,16 @@ main(int32_t argc, char **argv)
                sa_check_offloads(portid, &req_rx_offloads, &req_tx_offloads);
                port_init(portid, req_rx_offloads, req_tx_offloads);
        }
+       if (ddp_file != NULL && ddp_bkp_file != NULL) {
+               ret = load_ddp_esp_package(fdir_portid, ddp_file, ddp_bkp_file);
+               if (ret < 0)
+                       printf("loading ddp package failed\n");
+       }
+       if (ddp_unload_flag && ddp_bkp_file != NULL) {
+               ret = unload_ddp_esp_package(fdir_portid, ddp_bkp_file);
+               if (ret < 0)
+                       printf("unloading ddp package failed\n");
+       }
 
        cryptodevs_init();
 
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index 6e8120702..3840a0848 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -4,6 +4,9 @@
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include <rte_branch_prediction.h>
 #include <rte_log.h>
@@ -14,6 +17,9 @@
 #include <rte_ethdev.h>
 #include <rte_mbuf.h>
 #include <rte_hash.h>
+#ifdef RTE_LIBRTE_I40E_PMD
+#include <rte_pmd_i40e.h>
+#endif
 
 #include "ipsec.h"
 #include "esp.h"
@@ -155,6 +161,158 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, 
struct ipsec_sa *sa,
        return 0;
 }
 
+static int
+close_file(uint8_t *buf)
+{
+       if (buf) {
+               free((void *)buf);
+               return 0;
+       }
+
+       return -1;
+}
+
+static uint8_t *
+open_file(const char *file_path, uint32_t *size)
+{
+       int fd = open(file_path, O_RDONLY);
+       off_t pkg_size;
+       uint8_t *buf = NULL;
+       int ret = 0;
+       struct stat st_buf;
+
+       if (size)
+               *size = 0;
+
+       if (fd == -1) {
+               printf("%s: Failed to open %s\n", __func__, file_path);
+               return buf;
+       }
+
+       if ((fstat(fd, &st_buf) != 0) || (!S_ISREG(st_buf.st_mode))) {
+               close(fd);
+               printf("%s: File operations failed\n", __func__);
+               return buf;
+       }
+
+       pkg_size = st_buf.st_size;
+       if (pkg_size < 0) {
+               close(fd);
+               printf("%s: File operations failed\n", __func__);
+               return buf;
+       }
+
+       buf = (uint8_t *)malloc(pkg_size);
+       if (!buf) {
+               close(fd);
+               printf("%s: Failed to malloc memory\n", __func__);
+               return buf;
+       }
+
+       ret = read(fd, buf, pkg_size);
+       if (ret < 0) {
+               close(fd);
+               printf("%s: File read operation failed\n", __func__);
+               close_file(buf);
+               return NULL;
+       }
+
+       if (size)
+               *size = pkg_size;
+
+       close(fd);
+
+       return buf;
+}
+
+static int
+save_file(const char *file_path, uint8_t *buf, uint32_t size)
+{
+       FILE *fh = fopen(file_path, "wb");
+
+       if (fh == NULL) {
+               printf("%s: Failed to open %s\n", __func__, file_path);
+               return -1;
+       }
+
+       if (fwrite(buf, 1, size, fh) != size) {
+               fclose(fh);
+               printf("%s: File write operation failed\n", __func__);
+               return -1;
+       }
+
+       fclose(fh);
+
+       return 0;
+}
+
+/* Load dynamic device personalization profile */
+int
+load_ddp_esp_package(uint16_t fdir_portid, const char *ddp_file,
+               const char *ddp_bkp_file)
+{
+       uint8_t *buff;
+       uint32_t size;
+       int ret = -ENOTSUP;
+
+       buff = open_file(ddp_file, &size);
+       if (!buff)
+               return -1;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+       ret = rte_pmd_i40e_process_ddp_package(fdir_portid,
+                                              buff, size,
+                                              RTE_PMD_I40E_PKG_OP_WR_ADD);
+#endif
+
+       if (ret == -EEXIST)
+               printf("Profile has already existed.\n");
+       else if (ret < 0) {
+               printf("Failed to load profile.\n");
+               close_file(buff);
+               return -1;
+       } else
+               printf("loading ddp profile success\n");
+       if (ddp_bkp_file != NULL)
+               save_file(ddp_bkp_file, buff, size);
+
+       close_file(buff);
+       return 0;
+}
+
+/* Unload dynamic device personalization profile */
+int
+unload_ddp_esp_package(uint16_t fdir_portid, const char *ddp_bkp_file)
+{
+
+       uint8_t *buff;
+       uint32_t size;
+       int ret = -ENOTSUP;
+
+       buff = open_file(ddp_bkp_file, &size);
+       if (!buff)
+               return -1;
+
+#ifdef RTE_LIBRTE_I40E_PMD
+       ret = rte_pmd_i40e_process_ddp_package(fdir_portid,
+                                              buff, size,
+                                              RTE_PMD_I40E_PKG_OP_WR_DEL);
+#endif
+
+       if (ret == -EACCES) {
+               printf("Profile does not exist.\n");
+               close_file(buff);
+               return -1;
+       } else if (ret < 0) {
+               printf("Failed to delete profile.\n");
+               close_file(buff);
+               return -1;
+       } else
+               printf("ddp profile deleted successfully\n");
+       close_file(buff);
+       return 0;
+}
+
 int
 create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
                struct rte_ipsec_session *ips)
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 4f2fd6184..73eec47ab 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -383,5 +383,9 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, 
struct ipsec_sa *sa,
 int
 create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
                struct rte_ipsec_session *ips);
-
+int
+load_ddp_esp_package(uint16_t fdir_portid, const char *ddp_file,
+               const char *ddp_bkp_file);
+int
+unload_ddp_esp_package(uint16_t fdir_portid, const char *ddp_bkp_file);
 #endif /* __IPSEC_H__ */
-- 
2.17.1

Reply via email to