/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2016 Intel Corporation
*/
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
#include <rte_common.h>
#include <rte_crypto.h>
#include <rte_string_fns.h>
#include <cmdline_socket.h>
#include <cmdline.h>
+#include "flow.h"
#include "ipsec.h"
#include "parser.h"
return 0;
}
-#define INADDRSZ 4
-#define IN6ADDRSZ 16
-
-/* int
- * inet_pton4(src, dst)
- * like inet_aton() but without all the hexadecimal and shorthand.
- * return:
- * 1 if `src' is a valid dotted quad, else 0.
- * notice:
- * does not touch `dst' unless it's returning 1.
- * author:
- * Paul Vixie, 1996.
- */
-static int
-inet_pton4(const char *src, unsigned char *dst)
-{
- static const char digits[] = "0123456789";
- int saw_digit, octets, ch;
- unsigned char tmp[INADDRSZ], *tp;
-
- saw_digit = 0;
- octets = 0;
- *(tp = tmp) = 0;
- while ((ch = *src++) != '\0') {
- const char *pch;
-
- pch = strchr(digits, ch);
- if (pch != NULL) {
- unsigned int new = *tp * 10 + (pch - digits);
-
- if (new > 255)
- return 0;
- if (!saw_digit) {
- if (++octets > 4)
- return 0;
- saw_digit = 1;
- }
- *tp = (unsigned char)new;
- } else if (ch == '.' && saw_digit) {
- if (octets == 4)
- return 0;
- *++tp = 0;
- saw_digit = 0;
- } else
- return 0;
- }
- if (octets < 4)
- return 0;
-
- memcpy(dst, tmp, INADDRSZ);
- return 1;
-}
-
-/* int
- * inet_pton6(src, dst)
- * convert presentation level address to network order binary form.
- * return:
- * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- * (1) does not touch `dst' unless it's returning 1.
- * (2) :: in a full address is silently ignored.
- * credit:
- * inspired by Mark Andrews.
- * author:
- * Paul Vixie, 1996.
- */
-static int
-inet_pton6(const char *src, unsigned char *dst)
-{
- static const char xdigits_l[] = "0123456789abcdef",
- xdigits_u[] = "0123456789ABCDEF";
- unsigned char tmp[IN6ADDRSZ], *tp = 0, *endp = 0, *colonp = 0;
- const char *xdigits = 0, *curtok = 0;
- int ch = 0, saw_xdigit = 0, count_xdigit = 0;
- unsigned int val = 0;
- unsigned dbloct_count = 0;
-
- memset((tp = tmp), '\0', IN6ADDRSZ);
- endp = tp + IN6ADDRSZ;
- colonp = NULL;
- /* Leading :: requires some special handling. */
- if (*src == ':')
- if (*++src != ':')
- return 0;
- curtok = src;
- saw_xdigit = count_xdigit = 0;
- val = 0;
-
- while ((ch = *src++) != '\0') {
- const char *pch;
-
- pch = strchr((xdigits = xdigits_l), ch);
- if (pch == NULL)
- pch = strchr((xdigits = xdigits_u), ch);
- if (pch != NULL) {
- if (count_xdigit >= 4)
- return 0;
- val <<= 4;
- val |= (pch - xdigits);
- if (val > 0xffff)
- return 0;
- saw_xdigit = 1;
- count_xdigit++;
- continue;
- }
- if (ch == ':') {
- curtok = src;
- if (!saw_xdigit) {
- if (colonp)
- return 0;
- colonp = tp;
- continue;
- } else if (*src == '\0') {
- return 0;
- }
- if (tp + sizeof(int16_t) > endp)
- return 0;
- *tp++ = (unsigned char) ((val >> 8) & 0xff);
- *tp++ = (unsigned char) (val & 0xff);
- saw_xdigit = 0;
- count_xdigit = 0;
- val = 0;
- dbloct_count++;
- continue;
- }
- if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
- inet_pton4(curtok, tp) > 0) {
- tp += INADDRSZ;
- saw_xdigit = 0;
- dbloct_count += 2;
- break; /* '\0' was seen by inet_pton4(). */
- }
- return 0;
- }
- if (saw_xdigit) {
- if (tp + sizeof(int16_t) > endp)
- return 0;
- *tp++ = (unsigned char) ((val >> 8) & 0xff);
- *tp++ = (unsigned char) (val & 0xff);
- dbloct_count++;
- }
- if (colonp != NULL) {
- /* if we already have 8 double octets, having a colon
- * means error */
- if (dbloct_count == 8)
- return 0;
-
- /*
- * Since some memmove()'s erroneously fail to handle
- * overlapping regions, we'll do the shift by hand.
- */
- const int n = tp - colonp;
- int i;
-
- for (i = 1; i <= n; i++) {
- endp[-i] = colonp[n - i];
- colonp[n - i] = 0;
- }
- tp = endp;
- }
- if (tp != endp)
- return 0;
- memcpy(dst, tmp, IN6ADDRSZ);
- return 1;
-}
-
int
parse_ipv4_addr(const char *token, struct in_addr *ipv4, uint32_t *mask)
{
if (strlen(ip_str) >= INET_ADDRSTRLEN)
return -EINVAL;
- if (inet_pton4(ip_str, (unsigned char *)ipv4) != 1)
+ if (inet_pton(AF_INET, ip_str, ipv4) != 1)
return -EINVAL;
return 0;
if (strlen(ip_str) >= INET6_ADDRSTRLEN)
return -EINVAL;
- if (inet_pton6(ip_str, (unsigned char *)ipv6) != 1)
+ if (inet_pton(AF_INET6, ip_str, ipv6) != 1)
return -EINVAL;
return 0;
},
};
+/* flow add parse */
+struct cfg_flow_add_cfg_item {
+ cmdline_fixed_string_t flow_keyword;
+ cmdline_multi_string_t multi_string;
+};
+
+static void
+cfg_flow_add_cfg_item_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl, void *data)
+{
+ struct cfg_flow_add_cfg_item *params = parsed_result;
+ char *tokens[32];
+ uint32_t n_tokens = RTE_DIM(tokens);
+ struct parse_status *status = (struct parse_status *)data;
+
+ APP_CHECK(parse_tokenize_string(
+ params->multi_string, tokens, &n_tokens) == 0,
+ status, "too many arguments\n");
+ if (status->status < 0)
+ return;
+
+ parse_flow_tokens(tokens, n_tokens, status);
+}
+
+static cmdline_parse_token_string_t cfg_flow_add_flow_str =
+ TOKEN_STRING_INITIALIZER(struct cfg_flow_add_cfg_item,
+ flow_keyword, "flow");
+
+static cmdline_parse_token_string_t cfg_flow_add_multi_str =
+ TOKEN_STRING_INITIALIZER(struct cfg_flow_add_cfg_item, multi_string,
+ TOKEN_STRING_MULTI);
+
+cmdline_parse_inst_t cfg_flow_add_rule = {
+ .f = cfg_flow_add_cfg_item_parsed,
+ .data = NULL,
+ .help_str = "",
+ .tokens = {
+ (void *) &cfg_flow_add_flow_str,
+ (void *) &cfg_flow_add_multi_str,
+ NULL,
+ },
+};
+
/* neigh add parse */
struct cfg_neigh_add_item {
cmdline_fixed_string_t neigh;
cmdline_parse_token_string_t cfg_add_neigh_pstr =
TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, pstr, "port");
cmdline_parse_token_num_t cfg_add_neigh_port =
- TOKEN_NUM_INITIALIZER(struct cfg_neigh_add_item, port, UINT16);
+ TOKEN_NUM_INITIALIZER(struct cfg_neigh_add_item, port, RTE_UINT16);
cmdline_parse_token_string_t cfg_add_neigh_mac =
TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, mac, NULL);
(cmdline_parse_inst_t *)&cfg_sp_add_rule,
(cmdline_parse_inst_t *)&cfg_sa_add_rule,
(cmdline_parse_inst_t *)&cfg_rt_add_rule,
+ (cmdline_parse_inst_t *)&cfg_flow_add_rule,
(cmdline_parse_inst_t *)&cfg_neigh_add_rule,
NULL,
};
cfg_sp_add_rule.data = &status;
cfg_sa_add_rule.data = &status;
cfg_rt_add_rule.data = &status;
+ cfg_flow_add_rule.data = &status;
cfg_neigh_add_rule.data = &status;
do {
cmdline_stdin_exit(cl);
fclose(f);
+ sa_sort_arr();
+ sp4_sort_arr();
+ sp6_sort_arr();
+
return 0;
error_exit: