X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fconfig.c;h=035d336ab541ad7e0bfde665ec9a1472c5280fb5;hb=0e459ffa08891a3ba238821a80499b9b17e2f2d3;hp=72f25d15217dcd2b895aefd084022c8c04955be9;hpb=94a6f2def20486d80df2e289ae327eb2a7932209;p=dpdk.git diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 72f25d1521..035d336ab5 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1367,6 +1367,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, @@ -1377,28 +1397,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; @@ -1570,6 +1589,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])