app/testpmd: fix missing jump action in flow action
[dpdk.git] / app / test-pmd / config.c
index 107d7fd..794aa52 100644 (file)
@@ -121,15 +121,11 @@ nic_stats_display(portid_t port_id)
        struct rte_eth_stats stats;
        struct rte_port *port = &ports[port_id];
        uint8_t i;
-       portid_t pid;
 
        static const char *nic_stats_border = "########################";
 
        if (port_id_is_invalid(port_id, ENABLED_WARN)) {
-               printf("Valid port range is [0");
-               RTE_ETH_FOREACH_DEV(pid)
-                       printf(", %d", pid);
-               printf("]\n");
+               print_valid_ports();
                return;
        }
        rte_eth_stats_get(port_id, &stats);
@@ -203,13 +199,8 @@ nic_stats_display(portid_t port_id)
 void
 nic_stats_clear(portid_t port_id)
 {
-       portid_t pid;
-
        if (port_id_is_invalid(port_id, ENABLED_WARN)) {
-               printf("Valid port range is [0");
-               RTE_ETH_FOREACH_DEV(pid)
-                       printf(", %d", pid);
-               printf("]\n");
+               print_valid_ports();
                return;
        }
        rte_eth_stats_reset(port_id);
@@ -286,15 +277,11 @@ nic_stats_mapping_display(portid_t port_id)
 {
        struct rte_port *port = &ports[port_id];
        uint16_t i;
-       portid_t pid;
 
        static const char *nic_stats_mapping_border = "########################";
 
        if (port_id_is_invalid(port_id, ENABLED_WARN)) {
-               printf("Valid port range is [0");
-               RTE_ETH_FOREACH_DEV(pid)
-                       printf(", %d", pid);
-               printf("]\n");
+               print_valid_ports();
                return;
        }
 
@@ -405,14 +392,11 @@ port_infos_display(portid_t port_id)
        int vlan_offload;
        struct rte_mempool * mp;
        static const char *info_border = "*********************";
-       portid_t pid;
        uint16_t mtu;
+       char name[RTE_ETH_NAME_MAX_LEN];
 
        if (port_id_is_invalid(port_id, ENABLED_WARN)) {
-               printf("Valid port range is [0");
-               RTE_ETH_FOREACH_DEV(pid)
-                       printf(", %d", pid);
-               printf("]\n");
+               print_valid_ports();
                return;
        }
        port = &ports[port_id];
@@ -423,6 +407,8 @@ port_infos_display(portid_t port_id)
               info_border, port_id, info_border);
        rte_eth_macaddr_get(port_id, &mac_addr);
        print_ethaddr("MAC address: ", &mac_addr);
+       rte_eth_dev_get_name_by_port(port_id, name);
+       printf("\nDevice name: %s", name);
        printf("\nDriver name: %s", dev_info.driver_name);
        printf("\nConnect to socket: %u", port->socket_id);
 
@@ -517,6 +503,18 @@ port_infos_display(portid_t port_id)
        printf("Min possible number of TXDs per queue: %hu\n",
                dev_info.tx_desc_lim.nb_min);
        printf("TXDs number alignment: %hu\n", dev_info.tx_desc_lim.nb_align);
+
+       /* Show switch info only if valid switch domain and port id is set */
+       if (dev_info.switch_info.domain_id !=
+               RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) {
+               if (dev_info.switch_info.name)
+                       printf("Switch name: %s\n", dev_info.switch_info.name);
+
+               printf("Switch domain Id: %u\n",
+                       dev_info.switch_info.domain_id);
+               printf("Switch Port Id: %u\n",
+                       dev_info.switch_info.port_id);
+       }
 }
 
 void
@@ -579,7 +577,7 @@ port_offload_cap_display(portid_t port_id)
        }
 
        if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) {
-               printf("RX Outer IPv4 checksum:               ");
+               printf("RX Outer IPv4 checksum:        ");
                if (ports[port_id].dev_conf.rxmode.offloads &
                    DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM)
                        printf("on\n");
@@ -596,19 +594,37 @@ port_offload_cap_display(portid_t port_id)
                        printf("off\n");
        }
 
-       if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT) {
-               printf("VLAN insert:                   ");
-               if (ports[port_id].dev_conf.txmode.offloads &
-                   DEV_TX_OFFLOAD_VLAN_INSERT)
+       if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TIMESTAMP) {
+               printf("HW timestamp:                  ");
+               if (ports[port_id].dev_conf.rxmode.offloads &
+                   DEV_RX_OFFLOAD_TIMESTAMP)
                        printf("on\n");
                else
                        printf("off\n");
        }
 
