net: add rte prefix to ether defines
[dpdk.git] / app / test-pmd / cmdline_flow.c
index 91e2e35..7a1c5ab 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) +
@@ -3248,15 +3259,26 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
                        .func = RTE_ETH_HASH_FUNCTION_DEFAULT,
                        .level = 0,
                        .types = rss_hf,
-                       .key_len = 0,
+                       .key_len = sizeof(action_rss_data->key),
                        .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
-                       .key = NULL,
+                       .key = action_rss_data->key,
                        .queue = action_rss_data->queue,
                },
+               .key = "testpmd's default RSS hash key, "
+                       "override it for better balancing",
                .queue = { 0 },
        };
        for (i = 0; i < action_rss_data->conf.queue_num; ++i)
                action_rss_data->queue[i] = i;
+       if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
+           ctx->port != (portid_t)RTE_PORT_ALL) {
+               struct rte_eth_dev_info info;
+
+               rte_eth_dev_info_get(ctx->port, &info);
+               action_rss_data->conf.key_len =
+                       RTE_MIN(sizeof(action_rss_data->key),
+                               info.hash_key_size);
+       }
        action->conf = &action_rss_data->conf;
        return ret;
 }
@@ -3471,9 +3493,9 @@ parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
                .item_vxlan.flags = 0,
        };
        memcpy(action_vxlan_encap_data->item_eth.dst.addr_bytes,
-              vxlan_encap_conf.eth_dst, ETHER_ADDR_LEN);
+              vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
        memcpy(action_vxlan_encap_data->item_eth.src.addr_bytes,
-              vxlan_encap_conf.eth_src, ETHER_ADDR_LEN);
+              vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
        if (!vxlan_encap_conf.select_ipv4) {
                memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr,
                       &vxlan_encap_conf.ipv6_src,
@@ -3490,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;
@@ -3562,9 +3616,9 @@ parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token,
                .item_nvgre.flow_id = 0,
        };
        memcpy(action_nvgre_encap_data->item_eth.dst.addr_bytes,
-              nvgre_encap_conf.eth_dst, ETHER_ADDR_LEN);
+              nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
        memcpy(action_nvgre_encap_data->item_eth.src.addr_bytes,
-              nvgre_encap_conf.eth_src, ETHER_ADDR_LEN);
+              nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
        if (!nvgre_encap_conf.select_ipv4) {
                memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr,
                       &nvgre_encap_conf.ipv6_src,
@@ -3626,22 +3680,22 @@ parse_vc_action_l2_encap(struct context *ctx, const struct token *token,
        };
        header = action_encap_data->data;
        if (l2_encap_conf.select_vlan)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
        else if (l2_encap_conf.select_ipv4)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
        else
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
        memcpy(eth.dst.addr_bytes,
-              l2_encap_conf.eth_dst, ETHER_ADDR_LEN);
+              l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
        memcpy(eth.src.addr_bytes,
-              l2_encap_conf.eth_src, ETHER_ADDR_LEN);
+              l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
        memcpy(header, &eth, sizeof(eth));
        header += sizeof(eth);
        if (l2_encap_conf.select_vlan) {
                if (l2_encap_conf.select_ipv4)
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
                else
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
                memcpy(header, &vlan, sizeof(vlan));
                header += sizeof(vlan);
        }
@@ -3690,7 +3744,7 @@ parse_vc_action_l2_decap(struct context *ctx, const struct token *token,
        };
        header = action_decap_data->data;
        if (l2_decap_conf.select_vlan)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
        memcpy(header, &eth, sizeof(eth));
        header += sizeof(eth);
        if (l2_decap_conf.select_vlan) {
@@ -3761,22 +3815,22 @@ parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token,
        };
        header = action_encap_data->data;
        if (mplsogre_encap_conf.select_vlan)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
        else if (mplsogre_encap_conf.select_ipv4)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
        else
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
        memcpy(eth.dst.addr_bytes,
-              mplsogre_encap_conf.eth_dst, ETHER_ADDR_LEN);
+              mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
        memcpy(eth.src.addr_bytes,
-              mplsogre_encap_conf.eth_src, ETHER_ADDR_LEN);
+              mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
        memcpy(header, &eth, sizeof(eth));
        header += sizeof(eth);
        if (mplsogre_encap_conf.select_vlan) {
                if (mplsogre_encap_conf.select_ipv4)
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
                else
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
                memcpy(header, &vlan, sizeof(vlan));
                header += sizeof(vlan);
        }
@@ -3797,6 +3851,7 @@ parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token,
        header += sizeof(gre);
        memcpy(mpls.label_tc_s, mplsogre_encap_conf.label,
               RTE_DIM(mplsogre_encap_conf.label));
+       mpls.label_tc_s[2] |= 0x1;
        memcpy(header, &mpls, sizeof(mpls));
        header += sizeof(mpls);
        action_encap_data->conf.size = header -
@@ -3855,22 +3910,22 @@ parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token,
        };
        header = action_decap_data->data;
        if (mplsogre_decap_conf.select_vlan)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
        else if (mplsogre_encap_conf.select_ipv4)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
        else
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
        memcpy(eth.dst.addr_bytes,
-              mplsogre_encap_conf.eth_dst, ETHER_ADDR_LEN);
+              mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
        memcpy(eth.src.addr_bytes,
-              mplsogre_encap_conf.eth_src, ETHER_ADDR_LEN);
+              mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
        memcpy(header, &eth, sizeof(eth));
        header += sizeof(eth);
        if (mplsogre_encap_conf.select_vlan) {
                if (mplsogre_encap_conf.select_ipv4)
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
                else
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
                memcpy(header, &vlan, sizeof(vlan));
                header += sizeof(vlan);
        }
