xref: /dpdk/examples/ipsec-secgw/parser.c (revision c2341bb6713dcaa43113db6f8ee3dd40ae57aba7)
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
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
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
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
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 *
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
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
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
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
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
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
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
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