-       if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TIMESTAMP) {
-               printf("HW timestamp:                  ");
+       if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_KEEP_CRC) {
+               printf("Rx Keep CRC:                   ");
                if (ports[port_id].dev_conf.rxmode.offloads &
-                   DEV_RX_OFFLOAD_TIMESTAMP)
+                   DEV_RX_OFFLOAD_KEEP_CRC)
+                       printf("on\n");
+               else
+                       printf("off\n");
+       }
+
+       if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_SECURITY) {
+               printf("RX offload security:           ");
+               if (ports[port_id].dev_conf.rxmode.offloads &
+                   DEV_RX_OFFLOAD_SECURITY)
+                       printf("on\n");
+               else
+                       printf("off\n");
+       }
+
+       if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT) {
+               printf("VLAN insert:                   ");
+               if (ports[port_id].dev_conf.txmode.offloads &
+                   DEV_TX_OFFLOAD_VLAN_INSERT)
                        printf("on\n");
                else
                        printf("off\n");
@@ -759,6 +775,17 @@ port_id_is_invalid(portid_t port_id, enum print_warning warning)
        return 1;
 }
 
+void print_valid_ports(void)
+{
+       portid_t pid;
+
+       printf("The valid ports array is [");
+       RTE_ETH_FOREACH_DEV(pid) {
+               printf(" %d", pid);
+       }
+       printf(" ]\n");
+}
+
 static int
 vlan_id_is_invalid(uint16_t vlan_id)
 {
@@ -993,7 +1020,8 @@ static const struct {
        MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)),
        MK_FLOW_ITEM(PF, 0),
        MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
-       MK_FLOW_ITEM(PORT, sizeof(struct rte_flow_item_port)),
+       MK_FLOW_ITEM(PHY_PORT, sizeof(struct rte_flow_item_phy_port)),
+       MK_FLOW_ITEM(PORT_ID, sizeof(struct rte_flow_item_port_id)),
        MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)),
        MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
        MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
@@ -1013,6 +1041,17 @@ static const struct {
        MK_FLOW_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)),
        MK_FLOW_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)),
        MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
+       MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)),
+       MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)),
+       MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)),
+       MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
+       MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)),
+       MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)),
+       MK_FLOW_ITEM(ICMP6_ND_OPT, sizeof(struct rte_flow_item_icmp6_nd_opt)),
+       MK_FLOW_ITEM(ICMP6_ND_OPT_SLA_ETH,
+                    sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)),
+       MK_FLOW_ITEM(ICMP6_ND_OPT_TLA_ETH,
+                    sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)),
 };
 
 /** Pattern item specification types. */
