Support for xtesting
[samplevnf.git] / VNFs / DPPD-PROX / parse_utils.c
index d258c59..8d846fd 100644 (file)
 
 #include "quit.h"
 #include "cfgfile.h"
-#include "ip6_addr.h"
 #include "parse_utils.h"
 #include "prox_globals.h"
 #include "prox_cfg.h"
 #include "log.h"
 #include "prox_lua.h"
 #include "prox_lua_types.h"
+#include "prox_ipv6.h"
+#include "prox_compat.h"
 
 #define MAX_NB_PORT_NAMES PROX_MAX_PORTS
 #define MAX_LEN_PORT_NAME 24
@@ -106,7 +107,7 @@ static struct var *var_lookup(const char *name)
        return NULL;
 }
 
-static int parse_single_var(char *val, size_t len, const char *name)
+int parse_single_var(char *val, size_t len, const char *name)
 {
        struct var *match;
 
@@ -117,7 +118,7 @@ static int parse_single_var(char *val, size_t len, const char *name)
                                 match->name, match->val);
                        return -1;
                }
-               strncpy(val, match->val, len);
+               prox_strncpy(val, match->val, len);
                return 0;
        }
        else {
@@ -135,7 +136,7 @@ int parse_vars(char *val, size_t len, const char *name)
 {
        static char result[MAX_CFG_STRING_LEN];
        static char cur_var[MAX_CFG_STRING_LEN];
-       char parsed[2048];
+       char parsed[MAX_CFG_STRING_LEN];
        size_t name_len = strlen(name);
        enum parse_vars_state {NO_VAR, WHOLE_VAR, INLINE_VAR} state = NO_VAR;
        size_t result_len = 0;
@@ -195,7 +196,7 @@ int parse_vars(char *val, size_t len, const char *name)
                        break;
                }
        }
-       strncpy(val, result, len);
+       prox_strncpy(val, result, len);
 
        return 0;
 }
@@ -310,7 +311,7 @@ int parse_ip(uint32_t *addr, const char *str2)
        return 0;
 }
 
-int parse_ip4_cidr(struct ip4_subnet *val, const char *str2)
+int parse_ip4_and_prefix(struct ip4_subnet *val, const char *str2)
 {
        char str[MAX_STR_LEN_PROC];
        char *slash;
@@ -340,10 +341,16 @@ int parse_ip4_cidr(struct ip4_subnet *val, const char *str2)
        if (parse_ip(&val->ip, str))
                return -2;
 
+       return 0;
+}
+
+int parse_ip4_cidr(struct ip4_subnet *val, const char *str2)
+{
+       int rc = parse_ip4_and_prefix(val, str2);
        /* Apply mask making all bits outside the prefix zero */
-       val->ip &= ((int)(1 << 31)) >> (prefix - 1);
+       val->ip &= ((int)(1 << 31)) >> (val->prefix - 1);
 
-       return 0;
+       return rc;
 }
 
 int parse_ip6_cidr(struct ip6_subnet *val, const char *str2)
