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