@@ -3951,22 +4006,22 @@ parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token,
        };
        header = action_encap_data->data;
        if (mplsoudp_encap_conf.select_vlan)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
        else if (mplsoudp_encap_conf.select_ipv4)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
        else
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
        memcpy(eth.dst.addr_bytes,
-              mplsoudp_encap_conf.eth_dst, ETHER_ADDR_LEN);
+              mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
        memcpy(eth.src.addr_bytes,
-              mplsoudp_encap_conf.eth_src, ETHER_ADDR_LEN);
+              mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
        memcpy(header, &eth, sizeof(eth));
        header += sizeof(eth);
        if (mplsoudp_encap_conf.select_vlan) {
                if (mplsoudp_encap_conf.select_ipv4)
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
                else
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
                memcpy(header, &vlan, sizeof(vlan));
                header += sizeof(vlan);
        }
@@ -3987,6 +4042,7 @@ parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token,
        header += sizeof(udp);
        memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label,
               RTE_DIM(mplsoudp_encap_conf.label));
+       mpls.label_tc_s[2] |= 0x1;
        memcpy(header, &mpls, sizeof(mpls));
        header += sizeof(mpls);
        action_encap_data->conf.size = header -
@@ -4047,22 +4103,22 @@ parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token,
        };
        header = action_decap_data->data;
        if (mplsoudp_decap_conf.select_vlan)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
        else if (mplsoudp_encap_conf.select_ipv4)
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
        else
-               eth.type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+               eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
        memcpy(eth.dst.addr_bytes,
-              mplsoudp_encap_conf.eth_dst, ETHER_ADDR_LEN);
+              mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
        memcpy(eth.src.addr_bytes,
-              mplsoudp_encap_conf.eth_src, ETHER_ADDR_LEN);
+              mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
        memcpy(header, &eth, sizeof(eth));
        header += sizeof(eth);
        if (mplsoudp_encap_conf.select_vlan) {
                if (mplsoudp_encap_conf.select_ipv4)
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4);
                else
-                       vlan.inner_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+                       vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6);
                memcpy(header, &vlan, sizeof(vlan));
                header += sizeof(vlan);
        }
@@ -4314,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):
@@ -4428,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.
  *
@@ -4440,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;
@@ -4647,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;
@@ -4664,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;
@@ -4729,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;
@@ -4914,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;
@@ -4931,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