1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606 * Copyright(c) 2016 Intel Corporation
32bfe3f2eSlogwang */
40c6bd470Sfengbojiang #include <arpa/inet.h>
50c6bd470Sfengbojiang #include <sys/socket.h>
60c6bd470Sfengbojiang
72bfe3f2eSlogwang #include <rte_common.h>
82bfe3f2eSlogwang #include <rte_crypto.h>
9d30ea906Sjfb8856606 #include <rte_string_fns.h>
102bfe3f2eSlogwang
112bfe3f2eSlogwang #include <cmdline_parse_string.h>
122bfe3f2eSlogwang #include <cmdline_parse_num.h>
132bfe3f2eSlogwang #include <cmdline_parse_ipaddr.h>
142bfe3f2eSlogwang #include <cmdline_socket.h>
152bfe3f2eSlogwang #include <cmdline.h>
162bfe3f2eSlogwang
17*2d9fd380Sjfb8856606 #include "flow.h"
182bfe3f2eSlogwang #include "ipsec.h"
192bfe3f2eSlogwang #include "parser.h"
202bfe3f2eSlogwang
212bfe3f2eSlogwang #define PARSE_DELIMITER " \f\n\r\t\v"
222bfe3f2eSlogwang static int
parse_tokenize_string(char * string,char * tokens[],uint32_t * n_tokens)232bfe3f2eSlogwang parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
242bfe3f2eSlogwang {
252bfe3f2eSlogwang uint32_t i;
262bfe3f2eSlogwang
272bfe3f2eSlogwang if ((string == NULL) ||
282bfe3f2eSlogwang (tokens == NULL) ||
292bfe3f2eSlogwang (*n_tokens < 1))
302bfe3f2eSlogwang return -EINVAL;
312bfe3f2eSlogwang
322bfe3f2eSlogwang for (i = 0; i < *n_tokens; i++) {
332bfe3f2eSlogwang tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
342bfe3f2eSlogwang if (tokens[i] == NULL)
352bfe3f2eSlogwang break;
362bfe3f2eSlogwang }
372bfe3f2eSlogwang
382bfe3f2eSlogwang if ((i == *n_tokens) &&
392bfe3f2eSlogwang (NULL != strtok_r(string, PARSE_DELIMITER, &string)))
402bfe3f2eSlogwang return -E2BIG;
412bfe3f2eSlogwang
422bfe3f2eSlogwang *n_tokens = i;
432bfe3f2eSlogwang return 0;
442bfe3f2eSlogwang }
452bfe3f2eSlogwang
462bfe3f2eSlogwang int
parse_ipv4_addr(const char * token,struct in_addr * ipv4,uint32_t * mask)472bfe3f2eSlogwang parse_ipv4_addr(const char *token, struct in_addr *ipv4, uint32_t *mask)
482bfe3f2eSlogwang {
49d30ea906Sjfb8856606 char ip_str[INET_ADDRSTRLEN] = {0};
502bfe3f2eSlogwang char *pch;
512bfe3f2eSlogwang
522bfe3f2eSlogwang pch = strchr(token, '/');
532bfe3f2eSlogwang if (pch != NULL) {
54d30ea906Sjfb8856606 strlcpy(ip_str, token,
55d30ea906Sjfb8856606 RTE_MIN((unsigned int long)(pch - token + 1),
56d30ea906Sjfb8856606 sizeof(ip_str)));
572bfe3f2eSlogwang pch += 1;
582bfe3f2eSlogwang if (is_str_num(pch) != 0)
592bfe3f2eSlogwang return -EINVAL;
602bfe3f2eSlogwang if (mask)
612bfe3f2eSlogwang *mask = atoi(pch);
622bfe3f2eSlogwang } else {
63d30ea906Sjfb8856606 strlcpy(ip_str, token, sizeof(ip_str));
642bfe3f2eSlogwang if (mask)
652bfe3f2eSlogwang *mask = 0;
662bfe3f2eSlogwang }
672bfe3f2eSlogwang if (strlen(ip_str) >= INET_ADDRSTRLEN)
682bfe3f2eSlogwang return -EINVAL;
692bfe3f2eSlogwang
700c6bd470Sfengbojiang if (inet_pton(AF_INET, ip_str, ipv4) != 1)
712bfe3f2eSlogwang return -EINVAL;
722bfe3f2eSlogwang
732bfe3f2eSlogwang return 0;
742bfe3f2eSlogwang }
752bfe3f2eSlogwang
762bfe3f2eSlogwang int
parse_ipv6_addr(const char * token,struct in6_addr * ipv6,uint32_t * mask)772bfe3f2eSlogwang parse_ipv6_addr(const char *token, struct in6_addr *ipv6, uint32_t *mask)
782bfe3f2eSlogwang {
792bfe3f2eSlogwang char ip_str[256] = {0};
802bfe3f2eSlogwang char *pch;
812bfe3f2eSlogwang
822bfe3f2eSlogwang pch = strchr(token, '/');
832bfe3f2eSlogwang if (pch != NULL) {
84d30ea906Sjfb8856606 strlcpy(ip_str, token,
85d30ea906Sjfb8856606 RTE_MIN((unsigned int long)(pch - token + 1),
86d30ea906Sjfb8856606 sizeof(ip_str)));
872bfe3f2eSlogwang pch += 1;
882bfe3f2eSlogwang if (is_str_num(pch) != 0)
892bfe3f2eSlogwang return -EINVAL;
902bfe3f2eSlogwang if (mask)
912bfe3f2eSlogwang *mask = atoi(pch);
922bfe3f2eSlogwang } else {
93d30ea906Sjfb8856606 strlcpy(ip_str, token, sizeof(ip_str));
942bfe3f2eSlogwang if (mask)
952bfe3f2eSlogwang *mask = 0;
962bfe3f2eSlogwang }
972bfe3f2eSlogwang
982bfe3f2eSlogwang if (strlen(ip_str) >= INET6_ADDRSTRLEN)
992bfe3f2eSlogwang return -EINVAL;
1002bfe3f2eSlogwang
1010c6bd470Sfengbojiang if (inet_pton(AF_INET6, ip_str, ipv6) != 1)
1022bfe3f2eSlogwang return -EINVAL;
1032bfe3f2eSlogwang
1042bfe3f2eSlogwang return 0;
1052bfe3f2eSlogwang }
1062bfe3f2eSlogwang
1072bfe3f2eSlogwang int
parse_range(const char * token,uint16_t * low,uint16_t * high)1082bfe3f2eSlogwang parse_range(const char *token, uint16_t *low, uint16_t *high)
1092bfe3f2eSlogwang {
1102bfe3f2eSlogwang char ch;
1112bfe3f2eSlogwang char num_str[20];
1122bfe3f2eSlogwang uint32_t pos;
1132bfe3f2eSlogwang int range_low = -1;
1142bfe3f2eSlogwang int range_high = -1;
1152bfe3f2eSlogwang
1162bfe3f2eSlogwang if (!low || !high)
1172bfe3f2eSlogwang return -1;
1182bfe3f2eSlogwang
1192bfe3f2eSlogwang memset(num_str, 0, 20);
1202bfe3f2eSlogwang pos = 0;
1212bfe3f2eSlogwang
1222bfe3f2eSlogwang while ((ch = *token++) != '\0') {
1232bfe3f2eSlogwang if (isdigit(ch)) {
1242bfe3f2eSlogwang if (pos >= 19)
1252bfe3f2eSlogwang return -1;
1262bfe3f2eSlogwang num_str[pos++] = ch;
1272bfe3f2eSlogwang } else if (ch == ':') {
1282bfe3f2eSlogwang if (range_low != -1)
1292bfe3f2eSlogwang return -1;
1302bfe3f2eSlogwang range_low = atoi(num_str);
1312bfe3f2eSlogwang memset(num_str, 0, 20);
1322bfe3f2eSlogwang pos = 0;
1332bfe3f2eSlogwang }
1342bfe3f2eSlogwang }
1352bfe3f2eSlogwang
1362bfe3f2eSlogwang if (strlen(num_str) == 0)
1372bfe3f2eSlogwang return -1;
1382bfe3f2eSlogwang
1392bfe3f2eSlogwang range_high = atoi(num_str);
1402bfe3f2eSlogwang
1412bfe3f2eSlogwang *low = (uint16_t)range_low;
1422bfe3f2eSlogwang *high = (uint16_t)range_high;
1432bfe3f2eSlogwang
1442bfe3f2eSlogwang return 0;
1452bfe3f2eSlogwang }
1462bfe3f2eSlogwang
1474418919fSjohnjiang /*
1484418919fSjohnjiang * helper function for parse_mac, parse one section of the ether addr.
1494418919fSjohnjiang */
1504418919fSjohnjiang static const char *
parse_uint8x16(const char * s,uint8_t * v,uint8_t ls)1514418919fSjohnjiang parse_uint8x16(const char *s, uint8_t *v, uint8_t ls)
1524418919fSjohnjiang {
1534418919fSjohnjiang char *end;
1544418919fSjohnjiang unsigned long t;
1554418919fSjohnjiang
1564418919fSjohnjiang errno = 0;
1574418919fSjohnjiang t = strtoul(s, &end, 16);
1584418919fSjohnjiang if (errno != 0 || end[0] != ls || t > UINT8_MAX)
1594418919fSjohnjiang return NULL;
1604418919fSjohnjiang v[0] = t;
1614418919fSjohnjiang return end + 1;
1624418919fSjohnjiang }
1634418919fSjohnjiang
1644418919fSjohnjiang static int
parse_mac(const char * str,struct rte_ether_addr * addr)1654418919fSjohnjiang parse_mac(const char *str, struct rte_ether_addr *addr)
1664418919fSjohnjiang {
1674418919fSjohnjiang uint32_t i;
1684418919fSjohnjiang
1694418919fSjohnjiang static const uint8_t stop_sym[RTE_DIM(addr->addr_bytes)] = {
1704418919fSjohnjiang [0] = ':',
1714418919fSjohnjiang [1] = ':',
1724418919fSjohnjiang [2] = ':',
1734418919fSjohnjiang [3] = ':',
1744418919fSjohnjiang [4] = ':',
1754418919fSjohnjiang [5] = 0,
1764418919fSjohnjiang };
1774418919fSjohnjiang
1784418919fSjohnjiang for (i = 0; i != RTE_DIM(addr->addr_bytes); i++) {
1794418919fSjohnjiang str = parse_uint8x16(str, addr->addr_bytes + i, stop_sym[i]);
1804418919fSjohnjiang if (str == NULL)
1814418919fSjohnjiang return -EINVAL;
1824418919fSjohnjiang }
1834418919fSjohnjiang
1844418919fSjohnjiang return 0;
1854418919fSjohnjiang }
1864418919fSjohnjiang
1872bfe3f2eSlogwang /** sp add parse */
1882bfe3f2eSlogwang struct cfg_sp_add_cfg_item {
1892bfe3f2eSlogwang cmdline_fixed_string_t sp_keyword;
1902bfe3f2eSlogwang cmdline_multi_string_t multi_string;
1912bfe3f2eSlogwang };
1922bfe3f2eSlogwang
1932bfe3f2eSlogwang static void
cfg_sp_add_cfg_item_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data)1942bfe3f2eSlogwang cfg_sp_add_cfg_item_parsed(void *parsed_result,
1952bfe3f2eSlogwang __rte_unused struct cmdline *cl, void *data)
1962bfe3f2eSlogwang {
1972bfe3f2eSlogwang struct cfg_sp_add_cfg_item *params = parsed_result;
1982bfe3f2eSlogwang char *tokens[32];
1992bfe3f2eSlogwang uint32_t n_tokens = RTE_DIM(tokens);
2002bfe3f2eSlogwang struct parse_status *status = (struct parse_status *)data;
2012bfe3f2eSlogwang
2022bfe3f2eSlogwang APP_CHECK((parse_tokenize_string(params->multi_string, tokens,
2032bfe3f2eSlogwang &n_tokens) == 0), status, "too many arguments");
2042bfe3f2eSlogwang
2052bfe3f2eSlogwang if (status->status < 0)
2062bfe3f2eSlogwang return;
2072bfe3f2eSlogwang
2082bfe3f2eSlogwang if (strcmp(tokens[0], "ipv4") == 0) {
2092bfe3f2eSlogwang parse_sp4_tokens(tokens, n_tokens, status);
2102bfe3f2eSlogwang if (status->status < 0)
2112bfe3f2eSlogwang return;
2122bfe3f2eSlogwang } else if (strcmp(tokens[0], "ipv6") == 0) {
2132bfe3f2eSlogwang parse_sp6_tokens(tokens, n_tokens, status);
2142bfe3f2eSlogwang if (status->status < 0)
2152bfe3f2eSlogwang return;
2162bfe3f2eSlogwang } else {
2172bfe3f2eSlogwang APP_CHECK(0, status, "unrecognizable input %s\n",
2182bfe3f2eSlogwang tokens[0]);
2192bfe3f2eSlogwang return;
2202bfe3f2eSlogwang }
2212bfe3f2eSlogwang }
2222bfe3f2eSlogwang
2232bfe3f2eSlogwang static cmdline_parse_token_string_t cfg_sp_add_sp_str =
2242bfe3f2eSlogwang TOKEN_STRING_INITIALIZER(struct cfg_sp_add_cfg_item,
2252bfe3f2eSlogwang sp_keyword, "sp");
2262bfe3f2eSlogwang
2272bfe3f2eSlogwang static cmdline_parse_token_string_t cfg_sp_add_multi_str =
2282bfe3f2eSlogwang TOKEN_STRING_INITIALIZER(struct cfg_sp_add_cfg_item, multi_string,
2292bfe3f2eSlogwang TOKEN_STRING_MULTI);
2302bfe3f2eSlogwang
2312bfe3f2eSlogwang cmdline_parse_inst_t cfg_sp_add_rule = {
2322bfe3f2eSlogwang .f = cfg_sp_add_cfg_item_parsed,
2332bfe3f2eSlogwang .data = NULL,
2342bfe3f2eSlogwang .help_str = "",
2352bfe3f2eSlogwang .tokens = {
2362bfe3f2eSlogwang (void *) &cfg_sp_add_sp_str,
2372bfe3f2eSlogwang (void *) &cfg_sp_add_multi_str,
2382bfe3f2eSlogwang NULL,
2392bfe3f2eSlogwang },
2402bfe3f2eSlogwang };
2412bfe3f2eSlogwang
2422bfe3f2eSlogwang /* sa add parse */
2432bfe3f2eSlogwang struct cfg_sa_add_cfg_item {
2442bfe3f2eSlogwang cmdline_fixed_string_t sa_keyword;
2452bfe3f2eSlogwang cmdline_multi_string_t multi_string;
2462bfe3f2eSlogwang };
2472bfe3f2eSlogwang
2482bfe3f2eSlogwang static void
cfg_sa_add_cfg_item_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data)2492bfe3f2eSlogwang cfg_sa_add_cfg_item_parsed(void *parsed_result,
2502bfe3f2eSlogwang __rte_unused struct cmdline *cl, void *data)
2512bfe3f2eSlogwang {
2522bfe3f2eSlogwang struct cfg_sa_add_cfg_item *params = parsed_result;
2532bfe3f2eSlogwang char *tokens[32];
2542bfe3f2eSlogwang uint32_t n_tokens = RTE_DIM(tokens);
2552bfe3f2eSlogwang struct parse_status *status = (struct parse_status *)data;
2562bfe3f2eSlogwang
2572bfe3f2eSlogwang APP_CHECK(parse_tokenize_string(params->multi_string, tokens,
2582bfe3f2eSlogwang &n_tokens) == 0, status, "too many arguments\n");
2592bfe3f2eSlogwang
2602bfe3f2eSlogwang parse_sa_tokens(tokens, n_tokens, status);
2612bfe3f2eSlogwang }
2622bfe3f2eSlogwang
2632bfe3f2eSlogwang static cmdline_parse_token_string_t cfg_sa_add_sa_str =
2642bfe3f2eSlogwang TOKEN_STRING_INITIALIZER(struct cfg_sa_add_cfg_item,
2652bfe3f2eSlogwang sa_keyword, "sa");
2662bfe3f2eSlogwang
2672bfe3f2eSlogwang static cmdline_parse_token_string_t cfg_sa_add_multi_str =
2682bfe3f2eSlogwang TOKEN_STRING_INITIALIZER(struct cfg_sa_add_cfg_item, multi_string,
2692bfe3f2eSlogwang TOKEN_STRING_MULTI);
2702bfe3f2eSlogwang
2712bfe3f2eSlogwang cmdline_parse_inst_t cfg_sa_add_rule = {
2722bfe3f2eSlogwang .f = cfg_sa_add_cfg_item_parsed,
2732bfe3f2eSlogwang .data = NULL,
2742bfe3f2eSlogwang .help_str = "",
2752bfe3f2eSlogwang .tokens = {
2762bfe3f2eSlogwang (void *) &cfg_sa_add_sa_str,
2772bfe3f2eSlogwang (void *) &cfg_sa_add_multi_str,
2782bfe3f2eSlogwang NULL,
2792bfe3f2eSlogwang },
2802bfe3f2eSlogwang };
2812bfe3f2eSlogwang
2822bfe3f2eSlogwang /* rt add parse */
2832bfe3f2eSlogwang struct cfg_rt_add_cfg_item {
2842bfe3f2eSlogwang cmdline_fixed_string_t rt_keyword;
2852bfe3f2eSlogwang cmdline_multi_string_t multi_string;
2862bfe3f2eSlogwang };
2872bfe3f2eSlogwang
2882bfe3f2eSlogwang static void
cfg_rt_add_cfg_item_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data)2892bfe3f2eSlogwang cfg_rt_add_cfg_item_parsed(void *parsed_result,
2902bfe3f2eSlogwang __rte_unused struct cmdline *cl, void *data)
2912bfe3f2eSlogwang {
2922bfe3f2eSlogwang struct cfg_rt_add_cfg_item *params = parsed_result;
2932bfe3f2eSlogwang char *tokens[32];
2942bfe3f2eSlogwang uint32_t n_tokens = RTE_DIM(tokens);
2952bfe3f2eSlogwang struct parse_status *status = (struct parse_status *)data;
2962bfe3f2eSlogwang
2972bfe3f2eSlogwang APP_CHECK(parse_tokenize_string(
2982bfe3f2eSlogwang params->multi_string, tokens, &n_tokens) == 0,
2992bfe3f2eSlogwang status, "too many arguments\n");
3002bfe3f2eSlogwang if (status->status < 0)
3012bfe3f2eSlogwang return;
3022bfe3f2eSlogwang
3032bfe3f2eSlogwang parse_rt_tokens(tokens, n_tokens, status);
3042bfe3f2eSlogwang }
3052bfe3f2eSlogwang
3062bfe3f2eSlogwang static cmdline_parse_token_string_t cfg_rt_add_rt_str =
3072bfe3f2eSlogwang TOKEN_STRING_INITIALIZER(struct cfg_rt_add_cfg_item,
3082bfe3f2eSlogwang rt_keyword, "rt");
3092bfe3f2eSlogwang
3102bfe3f2eSlogwang static cmdline_parse_token_string_t cfg_rt_add_multi_str =
3112bfe3f2eSlogwang TOKEN_STRING_INITIALIZER(struct cfg_rt_add_cfg_item, multi_string,
3122bfe3f2eSlogwang TOKEN_STRING_MULTI);
3132bfe3f2eSlogwang
3142bfe3f2eSlogwang cmdline_parse_inst_t cfg_rt_add_rule = {
3152bfe3f2eSlogwang .f = cfg_rt_add_cfg_item_parsed,
3162bfe3f2eSlogwang .data = NULL,
3172bfe3f2eSlogwang .help_str = "",
3182bfe3f2eSlogwang .tokens = {
3192bfe3f2eSlogwang (void *) &cfg_rt_add_rt_str,
3202bfe3f2eSlogwang (void *) &cfg_rt_add_multi_str,
3212bfe3f2eSlogwang NULL,
3222bfe3f2eSlogwang },
3232bfe3f2eSlogwang };
3242bfe3f2eSlogwang
325*2d9fd380Sjfb8856606 /* flow add parse */
326*2d9fd380Sjfb8856606 struct cfg_flow_add_cfg_item {
327*2d9fd380Sjfb8856606 cmdline_fixed_string_t flow_keyword;
328*2d9fd380Sjfb8856606 cmdline_multi_string_t multi_string;
329*2d9fd380Sjfb8856606 };
330*2d9fd380Sjfb8856606
331*2d9fd380Sjfb8856606 static void
cfg_flow_add_cfg_item_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data)332*2d9fd380Sjfb8856606 cfg_flow_add_cfg_item_parsed(void *parsed_result,
333*2d9fd380Sjfb8856606 __rte_unused struct cmdline *cl, void *data)
334*2d9fd380Sjfb8856606 {
335*2d9fd380Sjfb8856606 struct cfg_flow_add_cfg_item *params = parsed_result;
336*2d9fd380Sjfb8856606 char *tokens[32];
337*2d9fd380Sjfb8856606 uint32_t n_tokens = RTE_DIM(tokens);
338*2d9fd380Sjfb8856606 struct parse_status *status = (struct parse_status *)data;
339*2d9fd380Sjfb8856606
340*2d9fd380Sjfb8856606 APP_CHECK(parse_tokenize_string(
341*2d9fd380Sjfb8856606 params->multi_string, tokens, &n_tokens) == 0,
342*2d9fd380Sjfb8856606 status, "too many arguments\n");
343*2d9fd380Sjfb8856606 if (status->status < 0)
344*2d9fd380Sjfb8856606 return;
345*2d9fd380Sjfb8856606
346*2d9fd380Sjfb8856606 parse_flow_tokens(tokens, n_tokens, status);
347*2d9fd380Sjfb8856606 }
348*2d9fd380Sjfb8856606
349*2d9fd380Sjfb8856606 static cmdline_parse_token_string_t cfg_flow_add_flow_str =
350*2d9fd380Sjfb8856606 TOKEN_STRING_INITIALIZER(struct cfg_flow_add_cfg_item,
351*2d9fd380Sjfb8856606 flow_keyword, "flow");
352*2d9fd380Sjfb8856606
353*2d9fd380Sjfb8856606 static cmdline_parse_token_string_t cfg_flow_add_multi_str =
354*2d9fd380Sjfb8856606 TOKEN_STRING_INITIALIZER(struct cfg_flow_add_cfg_item, multi_string,
355*2d9fd380Sjfb8856606 TOKEN_STRING_MULTI);
356*2d9fd380Sjfb8856606
357*2d9fd380Sjfb8856606 cmdline_parse_inst_t cfg_flow_add_rule = {
358*2d9fd380Sjfb8856606 .f = cfg_flow_add_cfg_item_parsed,
359*2d9fd380Sjfb8856606 .data = NULL,
360*2d9fd380Sjfb8856606 .help_str = "",
361*2d9fd380Sjfb8856606 .tokens = {
362*2d9fd380Sjfb8856606 (void *) &cfg_flow_add_flow_str,
363*2d9fd380Sjfb8856606 (void *) &cfg_flow_add_multi_str,
364*2d9fd380Sjfb8856606 NULL,
365*2d9fd380Sjfb8856606 },
366*2d9fd380Sjfb8856606 };
367*2d9fd380Sjfb8856606
3684418919fSjohnjiang /* neigh add parse */
3694418919fSjohnjiang struct cfg_neigh_add_item {
3704418919fSjohnjiang cmdline_fixed_string_t neigh;
3714418919fSjohnjiang cmdline_fixed_string_t pstr;
3724418919fSjohnjiang uint16_t port;
3734418919fSjohnjiang cmdline_fixed_string_t mac;
3744418919fSjohnjiang };
3754418919fSjohnjiang
3764418919fSjohnjiang static void
cfg_parse_neigh(void * parsed_result,__rte_unused struct cmdline * cl,void * data)3774418919fSjohnjiang cfg_parse_neigh(void *parsed_result, __rte_unused struct cmdline *cl,
3784418919fSjohnjiang void *data)
3794418919fSjohnjiang {
3804418919fSjohnjiang int32_t rc;
3814418919fSjohnjiang struct cfg_neigh_add_item *res;
3824418919fSjohnjiang struct parse_status *st;
3834418919fSjohnjiang struct rte_ether_addr mac;
3844418919fSjohnjiang
3854418919fSjohnjiang st = data;
3864418919fSjohnjiang res = parsed_result;
3874418919fSjohnjiang rc = parse_mac(res->mac, &mac);
3884418919fSjohnjiang APP_CHECK(rc == 0, st, "invalid ether addr:%s", res->mac);
3894418919fSjohnjiang rc = add_dst_ethaddr(res->port, &mac);
3904418919fSjohnjiang APP_CHECK(rc == 0, st, "invalid port numer:%hu", res->port);
3914418919fSjohnjiang if (st->status < 0)
3924418919fSjohnjiang return;
3934418919fSjohnjiang }
3944418919fSjohnjiang
3954418919fSjohnjiang cmdline_parse_token_string_t cfg_add_neigh_start =
3964418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, neigh, "neigh");
3974418919fSjohnjiang cmdline_parse_token_string_t cfg_add_neigh_pstr =
3984418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, pstr, "port");
3994418919fSjohnjiang cmdline_parse_token_num_t cfg_add_neigh_port =
400*2d9fd380Sjfb8856606 TOKEN_NUM_INITIALIZER(struct cfg_neigh_add_item, port, RTE_UINT16);
4014418919fSjohnjiang cmdline_parse_token_string_t cfg_add_neigh_mac =
4024418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, mac, NULL);
4034418919fSjohnjiang
4044418919fSjohnjiang cmdline_parse_inst_t cfg_neigh_add_rule = {
4054418919fSjohnjiang .f = cfg_parse_neigh,
4064418919fSjohnjiang .data = NULL,
4074418919fSjohnjiang .help_str = "",
4084418919fSjohnjiang .tokens = {
4094418919fSjohnjiang (void *)&cfg_add_neigh_start,
4104418919fSjohnjiang (void *)&cfg_add_neigh_pstr,
4114418919fSjohnjiang (void *)&cfg_add_neigh_port,
4124418919fSjohnjiang (void *)&cfg_add_neigh_mac,
4134418919fSjohnjiang NULL,
4144418919fSjohnjiang },
4154418919fSjohnjiang };
4164418919fSjohnjiang
4172bfe3f2eSlogwang /** set of cfg items */
4182bfe3f2eSlogwang cmdline_parse_ctx_t ipsec_ctx[] = {
4192bfe3f2eSlogwang (cmdline_parse_inst_t *)&cfg_sp_add_rule,
4202bfe3f2eSlogwang (cmdline_parse_inst_t *)&cfg_sa_add_rule,
4212bfe3f2eSlogwang (cmdline_parse_inst_t *)&cfg_rt_add_rule,
422*2d9fd380Sjfb8856606 (cmdline_parse_inst_t *)&cfg_flow_add_rule,
4234418919fSjohnjiang (cmdline_parse_inst_t *)&cfg_neigh_add_rule,
4242bfe3f2eSlogwang NULL,
4252bfe3f2eSlogwang };
4262bfe3f2eSlogwang
4272bfe3f2eSlogwang int
parse_cfg_file(const char * cfg_filename)4282bfe3f2eSlogwang parse_cfg_file(const char *cfg_filename)
4292bfe3f2eSlogwang {
4302bfe3f2eSlogwang struct cmdline *cl = cmdline_stdin_new(ipsec_ctx, "");
4312bfe3f2eSlogwang FILE *f = fopen(cfg_filename, "r");
4322bfe3f2eSlogwang char str[1024] = {0}, *get_s = NULL;
4332bfe3f2eSlogwang uint32_t line_num = 0;
4342bfe3f2eSlogwang struct parse_status status = {0};
4352bfe3f2eSlogwang
4362bfe3f2eSlogwang if (f == NULL) {
4372bfe3f2eSlogwang rte_panic("Error: invalid file descriptor %s\n", cfg_filename);
4382bfe3f2eSlogwang goto error_exit;
4392bfe3f2eSlogwang }
4402bfe3f2eSlogwang
4412bfe3f2eSlogwang if (cl == NULL) {
4422bfe3f2eSlogwang rte_panic("Error: cannot create cmdline instance\n");
4432bfe3f2eSlogwang goto error_exit;
4442bfe3f2eSlogwang }
4452bfe3f2eSlogwang
4462bfe3f2eSlogwang cfg_sp_add_rule.data = &status;
4472bfe3f2eSlogwang cfg_sa_add_rule.data = &status;
4482bfe3f2eSlogwang cfg_rt_add_rule.data = &status;
449*2d9fd380Sjfb8856606 cfg_flow_add_rule.data = &status;
4504418919fSjohnjiang cfg_neigh_add_rule.data = &status;
4512bfe3f2eSlogwang
4522bfe3f2eSlogwang do {
4532bfe3f2eSlogwang char oneline[1024];
4542bfe3f2eSlogwang char *pos;
4552bfe3f2eSlogwang get_s = fgets(oneline, 1024, f);
4562bfe3f2eSlogwang
4572bfe3f2eSlogwang if (!get_s)
4582bfe3f2eSlogwang break;
4592bfe3f2eSlogwang
4602bfe3f2eSlogwang line_num++;
4612bfe3f2eSlogwang
4622bfe3f2eSlogwang if (strlen(oneline) > 1022) {
4632bfe3f2eSlogwang rte_panic("%s:%u: error: "
4642bfe3f2eSlogwang "the line contains more characters the parser can handle\n",
4652bfe3f2eSlogwang cfg_filename, line_num);
4662bfe3f2eSlogwang goto error_exit;
4672bfe3f2eSlogwang }
4682bfe3f2eSlogwang
4692bfe3f2eSlogwang /* process comment char '#' */
4702bfe3f2eSlogwang if (oneline[0] == '#')
4712bfe3f2eSlogwang continue;
4722bfe3f2eSlogwang
4732bfe3f2eSlogwang pos = strchr(oneline, '#');
4742bfe3f2eSlogwang if (pos != NULL)
4752bfe3f2eSlogwang *pos = '\0';
4762bfe3f2eSlogwang
4772bfe3f2eSlogwang /* process line concatenator '\' */
4782bfe3f2eSlogwang pos = strchr(oneline, 92);
4792bfe3f2eSlogwang if (pos != NULL) {
4802bfe3f2eSlogwang if (pos != oneline+strlen(oneline) - 2) {
4812bfe3f2eSlogwang rte_panic("%s:%u: error: "
4822bfe3f2eSlogwang "no character should exist after '\\'\n",
4832bfe3f2eSlogwang cfg_filename, line_num);
4842bfe3f2eSlogwang goto error_exit;
4852bfe3f2eSlogwang }
4862bfe3f2eSlogwang
4872bfe3f2eSlogwang *pos = '\0';
4882bfe3f2eSlogwang
4892bfe3f2eSlogwang if (strlen(oneline) + strlen(str) > 1022) {
4902bfe3f2eSlogwang rte_panic("%s:%u: error: "
4912bfe3f2eSlogwang "the concatenated line contains more characters the parser can handle\n",
4922bfe3f2eSlogwang cfg_filename, line_num);
4932bfe3f2eSlogwang goto error_exit;
4942bfe3f2eSlogwang }
4952bfe3f2eSlogwang
496d30ea906Sjfb8856606 strcpy(str + strlen(str), oneline);
4972bfe3f2eSlogwang continue;
4982bfe3f2eSlogwang }
4992bfe3f2eSlogwang
5002bfe3f2eSlogwang /* copy the line to str and process */
5012bfe3f2eSlogwang if (strlen(oneline) + strlen(str) > 1022) {
5022bfe3f2eSlogwang rte_panic("%s:%u: error: "
5032bfe3f2eSlogwang "the line contains more characters the parser can handle\n",
5042bfe3f2eSlogwang cfg_filename, line_num);
5052bfe3f2eSlogwang goto error_exit;
5062bfe3f2eSlogwang }
507d30ea906Sjfb8856606 strcpy(str + strlen(str), oneline);
5082bfe3f2eSlogwang
5092bfe3f2eSlogwang str[strlen(str)] = '\n';
5102bfe3f2eSlogwang if (cmdline_parse(cl, str) < 0) {
5112bfe3f2eSlogwang rte_panic("%s:%u: error: parsing \"%s\" failed\n",
5122bfe3f2eSlogwang cfg_filename, line_num, str);
5132bfe3f2eSlogwang goto error_exit;
5142bfe3f2eSlogwang }
5152bfe3f2eSlogwang
5162bfe3f2eSlogwang if (status.status < 0) {
5172bfe3f2eSlogwang rte_panic("%s:%u: error: %s", cfg_filename,
5182bfe3f2eSlogwang line_num, status.parse_msg);
5192bfe3f2eSlogwang goto error_exit;
5202bfe3f2eSlogwang }
5212bfe3f2eSlogwang
5222bfe3f2eSlogwang memset(str, 0, 1024);
5232bfe3f2eSlogwang } while (1);
5242bfe3f2eSlogwang
5252bfe3f2eSlogwang cmdline_stdin_exit(cl);
5262bfe3f2eSlogwang fclose(f);
5272bfe3f2eSlogwang
528*2d9fd380Sjfb8856606 sa_sort_arr();
529*2d9fd380Sjfb8856606 sp4_sort_arr();
530*2d9fd380Sjfb8856606 sp6_sort_arr();
531*2d9fd380Sjfb8856606
5322bfe3f2eSlogwang return 0;
5332bfe3f2eSlogwang
5342bfe3f2eSlogwang error_exit:
5352bfe3f2eSlogwang if (cl)
5362bfe3f2eSlogwang cmdline_stdin_exit(cl);
5372bfe3f2eSlogwang if (f)
5382bfe3f2eSlogwang fclose(f);
5392bfe3f2eSlogwang
5402bfe3f2eSlogwang return -1;
5412bfe3f2eSlogwang }
542