+static void
+cmd_config_max_pkt_len_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_max_pkt_len_result *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "max-pkt-len")) {
+ if (res->value < ETHER_MIN_LEN) {
+ printf("max-pkt-len can not be less than %d\n",
+ ETHER_MIN_LEN);
+ return;
+ }
+ if (res->value == rx_mode.max_rx_pkt_len)
+ return;
+
+ rx_mode.max_rx_pkt_len = res->value;
+ if (res->value > ETHER_MAX_LEN)
+ rx_mode.jumbo_frame = 1;
+ else
+ rx_mode.jumbo_frame = 0;
+ } else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_max_pkt_len_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, port,
+ "port");
+cmdline_parse_token_string_t cmd_config_max_pkt_len_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, keyword,
+ "config");
+cmdline_parse_token_string_t cmd_config_max_pkt_len_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, all,
+ "all");
+cmdline_parse_token_string_t cmd_config_max_pkt_len_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, name,
+ "max-pkt-len");
+cmdline_parse_token_num_t cmd_config_max_pkt_len_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_max_pkt_len_result, value,
+ UINT32);
+
+cmdline_parse_inst_t cmd_config_max_pkt_len = {
+ .f = cmd_config_max_pkt_len_parsed,
+ .data = NULL,
+ .help_str = "port config all max-pkt-len value",
+ .tokens = {
+ (void *)&cmd_config_max_pkt_len_port,
+ (void *)&cmd_config_max_pkt_len_keyword,
+ (void *)&cmd_config_max_pkt_len_all,
+ (void *)&cmd_config_max_pkt_len_name,
+ (void *)&cmd_config_max_pkt_len_value,
+ NULL,
+ },
+};
+
+/* *** configure port MTU *** */
+struct cmd_config_mtu_result {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t mtu;
+ uint8_t port_id;
+ uint16_t value;
+};
+
+static void
+cmd_config_mtu_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_mtu_result *res = parsed_result;
+
+ if (res->value < ETHER_MIN_LEN) {
+ printf("mtu cannot be less than %d\n", ETHER_MIN_LEN);
+ return;
+ }
+ port_mtu_set(res->port_id, res->value);
+}
+
+cmdline_parse_token_string_t cmd_config_mtu_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, port,
+ "port");
+cmdline_parse_token_string_t cmd_config_mtu_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
+ "config");
+cmdline_parse_token_string_t cmd_config_mtu_mtu =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
+ "mtu");
+cmdline_parse_token_num_t cmd_config_mtu_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, port_id, UINT8);
+cmdline_parse_token_num_t cmd_config_mtu_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, value, UINT16);
+
+cmdline_parse_inst_t cmd_config_mtu = {
+ .f = cmd_config_mtu_parsed,
+ .data = NULL,
+ .help_str = "port config mtu value",
+ .tokens = {
+ (void *)&cmd_config_mtu_port,
+ (void *)&cmd_config_mtu_keyword,
+ (void *)&cmd_config_mtu_mtu,
+ (void *)&cmd_config_mtu_port_id,
+ (void *)&cmd_config_mtu_value,
+ NULL,
+ },
+};
+
+/* *** configure rx mode *** */
+struct cmd_config_rx_mode_flag {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ cmdline_fixed_string_t value;
+};
+
+static void
+cmd_config_rx_mode_flag_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_rx_mode_flag *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "crc-strip")) {
+ if (!strcmp(res->value, "on"))
+ rx_mode.hw_strip_crc = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_mode.hw_strip_crc = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "rx-cksum")) {
+ if (!strcmp(res->value, "on"))
+ rx_mode.hw_ip_checksum = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_mode.hw_ip_checksum = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "hw-vlan")) {
+ if (!strcmp(res->value, "on")) {
+ rx_mode.hw_vlan_filter = 1;
+ rx_mode.hw_vlan_strip = 1;
+ }
+ else if (!strcmp(res->value, "off")) {
+ rx_mode.hw_vlan_filter = 0;
+ rx_mode.hw_vlan_strip = 0;
+ }
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "hw-vlan-filter")) {
+ if (!strcmp(res->value, "on"))
+ rx_mode.hw_vlan_filter = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_mode.hw_vlan_filter = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "hw-vlan-strip")) {
+ if (!strcmp(res->value, "on"))
+ rx_mode.hw_vlan_strip = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_mode.hw_vlan_strip = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "hw-vlan-extend")) {
+ if (!strcmp(res->value, "on"))
+ rx_mode.hw_vlan_extend = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_mode.hw_vlan_extend = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "drop-en")) {
+ if (!strcmp(res->value, "on"))
+ rx_drop_en = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_drop_en = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, port, "port");
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, keyword,
+ "config");
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all");
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name,
+ "crc-strip#rx-cksum#hw-vlan#"
+ "hw-vlan-filter#hw-vlan-strip#hw-vlan-extend");
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value,
+ "on#off");
+
+cmdline_parse_inst_t cmd_config_rx_mode_flag = {
+ .f = cmd_config_rx_mode_flag_parsed,
+ .data = NULL,
+ .help_str = "port config all crc-strip|rx-cksum|hw-vlan|"
+ "hw-vlan-filter|hw-vlan-strip|hw-vlan-extend on|off",
+ .tokens = {
+ (void *)&cmd_config_rx_mode_flag_port,
+ (void *)&cmd_config_rx_mode_flag_keyword,
+ (void *)&cmd_config_rx_mode_flag_all,
+ (void *)&cmd_config_rx_mode_flag_name,
+ (void *)&cmd_config_rx_mode_flag_value,
+ NULL,
+ },
+};
+
+/* *** configure rss *** */
+struct cmd_config_rss {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ cmdline_fixed_string_t value;
+};
+
+static void
+cmd_config_rss_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_rss *res = parsed_result;
+ struct rte_eth_rss_conf rss_conf;
+ uint8_t i;
+
+ if (!strcmp(res->value, "all"))
+ rss_conf.rss_hf = ETH_RSS_IP | ETH_RSS_TCP |
+ ETH_RSS_UDP | ETH_RSS_SCTP |
+ ETH_RSS_L2_PAYLOAD;
+ else if (!strcmp(res->value, "ip"))
+ rss_conf.rss_hf = ETH_RSS_IP;
+ else if (!strcmp(res->value, "udp"))
+ rss_conf.rss_hf = ETH_RSS_UDP;
+ else if (!strcmp(res->value, "tcp"))
+ rss_conf.rss_hf = ETH_RSS_TCP;
+ else if (!strcmp(res->value, "sctp"))
+ rss_conf.rss_hf = ETH_RSS_SCTP;
+ else if (!strcmp(res->value, "ether"))
+ rss_conf.rss_hf = ETH_RSS_L2_PAYLOAD;
+ else if (!strcmp(res->value, "none"))
+ rss_conf.rss_hf = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ rss_conf.rss_key = NULL;
+ for (i = 0; i < rte_eth_dev_count(); i++)
+ rte_eth_dev_rss_hash_update(i, &rss_conf);
+}
+
+cmdline_parse_token_string_t cmd_config_rss_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss, keyword, "config");
+cmdline_parse_token_string_t cmd_config_rss_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss, all, "all");
+cmdline_parse_token_string_t cmd_config_rss_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
+cmdline_parse_token_string_t cmd_config_rss_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
+ "all#ip#tcp#udp#sctp#ether#none");
+
+cmdline_parse_inst_t cmd_config_rss = {
+ .f = cmd_config_rss_parsed,
+ .data = NULL,
+ .help_str = "port config all rss all|ip|tcp|udp|sctp|ether|none",
+ .tokens = {
+ (void *)&cmd_config_rss_port,
+ (void *)&cmd_config_rss_keyword,
+ (void *)&cmd_config_rss_all,
+ (void *)&cmd_config_rss_name,
+ (void *)&cmd_config_rss_value,
+ NULL,
+ },
+};
+
+/* *** configure rss hash key *** */
+struct cmd_config_rss_hash_key {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t config;
+ uint8_t port_id;
+ cmdline_fixed_string_t rss_hash_key;
+ cmdline_fixed_string_t rss_type;
+ cmdline_fixed_string_t key;
+};
+
+#define RSS_HASH_KEY_LENGTH 40
+static uint8_t
+hexa_digit_to_value(char hexa_digit)
+{
+ if ((hexa_digit >= '0') && (hexa_digit <= '9'))
+ return (uint8_t) (hexa_digit - '0');
+ if ((hexa_digit >= 'a') && (hexa_digit <= 'f'))
+ return (uint8_t) ((hexa_digit - 'a') + 10);
+ if ((hexa_digit >= 'A') && (hexa_digit <= 'F'))
+ return (uint8_t) ((hexa_digit - 'A') + 10);
+ /* Invalid hexa digit */
+ return 0xFF;
+}
+
+static uint8_t
+parse_and_check_key_hexa_digit(char *key, int idx)
+{
+ uint8_t hexa_v;
+
+ hexa_v = hexa_digit_to_value(key[idx]);
+ if (hexa_v == 0xFF)
+ printf("invalid key: character %c at position %d is not a "
+ "valid hexa digit\n", key[idx], idx);
+ return hexa_v;
+}
+
+static void
+cmd_config_rss_hash_key_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_rss_hash_key *res = parsed_result;
+ uint8_t hash_key[RSS_HASH_KEY_LENGTH];
+ uint8_t xdgt0;
+ uint8_t xdgt1;
+ int i;
+
+ /* Check the length of the RSS hash key */
+ if (strlen(res->key) != (RSS_HASH_KEY_LENGTH * 2)) {
+ printf("key length: %d invalid - key must be a string of %d"
+ "hexa-decimal numbers\n", (int) strlen(res->key),
+ RSS_HASH_KEY_LENGTH * 2);
+ return;
+ }
+ /* Translate RSS hash key into binary representation */
+ for (i = 0; i < RSS_HASH_KEY_LENGTH; i++) {
+ xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
+ if (xdgt0 == 0xFF)
+ return;
+ xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
+ if (xdgt1 == 0xFF)
+ return;
+ hash_key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
+ }
+ port_rss_hash_key_update(res->port_id, res->rss_type, hash_key,
+ RSS_HASH_KEY_LENGTH);
+}
+
+cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_config =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, config,
+ "config");
+cmdline_parse_token_num_t cmd_config_rss_hash_key_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_key, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
+ rss_hash_key, "rss-hash-key");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_type =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, rss_type,
+ "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
+ "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
+ "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
+ "ipv6-tcp-ex#ipv6-udp-ex");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
+
+cmdline_parse_inst_t cmd_config_rss_hash_key = {
+ .f = cmd_config_rss_hash_key_parsed,
+ .data = NULL,
+ .help_str =
+ "port config X rss-hash-key ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
+ "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
+ "ipv6-sctp|ipv6-other|l2-payload|"
+ "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex 80 hexa digits\n",
+ .tokens = {
+ (void *)&cmd_config_rss_hash_key_port,
+ (void *)&cmd_config_rss_hash_key_config,
+ (void *)&cmd_config_rss_hash_key_port_id,
+ (void *)&cmd_config_rss_hash_key_rss_hash_key,
+ (void *)&cmd_config_rss_hash_key_rss_type,
+ (void *)&cmd_config_rss_hash_key_value,
+ NULL,
+ },
+};
+
+/* *** configure port rxq/txq start/stop *** */
+struct cmd_config_rxtx_queue {
+ cmdline_fixed_string_t port;
+ uint8_t portid;
+ cmdline_fixed_string_t rxtxq;
+ uint16_t qid;
+ cmdline_fixed_string_t opname;
+};
+
+static void
+cmd_config_rxtx_queue_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_rxtx_queue *res = parsed_result;
+ uint8_t isrx;
+ uint8_t isstart;
+ int ret = 0;
+
+ if (test_done == 0) {
+ printf("Please stop forwarding first\n");
+ return;
+ }
+
+ if (port_id_is_invalid(res->portid, ENABLED_WARN))
+ return;
+
+ if (port_is_started(res->portid) != 1) {
+ printf("Please start port %u first\n", res->portid);
+ return;
+ }
+
+ if (!strcmp(res->rxtxq, "rxq"))
+ isrx = 1;
+ else if (!strcmp(res->rxtxq, "txq"))
+ isrx = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ if (isrx && rx_queue_id_is_invalid(res->qid))
+ return;
+ else if (!isrx && tx_queue_id_is_invalid(res->qid))
+ return;
+
+ if (!strcmp(res->opname, "start"))
+ isstart = 1;
+ else if (!strcmp(res->opname, "stop"))
+ isstart = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ if (isstart && isrx)
+ ret = rte_eth_dev_rx_queue_start(res->portid, res->qid);
+ else if (!isstart && isrx)
+ ret = rte_eth_dev_rx_queue_stop(res->portid, res->qid);
+ else if (isstart && !isrx)
+ ret = rte_eth_dev_tx_queue_start(res->portid, res->qid);
+ else
+ ret = rte_eth_dev_tx_queue_stop(res->portid, res->qid);
+
+ if (ret == -ENOTSUP)
+ printf("Function not supported in PMD driver\n");
+}
+
+cmdline_parse_token_string_t cmd_config_rxtx_queue_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, port, "port");
+cmdline_parse_token_num_t cmd_config_rxtx_queue_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, portid, UINT8);
+cmdline_parse_token_string_t cmd_config_rxtx_queue_rxtxq =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, rxtxq, "rxq#txq");
+cmdline_parse_token_num_t cmd_config_rxtx_queue_qid =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, qid, UINT16);
+cmdline_parse_token_string_t cmd_config_rxtx_queue_opname =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, opname,
+ "start#stop");
+
+cmdline_parse_inst_t cmd_config_rxtx_queue = {
+ .f = cmd_config_rxtx_queue_parsed,
+ .data = NULL,
+ .help_str = "port X rxq|txq ID start|stop",
+ .tokens = {
+ (void *)&cmd_config_speed_all_port,
+ (void *)&cmd_config_rxtx_queue_portid,
+ (void *)&cmd_config_rxtx_queue_rxtxq,
+ (void *)&cmd_config_rxtx_queue_qid,
+ (void *)&cmd_config_rxtx_queue_opname,
+ NULL,
+ },
+};
+
+/* *** Configure RSS RETA *** */
+struct cmd_config_rss_reta {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ uint8_t port_id;
+ cmdline_fixed_string_t name;
+ cmdline_fixed_string_t list_name;
+ cmdline_fixed_string_t list_of_items;
+};
+
+static int
+parse_reta_config(const char *str,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t nb_entries)
+{
+ int i;
+ unsigned size;
+ uint16_t hash_index, idx, shift;
+ uint8_t nb_queue;
+ char s[256];
+ const char *p, *p0 = str;
+ char *end;
+ enum fieldnames {
+ FLD_HASH_INDEX = 0,
+ FLD_QUEUE,
+ _NUM_FLD
+ };
+ unsigned long int_fld[_NUM_FLD];
+ char *str_fld[_NUM_FLD];
+
+ while ((p = strchr(p0,'(')) != NULL) {
+ ++p;
+ if((p0 = strchr(p,')')) == NULL)
+ return -1;
+
+ size = p0 - p;
+ if(size >= sizeof(s))
+ return -1;
+
+ snprintf(s, sizeof(s), "%.*s", size, p);
+ if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
+ return -1;
+ for (i = 0; i < _NUM_FLD; i++) {
+ errno = 0;
+ int_fld[i] = strtoul(str_fld[i], &end, 0);
+ if (errno != 0 || end == str_fld[i] ||
+ int_fld[i] > 65535)
+ return -1;
+ }
+
+ hash_index = (uint16_t)int_fld[FLD_HASH_INDEX];
+ nb_queue = (uint8_t)int_fld[FLD_QUEUE];
+
+ if (hash_index >= nb_entries) {
+ printf("Invalid RETA hash index=%d\n", hash_index);
+ return -1;
+ }
+
+ idx = hash_index / RTE_RETA_GROUP_SIZE;
+ shift = hash_index % RTE_RETA_GROUP_SIZE;
+ reta_conf[idx].mask |= (1ULL << shift);
+ reta_conf[idx].reta[shift] = nb_queue;
+ }
+
+ return 0;
+}
+
+static void
+cmd_set_rss_reta_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret;
+ struct rte_eth_dev_info dev_info;
+ struct rte_eth_rss_reta_entry64 reta_conf[8];
+ struct cmd_config_rss_reta *res = parsed_result;
+
+ memset(&dev_info, 0, sizeof(dev_info));
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+ if (dev_info.reta_size == 0) {
+ printf("Redirection table size is 0 which is "
+ "invalid for RSS\n");
+ return;
+ } else
+ printf("The reta size of port %d is %u\n",
+ res->port_id, dev_info.reta_size);
+ if (dev_info.reta_size > ETH_RSS_RETA_SIZE_512) {
+ printf("Currently do not support more than %u entries of "
+ "redirection table\n", ETH_RSS_RETA_SIZE_512);
+ return;
+ }
+
+ memset(reta_conf, 0, sizeof(reta_conf));
+ if (!strcmp(res->list_name, "reta")) {
+ if (parse_reta_config(res->list_of_items, reta_conf,
+ dev_info.reta_size)) {
+ printf("Invalid RSS Redirection Table "
+ "config entered\n");
+ return;
+ }
+ ret = rte_eth_dev_rss_reta_update(res->port_id,
+ reta_conf, dev_info.reta_size);
+ if (ret != 0)
+ printf("Bad redirection table parameter, "
+ "return code = %d \n", ret);
+ }
+}
+
+cmdline_parse_token_string_t cmd_config_rss_reta_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_reta_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, keyword, "config");
+cmdline_parse_token_num_t cmd_config_rss_reta_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_rss_reta, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_rss_reta_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, name, "rss");
+cmdline_parse_token_string_t cmd_config_rss_reta_list_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_name, "reta");
+cmdline_parse_token_string_t cmd_config_rss_reta_list_of_items =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_of_items,
+ NULL);
+cmdline_parse_inst_t cmd_config_rss_reta = {
+ .f = cmd_set_rss_reta_parsed,
+ .data = NULL,
+ .help_str = "port config X rss reta (hash,queue)[,(hash,queue)]",
+ .tokens = {
+ (void *)&cmd_config_rss_reta_port,
+ (void *)&cmd_config_rss_reta_keyword,
+ (void *)&cmd_config_rss_reta_port_id,
+ (void *)&cmd_config_rss_reta_name,
+ (void *)&cmd_config_rss_reta_list_name,
+ (void *)&cmd_config_rss_reta_list_of_items,
+ NULL,
+ },
+};
+
+/* *** SHOW PORT RETA INFO *** */
+struct cmd_showport_reta {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t port;
+ uint8_t port_id;
+ cmdline_fixed_string_t rss;
+ cmdline_fixed_string_t reta;
+ uint16_t size;
+ cmdline_fixed_string_t list_of_items;
+};
+
+static int
+showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf,
+ uint16_t nb_entries,
+ char *str)
+{
+ uint32_t size;
+ const char *p, *p0 = str;
+ char s[256];
+ char *end;
+ char *str_fld[8];
+ uint16_t i, num = nb_entries / RTE_RETA_GROUP_SIZE;
+ int ret;
+
+ p = strchr(p0, '(');
+ if (p == NULL)
+ return -1;
+ p++;
+ p0 = strchr(p, ')');
+ if (p0 == NULL)
+ return -1;
+ size = p0 - p;
+ if (size >= sizeof(s)) {
+ printf("The string size exceeds the internal buffer size\n");
+ return -1;
+ }
+ snprintf(s, sizeof(s), "%.*s", size, p);
+ ret = rte_strsplit(s, sizeof(s), str_fld, num, ',');
+ if (ret <= 0 || ret != num) {
+ printf("The bits of masks do not match the number of "
+ "reta entries: %u\n", num);
+ return -1;
+ }
+ for (i = 0; i < ret; i++)
+ conf[i].mask = (uint64_t)strtoul(str_fld[i], &end, 0);
+
+ return 0;
+}
+
+static void
+cmd_showport_reta_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_showport_reta *res = parsed_result;
+ struct rte_eth_rss_reta_entry64 reta_conf[8];
+ struct rte_eth_dev_info dev_info;
+
+ memset(&dev_info, 0, sizeof(dev_info));
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+ if (dev_info.reta_size == 0 || res->size != dev_info.reta_size ||
+ res->size > ETH_RSS_RETA_SIZE_512) {
+ printf("Invalid redirection table size: %u\n", res->size);
+ return;
+ }
+
+ memset(reta_conf, 0, sizeof(reta_conf));
+ if (showport_parse_reta_config(reta_conf, res->size,
+ res->list_of_items) < 0) {
+ printf("Invalid string: %s for reta masks\n",
+ res->list_of_items);
+ return;
+ }
+ port_rss_reta_info(res->port_id, reta_conf, res->size);
+}
+
+cmdline_parse_token_string_t cmd_showport_reta_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, show, "show");
+cmdline_parse_token_string_t cmd_showport_reta_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, port, "port");
+cmdline_parse_token_num_t cmd_showport_reta_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, port_id, UINT8);
+cmdline_parse_token_string_t cmd_showport_reta_rss =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, "rss");
+cmdline_parse_token_string_t cmd_showport_reta_reta =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, "reta");
+cmdline_parse_token_num_t cmd_showport_reta_size =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, size, UINT16);
+cmdline_parse_token_string_t cmd_showport_reta_list_of_items =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta,
+ list_of_items, NULL);
+
+cmdline_parse_inst_t cmd_showport_reta = {
+ .f = cmd_showport_reta_parsed,
+ .data = NULL,
+ .help_str = "show port X rss reta (size) (mask0,mask1,...)",
+ .tokens = {
+ (void *)&cmd_showport_reta_show,
+ (void *)&cmd_showport_reta_port,
+ (void *)&cmd_showport_reta_port_id,
+ (void *)&cmd_showport_reta_rss,
+ (void *)&cmd_showport_reta_reta,
+ (void *)&cmd_showport_reta_size,
+ (void *)&cmd_showport_reta_list_of_items,
+ NULL,
+ },
+};
+
+/* *** Show RSS hash configuration *** */
+struct cmd_showport_rss_hash {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t port;
+ uint8_t port_id;
+ cmdline_fixed_string_t rss_hash;
+ cmdline_fixed_string_t rss_type;
+ cmdline_fixed_string_t key; /* optional argument */
+};
+
+static void cmd_showport_rss_hash_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ void *show_rss_key)
+{
+ struct cmd_showport_rss_hash *res = parsed_result;
+
+ port_rss_hash_conf_show(res->port_id, res->rss_type,
+ show_rss_key != NULL);
+}
+
+cmdline_parse_token_string_t cmd_showport_rss_hash_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, show, "show");
+cmdline_parse_token_string_t cmd_showport_rss_hash_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, port, "port");
+cmdline_parse_token_num_t cmd_showport_rss_hash_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_rss_hash, port_id, UINT8);
+cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash,
+ "rss-hash");
+cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash_info =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_type,
+ "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
+ "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
+ "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
+ "ipv6-tcp-ex#ipv6-udp-ex");
+cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key");
+
+cmdline_parse_inst_t cmd_showport_rss_hash = {
+ .f = cmd_showport_rss_hash_parsed,
+ .data = NULL,
+ .help_str =
+ "show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
+ "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
+ "ipv6-sctp|ipv6-other|l2-payload|"
+ "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex (X = port number)\n",
+ .tokens = {
+ (void *)&cmd_showport_rss_hash_show,
+ (void *)&cmd_showport_rss_hash_port,
+ (void *)&cmd_showport_rss_hash_port_id,
+ (void *)&cmd_showport_rss_hash_rss_hash,
+ (void *)&cmd_showport_rss_hash_rss_hash_info,
+ NULL,
+ },
+};
+
+cmdline_parse_inst_t cmd_showport_rss_hash_key = {
+ .f = cmd_showport_rss_hash_parsed,
+ .data = (void *)1,
+ .help_str =
+ "show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
+ "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
+ "ipv6-sctp|ipv6-other|l2-payload|"
+ "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex key (X = port number)\n",
+ .tokens = {
+ (void *)&cmd_showport_rss_hash_show,
+ (void *)&cmd_showport_rss_hash_port,
+ (void *)&cmd_showport_rss_hash_port_id,
+ (void *)&cmd_showport_rss_hash_rss_hash,
+ (void *)&cmd_showport_rss_hash_rss_hash_info,
+ (void *)&cmd_showport_rss_hash_rss_key,
+ NULL,
+ },
+};
+
+/* *** Configure DCB *** */
+struct cmd_config_dcb {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t config;
+ uint8_t port_id;
+ cmdline_fixed_string_t dcb;
+ cmdline_fixed_string_t vt;
+ cmdline_fixed_string_t vt_en;
+ uint8_t num_tcs;
+ cmdline_fixed_string_t pfc;
+ cmdline_fixed_string_t pfc_en;
+};
+
+static void
+cmd_config_dcb_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_dcb *res = parsed_result;
+ portid_t port_id = res->port_id;
+ struct rte_port *port;
+ uint8_t pfc_en;
+ int ret;
+
+ port = &ports[port_id];
+ /** Check if the port is not started **/
+ if (port->port_status != RTE_PORT_STOPPED) {
+ printf("Please stop port %d first\n", port_id);
+ return;
+ }
+
+ if ((res->num_tcs != ETH_4_TCS) && (res->num_tcs != ETH_8_TCS)) {
+ printf("The invalid number of traffic class,"
+ " only 4 or 8 allowed.\n");
+ return;
+ }
+
+ if (nb_fwd_lcores < res->num_tcs) {
+ printf("nb_cores shouldn't be less than number of TCs.\n");
+ return;
+ }
+ if (!strncmp(res->pfc_en, "on", 2))
+ pfc_en = 1;
+ else
+ pfc_en = 0;
+
+ /* DCB in VT mode */
+ if (!strncmp(res->vt_en, "on", 2))
+ ret = init_port_dcb_config(port_id, DCB_VT_ENABLED,
+ (enum rte_eth_nb_tcs)res->num_tcs,
+ pfc_en);
+ else
+ ret = init_port_dcb_config(port_id, DCB_ENABLED,
+ (enum rte_eth_nb_tcs)res->num_tcs,
+ pfc_en);
+
+
+ if (ret != 0) {
+ printf("Cannot initialize network ports.\n");
+ return;
+ }
+
+ cmd_reconfig_device_queue(port_id, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_dcb_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, port, "port");
+cmdline_parse_token_string_t cmd_config_dcb_config =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, config, "config");
+cmdline_parse_token_num_t cmd_config_dcb_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_dcb_dcb =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, dcb, "dcb");
+cmdline_parse_token_string_t cmd_config_dcb_vt =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt, "vt");
+cmdline_parse_token_string_t cmd_config_dcb_vt_en =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt_en, "on#off");
+cmdline_parse_token_num_t cmd_config_dcb_num_tcs =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, num_tcs, UINT8);
+cmdline_parse_token_string_t cmd_config_dcb_pfc=
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc, "pfc");
+cmdline_parse_token_string_t cmd_config_dcb_pfc_en =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc_en, "on#off");
+
+cmdline_parse_inst_t cmd_config_dcb = {
+ .f = cmd_config_dcb_parsed,
+ .data = NULL,
+ .help_str = "port config port-id dcb vt on|off nb-tcs pfc on|off",
+ .tokens = {
+ (void *)&cmd_config_dcb_port,
+ (void *)&cmd_config_dcb_config,
+ (void *)&cmd_config_dcb_port_id,
+ (void *)&cmd_config_dcb_dcb,
+ (void *)&cmd_config_dcb_vt,
+ (void *)&cmd_config_dcb_vt_en,
+ (void *)&cmd_config_dcb_num_tcs,
+ (void *)&cmd_config_dcb_pfc,
+ (void *)&cmd_config_dcb_pfc_en,
+ NULL,
+ },
+};
+
+/* *** configure number of packets per burst *** */
+struct cmd_config_burst {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ uint16_t value;
+};
+
+static void
+cmd_config_burst_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_burst *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "burst")) {
+ if (res->value < 1 || res->value > MAX_PKT_BURST) {
+ printf("burst must be >= 1 && <= %d\n", MAX_PKT_BURST);
+ return;
+ }
+ nb_pkt_per_burst = res->value;
+ } else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_burst_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_burst, port, "port");
+cmdline_parse_token_string_t cmd_config_burst_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_burst, keyword, "config");
+cmdline_parse_token_string_t cmd_config_burst_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_burst, all, "all");
+cmdline_parse_token_string_t cmd_config_burst_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_burst, name, "burst");
+cmdline_parse_token_num_t cmd_config_burst_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_burst, value, UINT16);
+
+cmdline_parse_inst_t cmd_config_burst = {
+ .f = cmd_config_burst_parsed,
+ .data = NULL,
+ .help_str = "port config all burst value",
+ .tokens = {
+ (void *)&cmd_config_burst_port,
+ (void *)&cmd_config_burst_keyword,
+ (void *)&cmd_config_burst_all,
+ (void *)&cmd_config_burst_name,
+ (void *)&cmd_config_burst_value,
+ NULL,
+ },
+};
+
+/* *** configure rx/tx queues *** */
+struct cmd_config_thresh {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ uint8_t value;
+};
+
+static void
+cmd_config_thresh_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_thresh *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "txpt"))
+ tx_pthresh = res->value;
+ else if(!strcmp(res->name, "txht"))
+ tx_hthresh = res->value;
+ else if(!strcmp(res->name, "txwt"))
+ tx_wthresh = res->value;
+ else if(!strcmp(res->name, "rxpt"))
+ rx_pthresh = res->value;
+ else if(!strcmp(res->name, "rxht"))
+ rx_hthresh = res->value;
+ else if(!strcmp(res->name, "rxwt"))
+ rx_wthresh = res->value;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_thresh_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, port, "port");
+cmdline_parse_token_string_t cmd_config_thresh_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, keyword, "config");
+cmdline_parse_token_string_t cmd_config_thresh_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, all, "all");
+cmdline_parse_token_string_t cmd_config_thresh_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, name,
+ "txpt#txht#txwt#rxpt#rxht#rxwt");
+cmdline_parse_token_num_t cmd_config_thresh_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_thresh, value, UINT8);
+
+cmdline_parse_inst_t cmd_config_thresh = {
+ .f = cmd_config_thresh_parsed,
+ .data = NULL,
+ .help_str = "port config all txpt|txht|txwt|rxpt|rxht|rxwt value",
+ .tokens = {
+ (void *)&cmd_config_thresh_port,
+ (void *)&cmd_config_thresh_keyword,
+ (void *)&cmd_config_thresh_all,
+ (void *)&cmd_config_thresh_name,
+ (void *)&cmd_config_thresh_value,
+ NULL,
+ },
+};
+
+/* *** configure free/rs threshold *** */
+struct cmd_config_threshold {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ uint16_t value;
+};
+
+static void
+cmd_config_threshold_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_threshold *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "txfreet"))
+ tx_free_thresh = res->value;
+ else if (!strcmp(res->name, "txrst"))
+ tx_rs_thresh = res->value;
+ else if (!strcmp(res->name, "rxfreet"))
+ rx_free_thresh = res->value;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_threshold_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, port, "port");
+cmdline_parse_token_string_t cmd_config_threshold_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, keyword,
+ "config");
+cmdline_parse_token_string_t cmd_config_threshold_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, all, "all");
+cmdline_parse_token_string_t cmd_config_threshold_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, name,
+ "txfreet#txrst#rxfreet");
+cmdline_parse_token_num_t cmd_config_threshold_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_threshold, value, UINT16);
+
+cmdline_parse_inst_t cmd_config_threshold = {
+ .f = cmd_config_threshold_parsed,
+ .data = NULL,
+ .help_str = "port config all txfreet|txrst|rxfreet value",
+ .tokens = {
+ (void *)&cmd_config_threshold_port,
+ (void *)&cmd_config_threshold_keyword,
+ (void *)&cmd_config_threshold_all,
+ (void *)&cmd_config_threshold_name,
+ (void *)&cmd_config_threshold_value,
+ NULL,
+ },
+};
+
+/* *** stop *** */
+struct cmd_stop_result {
+ cmdline_fixed_string_t stop;
+};
+
+static void cmd_stop_parsed(__attribute__((unused)) void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ stop_packet_forwarding();
+}
+
+cmdline_parse_token_string_t cmd_stop_stop =
+ TOKEN_STRING_INITIALIZER(struct cmd_stop_result, stop, "stop");
+
+cmdline_parse_inst_t cmd_stop = {
+ .f = cmd_stop_parsed,
+ .data = NULL,
+ .help_str = "stop - stop packet forwarding",
+ .tokens = {
+ (void *)&cmd_stop_stop,
+ NULL,
+ },
+};
+
+/* *** SET CORELIST and PORTLIST CONFIGURATION *** */
+
+unsigned int
+parse_item_list(char* str, const char* item_name, unsigned int max_items,
+ unsigned int *parsed_items, int check_unique_values)
+{
+ unsigned int nb_item;
+ unsigned int value;
+ unsigned int i;
+ unsigned int j;
+ int value_ok;
+ char c;
+
+ /*
+ * First parse all items in the list and store their value.
+ */
+ value = 0;
+ nb_item = 0;
+ value_ok = 0;
+ for (i = 0; i < strnlen(str, STR_TOKEN_SIZE); i++) {
+ c = str[i];
+ if ((c >= '0') && (c <= '9')) {
+ value = (unsigned int) (value * 10 + (c - '0'));
+ value_ok = 1;
+ continue;
+ }
+ if (c != ',') {
+ printf("character %c is not a decimal digit\n", c);
+ return (0);
+ }
+ if (! value_ok) {
+ printf("No valid value before comma\n");
+ return (0);
+ }
+ if (nb_item < max_items) {
+ parsed_items[nb_item] = value;
+ value_ok = 0;
+ value = 0;
+ }
+ nb_item++;
+ }
+ if (nb_item >= max_items) {
+ printf("Number of %s = %u > %u (maximum items)\n",
+ item_name, nb_item + 1, max_items);
+ return (0);
+ }
+ parsed_items[nb_item++] = value;
+ if (! check_unique_values)
+ return (nb_item);
+
+ /*
+ * Then, check that all values in the list are differents.
+ * No optimization here...
+ */
+ for (i = 0; i < nb_item; i++) {
+ for (j = i + 1; j < nb_item; j++) {
+ if (parsed_items[j] == parsed_items[i]) {
+ printf("duplicated %s %u at index %u and %u\n",
+ item_name, parsed_items[i], i, j);
+ return (0);
+ }
+ }
+ }
+ return (nb_item);
+}
+
+struct cmd_set_list_result {
+ cmdline_fixed_string_t cmd_keyword;
+ cmdline_fixed_string_t list_name;
+ cmdline_fixed_string_t list_of_items;
+};
+
+static void cmd_set_list_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_list_result *res;
+ union {
+ unsigned int lcorelist[RTE_MAX_LCORE];
+ unsigned int portlist[RTE_MAX_ETHPORTS];
+ } parsed_items;
+ unsigned int nb_item;
+
+ if (test_done == 0) {
+ printf("Please stop forwarding first\n");
+ return;
+ }
+
+ res = parsed_result;
+ if (!strcmp(res->list_name, "corelist")) {
+ nb_item = parse_item_list(res->list_of_items, "core",
+ RTE_MAX_LCORE,
+ parsed_items.lcorelist, 1);
+ if (nb_item > 0)
+ set_fwd_lcores_list(parsed_items.lcorelist, nb_item);
+ return;
+ }
+ if (!strcmp(res->list_name, "portlist")) {
+ nb_item = parse_item_list(res->list_of_items, "port",
+ RTE_MAX_ETHPORTS,
+ parsed_items.portlist, 1);
+ if (nb_item > 0)
+ set_fwd_ports_list(parsed_items.portlist, nb_item);
+ }
+}
+
+cmdline_parse_token_string_t cmd_set_list_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, cmd_keyword,
+ "set");
+cmdline_parse_token_string_t cmd_set_list_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_name,
+ "corelist#portlist");
+cmdline_parse_token_string_t cmd_set_list_of_items =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_of_items,
+ NULL);
+
+cmdline_parse_inst_t cmd_set_fwd_list = {
+ .f = cmd_set_list_parsed,
+ .data = NULL,
+ .help_str = "set corelist|portlist x[,y]*",
+ .tokens = {
+ (void *)&cmd_set_list_keyword,
+ (void *)&cmd_set_list_name,
+ (void *)&cmd_set_list_of_items,
+ NULL,
+ },
+};
+
+/* *** SET COREMASK and PORTMASK CONFIGURATION *** */
+
+struct cmd_setmask_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t mask;
+ uint64_t hexavalue;
+};
+
+static void cmd_set_mask_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_setmask_result *res = parsed_result;
+
+ if (test_done == 0) {
+ printf("Please stop forwarding first\n");
+ return;
+ }
+ if (!strcmp(res->mask, "coremask"))
+ set_fwd_lcores_mask(res->hexavalue);
+ else if (!strcmp(res->mask, "portmask"))
+ set_fwd_ports_mask(res->hexavalue);
+}
+
+cmdline_parse_token_string_t cmd_setmask_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, set, "set");
+cmdline_parse_token_string_t cmd_setmask_mask =
+ TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, mask,
+ "coremask#portmask");
+cmdline_parse_token_num_t cmd_setmask_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_setmask_result, hexavalue, UINT64);
+
+cmdline_parse_inst_t cmd_set_fwd_mask = {
+ .f = cmd_set_mask_parsed,
+ .data = NULL,
+ .help_str = "set coremask|portmask hexadecimal value",
+ .tokens = {
+ (void *)&cmd_setmask_set,
+ (void *)&cmd_setmask_mask,
+ (void *)&cmd_setmask_value,
+ NULL,
+ },
+};
+
+/*
+ * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
+ */
+struct cmd_set_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t what;
+ uint16_t value;
+};
+
+static void cmd_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_result *res = parsed_result;
+ if (!strcmp(res->what, "nbport"))
+ set_fwd_ports_number(res->value);
+ else if (!strcmp(res->what, "nbcore"))
+ set_fwd_lcores_number(res->value);
+ else if (!strcmp(res->what, "burst"))
+ set_nb_pkt_per_burst(res->value);
+ else if (!strcmp(res->what, "verbose"))
+ set_verbose_level(res->value);
+}
+
+cmdline_parse_token_string_t cmd_set_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
+cmdline_parse_token_string_t cmd_set_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
+ "nbport#nbcore#burst#verbose");
+cmdline_parse_token_num_t cmd_set_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
+
+cmdline_parse_inst_t cmd_set_numbers = {
+ .f = cmd_set_parsed,
+ .data = NULL,
+ .help_str = "set nbport|nbcore|burst|verbose value",
+ .tokens = {
+ (void *)&cmd_set_set,
+ (void *)&cmd_set_what,
+ (void *)&cmd_set_value,
+ NULL,
+ },
+};
+
+/* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */
+
+struct cmd_set_txpkts_result {
+ cmdline_fixed_string_t cmd_keyword;
+ cmdline_fixed_string_t txpkts;
+ cmdline_fixed_string_t seg_lengths;
+};
+
+static void
+cmd_set_txpkts_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_txpkts_result *res;
+ unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT];
+ unsigned int nb_segs;
+
+ res = parsed_result;
+ nb_segs = parse_item_list(res->seg_lengths, "segment lengths",
+ RTE_MAX_SEGS_PER_PKT, seg_lengths, 0);
+ if (nb_segs > 0)
+ set_tx_pkt_segments(seg_lengths, nb_segs);
+}
+
+cmdline_parse_token_string_t cmd_set_txpkts_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
+ cmd_keyword, "set");
+cmdline_parse_token_string_t cmd_set_txpkts_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
+ txpkts, "txpkts");
+cmdline_parse_token_string_t cmd_set_txpkts_lengths =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
+ seg_lengths, NULL);
+
+cmdline_parse_inst_t cmd_set_txpkts = {
+ .f = cmd_set_txpkts_parsed,
+ .data = NULL,
+ .help_str = "set txpkts x[,y]*",
+ .tokens = {
+ (void *)&cmd_set_txpkts_keyword,
+ (void *)&cmd_set_txpkts_name,
+ (void *)&cmd_set_txpkts_lengths,
+ NULL,
+ },
+};
+
+/* *** SET COPY AND SPLIT POLICY ON TX PACKETS *** */
+
+struct cmd_set_txsplit_result {
+ cmdline_fixed_string_t cmd_keyword;
+ cmdline_fixed_string_t txsplit;
+ cmdline_fixed_string_t mode;
+};
+
+static void
+cmd_set_txsplit_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_txsplit_result *res;
+
+ res = parsed_result;
+ set_tx_pkt_split(res->mode);
+}
+
+cmdline_parse_token_string_t cmd_set_txsplit_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
+ cmd_keyword, "set");
+cmdline_parse_token_string_t cmd_set_txsplit_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
+ txsplit, "txsplit");
+cmdline_parse_token_string_t cmd_set_txsplit_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
+ mode, NULL);
+
+cmdline_parse_inst_t cmd_set_txsplit = {
+ .f = cmd_set_txsplit_parsed,
+ .data = NULL,
+ .help_str = "set txsplit on|off|rand",
+ .tokens = {
+ (void *)&cmd_set_txsplit_keyword,
+ (void *)&cmd_set_txsplit_name,
+ (void *)&cmd_set_txsplit_mode,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */
+struct cmd_rx_vlan_filter_all_result {
+ cmdline_fixed_string_t rx_vlan;
+ cmdline_fixed_string_t what;
+ cmdline_fixed_string_t all;
+ uint8_t port_id;
+};
+
+static void
+cmd_rx_vlan_filter_all_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_rx_vlan_filter_all_result *res = parsed_result;
+
+ if (!strcmp(res->what, "add"))
+ rx_vlan_all_filter_set(res->port_id, 1);
+ else
+ rx_vlan_all_filter_set(res->port_id, 0);
+}
+
+cmdline_parse_token_string_t cmd_rx_vlan_filter_all_rx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
+ rx_vlan, "rx_vlan");
+cmdline_parse_token_string_t cmd_rx_vlan_filter_all_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
+ what, "add#rm");
+cmdline_parse_token_string_t cmd_rx_vlan_filter_all_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
+ all, "all");
+cmdline_parse_token_num_t cmd_rx_vlan_filter_all_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
+ .f = cmd_rx_vlan_filter_all_parsed,
+ .data = NULL,
+ .help_str = "add/remove all identifiers to/from the set of VLAN "
+ "Identifiers filtered by a port",
+ .tokens = {
+ (void *)&cmd_rx_vlan_filter_all_rx_vlan,
+ (void *)&cmd_rx_vlan_filter_all_what,
+ (void *)&cmd_rx_vlan_filter_all_all,
+ (void *)&cmd_rx_vlan_filter_all_portid,
+ NULL,
+ },
+};
+
+/* *** VLAN OFFLOAD SET ON A PORT *** */
+struct cmd_vlan_offload_result {
+ cmdline_fixed_string_t vlan;
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t what;
+ cmdline_fixed_string_t on;
+ cmdline_fixed_string_t port_id;
+};
+
+static void
+cmd_vlan_offload_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int on;
+ struct cmd_vlan_offload_result *res = parsed_result;
+ char *str;
+ int i, len = 0;
+ portid_t port_id = 0;
+ unsigned int tmp;
+
+ str = res->port_id;
+ len = strnlen(str, STR_TOKEN_SIZE);
+ i = 0;
+ /* Get port_id first */
+ while(i < len){
+ if(str[i] == ',')
+ break;
+
+ i++;
+ }
+ str[i]='\0';
+ tmp = strtoul(str, NULL, 0);
+ /* If port_id greater that what portid_t can represent, return */
+ if(tmp >= RTE_MAX_ETHPORTS)
+ return;
+ port_id = (portid_t)tmp;
+
+ if (!strcmp(res->on, "on"))
+ on = 1;
+ else
+ on = 0;
+
+ if (!strcmp(res->what, "strip"))
+ rx_vlan_strip_set(port_id, on);
+ else if(!strcmp(res->what, "stripq")){
+ uint16_t queue_id = 0;
+
+ /* No queue_id, return */
+ if(i + 1 >= len) {
+ printf("must specify (port,queue_id)\n");
+ return;
+ }
+ tmp = strtoul(str + i + 1, NULL, 0);
+ /* If queue_id greater that what 16-bits can represent, return */
+ if(tmp > 0xffff)
+ return;
+
+ queue_id = (uint16_t)tmp;
+ rx_vlan_strip_set_on_queue(port_id, queue_id, on);
+ }
+ else if (!strcmp(res->what, "filter"))
+ rx_vlan_filter_set(port_id, on);
+ else
+ vlan_extend_set(port_id, on);
+
+ return;
+}
+
+cmdline_parse_token_string_t cmd_vlan_offload_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+ vlan, "vlan");
+cmdline_parse_token_string_t cmd_vlan_offload_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_vlan_offload_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+ what, "strip#filter#qinq#stripq");
+cmdline_parse_token_string_t cmd_vlan_offload_on =
+ TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+ on, "on#off");
+cmdline_parse_token_string_t cmd_vlan_offload_portid =
+ TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+ port_id, NULL);
+
+cmdline_parse_inst_t cmd_vlan_offload = {
+ .f = cmd_vlan_offload_parsed,
+ .data = NULL,
+ .help_str = "set strip|filter|qinq|stripq on|off port_id[,queue_id], filter/strip for rx side"
+ " qinq(extended) for both rx/tx sides ",
+ .tokens = {
+ (void *)&cmd_vlan_offload_vlan,
+ (void *)&cmd_vlan_offload_set,
+ (void *)&cmd_vlan_offload_what,
+ (void *)&cmd_vlan_offload_on,
+ (void *)&cmd_vlan_offload_portid,
+ NULL,
+ },
+};
+
+/* *** VLAN TPID SET ON A PORT *** */
+struct cmd_vlan_tpid_result {
+ cmdline_fixed_string_t vlan;
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t what;
+ uint16_t tp_id;
+ uint8_t port_id;
+};
+
+static void
+cmd_vlan_tpid_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_vlan_tpid_result *res = parsed_result;
+ vlan_tpid_set(res->port_id, res->tp_id);
+ return;
+}
+
+cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+ vlan, "vlan");
+cmdline_parse_token_string_t cmd_vlan_tpid_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_vlan_tpid_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+ what, "tpid");
+cmdline_parse_token_num_t cmd_vlan_tpid_tpid =
+ TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
+ tp_id, UINT16);
+cmdline_parse_token_num_t cmd_vlan_tpid_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_vlan_tpid = {
+ .f = cmd_vlan_tpid_parsed,
+ .data = NULL,
+ .help_str = "set tpid tp_id port_id, set the Outer VLAN Ether type",
+ .tokens = {
+ (void *)&cmd_vlan_tpid_vlan,
+ (void *)&cmd_vlan_tpid_set,
+ (void *)&cmd_vlan_tpid_what,
+ (void *)&cmd_vlan_tpid_tpid,
+ (void *)&cmd_vlan_tpid_portid,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
+struct cmd_rx_vlan_filter_result {
+ cmdline_fixed_string_t rx_vlan;
+ cmdline_fixed_string_t what;
+ uint16_t vlan_id;
+ uint8_t port_id;
+};
+
+static void
+cmd_rx_vlan_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_rx_vlan_filter_result *res = parsed_result;
+
+ if (!strcmp(res->what, "add"))
+ rx_vft_set(res->port_id, res->vlan_id, 1);
+ else
+ rx_vft_set(res->port_id, res->vlan_id, 0);
+}
+
+cmdline_parse_token_string_t cmd_rx_vlan_filter_rx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
+ rx_vlan, "rx_vlan");
+cmdline_parse_token_string_t cmd_rx_vlan_filter_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
+ what, "add#rm");
+cmdline_parse_token_num_t cmd_rx_vlan_filter_vlanid =
+ TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
+ vlan_id, UINT16);
+cmdline_parse_token_num_t cmd_rx_vlan_filter_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_rx_vlan_filter = {
+ .f = cmd_rx_vlan_filter_parsed,
+ .data = NULL,
+ .help_str = "add/remove a VLAN identifier to/from the set of VLAN "
+ "Identifiers filtered by a port",
+ .tokens = {
+ (void *)&cmd_rx_vlan_filter_rx_vlan,
+ (void *)&cmd_rx_vlan_filter_what,
+ (void *)&cmd_rx_vlan_filter_vlanid,
+ (void *)&cmd_rx_vlan_filter_portid,
+ NULL,
+ },
+};
+
+/* *** ENABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
+struct cmd_tx_vlan_set_result {
+ cmdline_fixed_string_t tx_vlan;
+ cmdline_fixed_string_t set;
+ uint8_t port_id;
+ uint16_t vlan_id;
+};
+
+static void
+cmd_tx_vlan_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tx_vlan_set_result *res = parsed_result;
+ int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
+
+ if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD) {
+ printf("Error, as QinQ has been enabled.\n");
+ return;
+ }
+
+ tx_vlan_set(res->port_id, res->vlan_id);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_set_tx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
+ tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_set_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
+ set, "set");
+cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
+ vlan_id, UINT16);
+cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tx_vlan_set = {
+ .f = cmd_tx_vlan_set_parsed,
+ .data = NULL,
+ .help_str = "enable hardware insertion of a single VLAN header "
+ "with a given TAG Identifier in packets sent on a port",
+ .tokens = {
+ (void *)&cmd_tx_vlan_set_tx_vlan,
+ (void *)&cmd_tx_vlan_set_set,
+ (void *)&cmd_tx_vlan_set_portid,
+ (void *)&cmd_tx_vlan_set_vlanid,
+ NULL,
+ },
+};
+
+/* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */
+struct cmd_tx_vlan_set_qinq_result {
+ cmdline_fixed_string_t tx_vlan;
+ cmdline_fixed_string_t set;
+ uint8_t port_id;
+ uint16_t vlan_id;
+ uint16_t vlan_id_outer;
+};
+
+static void
+cmd_tx_vlan_set_qinq_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tx_vlan_set_qinq_result *res = parsed_result;
+ int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
+
+ if (!(vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)) {
+ printf("Error, as QinQ hasn't been enabled.\n");
+ return;
+ }
+
+ tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+ tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+ set, "set");
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+ port_id, UINT8);
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+ vlan_id, UINT16);
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+ vlan_id_outer, UINT16);
+
+cmdline_parse_inst_t cmd_tx_vlan_set_qinq = {
+ .f = cmd_tx_vlan_set_qinq_parsed,
+ .data = NULL,
+ .help_str = "enable hardware insertion of double VLAN header "
+ "with given TAG Identifiers in packets sent on a port",
+ .tokens = {
+ (void *)&cmd_tx_vlan_set_qinq_tx_vlan,
+ (void *)&cmd_tx_vlan_set_qinq_set,
+ (void *)&cmd_tx_vlan_set_qinq_portid,
+ (void *)&cmd_tx_vlan_set_qinq_vlanid,
+ (void *)&cmd_tx_vlan_set_qinq_vlanid_outer,
+ NULL,
+ },
+};
+
+/* *** ENABLE/DISABLE PORT BASED TX VLAN INSERTION *** */
+struct cmd_tx_vlan_set_pvid_result {
+ cmdline_fixed_string_t tx_vlan;
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t pvid;
+ uint8_t port_id;
+ uint16_t vlan_id;
+ cmdline_fixed_string_t mode;
+};
+
+static void
+cmd_tx_vlan_set_pvid_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tx_vlan_set_pvid_result *res = parsed_result;
+
+ if (strcmp(res->mode, "on") == 0)
+ tx_vlan_pvid_set(res->port_id, res->vlan_id, 1);
+ else
+ tx_vlan_pvid_set(res->port_id, res->vlan_id, 0);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_tx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
+ tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_pvid =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
+ pvid, "pvid");
+cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
+ port_id, UINT8);
+cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_vlan_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
+ vlan_id, UINT16);
+cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
+ mode, "on#off");
+
+cmdline_parse_inst_t cmd_tx_vlan_set_pvid = {
+ .f = cmd_tx_vlan_set_pvid_parsed,
+ .data = NULL,
+ .help_str = "tx_vlan set pvid port_id vlan_id (on|off)",
+ .tokens = {
+ (void *)&cmd_tx_vlan_set_pvid_tx_vlan,
+ (void *)&cmd_tx_vlan_set_pvid_set,
+ (void *)&cmd_tx_vlan_set_pvid_pvid,
+ (void *)&cmd_tx_vlan_set_pvid_port_id,
+ (void *)&cmd_tx_vlan_set_pvid_vlan_id,
+ (void *)&cmd_tx_vlan_set_pvid_mode,
+ NULL,
+ },
+};
+
+/* *** DISABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
+struct cmd_tx_vlan_reset_result {
+ cmdline_fixed_string_t tx_vlan;
+ cmdline_fixed_string_t reset;
+ uint8_t port_id;
+};
+
+static void
+cmd_tx_vlan_reset_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tx_vlan_reset_result *res = parsed_result;
+
+ tx_vlan_reset(res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_reset_tx_vlan =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
+ tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_reset_reset =
+ TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
+ reset, "reset");
+cmdline_parse_token_num_t cmd_tx_vlan_reset_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_reset_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tx_vlan_reset = {
+ .f = cmd_tx_vlan_reset_parsed,
+ .data = NULL,
+ .help_str = "disable hardware insertion of a VLAN header in packets "
+ "sent on a port",
+ .tokens = {
+ (void *)&cmd_tx_vlan_reset_tx_vlan,
+ (void *)&cmd_tx_vlan_reset_reset,
+ (void *)&cmd_tx_vlan_reset_portid,
+ NULL,
+ },
+};
+
+
+/* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */
+struct cmd_csum_result {
+ cmdline_fixed_string_t csum;
+ cmdline_fixed_string_t mode;
+ cmdline_fixed_string_t proto;
+ cmdline_fixed_string_t hwsw;
+ uint8_t port_id;
+};
+
+static void
+csum_show(int port_id)
+{
+ struct rte_eth_dev_info dev_info;
+ uint16_t ol_flags;
+
+ ol_flags = ports[port_id].tx_ol_flags;
+ printf("Parse tunnel is %s\n",
+ (ol_flags & TESTPMD_TX_OFFLOAD_PARSE_TUNNEL) ? "on" : "off");
+ printf("IP checksum offload is %s\n",
+ (ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) ? "hw" : "sw");
+ printf("UDP checksum offload is %s\n",
+ (ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) ? "hw" : "sw");
+ printf("TCP checksum offload is %s\n",
+ (ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) ? "hw" : "sw");
+ printf("SCTP checksum offload is %s\n",
+ (ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) ? "hw" : "sw");
+ printf("Outer-Ip checksum offload is %s\n",
+ (ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) ? "hw" : "sw");
+
+ /* display warnings if configuration is not supported by the NIC */
+ rte_eth_dev_info_get(port_id, &dev_info);
+ if ((ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) {
+ printf("Warning: hardware IP checksum enabled but not "
+ "supported by port %d\n", port_id);
+ }
+ if ((ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) {
+ printf("Warning: hardware UDP checksum enabled but not "
+ "supported by port %d\n", port_id);
+ }
+ if ((ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) {
+ printf("Warning: hardware TCP checksum enabled but not "
+ "supported by port %d\n", port_id);
+ }
+ if ((ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) == 0) {
+ printf("Warning: hardware SCTP checksum enabled but not "
+ "supported by port %d\n", port_id);
+ }
+ if ((ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) == 0) {
+ printf("Warning: hardware outer IP checksum enabled but not "
+ "supported by port %d\n", port_id);
+ }
+}
+
+static void
+cmd_csum_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_csum_result *res = parsed_result;
+ int hw = 0;
+ uint16_t mask = 0;
+
+ if (port_id_is_invalid(res->port_id, ENABLED_WARN)) {
+ printf("invalid port %d\n", res->port_id);
+ return;
+ }
+
+ if (!strcmp(res->mode, "set")) {
+
+ if (!strcmp(res->hwsw, "hw"))
+ hw = 1;
+
+ if (!strcmp(res->proto, "ip")) {
+ mask = TESTPMD_TX_OFFLOAD_IP_CKSUM;
+ } else if (!strcmp(res->proto, "udp")) {
+ mask = TESTPMD_TX_OFFLOAD_UDP_CKSUM;
+ } else if (!strcmp(res->proto, "tcp")) {
+ mask = TESTPMD_TX_OFFLOAD_TCP_CKSUM;
+ } else if (!strcmp(res->proto, "sctp")) {
+ mask = TESTPMD_TX_OFFLOAD_SCTP_CKSUM;
+ } else if (!strcmp(res->proto, "outer-ip")) {
+ mask = TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM;
+ }
+
+ if (hw)
+ ports[res->port_id].tx_ol_flags |= mask;
+ else
+ ports[res->port_id].tx_ol_flags &= (~mask);
+ }
+ csum_show(res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_csum_csum =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+ csum, "csum");
+cmdline_parse_token_string_t cmd_csum_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+ mode, "set");
+cmdline_parse_token_string_t cmd_csum_proto =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+ proto, "ip#tcp#udp#sctp#outer-ip");
+cmdline_parse_token_string_t cmd_csum_hwsw =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+ hwsw, "hw#sw");
+cmdline_parse_token_num_t cmd_csum_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_csum_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_csum_set = {
+ .f = cmd_csum_parsed,
+ .data = NULL,
+ .help_str = "enable/disable hardware calculation of L3/L4 checksum when "
+ "using csum forward engine: csum set ip|tcp|udp|sctp|outer-ip hw|sw <port>",
+ .tokens = {
+ (void *)&cmd_csum_csum,
+ (void *)&cmd_csum_mode,
+ (void *)&cmd_csum_proto,
+ (void *)&cmd_csum_hwsw,
+ (void *)&cmd_csum_portid,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_csum_mode_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+ mode, "show");
+
+cmdline_parse_inst_t cmd_csum_show = {
+ .f = cmd_csum_parsed,
+ .data = NULL,
+ .help_str = "show checksum offload configuration: csum show <port>",
+ .tokens = {
+ (void *)&cmd_csum_csum,
+ (void *)&cmd_csum_mode_show,
+ (void *)&cmd_csum_portid,
+ NULL,
+ },
+};
+
+/* Enable/disable tunnel parsing */
+struct cmd_csum_tunnel_result {
+ cmdline_fixed_string_t csum;
+ cmdline_fixed_string_t parse;
+ cmdline_fixed_string_t onoff;
+ uint8_t port_id;
+};
+
+static void
+cmd_csum_tunnel_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_csum_tunnel_result *res = parsed_result;
+
+ if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+ return;
+
+ if (!strcmp(res->onoff, "on"))
+ ports[res->port_id].tx_ol_flags |=
+ TESTPMD_TX_OFFLOAD_PARSE_TUNNEL;
+ else
+ ports[res->port_id].tx_ol_flags &=
+ (~TESTPMD_TX_OFFLOAD_PARSE_TUNNEL);
+
+ csum_show(res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_csum_tunnel_csum =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
+ csum, "csum");
+cmdline_parse_token_string_t cmd_csum_tunnel_parse =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
+ parse, "parse_tunnel");
+cmdline_parse_token_string_t cmd_csum_tunnel_onoff =
+ TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
+ onoff, "on#off");
+cmdline_parse_token_num_t cmd_csum_tunnel_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_csum_tunnel_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_csum_tunnel = {
+ .f = cmd_csum_tunnel_parsed,
+ .data = NULL,
+ .help_str = "enable/disable parsing of tunnels for csum engine: "
+ "csum parse_tunnel on|off <tx-port>",
+ .tokens = {
+ (void *)&cmd_csum_tunnel_csum,
+ (void *)&cmd_csum_tunnel_parse,
+ (void *)&cmd_csum_tunnel_onoff,
+ (void *)&cmd_csum_tunnel_portid,
+ NULL,
+ },
+};
+
+/* *** ENABLE HARDWARE SEGMENTATION IN TX PACKETS *** */
+struct cmd_tso_set_result {
+ cmdline_fixed_string_t tso;
+ cmdline_fixed_string_t mode;
+ uint16_t tso_segsz;
+ uint8_t port_id;
+};
+
+static void
+cmd_tso_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tso_set_result *res = parsed_result;
+ struct rte_eth_dev_info dev_info;
+
+ if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+ return;
+
+ if (!strcmp(res->mode, "set"))
+ ports[res->port_id].tso_segsz = res->tso_segsz;
+
+ if (ports[res->port_id].tso_segsz == 0)
+ printf("TSO is disabled\n");
+ else
+ printf("TSO segment size is %d\n",
+ ports[res->port_id].tso_segsz);
+
+ /* display warnings if configuration is not supported by the NIC */
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+ if ((ports[res->port_id].tso_segsz != 0) &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) {
+ printf("Warning: TSO enabled but not "
+ "supported by port %d\n", res->port_id);
+ }
+}
+
+cmdline_parse_token_string_t cmd_tso_set_tso =
+ TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
+ tso, "tso");
+cmdline_parse_token_string_t cmd_tso_set_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
+ mode, "set");
+cmdline_parse_token_num_t cmd_tso_set_tso_segsz =
+ TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
+ tso_segsz, UINT16);
+cmdline_parse_token_num_t cmd_tso_set_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tso_set = {
+ .f = cmd_tso_set_parsed,
+ .data = NULL,
+ .help_str = "Set TSO segment size for csum engine (0 to disable): "
+ "tso set <tso_segsz> <port>",
+ .tokens = {
+ (void *)&cmd_tso_set_tso,
+ (void *)&cmd_tso_set_mode,
+ (void *)&cmd_tso_set_tso_segsz,
+ (void *)&cmd_tso_set_portid,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_tso_show_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
+ mode, "show");
+
+
+cmdline_parse_inst_t cmd_tso_show = {
+ .f = cmd_tso_set_parsed,
+ .data = NULL,
+ .help_str = "Show TSO segment size for csum engine: "
+ "tso show <port>",
+ .tokens = {
+ (void *)&cmd_tso_set_tso,
+ (void *)&cmd_tso_show_mode,
+ (void *)&cmd_tso_set_portid,
+ NULL,
+ },
+};
+
+/* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
+struct cmd_set_flush_rx {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t flush_rx;
+ cmdline_fixed_string_t mode;
+};
+
+static void
+cmd_set_flush_rx_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_flush_rx *res = parsed_result;
+ no_flush_rx = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
+}
+
+cmdline_parse_token_string_t cmd_setflushrx_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
+ set, "set");
+cmdline_parse_token_string_t cmd_setflushrx_flush_rx =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
+ flush_rx, "flush_rx");
+cmdline_parse_token_string_t cmd_setflushrx_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
+ mode, "on#off");
+
+
+cmdline_parse_inst_t cmd_set_flush_rx = {
+ .f = cmd_set_flush_rx_parsed,
+ .help_str = "set flush_rx on|off: enable/disable flush on rx streams",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_setflushrx_set,
+ (void *)&cmd_setflushrx_flush_rx,
+ (void *)&cmd_setflushrx_mode,
+ NULL,
+ },
+};
+
+/* *** ENABLE/DISABLE LINK STATUS CHECK *** */
+struct cmd_set_link_check {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t link_check;
+ cmdline_fixed_string_t mode;
+};
+
+static void
+cmd_set_link_check_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_link_check *res = parsed_result;
+ no_link_check = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
+}
+
+cmdline_parse_token_string_t cmd_setlinkcheck_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
+ set, "set");
+cmdline_parse_token_string_t cmd_setlinkcheck_link_check =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
+ link_check, "link_check");
+cmdline_parse_token_string_t cmd_setlinkcheck_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
+ mode, "on#off");
+
+
+cmdline_parse_inst_t cmd_set_link_check = {
+ .f = cmd_set_link_check_parsed,
+ .help_str = "set link_check on|off: enable/disable link status check "
+ "when starting/stopping a port",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_setlinkcheck_set,
+ (void *)&cmd_setlinkcheck_link_check,
+ (void *)&cmd_setlinkcheck_mode,
+ NULL,
+ },
+};
+
+#ifdef RTE_NIC_BYPASS
+/* *** SET NIC BYPASS MODE *** */
+struct cmd_set_bypass_mode_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t bypass;
+ cmdline_fixed_string_t mode;
+ cmdline_fixed_string_t value;
+ uint8_t port_id;
+};
+
+static void
+cmd_set_bypass_mode_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_bypass_mode_result *res = parsed_result;
+ portid_t port_id = res->port_id;
+ uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL;
+
+ if (!bypass_is_supported(port_id))
+ return;
+
+ if (!strcmp(res->value, "bypass"))
+ bypass_mode = RTE_BYPASS_MODE_BYPASS;
+ else if (!strcmp(res->value, "isolate"))
+ bypass_mode = RTE_BYPASS_MODE_ISOLATE;
+ else
+ bypass_mode = RTE_BYPASS_MODE_NORMAL;
+
+ /* Set the bypass mode for the relevant port. */
+ if (0 != rte_eth_dev_bypass_state_set(port_id, &bypass_mode)) {
+ printf("\t Failed to set bypass mode for port = %d.\n", port_id);
+ }
+}
+
+cmdline_parse_token_string_t cmd_setbypass_mode_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_setbypass_mode_bypass =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
+ bypass, "bypass");
+cmdline_parse_token_string_t cmd_setbypass_mode_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
+ mode, "mode");
+cmdline_parse_token_string_t cmd_setbypass_mode_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
+ value, "normal#bypass#isolate");
+cmdline_parse_token_num_t cmd_setbypass_mode_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_bypass_mode_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bypass_mode = {
+ .f = cmd_set_bypass_mode_parsed,
+ .help_str = "set bypass mode (normal|bypass|isolate) (port_id): "
+ "Set the NIC bypass mode for port_id",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_setbypass_mode_set,
+ (void *)&cmd_setbypass_mode_bypass,
+ (void *)&cmd_setbypass_mode_mode,
+ (void *)&cmd_setbypass_mode_value,
+ (void *)&cmd_setbypass_mode_port,
+ NULL,
+ },
+};
+
+/* *** SET NIC BYPASS EVENT *** */
+struct cmd_set_bypass_event_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t bypass;
+ cmdline_fixed_string_t event;
+ cmdline_fixed_string_t event_value;
+ cmdline_fixed_string_t mode;
+ cmdline_fixed_string_t mode_value;
+ uint8_t port_id;
+};
+
+static void
+cmd_set_bypass_event_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int32_t rc;
+ struct cmd_set_bypass_event_result *res = parsed_result;
+ portid_t port_id = res->port_id;
+ uint32_t bypass_event = RTE_BYPASS_EVENT_NONE;
+ uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL;
+
+ if (!bypass_is_supported(port_id))
+ return;
+
+ if (!strcmp(res->event_value, "timeout"))
+ bypass_event = RTE_BYPASS_EVENT_TIMEOUT;
+ else if (!strcmp(res->event_value, "os_on"))
+ bypass_event = RTE_BYPASS_EVENT_OS_ON;
+ else if (!strcmp(res->event_value, "os_off"))
+ bypass_event = RTE_BYPASS_EVENT_OS_OFF;
+ else if (!strcmp(res->event_value, "power_on"))
+ bypass_event = RTE_BYPASS_EVENT_POWER_ON;
+ else if (!strcmp(res->event_value, "power_off"))
+ bypass_event = RTE_BYPASS_EVENT_POWER_OFF;
+ else
+ bypass_event = RTE_BYPASS_EVENT_NONE;
+
+ if (!strcmp(res->mode_value, "bypass"))
+ bypass_mode = RTE_BYPASS_MODE_BYPASS;
+ else if (!strcmp(res->mode_value, "isolate"))
+ bypass_mode = RTE_BYPASS_MODE_ISOLATE;
+ else
+ bypass_mode = RTE_BYPASS_MODE_NORMAL;
+
+ /* Set the watchdog timeout. */
+ if (bypass_event == RTE_BYPASS_EVENT_TIMEOUT) {
+
+ rc = -EINVAL;
+ if (!RTE_BYPASS_TMT_VALID(bypass_timeout) ||
+ (rc = rte_eth_dev_wd_timeout_store(port_id,
+ bypass_timeout)) != 0) {
+ printf("Failed to set timeout value %u "
+ "for port %d, errto code: %d.\n",
+ bypass_timeout, port_id, rc);
+ }
+ }
+
+ /* Set the bypass event to transition to bypass mode. */
+ if (0 != rte_eth_dev_bypass_event_store(port_id,
+ bypass_event, bypass_mode)) {
+ printf("\t Failed to set bypass event for port = %d.\n", port_id);
+ }
+
+}
+
+cmdline_parse_token_string_t cmd_setbypass_event_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_setbypass_event_bypass =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
+ bypass, "bypass");
+cmdline_parse_token_string_t cmd_setbypass_event_event =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
+ event, "event");
+cmdline_parse_token_string_t cmd_setbypass_event_event_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
+ event_value, "none#timeout#os_off#os_on#power_on#power_off");
+cmdline_parse_token_string_t cmd_setbypass_event_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
+ mode, "mode");
+cmdline_parse_token_string_t cmd_setbypass_event_mode_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
+ mode_value, "normal#bypass#isolate");
+cmdline_parse_token_num_t cmd_setbypass_event_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_bypass_event_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bypass_event = {
+ .f = cmd_set_bypass_event_parsed,
+ .help_str = "set bypass event (timeout|os_on|os_off|power_on|power_off) "
+ "mode (normal|bypass|isolate) (port_id): "
+ "Set the NIC bypass event mode for port_id",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_setbypass_event_set,
+ (void *)&cmd_setbypass_event_bypass,
+ (void *)&cmd_setbypass_event_event,
+ (void *)&cmd_setbypass_event_event_value,
+ (void *)&cmd_setbypass_event_mode,
+ (void *)&cmd_setbypass_event_mode_value,
+ (void *)&cmd_setbypass_event_port,
+ NULL,
+ },
+};
+
+
+/* *** SET NIC BYPASS TIMEOUT *** */
+struct cmd_set_bypass_timeout_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t bypass;
+ cmdline_fixed_string_t timeout;
+ cmdline_fixed_string_t value;
+};
+
+static void
+cmd_set_bypass_timeout_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_bypass_timeout_result *res = parsed_result;
+
+ if (!strcmp(res->value, "1.5"))
+ bypass_timeout = RTE_BYPASS_TMT_1_5_SEC;
+ else if (!strcmp(res->value, "2"))
+ bypass_timeout = RTE_BYPASS_TMT_2_SEC;
+ else if (!strcmp(res->value, "3"))
+ bypass_timeout = RTE_BYPASS_TMT_3_SEC;
+ else if (!strcmp(res->value, "4"))
+ bypass_timeout = RTE_BYPASS_TMT_4_SEC;
+ else if (!strcmp(res->value, "8"))
+ bypass_timeout = RTE_BYPASS_TMT_8_SEC;
+ else if (!strcmp(res->value, "16"))
+ bypass_timeout = RTE_BYPASS_TMT_16_SEC;
+ else if (!strcmp(res->value, "32"))
+ bypass_timeout = RTE_BYPASS_TMT_32_SEC;
+ else
+ bypass_timeout = RTE_BYPASS_TMT_OFF;
+}
+
+cmdline_parse_token_string_t cmd_setbypass_timeout_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_setbypass_timeout_bypass =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
+ bypass, "bypass");
+cmdline_parse_token_string_t cmd_setbypass_timeout_timeout =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
+ timeout, "timeout");
+cmdline_parse_token_string_t cmd_setbypass_timeout_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
+ value, "0#1.5#2#3#4#8#16#32");
+
+cmdline_parse_inst_t cmd_set_bypass_timeout = {
+ .f = cmd_set_bypass_timeout_parsed,
+ .help_str = "set bypass timeout (0|1.5|2|3|4|8|16|32) seconds: "
+ "Set the NIC bypass watchdog timeout",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_setbypass_timeout_set,
+ (void *)&cmd_setbypass_timeout_bypass,
+ (void *)&cmd_setbypass_timeout_timeout,
+ (void *)&cmd_setbypass_timeout_value,
+ NULL,
+ },
+};
+
+/* *** SHOW NIC BYPASS MODE *** */
+struct cmd_show_bypass_config_result {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t bypass;
+ cmdline_fixed_string_t config;
+ uint8_t port_id;
+};
+
+static void
+cmd_show_bypass_config_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_show_bypass_config_result *res = parsed_result;
+ uint32_t event_mode;
+ uint32_t bypass_mode;
+ portid_t port_id = res->port_id;
+ uint32_t timeout = bypass_timeout;
+ int i;
+
+ static const char * const timeouts[RTE_BYPASS_TMT_NUM] =
+ {"off", "1.5", "2", "3", "4", "8", "16", "32"};
+ static const char * const modes[RTE_BYPASS_MODE_NUM] =
+ {"UNKNOWN", "normal", "bypass", "isolate"};
+ static const char * const events[RTE_BYPASS_EVENT_NUM] = {
+ "NONE",
+ "OS/board on",
+ "power supply on",
+ "OS/board off",
+ "power supply off",
+ "timeout"};
+ int num_events = (sizeof events) / (sizeof events[0]);
+
+ if (!bypass_is_supported(port_id))
+ return;
+
+ /* Display the bypass mode.*/
+ if (0 != rte_eth_dev_bypass_state_show(port_id, &bypass_mode)) {
+ printf("\tFailed to get bypass mode for port = %d\n", port_id);
+ return;
+ }
+ else {
+ if (!RTE_BYPASS_MODE_VALID(bypass_mode))
+ bypass_mode = RTE_BYPASS_MODE_NONE;
+
+ printf("\tbypass mode = %s\n", modes[bypass_mode]);
+ }
+
+ /* Display the bypass timeout.*/
+ if (!RTE_BYPASS_TMT_VALID(timeout))
+ timeout = RTE_BYPASS_TMT_OFF;
+
+ printf("\tbypass timeout = %s\n", timeouts[timeout]);
+
+ /* Display the bypass events and associated modes. */
+ for (i = RTE_BYPASS_EVENT_START; i < num_events; i++) {
+
+ if (0 != rte_eth_dev_bypass_event_show(port_id, i, &event_mode)) {
+ printf("\tFailed to get bypass mode for event = %s\n",
+ events[i]);
+ } else {
+ if (!RTE_BYPASS_MODE_VALID(event_mode))
+ event_mode = RTE_BYPASS_MODE_NONE;
+
+ printf("\tbypass event: %-16s = %s\n", events[i],
+ modes[event_mode]);
+ }
+ }
+}
+
+cmdline_parse_token_string_t cmd_showbypass_config_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
+ show, "show");
+cmdline_parse_token_string_t cmd_showbypass_config_bypass =
+ TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
+ bypass, "bypass");
+cmdline_parse_token_string_t cmd_showbypass_config_config =
+ TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
+ config, "config");
+cmdline_parse_token_num_t cmd_showbypass_config_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_show_bypass_config_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_show_bypass_config = {
+ .f = cmd_show_bypass_config_parsed,
+ .help_str = "show bypass config (port_id): "
+ "Show the NIC bypass config for port_id",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_showbypass_config_show,
+ (void *)&cmd_showbypass_config_bypass,
+ (void *)&cmd_showbypass_config_config,
+ (void *)&cmd_showbypass_config_port,
+ NULL,
+ },
+};
+#endif
+
+#ifdef RTE_LIBRTE_PMD_BOND
+/* *** SET BONDING MODE *** */
+struct cmd_set_bonding_mode_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t bonding;
+ cmdline_fixed_string_t mode;
+ uint8_t value;
+ uint8_t port_id;
+};
+
+static void cmd_set_bonding_mode_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_bonding_mode_result *res = parsed_result;
+ portid_t port_id = res->port_id;
+
+ /* Set the bonding mode for the relevant port. */
+ if (0 != rte_eth_bond_mode_set(port_id, res->value))
+ printf("\t Failed to set bonding mode for port = %d.\n", port_id);
+}
+
+cmdline_parse_token_string_t cmd_setbonding_mode_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+ bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_mode_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+ mode, "mode");
+cmdline_parse_token_num_t cmd_setbonding_mode_value =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+ value, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_mode_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_mode = {
+ .f = cmd_set_bonding_mode_parsed,
+ .help_str = "set bonding mode (mode_value) (port_id): Set the bonding mode for port_id",
+ .data = NULL,
+ .tokens = {
+ (void *) &cmd_setbonding_mode_set,
+ (void *) &cmd_setbonding_mode_bonding,
+ (void *) &cmd_setbonding_mode_mode,
+ (void *) &cmd_setbonding_mode_value,
+ (void *) &cmd_setbonding_mode_port,
+ NULL
+ }
+};
+
+/* *** SET BALANCE XMIT POLICY *** */
+struct cmd_set_bonding_balance_xmit_policy_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t bonding;
+ cmdline_fixed_string_t balance_xmit_policy;
+ uint8_t port_id;
+ cmdline_fixed_string_t policy;
+};
+
+static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
+ portid_t port_id = res->port_id;
+ uint8_t policy;
+
+ if (!strcmp(res->policy, "l2")) {
+ policy = BALANCE_XMIT_POLICY_LAYER2;
+ } else if (!strcmp(res->policy, "l23")) {
+ policy = BALANCE_XMIT_POLICY_LAYER23;
+ } else if (!strcmp(res->policy, "l34")) {
+ policy = BALANCE_XMIT_POLICY_LAYER34;
+ } else {
+ printf("\t Invalid xmit policy selection");
+ return;
+ }
+
+ /* Set the bonding mode for the relevant port. */
+ if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
+ printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
+ port_id);
+ }
+}
+
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+ bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+ balance_xmit_policy, "balance_xmit_policy");
+cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+ policy, "l2#l23#l34");
+
+cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
+ .f = cmd_set_bonding_balance_xmit_policy_parsed,
+ .help_str = "set bonding balance_xmit_policy (port_id) (policy_value): Set the bonding balance_xmit_policy for port_id",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_setbonding_balance_xmit_policy_set,
+ (void *)&cmd_setbonding_balance_xmit_policy_bonding,
+ (void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
+ (void *)&cmd_setbonding_balance_xmit_policy_port,
+ (void *)&cmd_setbonding_balance_xmit_policy_policy,
+ NULL
+ }
+};
+
+/* *** SHOW NIC BONDING CONFIGURATION *** */
+struct cmd_show_bonding_config_result {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t bonding;
+ cmdline_fixed_string_t config;
+ uint8_t port_id;
+};
+
+static void cmd_show_bonding_config_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_show_bonding_config_result *res = parsed_result;
+ int bonding_mode;
+ uint8_t slaves[RTE_MAX_ETHPORTS];
+ int num_slaves, num_active_slaves;
+ int primary_id;
+ int i;
+ portid_t port_id = res->port_id;
+
+ /* Display the bonding mode.*/
+ bonding_mode = rte_eth_bond_mode_get(port_id);
+ if (bonding_mode < 0) {
+ printf("\tFailed to get bonding mode for port = %d\n", port_id);
+ return;
+ } else
+ printf("\tBonding mode: %d\n", bonding_mode);
+
+ if (bonding_mode == BONDING_MODE_BALANCE) {
+ int balance_xmit_policy;
+
+ balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
+ if (balance_xmit_policy < 0) {
+ printf("\tFailed to get balance xmit policy for port = %d\n",
+ port_id);
+ return;
+ } else {
+ printf("\tBalance Xmit Policy: ");
+
+ switch (balance_xmit_policy) {
+ case BALANCE_XMIT_POLICY_LAYER2:
+ printf("BALANCE_XMIT_POLICY_LAYER2");
+ break;
+ case BALANCE_XMIT_POLICY_LAYER23:
+ printf("BALANCE_XMIT_POLICY_LAYER23");
+ break;
+ case BALANCE_XMIT_POLICY_LAYER34:
+ printf("BALANCE_XMIT_POLICY_LAYER34");
+ break;
+ }
+ printf("\n");
+ }
+ }
+
+ num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
+
+ if (num_slaves < 0) {
+ printf("\tFailed to get slave list for port = %d\n", port_id);
+ return;
+ }
+ if (num_slaves > 0) {
+ printf("\tSlaves (%d): [", num_slaves);
+ for (i = 0; i < num_slaves - 1; i++)
+ printf("%d ", slaves[i]);
+
+ printf("%d]\n", slaves[num_slaves - 1]);
+ } else {
+ printf("\tSlaves: []\n");
+
+ }
+
+ num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
+ RTE_MAX_ETHPORTS);
+
+ if (num_active_slaves < 0) {
+ printf("\tFailed to get active slave list for port = %d\n", port_id);
+ return;
+ }
+ if (num_active_slaves > 0) {
+ printf("\tActive Slaves (%d): [", num_active_slaves);
+ for (i = 0; i < num_active_slaves - 1; i++)
+ printf("%d ", slaves[i]);
+
+ printf("%d]\n", slaves[num_active_slaves - 1]);
+
+ } else {
+ printf("\tActive Slaves: []\n");
+
+ }
+
+ primary_id = rte_eth_bond_primary_get(port_id);
+ if (primary_id < 0) {
+ printf("\tFailed to get primary slave for port = %d\n", port_id);
+ return;
+ } else
+ printf("\tPrimary: [%d]\n", primary_id);
+
+}
+
+cmdline_parse_token_string_t cmd_showbonding_config_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+ show, "show");
+cmdline_parse_token_string_t cmd_showbonding_config_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+ bonding, "bonding");
+cmdline_parse_token_string_t cmd_showbonding_config_config =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+ config, "config");
+cmdline_parse_token_num_t cmd_showbonding_config_port =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_show_bonding_config = {
+ .f = cmd_show_bonding_config_parsed,
+ .help_str = "show bonding config (port_id): Show the bonding config for port_id",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_showbonding_config_show,
+ (void *)&cmd_showbonding_config_bonding,
+ (void *)&cmd_showbonding_config_config,
+ (void *)&cmd_showbonding_config_port,
+ NULL
+ }
+};
+
+/* *** SET BONDING PRIMARY *** */
+struct cmd_set_bonding_primary_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t bonding;
+ cmdline_fixed_string_t primary;
+ uint8_t slave_id;
+ uint8_t port_id;
+};
+
+static void cmd_set_bonding_primary_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_bonding_primary_result *res = parsed_result;
+ portid_t master_port_id = res->port_id;
+ portid_t slave_port_id = res->slave_id;
+
+ /* Set the primary slave for a bonded device. */
+ if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
+ printf("\t Failed to set primary slave for port = %d.\n",
+ master_port_id);
+ return;
+ }
+ init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_setbonding_primary_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+ bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_primary_primary =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+ primary, "primary");
+cmdline_parse_token_num_t cmd_setbonding_primary_slave =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+ slave_id, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_primary_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_primary = {
+ .f = cmd_set_bonding_primary_parsed,
+ .help_str = "set bonding primary (slave_id) (port_id): Set the primary slave for port_id",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_setbonding_primary_set,
+ (void *)&cmd_setbonding_primary_bonding,
+ (void *)&cmd_setbonding_primary_primary,
+ (void *)&cmd_setbonding_primary_slave,
+ (void *)&cmd_setbonding_primary_port,
+ NULL
+ }
+};
+
+/* *** ADD SLAVE *** */
+struct cmd_add_bonding_slave_result {
+ cmdline_fixed_string_t add;
+ cmdline_fixed_string_t bonding;
+ cmdline_fixed_string_t slave;
+ uint8_t slave_id;
+ uint8_t port_id;
+};
+
+static void cmd_add_bonding_slave_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_add_bonding_slave_result *res = parsed_result;
+ portid_t master_port_id = res->port_id;
+ portid_t slave_port_id = res->slave_id;
+
+ /* Set the primary slave for a bonded device. */
+ if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
+ printf("\t Failed to add slave %d to master port = %d.\n",
+ slave_port_id, master_port_id);
+ return;
+ }
+ init_port_config();
+ set_port_slave_flag(slave_port_id);
+}
+
+cmdline_parse_token_string_t cmd_addbonding_slave_add =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+ add, "add");
+cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+ bonding, "bonding");
+cmdline_parse_token_string_t cmd_addbonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+ slave, "slave");
+cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+ slave_id, UINT8);
+cmdline_parse_token_num_t cmd_addbonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_add_bonding_slave = {
+ .f = cmd_add_bonding_slave_parsed,
+ .help_str = "add bonding slave (slave_id) (port_id): Add a slave device to a bonded device",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_addbonding_slave_add,
+ (void *)&cmd_addbonding_slave_bonding,
+ (void *)&cmd_addbonding_slave_slave,
+ (void *)&cmd_addbonding_slave_slaveid,
+ (void *)&cmd_addbonding_slave_port,
+ NULL
+ }
+};
+
+/* *** REMOVE SLAVE *** */
+struct cmd_remove_bonding_slave_result {
+ cmdline_fixed_string_t remove;
+ cmdline_fixed_string_t bonding;
+ cmdline_fixed_string_t slave;
+ uint8_t slave_id;
+ uint8_t port_id;
+};
+
+static void cmd_remove_bonding_slave_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_remove_bonding_slave_result *res = parsed_result;
+ portid_t master_port_id = res->port_id;
+ portid_t slave_port_id = res->slave_id;
+
+ /* Set the primary slave for a bonded device. */
+ if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
+ printf("\t Failed to remove slave %d from master port = %d.\n",
+ slave_port_id, master_port_id);
+ return;
+ }
+ init_port_config();
+ clear_port_slave_flag(slave_port_id);
+}
+
+cmdline_parse_token_string_t cmd_removebonding_slave_remove =
+ TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+ remove, "remove");
+cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
+ TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+ bonding, "bonding");
+cmdline_parse_token_string_t cmd_removebonding_slave_slave =
+ TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+ slave, "slave");
+cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
+ TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+ slave_id, UINT8);
+cmdline_parse_token_num_t cmd_removebonding_slave_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_remove_bonding_slave = {
+ .f = cmd_remove_bonding_slave_parsed,
+ .help_str = "remove bonding slave (slave_id) (port_id): Remove a slave device from a bonded device",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_removebonding_slave_remove,
+ (void *)&cmd_removebonding_slave_bonding,
+ (void *)&cmd_removebonding_slave_slave,
+ (void *)&cmd_removebonding_slave_slaveid,
+ (void *)&cmd_removebonding_slave_port,
+ NULL
+ }
+};
+
+/* *** CREATE BONDED DEVICE *** */
+struct cmd_create_bonded_device_result {
+ cmdline_fixed_string_t create;
+ cmdline_fixed_string_t bonded;
+ cmdline_fixed_string_t device;
+ uint8_t mode;
+ uint8_t socket;
+};
+
+static int bond_dev_num = 0;
+
+static void cmd_create_bonded_device_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_create_bonded_device_result *res = parsed_result;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+ int port_id;
+
+ if (test_done == 0) {
+ printf("Please stop forwarding first\n");
+ return;
+ }
+
+ snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "eth_bond_testpmd_%d",
+ bond_dev_num++);
+
+ /* Create a new bonded device. */
+ port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
+ if (port_id < 0) {
+ printf("\t Failed to create bonded device.\n");
+ return;
+ } else {
+ printf("Created new bonded device %s on (port %d).\n", ethdev_name,
+ port_id);
+
+ /* Update number of ports */
+ nb_ports = rte_eth_dev_count();
+ reconfig(port_id, res->socket);
+ rte_eth_promiscuous_enable(port_id);
+ ports[port_id].enabled = 1;
+ }
+
+}
+
+cmdline_parse_token_string_t cmd_createbonded_device_create =
+ TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+ create, "create");
+cmdline_parse_token_string_t cmd_createbonded_device_bonded =
+ TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+ bonded, "bonded");
+cmdline_parse_token_string_t cmd_createbonded_device_device =
+ TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+ device, "device");
+cmdline_parse_token_num_t cmd_createbonded_device_mode =
+ TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+ mode, UINT8);
+cmdline_parse_token_num_t cmd_createbonded_device_socket =
+ TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+ socket, UINT8);
+
+cmdline_parse_inst_t cmd_create_bonded_device = {
+ .f = cmd_create_bonded_device_parsed,
+ .help_str = "create bonded device (mode) (socket): Create a new bonded device with specific bonding mode and socket",
+ .data = NULL,
+ .tokens = {
+ (void *)&cmd_createbonded_device_create,
+ (void *)&cmd_createbonded_device_bonded,
+ (void *)&cmd_createbonded_device_device,
+ (void *)&cmd_createbonded_device_mode,
+ (void *)&cmd_createbonded_device_socket,
+ NULL
+ }
+};
+
+/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
+struct cmd_set_bond_mac_addr_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t bonding;
+ cmdline_fixed_string_t mac_addr;
+ uint8_t port_num;
+ struct ether_addr address;
+};
+
+static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_bond_mac_addr_result *res = parsed_result;
+ int ret;
+
+ if (port_id_is_invalid(res->port_num, ENABLED_WARN))
+ return;
+
+ ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
+
+ /* check the return value and print it if is < 0 */
+ if (ret < 0)
+ printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
+ "bonding");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
+ "mac_addr");
+cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
+ TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_set_bond_mac_addr = {
+ .f = cmd_set_bond_mac_addr_parsed,
+ .data = (void *) 0,
+ .help_str = "set bonding mac_addr (port_id) (address): ",
+ .tokens = {
+ (void *)&cmd_set_bond_mac_addr_set,
+ (void *)&cmd_set_bond_mac_addr_bonding,
+ (void *)&cmd_set_bond_mac_addr_mac,
+ (void *)&cmd_set_bond_mac_addr_portnum,
+ (void *)&cmd_set_bond_mac_addr_addr,
+ NULL
+ }
+};
+
+
+/* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
+struct cmd_set_bond_mon_period_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t bonding;
+ cmdline_fixed_string_t mon_period;
+ uint8_t port_num;
+ uint32_t period_ms;
+};
+
+static void cmd_set_bond_mon_period_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_bond_mon_period_result *res = parsed_result;
+ int ret;
+
+ if (res->port_num >= nb_ports) {
+ printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
+ return;
+ }
+
+ ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
+
+ /* check the return value and print it if is < 0 */
+ if (ret < 0)
+ printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
+ bonding, "bonding");
+cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
+ mon_period, "mon_period");
+cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
+ port_num, UINT8);
+cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
+ period_ms, UINT32);
+
+cmdline_parse_inst_t cmd_set_bond_mon_period = {
+ .f = cmd_set_bond_mon_period_parsed,
+ .data = (void *) 0,
+ .help_str = "set bonding mon_period (port_id) (period_ms): ",
+ .tokens = {
+ (void *)&cmd_set_bond_mon_period_set,
+ (void *)&cmd_set_bond_mon_period_bonding,
+ (void *)&cmd_set_bond_mon_period_mon_period,
+ (void *)&cmd_set_bond_mon_period_portnum,
+ (void *)&cmd_set_bond_mon_period_period_ms,
+ NULL
+ }
+};
+
+#endif /* RTE_LIBRTE_PMD_BOND */
+
+/* *** SET FORWARDING MODE *** */
+struct cmd_set_fwd_mode_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t fwd;
+ cmdline_fixed_string_t mode;
+};
+
+static void cmd_set_fwd_mode_parsed(void *parsed_result,