net: add rte prefix to ether structures
[dpdk.git] / examples / ipsec-secgw / parser.c
index 99bdfc5..fc8c238 100644 (file)
@@ -1,37 +1,9 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2016 Intel Corporation
  */
 #include <rte_common.h>
 #include <rte_crypto.h>
+#include <rte_string_fns.h>
 
 #include <cmdline_parse_string.h>
 #include <cmdline_parse_num.h>
@@ -236,23 +208,24 @@ inet_pton6(const char *src, unsigned char *dst)
 int
 parse_ipv4_addr(const char *token, struct in_addr *ipv4, uint32_t *mask)
 {
-       char ip_str[256] = {0};
+       char ip_str[INET_ADDRSTRLEN] = {0};
        char *pch;
 
        pch = strchr(token, '/');
        if (pch != NULL) {
-               strncpy(ip_str, token, pch - token);
+               strlcpy(ip_str, token,
+                       RTE_MIN((unsigned int long)(pch - token + 1),
+                       sizeof(ip_str)));
                pch += 1;
                if (is_str_num(pch) != 0)
                        return -EINVAL;
                if (mask)
                        *mask = atoi(pch);
        } else {
-               strncpy(ip_str, token, sizeof(ip_str));
+               strlcpy(ip_str, token, sizeof(ip_str));
                if (mask)
                        *mask = 0;
        }
-
        if (strlen(ip_str) >= INET_ADDRSTRLEN)
                return -EINVAL;
 
@@ -270,14 +243,16 @@ parse_ipv6_addr(const char *token, struct in6_addr *ipv6, uint32_t *mask)
 
        pch = strchr(token, '/');
        if (pch != NULL) {
-               strncpy(ip_str, token, pch - token);
+               strlcpy(ip_str, token,
+                       RTE_MIN((unsigned int long)(pch - token + 1),
+                                       sizeof(ip_str)));
                pch += 1;
                if (is_str_num(pch) != 0)
                        return -EINVAL;
                if (mask)
                        *mask = atoi(pch);
        } else {
-               strncpy(ip_str, token, sizeof(ip_str));
+               strlcpy(ip_str, token, sizeof(ip_str));
                if (mask)
                        *mask = 0;
        }
@@ -331,6 +306,46 @@ parse_range(const char *token, uint16_t *low, uint16_t *high)
        return 0;
 }
 
+/*
+ * helper function for parse_mac, parse one section of the ether addr.
+ */
+static const char *
+parse_uint8x16(const char *s, uint8_t *v, uint8_t ls)
+{
+       char *end;
+       unsigned long t;
+
+       errno = 0;
+       t = strtoul(s, &end, 16);
+       if (errno != 0 || end[0] != ls || t > UINT8_MAX)
+               return NULL;
+       v[0] = t;
+       return end + 1;
+}
+
+static int
+parse_mac(const char *str, struct rte_ether_addr *addr)
+{
+       uint32_t i;
+
+       static const uint8_t stop_sym[RTE_DIM(addr->addr_bytes)] = {
+               [0] = ':',
+               [1] = ':',
+               [2] = ':',
+               [3] = ':',
+               [4] = ':',
+               [5] = 0,
+       };
+
+       for (i = 0; i != RTE_DIM(addr->addr_bytes); i++) {
+               str = parse_uint8x16(str, addr->addr_bytes + i, stop_sym[i]);
+               if (str == NULL)
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
 /** sp add parse */
 struct cfg_sp_add_cfg_item {
        cmdline_fixed_string_t sp_keyword;
@@ -469,11 +484,61 @@ cmdline_parse_inst_t cfg_rt_add_rule = {
        },
 };
 
+/* neigh add parse */
+struct cfg_neigh_add_item {
+       cmdline_fixed_string_t neigh;
+       cmdline_fixed_string_t pstr;
+       uint16_t port;
+       cmdline_fixed_string_t mac;
+};
+
+static void
+cfg_parse_neigh(void *parsed_result, __rte_unused struct cmdline *cl,
+       void *data)
+{
+       int32_t rc;
+       struct cfg_neigh_add_item *res;
+       struct parse_status *st;
+       struct rte_ether_addr mac;
+
+       st = data;
+       res = parsed_result;
+       rc = parse_mac(res->mac, &mac);
+       APP_CHECK(rc == 0, st, "invalid ether addr:%s", res->mac);
+       rc = add_dst_ethaddr(res->port, &mac);
+       APP_CHECK(rc == 0, st, "invalid port numer:%hu", res->port);
+       if (st->status < 0)
+               return;
+}
+
+cmdline_parse_token_string_t cfg_add_neigh_start =
+       TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, neigh, "neigh");
+cmdline_parse_token_string_t cfg_add_neigh_pstr =
+       TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, pstr, "port");
+cmdline_parse_token_num_t cfg_add_neigh_port =
+       TOKEN_NUM_INITIALIZER(struct cfg_neigh_add_item, port, UINT16);
+cmdline_parse_token_string_t cfg_add_neigh_mac =
+       TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, mac, NULL);
+
+cmdline_parse_inst_t cfg_neigh_add_rule = {
+       .f = cfg_parse_neigh,
+       .data = NULL,
+       .help_str = "",
+       .tokens = {
+               (void *)&cfg_add_neigh_start,
+               (void *)&cfg_add_neigh_pstr,
+               (void *)&cfg_add_neigh_port,
+               (void *)&cfg_add_neigh_mac,
+               NULL,
+       },
+};
+
 /** set of cfg items */
 cmdline_parse_ctx_t ipsec_ctx[] = {
        (cmdline_parse_inst_t *)&cfg_sp_add_rule,
        (cmdline_parse_inst_t *)&cfg_sa_add_rule,
        (cmdline_parse_inst_t *)&cfg_rt_add_rule,
+       (cmdline_parse_inst_t *)&cfg_neigh_add_rule,
        NULL,
 };
 
@@ -487,8 +552,7 @@ parse_cfg_file(const char *cfg_filename)
        struct parse_status status = {0};
 
        if (f == NULL) {
-               rte_panic("Error: invalid file descriptor %s\n",
-                       cfg_filename);
+               rte_panic("Error: invalid file descriptor %s\n", cfg_filename);
                goto error_exit;
        }
 
@@ -500,89 +564,80 @@ parse_cfg_file(const char *cfg_filename)
        cfg_sp_add_rule.data = &status;
        cfg_sa_add_rule.data = &status;
        cfg_rt_add_rule.data = &status;
+       cfg_neigh_add_rule.data = &status;
 
        do {
                char oneline[1024];
-
+               char *pos;
                get_s = fgets(oneline, 1024, f);
-               if (get_s) {
-                       char *pos;
 
-                       line_num++;
+               if (!get_s)
+                       break;
 
-                       if (strlen(oneline) > 1022) {
-                               rte_panic("%s:%u: error: the line "
-                                       "contains more characters the "
-                                       "parser can handle\n",
-                                       cfg_filename, line_num);
-                               goto error_exit;
-                       }
+               line_num++;
 
-                       /* process comment char '#' */
-                       if (oneline[0] == '#')
-                               continue;
+               if (strlen(oneline) > 1022) {
+                       rte_panic("%s:%u: error: "
+                               "the line contains more characters the parser can handle\n",
+                               cfg_filename, line_num);
+                       goto error_exit;
+               }
 
-                       pos = strchr(oneline, '#');
-                       if (pos != NULL)
-                               *pos = '\0';
-
-                       /* process line concatenator '\' */
-                       pos = strchr(oneline, 92);
-                       if (pos != NULL) {
-                               if (pos != oneline+strlen(oneline) - 2) {
-                                       rte_panic("%s:%u: error: no "
-                                               "character should exist "
-                                               "after '\\' symbol\n",
-                                               cfg_filename, line_num);
-                                       goto error_exit;
-                               }
-
-                               *pos = '\0';
-
-                               if (strlen(oneline) + strlen(str) > 1022) {
-                                       rte_panic("%s:%u: error: the "
-                                               "concatenated line "
-                                               "contains more characters "
-                                               "the parser can handle\n",
-                                               cfg_filename, line_num);
-                                       goto error_exit;
-                               }
-
-                               strncpy(str + strlen(str), oneline,
-                                       strlen(oneline));
+               /* process comment char '#' */
+               if (oneline[0] == '#')
+                       continue;
 
-                               continue;
-                       }
+               pos = strchr(oneline, '#');
+               if (pos != NULL)
+                       *pos = '\0';
 
-                       /* copy the line to str and process */
-                       if (strlen(oneline) + strlen(str) > 1022) {
-                               rte_panic("%s:%u: error: the line "
-                                       "contains more characters the "
-                                       "parser can handle\n",
+               /* process line concatenator '\' */
+               pos = strchr(oneline, 92);
+               if (pos != NULL) {
+                       if (pos != oneline+strlen(oneline) - 2) {
+                               rte_panic("%s:%u: error: "
+                                       "no character should exist after '\\'\n",
                                        cfg_filename, line_num);
                                goto error_exit;
                        }
-                       strncpy(str + strlen(str), oneline,
-                               strlen(oneline));
-
-                       str[strlen(str)] = '\n';
-                       if (cmdline_parse(cl, str) < 0) {
-                               rte_panic("%s:%u: error: parsing \"%s\" "
-                                       "failed\n", cfg_filename,
-                                       line_num, str);
-                               goto error_exit;
-                       }
 
-                       if (status.status < 0) {
-                               rte_panic("%s:%u: error: %s",
-                                       cfg_filename, line_num,
-                                       status.parse_msg);
+                       *pos = '\0';
+
+                       if (strlen(oneline) + strlen(str) > 1022) {
+                               rte_panic("%s:%u: error: "
+                                       "the concatenated line contains more characters the parser can handle\n",
+                                       cfg_filename, line_num);
                                goto error_exit;
                        }
 
-                       memset(str, 0, 1024);
+                       strcpy(str + strlen(str), oneline);
+                       continue;
                }
-       } while (get_s != NULL);
+
+               /* copy the line to str and process */
+               if (strlen(oneline) + strlen(str) > 1022) {
+                       rte_panic("%s:%u: error: "
+                               "the line contains more characters the parser can handle\n",
+                               cfg_filename, line_num);
+                       goto error_exit;
+               }
+               strcpy(str + strlen(str), oneline);
+
+               str[strlen(str)] = '\n';
+               if (cmdline_parse(cl, str) < 0) {
+                       rte_panic("%s:%u: error: parsing \"%s\" failed\n",
+                               cfg_filename, line_num, str);
+                       goto error_exit;
+               }
+
+               if (status.status < 0) {
+                       rte_panic("%s:%u: error: %s", cfg_filename,
+                               line_num, status.parse_msg);
+                       goto error_exit;
+               }
+
+               memset(str, 0, 1024);
+       } while (1);
 
        cmdline_stdin_exit(cl);
        fclose(f);