@@ -405,12 +412,12 @@ int parse_ip6(struct ipv6_addr *addr, const char *str2)
 
        for (uint8_t i = 0, j = 0; i < ret; ++i, ++j) {
                if (*addr_parts[i] == 0) {
-                       if (omitted == 0) {
+                       if (omitted) {
                                set_errf("Can only omit zeros once");
                                return -1;
                        }
                        omitted = 1;
-                       j += 8 - ret;
+                       j += 2 * (8 - ret) + 1;
                }
                else {
                        uint16_t w = strtoll(addr_parts[i], NULL, 16);
@@ -421,7 +428,7 @@ int parse_ip6(struct ipv6_addr *addr, const char *str2)
        return 0;
 }
 
-int parse_mac(struct ether_addr *ether_addr, const char *str2)
+int parse_mac(prox_rte_ether_addr *ether_addr, const char *str2)
 {
        char str[MAX_STR_LEN_PROC];
        char *addr_parts[7];
@@ -430,6 +437,8 @@ int parse_mac(struct ether_addr *ether_addr, const char *str2)
                return -1;
 
        uint8_t ret = rte_strsplit(str, strlen(str), addr_parts, 7, ':');
+       if (ret != 6)
+               ret = rte_strsplit(str, strlen(str), addr_parts, 7, ' ');
 
        if (ret != 6) {
                set_errf("Invalid MAC address format");
@@ -837,6 +846,72 @@ int parse_task_set(struct core_task_set *cts, const char *str2)
        return 0;
 }
 
+int parse_ip_set(struct ip4_subnet *list, const char *str2, uint32_t max_list)
+{
+       char str[MAX_STR_LEN_PROC];
+       char *parts[MAX_STR_LEN_PROC];
+       int n = 0, rc;
+
+       if (parse_vars(str, sizeof(str), str2))
+               return -1;
+       int n_parts = rte_strsplit(str, strlen(str), parts, MAX_STR_LEN_PROC, ',');
+       for (int i = 0; i < n_parts; i++) {
+               if ((rc = parse_ip4_and_prefix(&list[i], parts[i])) < 0) {
+                       set_errf("Unable to parse ip4/prefix");
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+int parse_int_set(uint32_t *list, const char *str2, uint32_t max_list)
+{
+       char str[MAX_STR_LEN_PROC];
+       char *parts[MAX_STR_LEN_PROC];
+       uint32_t n = 0;
+
+       if (parse_vars(str, sizeof(str), str2))
+               return -1;
+
+       int n_parts = rte_strsplit(str, strlen(str), parts, MAX_STR_LEN_PROC, ',');
+       for (int i = 0; i < n_parts; i++) {
+               char *cur_part = parts[i];
+               char *sub_parts[3];
+               int n_sub_parts = rte_strsplit(cur_part, strlen(cur_part), sub_parts, 3, '-');
+               uint32_t n1, n2;
+               int ret = 0;
+
+               if (n_sub_parts == 1) {
+                       if (n >= max_list - 1) {
+                               set_errf("Too many entries\n");
+                               return -1;
+                       }
+                       if (parse_int(&list[n], sub_parts[0]))
+                               return -1;
+                       n++;
+               } else if (n_sub_parts == 2) {
+                       if (parse_int(&n1, sub_parts[0]))
+                               return -1;
+                       if (parse_int(&n2, sub_parts[1]))
+                               return -1;
+                       if (n + n2 - n1 >= max_list) {
+                               set_errf("Too many entries\n");
+                               return -1;
+                       }
+                       for (uint32_t j = n1; j < n2; j++) {
+                               list[n++] = j;
+                       }
+               } else if (n_sub_parts >= 3) {
+                       set_errf("Multiple '-' characters in range syntax found");
+                       return -1;
+               } else {
+                       set_errf("Invalid list syntax");
+                       return -1;
+               }
+       }
+       return 0;
+}
+
 int parse_list_set(uint32_t *list, const char *str2, uint32_t max_list)
 {
        char str[MAX_STR_LEN_PROC];
@@ -895,7 +970,7 @@ int parse_list_set(uint32_t *list, const char *str2, uint32_t max_list)
                                effective_core = cur_core;
 
                        if (list_count >= max_list) {
-                               set_errf("Too many elements in list\n");
+                               set_errf("Too many elements in list");
                                return -1;
                        }
                        list[list_count++] = effective_core;
@@ -920,10 +995,12 @@ int parse_kmg(uint32_t* val, const char *str2)
                if (*val >> 22)
                        return -2;
                *val <<= 10;
+               // __attribute__ ((fallthrough));
        case 'M':
                if (*val >> 22)
                        return -2;
                *val <<= 10;
+               // __attribute__ ((fallthrough));
        case 'K':
                if (*val >> 22)
                        return -2;
@@ -1046,7 +1123,7 @@ int parse_str(char* dst, const char *str2, size_t max_len)
                return -2;
        }
 
-       strncpy(dst, str, max_len);
+       prox_strncpy(dst, str, max_len);
        return 0;
 }
 
@@ -1120,7 +1197,7 @@ int parse_remap(uint8_t *mapping, const char *str)
                set_errf("String too long (max supported: %d)", MAX_STR_LEN_PROC);
                return -2;
        }
-       strncpy(str_cpy, str, MAX_STR_LEN_PROC);
+       prox_strncpy(str_cpy, str, MAX_STR_LEN_PROC);
 
        ret = rte_strsplit(str_cpy, strlen(str_cpy), elements, PROX_MAX_PORTS + 1, ',');
        if (ret <= 0) {
@@ -1177,7 +1254,7 @@ int add_port_name(uint32_t val, const char *str2)
        }
 
        pn = &port_names[nb_port_names];
-       strncpy(pn->name, str, sizeof(pn->name));
+       prox_strncpy(pn->name, str, sizeof(pn->name));
        pn->id = val;
 
        ++nb_port_names;
@@ -1195,7 +1272,7 @@ int set_self_var(const char *str)
 
        struct var *v = &vars[nb_vars];
 
-       strncpy(v->name, "$self", strlen("$self"));
+       prox_strncpy(v->name, "$self", strlen("$self") + 1);
        sprintf(v->val, "%s", str);
        nb_vars++;
 
@@ -1243,8 +1320,8 @@ int add_var(const char* name, const char *str2, uint8_t cli)
        v = &vars[nb_vars];
        PROX_PANIC(strlen(name) > sizeof(v->name), "\tUnable to parse var %s: too long\n", name);
        PROX_PANIC(strlen(str) > sizeof(v->val), "\tUnable to parse var %s=%s: too long\n", name,str);
-       strncpy(v->name, name, sizeof(v->name));
-       strncpy(v->val, str, sizeof(v->val));
+       prox_strncpy(v->name, name, sizeof(v->name));
+       prox_strncpy(v->val, str, sizeof(v->val));
        v->cli = cli;
 
        ++nb_vars;