@@ -1028,15 +1067,24 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item,
                    enum item_spec_type type)
 {
        size_t size = 0;
-       const void *item_spec =
+       const void *data =
                type == ITEM_SPEC ? item->spec :
                type == ITEM_LAST ? item->last :
                type == ITEM_MASK ? item->mask :
                NULL;
 
-       if (!item_spec)
+       if (!item->spec || !data)
                goto empty;
        switch (item->type) {
+               union {
+                       const struct rte_flow_item_raw *raw;
+               } spec;
+               union {
+                       const struct rte_flow_item_raw *raw;
+               } last;
+               union {
+                       const struct rte_flow_item_raw *raw;
+               } mask;
                union {
                        const struct rte_flow_item_raw *raw;
                } src;
@@ -1046,11 +1094,21 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item,
                size_t off;
 
        case RTE_FLOW_ITEM_TYPE_RAW:
-               src.raw = item_spec;
+               spec.raw = item->spec;
+               last.raw = item->last ? item->last : item->spec;
+               mask.raw = item->mask ? item->mask : &rte_flow_item_raw_mask;
+               src.raw = data;
                dst.raw = buf;
                off = RTE_ALIGN_CEIL(sizeof(struct rte_flow_item_raw),
                                     sizeof(*src.raw->pattern));
-               size = off + src.raw->length * sizeof(*src.raw->pattern);
+               if (type == ITEM_SPEC ||
+                   (type == ITEM_MASK &&
+                    ((spec.raw->length & mask.raw->length) >=
+                     (last.raw->length & mask.raw->length))))
+                       size = spec.raw->length & mask.raw->length;
+               else
+                       size = last.raw->length & mask.raw->length;
+               size = off + size * sizeof(*src.raw->pattern);
                if (dst.raw) {
                        memcpy(dst.raw, src.raw, sizeof(*src.raw));
                        dst.raw->pattern = memcpy((uint8_t *)dst.raw + off,
@@ -1061,7 +1119,7 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item,
        default:
                size = flow_item[item->type].size;
                if (buf)
-                       memcpy(buf, item_spec, size);
+                       memcpy(buf, data, size);
                break;
        }
 empty:
@@ -1083,15 +1141,37 @@ static const struct {
        MK_FLOW_ACTION(END, 0),
        MK_FLOW_ACTION(VOID, 0),
        MK_FLOW_ACTION(PASSTHRU, 0),
+       MK_FLOW_ACTION(JUMP, 0),
        MK_FLOW_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
        MK_FLOW_ACTION(FLAG, 0),
        MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
        MK_FLOW_ACTION(DROP, 0),
-       MK_FLOW_ACTION(COUNT, 0),
+       MK_FLOW_ACTION(COUNT, sizeof(struct rte_flow_action_count)),
        MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
        MK_FLOW_ACTION(PF, 0),
        MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
+       MK_FLOW_ACTION(PHY_PORT, sizeof(struct rte_flow_action_phy_port)),
+       MK_FLOW_ACTION(PORT_ID, sizeof(struct rte_flow_action_port_id)),
        MK_FLOW_ACTION(METER, sizeof(struct rte_flow_action_meter)),
+       MK_FLOW_ACTION(OF_SET_MPLS_TTL,
+                      sizeof(struct rte_flow_action_of_set_mpls_ttl)),
+       MK_FLOW_ACTION(OF_DEC_MPLS_TTL, 0),
+       MK_FLOW_ACTION(OF_SET_NW_TTL,
+                      sizeof(struct rte_flow_action_of_set_nw_ttl)),
+       MK_FLOW_ACTION(OF_DEC_NW_TTL, 0),
+       MK_FLOW_ACTION(OF_COPY_TTL_OUT, 0),
+       MK_FLOW_ACTION(OF_COPY_TTL_IN, 0),
+       MK_FLOW_ACTION(OF_POP_VLAN, 0),
+       MK_FLOW_ACTION(OF_PUSH_VLAN,
+                      sizeof(struct rte_flow_action_of_push_vlan)),
+       MK_FLOW_ACTION(OF_SET_VLAN_VID,
+                      sizeof(struct rte_flow_action_of_set_vlan_vid)),
+       MK_FLOW_ACTION(OF_SET_VLAN_PCP,
+                      sizeof(struct rte_flow_action_of_set_vlan_pcp)),
+       MK_FLOW_ACTION(OF_POP_MPLS,
+                      sizeof(struct rte_flow_action_of_pop_mpls)),
+       MK_FLOW_ACTION(OF_PUSH_MPLS,
+                      sizeof(struct rte_flow_action_of_push_mpls)),
 };
 
 /** Compute storage space needed by action configuration and copy it. */
@@ -1118,6 +1198,7 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
                if (dst.rss)
                        *dst.rss = (struct rte_flow_action_rss){
                                .func = src.rss->func,
+                               .level = src.rss->level,
                                .types = src.rss->types,
                                .key_len = src.rss->key_len,
                                .queue_num = src.rss->queue_num,
@@ -1255,6 +1336,7 @@ port_flow_complain(struct rte_flow_error *error)
                [RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY] = "priority field",
                [RTE_FLOW_ERROR_TYPE_ATTR_INGRESS] = "ingress field",
                [RTE_FLOW_ERROR_TYPE_ATTR_EGRESS] = "egress field",
+               [RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER] = "transfer field",
                [RTE_FLOW_ERROR_TYPE_ATTR] = "attributes structure",
                [RTE_FLOW_ERROR_TYPE_ITEM_NUM] = "pattern length",
                [RTE_FLOW_ERROR_TYPE_ITEM_SPEC] = "item specification",
@@ -1274,11 +1356,12 @@ port_flow_complain(struct rte_flow_error *error)
                errstr = "unknown type";
        else
                errstr = errstrlist[error->type];
-       printf("Caught error type %d (%s): %s%s\n",
+       printf("Caught error type %d (%s): %s%s: %s\n",
               error->type, errstr,
               error->cause ? (snprintf(buf, sizeof(buf), "cause: %p, ",
                                        error->cause), buf) : "",
-              error->message ? error->message : "(no stated reason)");
+              error->message ? error->message : "(no stated reason)",
+              rte_strerror(err));
        return -err;
 }
 
@@ -1417,7 +1500,7 @@ port_flow_flush(portid_t port_id)
 /** Query a flow rule. */
 int
 port_flow_query(portid_t port_id, uint32_t rule,
-               enum rte_flow_action_type action)
+               const struct rte_flow_action *action)
 {
        struct rte_flow_error error;
        struct rte_port *port;
@@ -1438,16 +1521,17 @@ port_flow_query(portid_t port_id, uint32_t rule,
                printf("Flow rule #%u not found\n", rule);
                return -ENOENT;
        }
-       if ((unsigned int)action >= RTE_DIM(flow_action) ||
-           !flow_action[action].name)
+       if ((unsigned int)action->type >= RTE_DIM(flow_action) ||
+           !flow_action[action->type].name)
                name = "unknown";
        else
-               name = flow_action[action].name;
-       switch (action) {
+               name = flow_action[action->type].name;
+       switch (action->type) {
        case RTE_FLOW_ACTION_TYPE_COUNT:
                break;
        default:
-               printf("Cannot query action type %d (%s)\n", action, name);
+               printf("Cannot query action type %d (%s)\n",
+                       action->type, name);
                return -ENOTSUP;
        }
        /* Poisoning to make sure PMDs update it in case of error. */
@@ -1455,7 +1539,7 @@ port_flow_query(portid_t port_id, uint32_t rule,
        memset(&query, 0, sizeof(query));
        if (rte_flow_query(port_id, pf->flow, action, &query, &error))
                return port_flow_complain(&error);
-       switch (action) {
+       switch (action->type) {
        case RTE_FLOW_ACTION_TYPE_COUNT:
                printf("%s:\n"
                       " hits_set: %u\n"
@@ -1470,7 +1554,7 @@ port_flow_query(portid_t port_id, uint32_t rule,
                break;
        default:
                printf("Cannot display result for action type %d (%s)\n",
-                      action, name);
+                      action->type, name);
                break;
        }
        return 0;
@@ -1520,12 +1604,13 @@ port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n])
                const struct rte_flow_item *item = pf->pattern;
                const struct rte_flow_action *action = pf->actions;
 
-               printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c\t",
+               printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c%c\t",
                       pf->id,
                       pf->attr.group,
                       pf->attr.priority,
                       pf->attr.ingress ? 'i' : '-',
-                      pf->attr.egress ? 'e' : '-');
+                      pf->attr.egress ? 'e' : '-',
+                      pf->attr.transfer ? 't' : '-');
                while (item->type != RTE_FLOW_ITEM_TYPE_END) {
                        if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
                                printf("%s ", flow_item[item->type].name);
@@ -1774,6 +1859,11 @@ rxtx_config_display(void)
                struct rte_eth_txconf *tx_conf = &ports[pid].tx_conf[0];
                uint16_t *nb_rx_desc = &ports[pid].nb_rx_desc[0];
                uint16_t *nb_tx_desc = &ports[pid].nb_tx_desc[0];
+               uint16_t nb_rx_desc_tmp;
+               uint16_t nb_tx_desc_tmp;
+               struct rte_eth_rxq_info rx_qinfo;
+               struct rte_eth_txq_info tx_qinfo;
+               int32_t rc;
 
                /* per port config */
                printf("  port %d: RX queue number: %d Tx queue number: %d\n",
@@ -1785,9 +1875,15 @@ rxtx_config_display(void)
 
                /* per rx queue config only for first queue to be less verbose */
                for (qid = 0; qid < 1; qid++) {
+                       rc = rte_eth_rx_queue_info_get(pid, qid, &rx_qinfo);
+                       if (rc)
+                               nb_rx_desc_tmp = nb_rx_desc[qid];
+                       else
+                               nb_rx_desc_tmp = rx_qinfo.nb_desc;
+
                        printf("    RX queue: %d\n", qid);
                        printf("      RX desc=%d - RX free threshold=%d\n",
-                               nb_rx_desc[qid], rx_conf[qid].rx_free_thresh);
+                               nb_rx_desc_tmp, rx_conf[qid].rx_free_thresh);
                        printf("      RX threshold registers: pthresh=%d hthresh=%d "
                                " wthresh=%d\n",
                                rx_conf[qid].rx_thresh.pthresh,
@@ -1799,9 +1895,15 @@ rxtx_config_display(void)
 
                /* per tx queue config only for first queue to be less verbose */
                for (qid = 0; qid < 1; qid++) {
+                       rc = rte_eth_tx_queue_info_get(pid, qid, &tx_qinfo);
+                       if (rc)
+                               nb_tx_desc_tmp = nb_tx_desc[qid];
+                       else
+                               nb_tx_desc_tmp = tx_qinfo.nb_desc;
+
                        printf("    TX queue: %d\n", qid);
                        printf("      TX desc=%d - TX free threshold=%d\n",
-                               nb_tx_desc[qid], tx_conf[qid].tx_free_thresh);
+                               nb_tx_desc_tmp, tx_conf[qid].tx_free_thresh);
                        printf("      TX threshold registers: pthresh=%d hthresh=%d "
                                " wthresh=%d\n",
                                tx_conf[qid].tx_thresh.pthresh,
@@ -2095,15 +2197,11 @@ rss_fwd_config_setup(void)
                fs->tx_queue = rxq;
                fs->peer_addr = fs->tx_port;
                fs->retry_enabled = retry_enabled;
-               rxq = (queueid_t) (rxq + 1);
-               if (rxq < nb_q)
-                       continue;
-               /*
-                * rxq == nb_q
-                * Restart from RX queue 0 on next RX port
-                */
-               rxq = 0;
                rxp++;
+               if (rxp < nb_fwd_ports)
+                       continue;
+               rxp = 0;
+               rxq++;
        }
 }
 
@@ -2250,6 +2348,55 @@ icmp_echo_config_setup(void)
        }
 }
 
+#if defined RTE_LIBRTE_PMD_SOFTNIC
+static void
+softnic_fwd_config_setup(void)
+{
+       struct rte_port *port;
+       portid_t pid, softnic_portid;
+       queueid_t i;
+       uint8_t softnic_enable = 0;
+
+       RTE_ETH_FOREACH_DEV(pid) {
+                       port = &ports[pid];
+                       const char *driver = port->dev_info.driver_name;
+
+                       if (strcmp(driver, "net_softnic") == 0) {
+                               softnic_portid = pid;
+                               softnic_enable = 1;
+                               break;
+                       }
+       }
+
+       if (softnic_enable == 0) {
+               printf("Softnic mode not configured(%s)!\n", __func__);
+               return;
+       }
+
+       cur_fwd_config.nb_fwd_ports = 1;
+       cur_fwd_config.nb_fwd_streams = (streamid_t) nb_rxq;
+
+       /* Re-initialize forwarding streams */
+       init_fwd_streams();
+
+       /*
+        * In the softnic forwarding test, the number of forwarding cores
+        * is set to one and remaining are used for softnic packet processing.
+        */
+       cur_fwd_config.nb_fwd_lcores = 1;
+       setup_fwd_config_of_each_lcore(&cur_fwd_config);
+
+       for (i = 0; i < cur_fwd_config.nb_fwd_streams; i++) {
+               fwd_streams[i]->rx_port   = softnic_portid;
+               fwd_streams[i]->rx_queue  = i;
+               fwd_streams[i]->tx_port   = softnic_portid;
+               fwd_streams[i]->tx_queue  = i;
+               fwd_streams[i]->peer_addr = fwd_streams[i]->tx_port;
+               fwd_streams[i]->retry_enabled = retry_enabled;
+       }
+}
+#endif
+
 void
 fwd_config_setup(void)
 {
@@ -2258,6 +2405,14 @@ fwd_config_setup(void)
                icmp_echo_config_setup();
                return;
        }
+
+#if defined RTE_LIBRTE_PMD_SOFTNIC
+       if (strcmp(cur_fwd_eng->fwd_mode_name, "softnic") == 0) {
+               softnic_fwd_config_setup();
+               return;
+       }
+#endif
+
        if ((nb_rxq > 1) && (nb_txq > 1)){
                if (dcb_config)
                        dcb_fwd_config_setup();
@@ -3126,6 +3281,7 @@ flowtype_to_str(uint16_t flow_type)
                {"vxlan", RTE_ETH_FLOW_VXLAN},
                {"geneve", RTE_ETH_FLOW_GENEVE},
                {"nvgre", RTE_ETH_FLOW_NVGRE},
+               {"vxlan-gpe", RTE_ETH_FLOW_VXLAN_GPE},
        };
 
        for (i = 0; i < RTE_DIM(flowtype_str_table); i++) {