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