diff options
Diffstat (limited to 'app/test-pmd/config.c')
-rw-r--r-- | app/test-pmd/config.c | 652 |
1 files changed, 284 insertions, 368 deletions
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 14ccd686..b9e5dd92 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -50,6 +50,7 @@ #endif #include <rte_gro.h> #include <cmdline_parse_etheraddr.h> +#include <rte_config.h> #include "testpmd.h" @@ -74,6 +75,10 @@ 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 }, + { "none", 0 }, { "ipv4", ETH_RSS_IPV4 }, { "ipv4-frag", ETH_RSS_FRAG_IPV4 }, { "ipv4-tcp", ETH_RSS_NONFRAG_IPV4_TCP }, @@ -410,6 +415,8 @@ port_infos_display(portid_t port_id) rte_eth_dev_get_name_by_port(port_id, name); printf("\nDevice name: %s", name); printf("\nDriver name: %s", dev_info.driver_name); + if (dev_info.device->devargs && dev_info.device->devargs->args) + printf("\nDevargs: %s", dev_info.device->devargs->args); printf("\nConnect to socket: %u", port->socket_id); if (port_numa[port_id] != NUMA_NO_CONFIG) { @@ -461,12 +468,12 @@ port_infos_display(portid_t port_id) if (dev_info.reta_size > 0) printf("Redirection table size: %u\n", dev_info.reta_size); if (!dev_info.flow_type_rss_offloads) - printf("No flow type is supported.\n"); + printf("No RSS offload flow type is supported.\n"); else { uint16_t i; char *p; - printf("Supported flow types:\n"); + printf("Supported RSS offload flow types:\n"); for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < sizeof(dev_info.flow_type_rss_offloads) * CHAR_BIT; i++) { if (!(dev_info.flow_type_rss_offloads & (1ULL << i))) @@ -518,6 +525,43 @@ port_infos_display(portid_t port_id) } void +port_summary_header_display(void) +{ + uint16_t port_number; + + port_number = rte_eth_dev_count_avail(); + printf("Number of available ports: %i\n", port_number); + printf("%-4s %-17s %-12s %-14s %-8s %s\n", "Port", "MAC Address", "Name", + "Driver", "Status", "Link"); +} + +void +port_summary_display(portid_t port_id) +{ + struct ether_addr mac_addr; + struct rte_eth_link link; + struct rte_eth_dev_info dev_info; + char name[RTE_ETH_NAME_MAX_LEN]; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) { + print_valid_ports(); + return; + } + + rte_eth_link_get_nowait(port_id, &link); + rte_eth_dev_info_get(port_id, &dev_info); + rte_eth_dev_get_name_by_port(port_id, name); + rte_eth_macaddr_get(port_id, &mac_addr); + + printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n", + port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], + mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], + mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name, + dev_info.driver_name, (link.link_status) ? ("up") : ("down"), + (unsigned int) link.link_speed); +} + +void port_offload_cap_display(portid_t port_id) { struct rte_eth_dev_info dev_info; @@ -543,7 +587,7 @@ port_offload_cap_display(portid_t port_id) if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_QINQ_STRIP) { printf("Double VLANs stripped: "); if (ports[port_id].dev_conf.rxmode.offloads & - DEV_RX_OFFLOAD_VLAN_EXTEND) + DEV_RX_OFFLOAD_QINQ_STRIP) printf("on\n"); else printf("off\n"); @@ -576,8 +620,17 @@ port_offload_cap_display(portid_t port_id) printf("off\n"); } + if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_SCTP_CKSUM) { + printf("RX SCTP checksum: "); + if (ports[port_id].dev_conf.rxmode.offloads & + DEV_RX_OFFLOAD_SCTP_CKSUM) + printf("on\n"); + else + printf("off\n"); + } + 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"); @@ -585,19 +638,19 @@ port_offload_cap_display(portid_t port_id) printf("off\n"); } - if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) { - printf("Large receive offload: "); + if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_UDP_CKSUM) { + printf("RX Outer UDP checksum: "); if (ports[port_id].dev_conf.rxmode.offloads & - DEV_RX_OFFLOAD_TCP_LRO) + DEV_RX_OFFLOAD_OUTER_UDP_CKSUM) 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) + if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) { + printf("Large receive offload: "); + if (ports[port_id].dev_conf.rxmode.offloads & + DEV_RX_OFFLOAD_TCP_LRO) printf("on\n"); else printf("off\n"); @@ -612,6 +665,33 @@ port_offload_cap_display(portid_t port_id) printf("off\n"); } + 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_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"); + } + if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_QINQ_INSERT) { printf("Double VLANs insert: "); if (ports[port_id].dev_conf.txmode.offloads & @@ -737,6 +817,16 @@ port_offload_cap_display(portid_t port_id) else printf("off\n"); } + + if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) { + printf("TX Outer UDP checksum: "); + if (ports[port_id].dev_conf.txmode.offloads & + DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) + printf("on\n"); + else + printf("off\n"); + } + } int @@ -984,324 +1074,35 @@ port_mtu_set(portid_t port_id, uint16_t mtu) /* Generic flow management functions. */ -/** Generate flow_item[] entry. */ -#define MK_FLOW_ITEM(t, s) \ - [RTE_FLOW_ITEM_TYPE_ ## t] = { \ - .name = # t, \ - .size = s, \ - } - -/** Information about known flow pattern items. */ -static const struct { - const char *name; - size_t size; -} flow_item[] = { - MK_FLOW_ITEM(END, 0), - MK_FLOW_ITEM(VOID, 0), - MK_FLOW_ITEM(INVERT, 0), - 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(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)), - MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), - MK_FLOW_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), - MK_FLOW_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), - MK_FLOW_ITEM(UDP, sizeof(struct rte_flow_item_udp)), - MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), - MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), - MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), - MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), - MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), - MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), - MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)), - MK_FLOW_ITEM(FUZZY, sizeof(struct rte_flow_item_fuzzy)), - MK_FLOW_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), - 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. */ -enum item_spec_type { - ITEM_SPEC, - ITEM_LAST, - ITEM_MASK, -}; - -/** Compute storage space needed by item specification and copy it. */ -static size_t -flow_item_spec_copy(void *buf, const struct rte_flow_item *item, - enum item_spec_type type) -{ - size_t size = 0; - const void *data = - type == ITEM_SPEC ? item->spec : - type == ITEM_LAST ? item->last : - type == ITEM_MASK ? item->mask : - NULL; - - 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; - union { - struct rte_flow_item_raw *raw; - } dst; - size_t off; - - case RTE_FLOW_ITEM_TYPE_RAW: - 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)); - 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, - src.raw->pattern, - size - off); - } - break; - default: - size = flow_item[item->type].size; - if (buf) - memcpy(buf, data, size); - break; - } -empty: - return RTE_ALIGN_CEIL(size, sizeof(double)); -} - -/** Generate flow_action[] entry. */ -#define MK_FLOW_ACTION(t, s) \ - [RTE_FLOW_ACTION_TYPE_ ## t] = { \ - .name = # t, \ - .size = s, \ - } - -/** Information about known flow actions. */ -static const struct { - const char *name; - size_t size; -} flow_action[] = { - MK_FLOW_ACTION(END, 0), - MK_FLOW_ACTION(VOID, 0), - MK_FLOW_ACTION(PASSTHRU, 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, 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. */ -static size_t -flow_action_conf_copy(void *buf, const struct rte_flow_action *action) -{ - size_t size = 0; - - if (!action->conf) - goto empty; - switch (action->type) { - union { - const struct rte_flow_action_rss *rss; - } src; - union { - struct rte_flow_action_rss *rss; - } dst; - size_t off; - - case RTE_FLOW_ACTION_TYPE_RSS: - src.rss = action->conf; - dst.rss = buf; - off = 0; - 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, - }; - off += sizeof(*src.rss); - if (src.rss->key_len) { - off = RTE_ALIGN_CEIL(off, sizeof(double)); - size = sizeof(*src.rss->key) * src.rss->key_len; - if (dst.rss) - dst.rss->key = memcpy - ((void *)((uintptr_t)dst.rss + off), - src.rss->key, size); - off += size; - } - if (src.rss->queue_num) { - off = RTE_ALIGN_CEIL(off, sizeof(double)); - size = sizeof(*src.rss->queue) * src.rss->queue_num; - if (dst.rss) - dst.rss->queue = memcpy - ((void *)((uintptr_t)dst.rss + off), - src.rss->queue, size); - off += size; - } - size = off; - break; - default: - size = flow_action[action->type].size; - if (buf) - memcpy(buf, action->conf, size); - break; - } -empty: - return RTE_ALIGN_CEIL(size, sizeof(double)); -} - /** Generate a port_flow entry from attributes/pattern/actions. */ static struct port_flow * port_flow_new(const struct rte_flow_attr *attr, const struct rte_flow_item *pattern, - const struct rte_flow_action *actions) -{ - const struct rte_flow_item *item; - const struct rte_flow_action *action; - struct port_flow *pf = NULL; - size_t tmp; - size_t off1 = 0; - size_t off2 = 0; - int err = ENOTSUP; - -store: - item = pattern; - if (pf) - pf->pattern = (void *)&pf->data[off1]; - do { - struct rte_flow_item *dst = NULL; - - if ((unsigned int)item->type >= RTE_DIM(flow_item) || - !flow_item[item->type].name) - goto notsup; - if (pf) - dst = memcpy(pf->data + off1, item, sizeof(*item)); - off1 += sizeof(*item); - if (item->spec) { - if (pf) - dst->spec = pf->data + off2; - off2 += flow_item_spec_copy - (pf ? pf->data + off2 : NULL, item, ITEM_SPEC); - } - if (item->last) { - if (pf) - dst->last = pf->data + off2; - off2 += flow_item_spec_copy - (pf ? pf->data + off2 : NULL, item, ITEM_LAST); - } - if (item->mask) { - if (pf) - dst->mask = pf->data + off2; - off2 += flow_item_spec_copy - (pf ? pf->data + off2 : NULL, item, ITEM_MASK); - } - off2 = RTE_ALIGN_CEIL(off2, sizeof(double)); - } while ((item++)->type != RTE_FLOW_ITEM_TYPE_END); - off1 = RTE_ALIGN_CEIL(off1, sizeof(double)); - action = actions; - if (pf) - pf->actions = (void *)&pf->data[off1]; - do { - struct rte_flow_action *dst = NULL; - - if ((unsigned int)action->type >= RTE_DIM(flow_action) || - !flow_action[action->type].name) - goto notsup; - if (pf) - dst = memcpy(pf->data + off1, action, sizeof(*action)); - off1 += sizeof(*action); - if (action->conf) { - if (pf) - dst->conf = pf->data + off2; - off2 += flow_action_conf_copy - (pf ? pf->data + off2 : NULL, action); - } - off2 = RTE_ALIGN_CEIL(off2, sizeof(double)); - } while ((action++)->type != RTE_FLOW_ACTION_TYPE_END); - if (pf != NULL) + const struct rte_flow_action *actions, + struct rte_flow_error *error) +{ + const struct rte_flow_conv_rule rule = { + .attr_ro = attr, + .pattern_ro = pattern, + .actions_ro = actions, + }; + struct port_flow *pf; + int ret; + + ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, NULL, 0, &rule, error); + if (ret < 0) + return NULL; + pf = calloc(1, offsetof(struct port_flow, rule) + ret); + if (!pf) { + rte_flow_error_set + (error, errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "calloc() failed"); + return NULL; + } + if (rte_flow_conv(RTE_FLOW_CONV_OP_RULE, &pf->rule, ret, &rule, + error) >= 0) return pf; - off1 = RTE_ALIGN_CEIL(off1, sizeof(double)); - tmp = RTE_ALIGN_CEIL(offsetof(struct port_flow, data), sizeof(double)); - pf = calloc(1, tmp + off1 + off2); - if (pf == NULL) - err = errno; - else { - *pf = (const struct port_flow){ - .size = tmp + off1 + off2, - .attr = *attr, - }; - tmp -= offsetof(struct port_flow, data); - off2 = tmp + off1; - off1 = tmp; - goto store; - } -notsup: - rte_errno = err; + free(pf); return NULL; } @@ -1337,11 +1138,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; } @@ -1391,13 +1193,10 @@ port_flow_create(portid_t port_id, id = port->flow_list->id + 1; } else id = 0; - pf = port_flow_new(attr, pattern, actions); + pf = port_flow_new(attr, pattern, actions, &error); if (!pf) { - int err = rte_errno; - - printf("Cannot allocate flow: %s\n", rte_strerror(err)); rte_flow_destroy(port_id, flow, NULL); - return -err; + return port_flow_complain(&error); } pf->next = port->flow_list; pf->id = id; @@ -1489,6 +1288,7 @@ port_flow_query(portid_t port_id, uint32_t rule, union { struct rte_flow_query_count count; } query; + int ret; if (port_id_is_invalid(port_id, ENABLED_WARN) || port_id == (portid_t)RTE_PORT_ALL) @@ -1501,11 +1301,11 @@ port_flow_query(portid_t port_id, uint32_t rule, printf("Flow rule #%u not found\n", rule); return -ENOENT; } - if ((unsigned int)action->type >= RTE_DIM(flow_action) || - !flow_action[action->type].name) - name = "unknown"; - else - name = flow_action[action->type].name; + ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR, + &name, sizeof(name), + (void *)(uintptr_t)action->type, &error); + if (ret < 0) + return port_flow_complain(&error); switch (action->type) { case RTE_FLOW_ACTION_TYPE_COUNT: break; @@ -1558,48 +1358,63 @@ port_flow_list(portid_t port_id, uint32_t n, const uint32_t group[n]) /* Sort flows by group, priority and ID. */ for (pf = port->flow_list; pf != NULL; pf = pf->next) { struct port_flow **tmp; + const struct rte_flow_attr *curr = pf->rule.attr; if (n) { /* Filter out unwanted groups. */ for (i = 0; i != n; ++i) - if (pf->attr.group == group[i]) + if (curr->group == group[i]) break; if (i == n) continue; } - tmp = &list; - while (*tmp && - (pf->attr.group > (*tmp)->attr.group || - (pf->attr.group == (*tmp)->attr.group && - pf->attr.priority > (*tmp)->attr.priority) || - (pf->attr.group == (*tmp)->attr.group && - pf->attr.priority == (*tmp)->attr.priority && - pf->id > (*tmp)->id))) - tmp = &(*tmp)->tmp; + for (tmp = &list; *tmp; tmp = &(*tmp)->tmp) { + const struct rte_flow_attr *comp = (*tmp)->rule.attr; + + if (curr->group > comp->group || + (curr->group == comp->group && + curr->priority > comp->priority) || + (curr->group == comp->group && + curr->priority == comp->priority && + pf->id > (*tmp)->id)) + continue; + break; + } pf->tmp = *tmp; *tmp = pf; } printf("ID\tGroup\tPrio\tAttr\tRule\n"); for (pf = list; pf != NULL; pf = pf->tmp) { - const struct rte_flow_item *item = pf->pattern; - const struct rte_flow_action *action = pf->actions; + const struct rte_flow_item *item = pf->rule.pattern; + const struct rte_flow_action *action = pf->rule.actions; + const char *name; 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.transfer ? 't' : '-'); + pf->rule.attr->group, + pf->rule.attr->priority, + pf->rule.attr->ingress ? 'i' : '-', + pf->rule.attr->egress ? 'e' : '-', + pf->rule.attr->transfer ? 't' : '-'); while (item->type != RTE_FLOW_ITEM_TYPE_END) { + if (rte_flow_conv(RTE_FLOW_CONV_OP_ITEM_NAME_PTR, + &name, sizeof(name), + (void *)(uintptr_t)item->type, + NULL) <= 0) + name = "[UNKNOWN]"; if (item->type != RTE_FLOW_ITEM_TYPE_VOID) - printf("%s ", flow_item[item->type].name); + printf("%s ", name); ++item; } printf("=>"); while (action->type != RTE_FLOW_ACTION_TYPE_END) { + if (rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR, + &name, sizeof(name), + (void *)(uintptr_t)action->type, + NULL) <= 0) + name = "[UNKNOWN]"; if (action->type != RTE_FLOW_ACTION_TYPE_VOID) - printf(" %s", flow_action[action->type].name); + printf(" %s", name); ++action; } printf("\n"); @@ -1669,8 +1484,8 @@ ring_dma_zone_lookup(const char *ring_name, portid_t port_id, uint16_t q_id) char mz_name[RTE_MEMZONE_NAMESIZE]; const struct rte_memzone *mz; - snprintf(mz_name, sizeof(mz_name), "%s_%s_%d_%d", - ports[port_id].dev_info.driver_name, ring_name, port_id, q_id); + snprintf(mz_name, sizeof(mz_name), "eth_p%d_q%d_%s", + port_id, q_id, ring_name); mz = rte_memzone_lookup(mz_name); if (mz == NULL) printf("%s ring memory zoneof (port %d, queue %d) not" @@ -1927,9 +1742,9 @@ port_rss_reta_info(portid_t port_id, * key of the port. */ void -port_rss_hash_conf_show(portid_t port_id, char rss_info[], int show_rss_key) +port_rss_hash_conf_show(portid_t port_id, int show_rss_key) { - struct rte_eth_rss_conf rss_conf; + struct rte_eth_rss_conf rss_conf = {0}; uint8_t rss_key[RSS_HASH_KEY_LENGTH]; uint64_t rss_hf; uint8_t i; @@ -1940,7 +1755,6 @@ port_rss_hash_conf_show(portid_t port_id, char rss_info[], int show_rss_key) if (port_id_is_invalid(port_id, ENABLED_WARN)) return; - memset(&dev_info, 0, sizeof(dev_info)); rte_eth_dev_info_get(port_id, &dev_info); if (dev_info.hash_key_size > 0 && dev_info.hash_key_size <= sizeof(rss_key)) @@ -1950,12 +1764,6 @@ port_rss_hash_conf_show(portid_t port_id, char rss_info[], int show_rss_key) return; } - rss_conf.rss_hf = 0; - for (i = 0; rss_type_table[i].str; i++) { - if (!strcmp(rss_info, rss_type_table[i].str)) - rss_conf.rss_hf = rss_type_table[i].rss_type; - } - /* Get RSS hash key if asked to display it */ rss_conf.rss_key = (show_rss_key) ? rss_key : NULL; rss_conf.rss_key_len = hash_key_size; @@ -2403,6 +2211,23 @@ fwd_config_setup(void) simple_fwd_config_setup(); } +static const char * +mp_alloc_to_str(uint8_t mode) +{ + switch (mode) { + case MP_ALLOC_NATIVE: + return "native"; + case MP_ALLOC_ANON: + return "anon"; + case MP_ALLOC_XMEM: + return "xmem"; + case MP_ALLOC_XMEM_HUGE: + return "xmemhuge"; + default: + return "invalid"; + } +} + void pkt_fwd_config_display(struct fwd_config *cfg) { @@ -2411,12 +2236,12 @@ pkt_fwd_config_display(struct fwd_config *cfg) streamid_t sm_id; printf("%s packet forwarding%s - ports=%d - cores=%d - streams=%d - " - "NUMA support %s, MP over anonymous pages %s\n", + "NUMA support %s, MP allocation mode: %s\n", cfg->fwd_eng->fwd_mode_name, retry_enabled == 0 ? "" : " with retry", cfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams, numa_support == 1 ? "enabled" : "disabled", - mp_anon != 0 ? "enabled" : "disabled"); + mp_alloc_to_str(mp_alloc_type)); if (retry_enabled) printf("TX retry num: %u, delay between TX retries: %uus\n", @@ -2886,11 +2711,102 @@ set_pkt_forwarding_mode(const char *fwd_mode_name) } void +add_rx_dump_callbacks(portid_t portid) +{ + struct rte_eth_dev_info dev_info; + uint16_t queue; + + if (port_id_is_invalid(portid, ENABLED_WARN)) + return; + + rte_eth_dev_info_get(portid, &dev_info); + for (queue = 0; queue < dev_info.nb_rx_queues; queue++) + if (!ports[portid].rx_dump_cb[queue]) + ports[portid].rx_dump_cb[queue] = + rte_eth_add_rx_callback(portid, queue, + dump_rx_pkts, NULL); +} + +void +add_tx_dump_callbacks(portid_t portid) +{ + struct rte_eth_dev_info dev_info; + uint16_t queue; + + if (port_id_is_invalid(portid, ENABLED_WARN)) + return; + rte_eth_dev_info_get(portid, &dev_info); + for (queue = 0; queue < dev_info.nb_tx_queues; queue++) + if (!ports[portid].tx_dump_cb[queue]) + ports[portid].tx_dump_cb[queue] = + rte_eth_add_tx_callback(portid, queue, + dump_tx_pkts, NULL); +} + +void +remove_rx_dump_callbacks(portid_t portid) +{ + struct rte_eth_dev_info dev_info; + uint16_t queue; + + if (port_id_is_invalid(portid, ENABLED_WARN)) + return; + rte_eth_dev_info_get(portid, &dev_info); + for (queue = 0; queue < dev_info.nb_rx_queues; queue++) + if (ports[portid].rx_dump_cb[queue]) { + rte_eth_remove_rx_callback(portid, queue, + ports[portid].rx_dump_cb[queue]); + ports[portid].rx_dump_cb[queue] = NULL; + } +} + +void +remove_tx_dump_callbacks(portid_t portid) +{ + struct rte_eth_dev_info dev_info; + uint16_t queue; + + if (port_id_is_invalid(portid, ENABLED_WARN)) + return; + rte_eth_dev_info_get(portid, &dev_info); + for (queue = 0; queue < dev_info.nb_tx_queues; queue++) + if (ports[portid].tx_dump_cb[queue]) { + rte_eth_remove_tx_callback(portid, queue, + ports[portid].tx_dump_cb[queue]); + ports[portid].tx_dump_cb[queue] = NULL; + } +} + +void +configure_rxtx_dump_callbacks(uint16_t verbose) +{ + portid_t portid; + +#ifndef RTE_ETHDEV_RXTX_CALLBACKS + TESTPMD_LOG(ERR, "setting rxtx callbacks is not enabled\n"); + return; +#endif + + RTE_ETH_FOREACH_DEV(portid) + { + if (verbose == 1 || verbose > 2) + add_rx_dump_callbacks(portid); + else + remove_rx_dump_callbacks(portid); + if (verbose >= 2) + add_tx_dump_callbacks(portid); + else + remove_tx_dump_callbacks(portid); + } +} + +void set_verbose_level(uint16_t vb_level) { printf("Change verbose level from %u to %u\n", (unsigned int) verbose_level, (unsigned int) vb_level); verbose_level = vb_level; + configure_rxtx_dump_callbacks(verbose_level); } void |