X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fconfig.c;h=a7112c998bdb5fbe32a675310873b6d1693c3d46;hb=f4823a3982fd62993a1a128c2a0396cdbe01be8a;hp=71aeb5413c616b425e766bfd8f4d7007417337a6;hpb=476ec8e2788eaa614e937f579ea4b437e5a930b2;p=dpdk.git diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 71aeb5413c..a7112c998b 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -75,10 +75,16 @@ static const struct { }; const struct rss_type_info rss_type_table[] = { - { "all", ETH_RSS_IP | ETH_RSS_TCP | - ETH_RSS_UDP | ETH_RSS_SCTP | - ETH_RSS_L2_PAYLOAD }, + { "all", ETH_RSS_ETH | ETH_RSS_VLAN | ETH_RSS_IP | ETH_RSS_TCP | + ETH_RSS_UDP | ETH_RSS_SCTP | ETH_RSS_L2_PAYLOAD | + ETH_RSS_L2TPV3 | ETH_RSS_ESP | ETH_RSS_AH | ETH_RSS_PFCP}, { "none", 0 }, + { "eth", ETH_RSS_ETH }, + { "l2-src-only", ETH_RSS_L2_SRC_ONLY }, + { "l2-dst-only", ETH_RSS_L2_DST_ONLY }, + { "vlan", ETH_RSS_VLAN }, + { "s-vlan", ETH_RSS_S_VLAN }, + { "c-vlan", ETH_RSS_C_VLAN }, { "ipv4", ETH_RSS_IPV4 }, { "ipv4-frag", ETH_RSS_FRAG_IPV4 }, { "ipv4-tcp", ETH_RSS_NONFRAG_IPV4_TCP }, @@ -108,6 +114,10 @@ const struct rss_type_info rss_type_table[] = { { "l3-dst-only", ETH_RSS_L3_DST_ONLY }, { "l4-src-only", ETH_RSS_L4_SRC_ONLY }, { "l4-dst-only", ETH_RSS_L4_DST_ONLY }, + { "esp", ETH_RSS_ESP }, + { "ah", ETH_RSS_AH }, + { "l2tpv3", ETH_RSS_L2TPV3 }, + { "pfcp", ETH_RSS_PFCP }, { NULL, 0 }, }; @@ -224,11 +234,28 @@ nic_stats_display(portid_t port_id) void nic_stats_clear(portid_t port_id) { + int ret; + if (port_id_is_invalid(port_id, ENABLED_WARN)) { print_valid_ports(); return; } - rte_eth_stats_reset(port_id); + + ret = rte_eth_stats_reset(port_id); + if (ret != 0) { + printf("%s: Error: failed to reset stats (port %u): %s", + __func__, port_id, strerror(-ret)); + return; + } + + ret = rte_eth_stats_get(port_id, &ports[port_id].stats); + if (ret != 0) { + if (ret < 0) + ret = -ret; + printf("%s: Error: failed to get stats (port %u): %s", + __func__, port_id, strerror(ret)); + return; + } printf("\n NIC statistics for port %d cleared\n", port_id); } @@ -304,10 +331,21 @@ nic_xstats_clear(portid_t port_id) print_valid_ports(); return; } + ret = rte_eth_xstats_reset(port_id); if (ret != 0) { printf("%s: Error: failed to reset xstats (port %u): %s", + __func__, port_id, strerror(-ret)); + return; + } + + ret = rte_eth_stats_get(port_id, &ports[port_id].stats); + if (ret != 0) { + if (ret < 0) + ret = -ret; + printf("%s: Error: failed to get stats (port %u): %s", __func__, port_id, strerror(ret)); + return; } } @@ -1243,8 +1281,9 @@ port_mtu_set(portid_t port_id, uint16_t mtu) return; } diag = rte_eth_dev_set_mtu(port_id, mtu); - if (diag == 0 && - dev_info.rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME) { + if (diag) + printf("Set MTU failed. diag=%d\n", diag); + else if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME) { /* * Ether overhead in driver is equal to the difference of * max_rx_pktlen and max_mtu in rte_eth_dev_info when the @@ -1259,10 +1298,7 @@ port_mtu_set(portid_t port_id, uint16_t mtu) } else rte_port->dev_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; - - return; } - printf("Set MTU failed. diag=%d\n", diag); } /* Generic flow management functions. */ @@ -1357,6 +1393,26 @@ port_flow_validate(portid_t port_id, return 0; } +/** Update age action context by port_flow pointer. */ +void +update_age_action_context(const struct rte_flow_action *actions, + struct port_flow *pf) +{ + struct rte_flow_action_age *age = NULL; + + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { + switch (actions->type) { + case RTE_FLOW_ACTION_TYPE_AGE: + age = (struct rte_flow_action_age *) + (uintptr_t)actions->conf; + age->context = pf; + return; + default: + break; + } + } +} + /** Create flow rule. */ int port_flow_create(portid_t port_id, @@ -1367,28 +1423,27 @@ port_flow_create(portid_t port_id, struct rte_flow *flow; struct rte_port *port; struct port_flow *pf; - uint32_t id; + uint32_t id = 0; struct rte_flow_error error; - /* Poisoning to make sure PMDs update it in case of error. */ - memset(&error, 0x22, sizeof(error)); - flow = rte_flow_create(port_id, attr, pattern, actions, &error); - if (!flow) - return port_flow_complain(&error); port = &ports[port_id]; if (port->flow_list) { if (port->flow_list->id == UINT32_MAX) { printf("Highest rule ID is already assigned, delete" " it first"); - rte_flow_destroy(port_id, flow, NULL); return -ENOMEM; } id = port->flow_list->id + 1; - } else - id = 0; + } pf = port_flow_new(attr, pattern, actions, &error); - if (!pf) { - rte_flow_destroy(port_id, flow, NULL); + if (!pf) + return port_flow_complain(&error); + update_age_action_context(actions, pf); + /* Poisoning to make sure PMDs update it in case of error. */ + memset(&error, 0x22, sizeof(error)); + flow = rte_flow_create(port_id, attr, pattern, actions, &error); + if (!flow) { + free(pf); return port_flow_complain(&error); } pf->next = port->flow_list; @@ -1560,6 +1615,73 @@ port_flow_query(portid_t port_id, uint32_t rule, return 0; } +/** List simply and destroy all aged flows. */ +void +port_flow_aged(portid_t port_id, uint8_t destroy) +{ + void **contexts; + int nb_context, total = 0, idx; + struct rte_flow_error error; + struct port_flow *pf; + + if (port_id_is_invalid(port_id, ENABLED_WARN) || + port_id == (portid_t)RTE_PORT_ALL) + return; + total = rte_flow_get_aged_flows(port_id, NULL, 0, &error); + printf("Port %u total aged flows: %d\n", port_id, total); + if (total < 0) { + port_flow_complain(&error); + return; + } + if (total == 0) + return; + contexts = malloc(sizeof(void *) * total); + if (contexts == NULL) { + printf("Cannot allocate contexts for aged flow\n"); + return; + } + printf("ID\tGroup\tPrio\tAttr\n"); + nb_context = rte_flow_get_aged_flows(port_id, contexts, total, &error); + if (nb_context != total) { + printf("Port:%d get aged flows count(%d) != total(%d)\n", + port_id, nb_context, total); + free(contexts); + return; + } + for (idx = 0; idx < nb_context; idx++) { + pf = (struct port_flow *)contexts[idx]; + if (!pf) { + printf("Error: get Null context in port %u\n", port_id); + continue; + } + printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c%c\t\n", + pf->id, + pf->rule.attr->group, + pf->rule.attr->priority, + pf->rule.attr->ingress ? 'i' : '-', + pf->rule.attr->egress ? 'e' : '-', + pf->rule.attr->transfer ? 't' : '-'); + } + if (destroy) { + int ret; + uint32_t flow_id; + + total = 0; + printf("\n"); + for (idx = 0; idx < nb_context; idx++) { + pf = (struct port_flow *)contexts[idx]; + if (!pf) + continue; + flow_id = pf->id; + ret = port_flow_destroy(port_id, 1, &flow_id); + if (!ret) + total++; + } + printf("%d flows be destroyed\n", total); + } + free(contexts); +} + /** List flow rules. */ void port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n])