net: add rte prefix to ether structures
[dpdk.git] / app / test-pmd / cmdline_flow.c
index 5c0108f..2e274f9 100644 (file)
@@ -13,8 +13,8 @@
 #include <arpa/inet.h>
 #include <sys/socket.h>
 
+#include <rte_string_fns.h>
 #include <rte_common.h>
-#include <rte_eth_ctrl.h>
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
@@ -35,6 +35,7 @@ enum index {
        PREFIX,
        BOOLEAN,
        STRING,
+       HEX,
        MAC_ADDR,
        IPV4_ADDR,
        IPV6_ADDR,
@@ -1122,6 +1123,9 @@ static int parse_boolean(struct context *, const struct token *,
 static int parse_string(struct context *, const struct token *,
                        const char *, unsigned int,
                        void *, unsigned int);
+static int parse_hex(struct context *ctx, const struct token *token,
+                       const char *str, unsigned int len,
+                       void *buf, unsigned int size);
 static int parse_mac_addr(struct context *, const struct token *,
                          const char *, unsigned int,
                          void *, unsigned int);
@@ -1198,6 +1202,13 @@ static const struct token token_list[] = {
                .call = parse_string,
                .comp = comp_none,
        },
+       [HEX] = {
+               .name = "{hex}",
+               .type = "HEX",
+               .help = "fixed string",
+               .call = parse_hex,
+               .comp = comp_none,
+       },
        [MAC_ADDR] = {
                .name = "{MAC address}",
                .type = "MAC-48",
@@ -2306,7 +2317,7 @@ static const struct token token_list[] = {
        [ACTION_RSS_KEY] = {
                .name = "key",
                .help = "RSS hash key",
-               .next = NEXT(action_rss, NEXT_ENTRY(STRING)),
+               .next = NEXT(action_rss, NEXT_ENTRY(HEX)),
                .args = ARGS(ARGS_ENTRY_ARB(0, 0),
                             ARGS_ENTRY_ARB
                             (offsetof(struct action_rss_data, conf) +
@@ -3501,6 +3512,38 @@ parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
        if (!vxlan_encap_conf.select_vlan)
                action_vxlan_encap_data->items[1].type =
                        RTE_FLOW_ITEM_TYPE_VOID;
+       if (vxlan_encap_conf.select_tos_ttl) {
+               if (vxlan_encap_conf.select_ipv4) {
+                       static struct rte_flow_item_ipv4 ipv4_mask_tos;
+
+                       memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask,
+                              sizeof(ipv4_mask_tos));
+                       ipv4_mask_tos.hdr.type_of_service = 0xff;
+                       ipv4_mask_tos.hdr.time_to_live = 0xff;
+                       action_vxlan_encap_data->item_ipv4.hdr.type_of_service =
+                                       vxlan_encap_conf.ip_tos;
+                       action_vxlan_encap_data->item_ipv4.hdr.time_to_live =
+                                       vxlan_encap_conf.ip_ttl;
+                       action_vxlan_encap_data->items[2].mask =
+                                                       &ipv4_mask_tos;
+               } else {
+                       static struct rte_flow_item_ipv6 ipv6_mask_tos;
+
+                       memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask,
+                              sizeof(ipv6_mask_tos));
+                       ipv6_mask_tos.hdr.vtc_flow |=
+                               RTE_BE32(0xfful << IPV6_HDR_TC_SHIFT);
+                       ipv6_mask_tos.hdr.hop_limits = 0xff;
+                       action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |=
+                               rte_cpu_to_be_32
+                                       ((uint32_t)vxlan_encap_conf.ip_tos <<
+                                        IPV6_HDR_TC_SHIFT);
+                       action_vxlan_encap_data->item_ipv6.hdr.hop_limits =
+                                       vxlan_encap_conf.ip_ttl;
+                       action_vxlan_encap_data->items[2].mask =
+                                                       &ipv6_mask_tos;
+               }
+       }
        memcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni,
               RTE_DIM(vxlan_encap_conf.vni));
        action->conf = &action_vxlan_encap_data->conf;
@@ -4327,6 +4370,8 @@ parse_int(struct context *ctx, const struct token *token,
        }
        buf = (uint8_t *)ctx->object + arg->offset;
        size = arg->size;
+       if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t))
+               return -1;
 objmask:
        switch (size) {
        case sizeof(uint8_t):
@@ -4441,6 +4486,121 @@ error:
        return -1;
 }
 
+static int
+parse_hex_string(const char *src, uint8_t *dst, uint32_t *size)
+{
+       char *c = NULL;
+       uint32_t i, len;
+       char tmp[3];
+
+       /* Check input parameters */
+       if ((src == NULL) ||
+               (dst == NULL) ||
+               (size == NULL) ||
+               (*size == 0))
+               return -1;
+
+       /* Convert chars to bytes */
+       for (i = 0, len = 0; i < *size; i += 2) {
+               snprintf(tmp, 3, "%s", src + i);
+               dst[len++] = strtoul(tmp, &c, 16);
+               if (*c != 0) {
+                       len--;
+                       dst[len] = 0;
+                       *size = len;
+                       return -1;
+               }
+       }
+       dst[len] = 0;
+       *size = len;
+
+       return 0;
+}
+
+static int
+parse_hex(struct context *ctx, const struct token *token,
+               const char *str, unsigned int len,
+               void *buf, unsigned int size)
+{
+       const struct arg *arg_data = pop_args(ctx);
+       const struct arg *arg_len = pop_args(ctx);
+       const struct arg *arg_addr = pop_args(ctx);
+       char tmp[16]; /* Ought to be enough. */
+       int ret;
+       unsigned int hexlen = len;
+       unsigned int length = 256;
+       uint8_t hex_tmp[length];
+
+       /* Arguments are expected. */
+       if (!arg_data)
+               return -1;
+       if (!arg_len) {
+               push_args(ctx, arg_data);
+               return -1;
+       }
+       if (!arg_addr) {
+               push_args(ctx, arg_len);
+               push_args(ctx, arg_data);
+               return -1;
+       }
+       size = arg_data->size;
+       /* Bit-mask fill is not supported. */
+       if (arg_data->mask)
+               goto error;
+       if (!ctx->object)
+               return len;
+
+       /* translate bytes string to array. */
+       if (str[0] == '0' && ((str[1] == 'x') ||
+                       (str[1] == 'X'))) {
+               str += 2;
+               hexlen -= 2;
+       }
+       if (hexlen > length)
+               return -1;
+       ret = parse_hex_string(str, hex_tmp, &hexlen);
+       if (ret < 0)
+               goto error;
+       /* Let parse_int() fill length information first. */
+       ret = snprintf(tmp, sizeof(tmp), "%u", hexlen);
+       if (ret < 0)
+               goto error;
+       push_args(ctx, arg_len);
+       ret = parse_int(ctx, token, tmp, ret, NULL, 0);
+       if (ret < 0) {
+               pop_args(ctx);
+               goto error;
+       }
+       buf = (uint8_t *)ctx->object + arg_data->offset;
+       /* Output buffer is not necessarily NUL-terminated. */
+       memcpy(buf, hex_tmp, hexlen);
+       memset((uint8_t *)buf + hexlen, 0x00, size - hexlen);
+       if (ctx->objmask)
+               memset((uint8_t *)ctx->objmask + arg_data->offset,
+                                       0xff, hexlen);
+       /* Save address if requested. */
+       if (arg_addr->size) {
+               memcpy((uint8_t *)ctx->object + arg_addr->offset,
+                      (void *[]){
+                       (uint8_t *)ctx->object + arg_data->offset
+                      },
+                      arg_addr->size);
+               if (ctx->objmask)
+                       memcpy((uint8_t *)ctx->objmask + arg_addr->offset,
+                              (void *[]){
+                               (uint8_t *)ctx->objmask + arg_data->offset
+                              },
+                              arg_addr->size);
+       }
+       return len;
+error:
+       push_args(ctx, arg_addr);
+       push_args(ctx, arg_len);
+       push_args(ctx, arg_data);
+       return -1;
+
+}
+
 /**
  * Parse a MAC address.
  *
@@ -4453,7 +4613,7 @@ parse_mac_addr(struct context *ctx, const struct token *token,
               void *buf, unsigned int size)
 {
        const struct arg *arg = pop_args(ctx);
-       struct ether_addr tmp;
+       struct rte_ether_addr tmp;
        int ret;
 
        (void)token;
@@ -4660,7 +4820,7 @@ comp_boolean(struct context *ctx, const struct token *token,
        (void)token;
        for (i = 0; boolean_name[i]; ++i)
                if (buf && i == ent)
-                       return snprintf(buf, size, "%s", boolean_name[i]);
+                       return strlcpy(buf, boolean_name[i], size);
        if (buf)
                return -1;
        return i;
@@ -4677,8 +4837,8 @@ comp_action(struct context *ctx, const struct token *token,
        (void)token;
        for (i = 0; next_action[i]; ++i)
                if (buf && i == ent)
-                       return snprintf(buf, size, "%s",
-                                       token_list[next_action[i]].name);
+                       return strlcpy(buf, token_list[next_action[i]].name,
+                                      size);
        if (buf)
                return -1;
        return i;
@@ -4742,7 +4902,7 @@ comp_vc_action_rss_type(struct context *ctx, const struct token *token,
        if (!buf)
                return i + 1;
        if (ent < i)
-               return snprintf(buf, size, "%s", rss_type_table[ent].str);
+               return strlcpy(buf, rss_type_table[ent].str, size);
        if (ent == i)
                return snprintf(buf, size, "end");
        return -1;
@@ -4927,7 +5087,7 @@ cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index,
        if (index >= i)
                return -1;
        token = &token_list[list[index]];
-       snprintf(dst, size, "%s", token->name);
+       strlcpy(dst, token->name, size);
        /* Save index for cmd_flow_get_help(). */
        ctx->prev = list[index];
        return 0;
@@ -4944,7 +5104,7 @@ cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size)
        if (!size)
                return -1;
        /* Set token type and update global help with details. */
-       snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN"));
+       strlcpy(dst, (token->type ? token->type : "TOKEN"), size);
        if (token->help)
                cmd_flow.help_str = token->help;
        else