13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
23998e2a0SBruce Richardson * Copyright(c) 2016 Intel Corporation
30d547ed0SFan Zhang */
44054466bSIbtisam Tariq #include <arpa/inet.h>
54054466bSIbtisam Tariq #include <sys/socket.h>
64054466bSIbtisam Tariq
70d547ed0SFan Zhang #include <rte_common.h>
80d547ed0SFan Zhang #include <rte_crypto.h>
9ae943ebeSReshma Pattan #include <rte_string_fns.h>
100d547ed0SFan Zhang
110d547ed0SFan Zhang #include <cmdline_parse_string.h>
120d547ed0SFan Zhang #include <cmdline_parse_num.h>
130d547ed0SFan Zhang #include <cmdline_parse_ipaddr.h>
140d547ed0SFan Zhang #include <cmdline_socket.h>
150d547ed0SFan Zhang #include <cmdline.h>
160d547ed0SFan Zhang
178e693616SAnoob Joseph #include "flow.h"
180d547ed0SFan Zhang #include "ipsec.h"
190d547ed0SFan Zhang #include "parser.h"
200d547ed0SFan Zhang
210d547ed0SFan Zhang #define PARSE_DELIMITER " \f\n\r\t\v"
220d547ed0SFan Zhang static int
parse_tokenize_string(char * string,char * tokens[],uint32_t * n_tokens)230d547ed0SFan Zhang parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
240d547ed0SFan Zhang {
250d547ed0SFan Zhang uint32_t i;
260d547ed0SFan Zhang
270d547ed0SFan Zhang if ((string == NULL) ||
280d547ed0SFan Zhang (tokens == NULL) ||
290d547ed0SFan Zhang (*n_tokens < 1))
300d547ed0SFan Zhang return -EINVAL;
310d547ed0SFan Zhang
320d547ed0SFan Zhang for (i = 0; i < *n_tokens; i++) {
330d547ed0SFan Zhang tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
340d547ed0SFan Zhang if (tokens[i] == NULL)
350d547ed0SFan Zhang break;
360d547ed0SFan Zhang }
370d547ed0SFan Zhang
380d547ed0SFan Zhang if ((i == *n_tokens) &&
390d547ed0SFan Zhang (NULL != strtok_r(string, PARSE_DELIMITER, &string)))
400d547ed0SFan Zhang return -E2BIG;
410d547ed0SFan Zhang
420d547ed0SFan Zhang *n_tokens = i;
430d547ed0SFan Zhang return 0;
440d547ed0SFan Zhang }
450d547ed0SFan Zhang
460d547ed0SFan Zhang int
parse_ipv4_addr(const char * token,struct in_addr * ipv4,uint32_t * mask)470d547ed0SFan Zhang parse_ipv4_addr(const char *token, struct in_addr *ipv4, uint32_t *mask)
480d547ed0SFan Zhang {
49ae943ebeSReshma Pattan char ip_str[INET_ADDRSTRLEN] = {0};
500d547ed0SFan Zhang char *pch;
510d547ed0SFan Zhang
520d547ed0SFan Zhang pch = strchr(token, '/');
530d547ed0SFan Zhang if (pch != NULL) {
541bdea611SKirill Rybalchenko strlcpy(ip_str, token,
551bdea611SKirill Rybalchenko RTE_MIN((unsigned int long)(pch - token + 1),
56ae943ebeSReshma Pattan sizeof(ip_str)));
570d547ed0SFan Zhang pch += 1;
580d547ed0SFan Zhang if (is_str_num(pch) != 0)
590d547ed0SFan Zhang return -EINVAL;
600d547ed0SFan Zhang if (mask)
610d547ed0SFan Zhang *mask = atoi(pch);
620d547ed0SFan Zhang } else {
63ae943ebeSReshma Pattan strlcpy(ip_str, token, sizeof(ip_str));
640d547ed0SFan Zhang if (mask)
650d547ed0SFan Zhang *mask = 0;
660d547ed0SFan Zhang }
670d547ed0SFan Zhang if (strlen(ip_str) >= INET_ADDRSTRLEN)
680d547ed0SFan Zhang return -EINVAL;
690d547ed0SFan Zhang
704054466bSIbtisam Tariq if (inet_pton(AF_INET, ip_str, ipv4) != 1)
710d547ed0SFan Zhang return -EINVAL;
720d547ed0SFan Zhang
730d547ed0SFan Zhang return 0;
740d547ed0SFan Zhang }
750d547ed0SFan Zhang
760d547ed0SFan Zhang int
parse_ipv6_addr(const char * token,struct in6_addr * ipv6,uint32_t * mask)770d547ed0SFan Zhang parse_ipv6_addr(const char *token, struct in6_addr *ipv6, uint32_t *mask)
780d547ed0SFan Zhang {
790d547ed0SFan Zhang char ip_str[256] = {0};
800d547ed0SFan Zhang char *pch;
810d547ed0SFan Zhang
820d547ed0SFan Zhang pch = strchr(token, '/');
830d547ed0SFan Zhang if (pch != NULL) {
841bdea611SKirill Rybalchenko strlcpy(ip_str, token,
851bdea611SKirill Rybalchenko RTE_MIN((unsigned int long)(pch - token + 1),
86ae943ebeSReshma Pattan sizeof(ip_str)));
870d547ed0SFan Zhang pch += 1;
880d547ed0SFan Zhang if (is_str_num(pch) != 0)
890d547ed0SFan Zhang return -EINVAL;
900d547ed0SFan Zhang if (mask)
910d547ed0SFan Zhang *mask = atoi(pch);
920d547ed0SFan Zhang } else {
93ae943ebeSReshma Pattan strlcpy(ip_str, token, sizeof(ip_str));
940d547ed0SFan Zhang if (mask)
950d547ed0SFan Zhang *mask = 0;
960d547ed0SFan Zhang }
970d547ed0SFan Zhang
980d547ed0SFan Zhang if (strlen(ip_str) >= INET6_ADDRSTRLEN)
990d547ed0SFan Zhang return -EINVAL;
1000d547ed0SFan Zhang
1014054466bSIbtisam Tariq if (inet_pton(AF_INET6, ip_str, ipv6) != 1)
1020d547ed0SFan Zhang return -EINVAL;
1030d547ed0SFan Zhang
1040d547ed0SFan Zhang return 0;
1050d547ed0SFan Zhang }
1060d547ed0SFan Zhang
1070d547ed0SFan Zhang int
parse_range(const char * token,uint16_t * low,uint16_t * high)1080d547ed0SFan Zhang parse_range(const char *token, uint16_t *low, uint16_t *high)
1090d547ed0SFan Zhang {
1100d547ed0SFan Zhang char ch;
1110d547ed0SFan Zhang char num_str[20];
1120d547ed0SFan Zhang uint32_t pos;
1130d547ed0SFan Zhang int range_low = -1;
1140d547ed0SFan Zhang int range_high = -1;
1150d547ed0SFan Zhang
1160d547ed0SFan Zhang if (!low || !high)
1170d547ed0SFan Zhang return -1;
1180d547ed0SFan Zhang
1190d547ed0SFan Zhang memset(num_str, 0, 20);
1200d547ed0SFan Zhang pos = 0;
1210d547ed0SFan Zhang
1220d547ed0SFan Zhang while ((ch = *token++) != '\0') {
1230d547ed0SFan Zhang if (isdigit(ch)) {
1240d547ed0SFan Zhang if (pos >= 19)
1250d547ed0SFan Zhang return -1;
1260d547ed0SFan Zhang num_str[pos++] = ch;
1270d547ed0SFan Zhang } else if (ch == ':') {
1280d547ed0SFan Zhang if (range_low != -1)
1290d547ed0SFan Zhang return -1;
1300d547ed0SFan Zhang range_low = atoi(num_str);
1310d547ed0SFan Zhang memset(num_str, 0, 20);
1320d547ed0SFan Zhang pos = 0;
1330d547ed0SFan Zhang }
1340d547ed0SFan Zhang }
1350d547ed0SFan Zhang
1360d547ed0SFan Zhang if (strlen(num_str) == 0)
1370d547ed0SFan Zhang return -1;
1380d547ed0SFan Zhang
1390d547ed0SFan Zhang range_high = atoi(num_str);
1400d547ed0SFan Zhang
1410d547ed0SFan Zhang *low = (uint16_t)range_low;
1420d547ed0SFan Zhang *high = (uint16_t)range_high;
1430d547ed0SFan Zhang
1440d547ed0SFan Zhang return 0;
1450d547ed0SFan Zhang }
1460d547ed0SFan Zhang
1477622291bSKonstantin Ananyev /*
1487622291bSKonstantin Ananyev * helper function for parse_mac, parse one section of the ether addr.
1497622291bSKonstantin Ananyev */
1507622291bSKonstantin Ananyev static const char *
parse_uint8x16(const char * s,uint8_t * v,uint8_t ls)1517622291bSKonstantin Ananyev parse_uint8x16(const char *s, uint8_t *v, uint8_t ls)
1527622291bSKonstantin Ananyev {
1537622291bSKonstantin Ananyev char *end;
1547622291bSKonstantin Ananyev unsigned long t;
1557622291bSKonstantin Ananyev
1567622291bSKonstantin Ananyev errno = 0;
1577622291bSKonstantin Ananyev t = strtoul(s, &end, 16);
1587622291bSKonstantin Ananyev if (errno != 0 || end[0] != ls || t > UINT8_MAX)
1597622291bSKonstantin Ananyev return NULL;
1607622291bSKonstantin Ananyev v[0] = t;
1617622291bSKonstantin Ananyev return end + 1;
1627622291bSKonstantin Ananyev }
1637622291bSKonstantin Ananyev
1647622291bSKonstantin Ananyev static int
parse_mac(const char * str,struct rte_ether_addr * addr)1656d13ea8eSOlivier Matz parse_mac(const char *str, struct rte_ether_addr *addr)
1667622291bSKonstantin Ananyev {
1677622291bSKonstantin Ananyev uint32_t i;
1687622291bSKonstantin Ananyev
1697622291bSKonstantin Ananyev static const uint8_t stop_sym[RTE_DIM(addr->addr_bytes)] = {
1707622291bSKonstantin Ananyev [0] = ':',
1717622291bSKonstantin Ananyev [1] = ':',
1727622291bSKonstantin Ananyev [2] = ':',
1737622291bSKonstantin Ananyev [3] = ':',
1747622291bSKonstantin Ananyev [4] = ':',
1757622291bSKonstantin Ananyev [5] = 0,
1767622291bSKonstantin Ananyev };
1777622291bSKonstantin Ananyev
1787622291bSKonstantin Ananyev for (i = 0; i != RTE_DIM(addr->addr_bytes); i++) {
1797622291bSKonstantin Ananyev str = parse_uint8x16(str, addr->addr_bytes + i, stop_sym[i]);
1807622291bSKonstantin Ananyev if (str == NULL)
1817622291bSKonstantin Ananyev return -EINVAL;
1827622291bSKonstantin Ananyev }
1837622291bSKonstantin Ananyev
1847622291bSKonstantin Ananyev return 0;
1857622291bSKonstantin Ananyev }
1867622291bSKonstantin Ananyev
1870d547ed0SFan Zhang /** sp add parse */
1880d547ed0SFan Zhang struct cfg_sp_add_cfg_item {
1890d547ed0SFan Zhang cmdline_fixed_string_t sp_keyword;
1900d547ed0SFan Zhang cmdline_multi_string_t multi_string;
1910d547ed0SFan Zhang };
1920d547ed0SFan Zhang
1930d547ed0SFan Zhang static void
cfg_sp_add_cfg_item_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data)1940d547ed0SFan Zhang cfg_sp_add_cfg_item_parsed(void *parsed_result,
1950d547ed0SFan Zhang __rte_unused struct cmdline *cl, void *data)
1960d547ed0SFan Zhang {
1970d547ed0SFan Zhang struct cfg_sp_add_cfg_item *params = parsed_result;
1980d547ed0SFan Zhang char *tokens[32];
1990d547ed0SFan Zhang uint32_t n_tokens = RTE_DIM(tokens);
2000d547ed0SFan Zhang struct parse_status *status = (struct parse_status *)data;
2010d547ed0SFan Zhang
2020d547ed0SFan Zhang APP_CHECK((parse_tokenize_string(params->multi_string, tokens,
2030d547ed0SFan Zhang &n_tokens) == 0), status, "too many arguments");
2040d547ed0SFan Zhang
2050d547ed0SFan Zhang if (status->status < 0)
2060d547ed0SFan Zhang return;
2070d547ed0SFan Zhang
2080d547ed0SFan Zhang if (strcmp(tokens[0], "ipv4") == 0) {
2090d547ed0SFan Zhang parse_sp4_tokens(tokens, n_tokens, status);
2100d547ed0SFan Zhang if (status->status < 0)
2110d547ed0SFan Zhang return;
2120d547ed0SFan Zhang } else if (strcmp(tokens[0], "ipv6") == 0) {
2130d547ed0SFan Zhang parse_sp6_tokens(tokens, n_tokens, status);
2140d547ed0SFan Zhang if (status->status < 0)
2150d547ed0SFan Zhang return;
2160d547ed0SFan Zhang } else {
2170d547ed0SFan Zhang APP_CHECK(0, status, "unrecognizable input %s\n",
2180d547ed0SFan Zhang tokens[0]);
2190d547ed0SFan Zhang return;
2200d547ed0SFan Zhang }
2210d547ed0SFan Zhang }
2220d547ed0SFan Zhang
2230d547ed0SFan Zhang static cmdline_parse_token_string_t cfg_sp_add_sp_str =
2240d547ed0SFan Zhang TOKEN_STRING_INITIALIZER(struct cfg_sp_add_cfg_item,
2250d547ed0SFan Zhang sp_keyword, "sp");
2260d547ed0SFan Zhang
2270d547ed0SFan Zhang static cmdline_parse_token_string_t cfg_sp_add_multi_str =
2280d547ed0SFan Zhang TOKEN_STRING_INITIALIZER(struct cfg_sp_add_cfg_item, multi_string,
2290d547ed0SFan Zhang TOKEN_STRING_MULTI);
2300d547ed0SFan Zhang
2310d547ed0SFan Zhang cmdline_parse_inst_t cfg_sp_add_rule = {
2320d547ed0SFan Zhang .f = cfg_sp_add_cfg_item_parsed,
2330d547ed0SFan Zhang .data = NULL,
2340d547ed0SFan Zhang .help_str = "",
2350d547ed0SFan Zhang .tokens = {
2360d547ed0SFan Zhang (void *) &cfg_sp_add_sp_str,
2370d547ed0SFan Zhang (void *) &cfg_sp_add_multi_str,
2380d547ed0SFan Zhang NULL,
2390d547ed0SFan Zhang },
2400d547ed0SFan Zhang };
2410d547ed0SFan Zhang
2420d547ed0SFan Zhang /* sa add parse */
2430d547ed0SFan Zhang struct cfg_sa_add_cfg_item {
2440d547ed0SFan Zhang cmdline_fixed_string_t sa_keyword;
2450d547ed0SFan Zhang cmdline_multi_string_t multi_string;
2460d547ed0SFan Zhang };
2470d547ed0SFan Zhang
2480d547ed0SFan Zhang static void
cfg_sa_add_cfg_item_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data)2490d547ed0SFan Zhang cfg_sa_add_cfg_item_parsed(void *parsed_result,
2500d547ed0SFan Zhang __rte_unused struct cmdline *cl, void *data)
2510d547ed0SFan Zhang {
2520d547ed0SFan Zhang struct cfg_sa_add_cfg_item *params = parsed_result;
2530d547ed0SFan Zhang char *tokens[32];
2540d547ed0SFan Zhang uint32_t n_tokens = RTE_DIM(tokens);
2550d547ed0SFan Zhang struct parse_status *status = (struct parse_status *)data;
2560d547ed0SFan Zhang
2570d547ed0SFan Zhang APP_CHECK(parse_tokenize_string(params->multi_string, tokens,
2580d547ed0SFan Zhang &n_tokens) == 0, status, "too many arguments\n");
2590d547ed0SFan Zhang
2600d547ed0SFan Zhang parse_sa_tokens(tokens, n_tokens, status);
2610d547ed0SFan Zhang }
2620d547ed0SFan Zhang
2630d547ed0SFan Zhang static cmdline_parse_token_string_t cfg_sa_add_sa_str =
2640d547ed0SFan Zhang TOKEN_STRING_INITIALIZER(struct cfg_sa_add_cfg_item,
2650d547ed0SFan Zhang sa_keyword, "sa");
2660d547ed0SFan Zhang
2670d547ed0SFan Zhang static cmdline_parse_token_string_t cfg_sa_add_multi_str =
2680d547ed0SFan Zhang TOKEN_STRING_INITIALIZER(struct cfg_sa_add_cfg_item, multi_string,
2690d547ed0SFan Zhang TOKEN_STRING_MULTI);
2700d547ed0SFan Zhang
2710d547ed0SFan Zhang cmdline_parse_inst_t cfg_sa_add_rule = {
2720d547ed0SFan Zhang .f = cfg_sa_add_cfg_item_parsed,
2730d547ed0SFan Zhang .data = NULL,
2740d547ed0SFan Zhang .help_str = "",
2750d547ed0SFan Zhang .tokens = {
2760d547ed0SFan Zhang (void *) &cfg_sa_add_sa_str,
2770d547ed0SFan Zhang (void *) &cfg_sa_add_multi_str,
2780d547ed0SFan Zhang NULL,
2790d547ed0SFan Zhang },
2800d547ed0SFan Zhang };
2810d547ed0SFan Zhang
2820d547ed0SFan Zhang /* rt add parse */
2830d547ed0SFan Zhang struct cfg_rt_add_cfg_item {
2840d547ed0SFan Zhang cmdline_fixed_string_t rt_keyword;
2850d547ed0SFan Zhang cmdline_multi_string_t multi_string;
2860d547ed0SFan Zhang };
2870d547ed0SFan Zhang
2880d547ed0SFan Zhang static void
cfg_rt_add_cfg_item_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data)2890d547ed0SFan Zhang cfg_rt_add_cfg_item_parsed(void *parsed_result,
2900d547ed0SFan Zhang __rte_unused struct cmdline *cl, void *data)
2910d547ed0SFan Zhang {
2920d547ed0SFan Zhang struct cfg_rt_add_cfg_item *params = parsed_result;
2930d547ed0SFan Zhang char *tokens[32];
2940d547ed0SFan Zhang uint32_t n_tokens = RTE_DIM(tokens);
2950d547ed0SFan Zhang struct parse_status *status = (struct parse_status *)data;
2960d547ed0SFan Zhang
2970d547ed0SFan Zhang APP_CHECK(parse_tokenize_string(
2980d547ed0SFan Zhang params->multi_string, tokens, &n_tokens) == 0,
2990d547ed0SFan Zhang status, "too many arguments\n");
3000d547ed0SFan Zhang if (status->status < 0)
3010d547ed0SFan Zhang return;
3020d547ed0SFan Zhang
3030d547ed0SFan Zhang parse_rt_tokens(tokens, n_tokens, status);
3040d547ed0SFan Zhang }
3050d547ed0SFan Zhang
3060d547ed0SFan Zhang static cmdline_parse_token_string_t cfg_rt_add_rt_str =
3070d547ed0SFan Zhang TOKEN_STRING_INITIALIZER(struct cfg_rt_add_cfg_item,
3080d547ed0SFan Zhang rt_keyword, "rt");
3090d547ed0SFan Zhang
3100d547ed0SFan Zhang static cmdline_parse_token_string_t cfg_rt_add_multi_str =
3110d547ed0SFan Zhang TOKEN_STRING_INITIALIZER(struct cfg_rt_add_cfg_item, multi_string,
3120d547ed0SFan Zhang TOKEN_STRING_MULTI);
3130d547ed0SFan Zhang
3140d547ed0SFan Zhang cmdline_parse_inst_t cfg_rt_add_rule = {
3150d547ed0SFan Zhang .f = cfg_rt_add_cfg_item_parsed,
3160d547ed0SFan Zhang .data = NULL,
3170d547ed0SFan Zhang .help_str = "",
3180d547ed0SFan Zhang .tokens = {
3190d547ed0SFan Zhang (void *) &cfg_rt_add_rt_str,
3200d547ed0SFan Zhang (void *) &cfg_rt_add_multi_str,
3210d547ed0SFan Zhang NULL,
3220d547ed0SFan Zhang },
3230d547ed0SFan Zhang };
3240d547ed0SFan Zhang
3258e693616SAnoob Joseph /* flow add parse */
3268e693616SAnoob Joseph struct cfg_flow_add_cfg_item {
3278e693616SAnoob Joseph cmdline_fixed_string_t flow_keyword;
3288e693616SAnoob Joseph cmdline_multi_string_t multi_string;
3298e693616SAnoob Joseph };
3308e693616SAnoob Joseph
3318e693616SAnoob Joseph static void
cfg_flow_add_cfg_item_parsed(void * parsed_result,__rte_unused struct cmdline * cl,void * data)3328e693616SAnoob Joseph cfg_flow_add_cfg_item_parsed(void *parsed_result,
3338e693616SAnoob Joseph __rte_unused struct cmdline *cl, void *data)
3348e693616SAnoob Joseph {
3358e693616SAnoob Joseph struct cfg_flow_add_cfg_item *params = parsed_result;
3368e693616SAnoob Joseph char *tokens[32];
3378e693616SAnoob Joseph uint32_t n_tokens = RTE_DIM(tokens);
3388e693616SAnoob Joseph struct parse_status *status = (struct parse_status *)data;
3398e693616SAnoob Joseph
3408e693616SAnoob Joseph APP_CHECK(parse_tokenize_string(
3418e693616SAnoob Joseph params->multi_string, tokens, &n_tokens) == 0,
3428e693616SAnoob Joseph status, "too many arguments\n");
3438e693616SAnoob Joseph if (status->status < 0)
3448e693616SAnoob Joseph return;
3458e693616SAnoob Joseph
3468e693616SAnoob Joseph parse_flow_tokens(tokens, n_tokens, status);
3478e693616SAnoob Joseph }
3488e693616SAnoob Joseph
3498e693616SAnoob Joseph static cmdline_parse_token_string_t cfg_flow_add_flow_str =
3508e693616SAnoob Joseph TOKEN_STRING_INITIALIZER(struct cfg_flow_add_cfg_item,
3518e693616SAnoob Joseph flow_keyword, "flow");
3528e693616SAnoob Joseph
3538e693616SAnoob Joseph static cmdline_parse_token_string_t cfg_flow_add_multi_str =
3548e693616SAnoob Joseph TOKEN_STRING_INITIALIZER(struct cfg_flow_add_cfg_item, multi_string,
3558e693616SAnoob Joseph TOKEN_STRING_MULTI);
3568e693616SAnoob Joseph
3578e693616SAnoob Joseph cmdline_parse_inst_t cfg_flow_add_rule = {
3588e693616SAnoob Joseph .f = cfg_flow_add_cfg_item_parsed,
3598e693616SAnoob Joseph .data = NULL,
3608e693616SAnoob Joseph .help_str = "",
3618e693616SAnoob Joseph .tokens = {
3628e693616SAnoob Joseph (void *) &cfg_flow_add_flow_str,
3638e693616SAnoob Joseph (void *) &cfg_flow_add_multi_str,
3648e693616SAnoob Joseph NULL,
3658e693616SAnoob Joseph },
3668e693616SAnoob Joseph };
3678e693616SAnoob Joseph
3687622291bSKonstantin Ananyev /* neigh add parse */
3697622291bSKonstantin Ananyev struct cfg_neigh_add_item {
3707622291bSKonstantin Ananyev cmdline_fixed_string_t neigh;
3717622291bSKonstantin Ananyev cmdline_fixed_string_t pstr;
3727622291bSKonstantin Ananyev uint16_t port;
3737622291bSKonstantin Ananyev cmdline_fixed_string_t mac;
3747622291bSKonstantin Ananyev };
3757622291bSKonstantin Ananyev
3767622291bSKonstantin Ananyev static void
cfg_parse_neigh(void * parsed_result,__rte_unused struct cmdline * cl,void * data)3777622291bSKonstantin Ananyev cfg_parse_neigh(void *parsed_result, __rte_unused struct cmdline *cl,
3787622291bSKonstantin Ananyev void *data)
3797622291bSKonstantin Ananyev {
3807622291bSKonstantin Ananyev int32_t rc;
3817622291bSKonstantin Ananyev struct cfg_neigh_add_item *res;
3827622291bSKonstantin Ananyev struct parse_status *st;
3836d13ea8eSOlivier Matz struct rte_ether_addr mac;
3847622291bSKonstantin Ananyev
3857622291bSKonstantin Ananyev st = data;
3867622291bSKonstantin Ananyev res = parsed_result;
3877622291bSKonstantin Ananyev rc = parse_mac(res->mac, &mac);
3887622291bSKonstantin Ananyev APP_CHECK(rc == 0, st, "invalid ether addr:%s", res->mac);
3897622291bSKonstantin Ananyev rc = add_dst_ethaddr(res->port, &mac);
3907622291bSKonstantin Ananyev APP_CHECK(rc == 0, st, "invalid port numer:%hu", res->port);
3917622291bSKonstantin Ananyev if (st->status < 0)
3927622291bSKonstantin Ananyev return;
3937622291bSKonstantin Ananyev }
3947622291bSKonstantin Ananyev
3957622291bSKonstantin Ananyev cmdline_parse_token_string_t cfg_add_neigh_start =
3967622291bSKonstantin Ananyev TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, neigh, "neigh");
3977622291bSKonstantin Ananyev cmdline_parse_token_string_t cfg_add_neigh_pstr =
3987622291bSKonstantin Ananyev TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, pstr, "port");
3997622291bSKonstantin Ananyev cmdline_parse_token_num_t cfg_add_neigh_port =
400*c2341bb6SDmitry Kozlyuk TOKEN_NUM_INITIALIZER(struct cfg_neigh_add_item, port, RTE_UINT16);
4017622291bSKonstantin Ananyev cmdline_parse_token_string_t cfg_add_neigh_mac =
4027622291bSKonstantin Ananyev TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, mac, NULL);
4037622291bSKonstantin Ananyev
4047622291bSKonstantin Ananyev cmdline_parse_inst_t cfg_neigh_add_rule = {
4057622291bSKonstantin Ananyev .f = cfg_parse_neigh,
4067622291bSKonstantin Ananyev .data = NULL,
4077622291bSKonstantin Ananyev .help_str = "",
4087622291bSKonstantin Ananyev .tokens = {
4097622291bSKonstantin Ananyev (void *)&cfg_add_neigh_start,
4107622291bSKonstantin Ananyev (void *)&cfg_add_neigh_pstr,
4117622291bSKonstantin Ananyev (void *)&cfg_add_neigh_port,
4127622291bSKonstantin Ananyev (void *)&cfg_add_neigh_mac,
4137622291bSKonstantin Ananyev NULL,
4147622291bSKonstantin Ananyev },
4157622291bSKonstantin Ananyev };
4167622291bSKonstantin Ananyev
4170d547ed0SFan Zhang /** set of cfg items */
4180d547ed0SFan Zhang cmdline_parse_ctx_t ipsec_ctx[] = {
4190d547ed0SFan Zhang (cmdline_parse_inst_t *)&cfg_sp_add_rule,
4200d547ed0SFan Zhang (cmdline_parse_inst_t *)&cfg_sa_add_rule,
4210d547ed0SFan Zhang (cmdline_parse_inst_t *)&cfg_rt_add_rule,
4228e693616SAnoob Joseph (cmdline_parse_inst_t *)&cfg_flow_add_rule,
4237622291bSKonstantin Ananyev (cmdline_parse_inst_t *)&cfg_neigh_add_rule,
4240d547ed0SFan Zhang NULL,
4250d547ed0SFan Zhang };
4260d547ed0SFan Zhang
4270d547ed0SFan Zhang int
parse_cfg_file(const char * cfg_filename)4280d547ed0SFan Zhang parse_cfg_file(const char *cfg_filename)
4290d547ed0SFan Zhang {
4300d547ed0SFan Zhang struct cmdline *cl = cmdline_stdin_new(ipsec_ctx, "");
4310d547ed0SFan Zhang FILE *f = fopen(cfg_filename, "r");
4320d547ed0SFan Zhang char str[1024] = {0}, *get_s = NULL;
4330d547ed0SFan Zhang uint32_t line_num = 0;
4340d547ed0SFan Zhang struct parse_status status = {0};
4350d547ed0SFan Zhang
4360d547ed0SFan Zhang if (f == NULL) {
437a1469c31SFan Zhang rte_panic("Error: invalid file descriptor %s\n", cfg_filename);
4380d547ed0SFan Zhang goto error_exit;
4390d547ed0SFan Zhang }
4400d547ed0SFan Zhang
4410d547ed0SFan Zhang if (cl == NULL) {
4420d547ed0SFan Zhang rte_panic("Error: cannot create cmdline instance\n");
4430d547ed0SFan Zhang goto error_exit;
4440d547ed0SFan Zhang }
4450d547ed0SFan Zhang
4460d547ed0SFan Zhang cfg_sp_add_rule.data = &status;
4470d547ed0SFan Zhang cfg_sa_add_rule.data = &status;
4480d547ed0SFan Zhang cfg_rt_add_rule.data = &status;
4498e693616SAnoob Joseph cfg_flow_add_rule.data = &status;
4507622291bSKonstantin Ananyev cfg_neigh_add_rule.data = &status;
4510d547ed0SFan Zhang
4520d547ed0SFan Zhang do {
4530d547ed0SFan Zhang char oneline[1024];
4540d547ed0SFan Zhang char *pos;
455a1469c31SFan Zhang get_s = fgets(oneline, 1024, f);
456a1469c31SFan Zhang
457a1469c31SFan Zhang if (!get_s)
458a1469c31SFan Zhang break;
4590d547ed0SFan Zhang
4600d547ed0SFan Zhang line_num++;
4610d547ed0SFan Zhang
4620d547ed0SFan Zhang if (strlen(oneline) > 1022) {
463a1469c31SFan Zhang rte_panic("%s:%u: error: "
464a1469c31SFan Zhang "the line contains more characters the parser can handle\n",
4650d547ed0SFan Zhang cfg_filename, line_num);
4660d547ed0SFan Zhang goto error_exit;
4670d547ed0SFan Zhang }
4680d547ed0SFan Zhang
4690d547ed0SFan Zhang /* process comment char '#' */
4700d547ed0SFan Zhang if (oneline[0] == '#')
4710d547ed0SFan Zhang continue;
4720d547ed0SFan Zhang
4730d547ed0SFan Zhang pos = strchr(oneline, '#');
4740d547ed0SFan Zhang if (pos != NULL)
4750d547ed0SFan Zhang *pos = '\0';
4760d547ed0SFan Zhang
4770d547ed0SFan Zhang /* process line concatenator '\' */
4780d547ed0SFan Zhang pos = strchr(oneline, 92);
4790d547ed0SFan Zhang if (pos != NULL) {
4800d547ed0SFan Zhang if (pos != oneline+strlen(oneline) - 2) {
481a1469c31SFan Zhang rte_panic("%s:%u: error: "
482a1469c31SFan Zhang "no character should exist after '\\'\n",
4830d547ed0SFan Zhang cfg_filename, line_num);
4840d547ed0SFan Zhang goto error_exit;
4850d547ed0SFan Zhang }
4860d547ed0SFan Zhang
4870d547ed0SFan Zhang *pos = '\0';
4880d547ed0SFan Zhang
4890d547ed0SFan Zhang if (strlen(oneline) + strlen(str) > 1022) {
490a1469c31SFan Zhang rte_panic("%s:%u: error: "
491a1469c31SFan Zhang "the concatenated line contains more characters the parser can handle\n",
4920d547ed0SFan Zhang cfg_filename, line_num);
4930d547ed0SFan Zhang goto error_exit;
4940d547ed0SFan Zhang }
4950d547ed0SFan Zhang
496ae943ebeSReshma Pattan strcpy(str + strlen(str), oneline);
4970d547ed0SFan Zhang continue;
4980d547ed0SFan Zhang }
4990d547ed0SFan Zhang
5000d547ed0SFan Zhang /* copy the line to str and process */
5010d547ed0SFan Zhang if (strlen(oneline) + strlen(str) > 1022) {
502a1469c31SFan Zhang rte_panic("%s:%u: error: "
503a1469c31SFan Zhang "the line contains more characters the parser can handle\n",
5040d547ed0SFan Zhang cfg_filename, line_num);
5050d547ed0SFan Zhang goto error_exit;
5060d547ed0SFan Zhang }
507ae943ebeSReshma Pattan strcpy(str + strlen(str), oneline);
5080d547ed0SFan Zhang
5090d547ed0SFan Zhang str[strlen(str)] = '\n';
5100d547ed0SFan Zhang if (cmdline_parse(cl, str) < 0) {
511a1469c31SFan Zhang rte_panic("%s:%u: error: parsing \"%s\" failed\n",
512a1469c31SFan Zhang cfg_filename, line_num, str);
5130d547ed0SFan Zhang goto error_exit;
5140d547ed0SFan Zhang }
5150d547ed0SFan Zhang
5160d547ed0SFan Zhang if (status.status < 0) {
517a1469c31SFan Zhang rte_panic("%s:%u: error: %s", cfg_filename,
518a1469c31SFan Zhang line_num, status.parse_msg);
5190d547ed0SFan Zhang goto error_exit;
5200d547ed0SFan Zhang }
5210d547ed0SFan Zhang
5220d547ed0SFan Zhang memset(str, 0, 1024);
523a1469c31SFan Zhang } while (1);
5240d547ed0SFan Zhang
5250d547ed0SFan Zhang cmdline_stdin_exit(cl);
5260d547ed0SFan Zhang fclose(f);
5270d547ed0SFan Zhang
528e1143d7dSVladimir Medvedkin sa_sort_arr();
529b0806375SVladimir Medvedkin sp4_sort_arr();
530b0806375SVladimir Medvedkin sp6_sort_arr();
531e1143d7dSVladimir Medvedkin
5320d547ed0SFan Zhang return 0;
5330d547ed0SFan Zhang
5340d547ed0SFan Zhang error_exit:
5350d547ed0SFan Zhang if (cl)
5360d547ed0SFan Zhang cmdline_stdin_exit(cl);
5370d547ed0SFan Zhang if (f)
5380d547ed0SFan Zhang fclose(f);
5390d547ed0SFan Zhang
5400d547ed0SFan Zhang return -1;
5410d547ed0SFan Zhang }
542