From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f41.google.com (mail-wm0-f41.google.com [74.125.82.41]) by dpdk.org (Postfix) with ESMTP id 1983A1B19E for ; Thu, 5 Oct 2017 11:49:26 +0200 (CEST) Received: by mail-wm0-f41.google.com with SMTP id m72so1013456wmc.1 for ; Thu, 05 Oct 2017 02:49:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AaC1tJBYJ8rPQSxdefjYxkOtHBDNFIAGt+JZgZS7A6Q=; b=wvDUMOXOTFhVkTx1rRWEEd6YQDyAr9hZHObnpY5ZpYb4Z6xUygG6xAaPIZeUDqPIUk WVEOzmxchm+tudAhvjVX8nx+a6tmtl+GDi6dSNZZdx9/gA7Y0jX73CbKiGUnU2N0a/88 CU0kLfO3OJ4UZF2Lb60zkVLqq9PeEZp5ICL4fw1hhxpBpXKYQF9H7dk+tTN3JtFqsDQv CG+UMe4JZ5lF7Y4B/Qv65tIQW1IGViTplbMP5tvM0QNoGDMUu2D333ndhZ2jom4ygD6J /ZvGCDD0XeyGMX+us7BmLDh0EVOiT7E2uRCjZV0zmcm6Lm4k0RVSkmD6DacVlyucHdw7 DK5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=AaC1tJBYJ8rPQSxdefjYxkOtHBDNFIAGt+JZgZS7A6Q=; b=ByqjHHdt6637imsr+lGy6iZ1XgpggzjiYNBADHbP0tufYl8lcqiCeqOCpVzg5dt+QL qO0TiuSxPZo5jHoSkc4wUq02ivHH7NJK3wjf+Svv6Tzxdhbmx8BeHTjFX1FNoJzNXbFW x3zJV8Av70OeeiECsewY35JE5N+YR/BQghJC2hV4JjDcrJJfiw517ghwH1kgkT+WFNMD dh2qHxQIBanhUPpHQ1T4zjW5udpIIn4nOSSLb+5Gk1ZyGadAdDvZnBopN6S9/Z1pKkED 6OJBEgJ+UsVglTZmmfuNxBA0zbXi5Vl2ANCjcuiQXgIE1E8TmkHQqYCrS0zFycRrsqA+ CPxg== X-Gm-Message-State: AHPjjUi7OOM+4EY4I0QNNq6G0cwNWSewzFyBmXESwwClABn6BvwnOzbE l4j+8JWKGxF2ScBb6AoyEi15oQ== X-Google-Smtp-Source: AOwi7QDW5D3QLAuWDgAgH4Ca45+dnMII++HuH5K5hdtUxS1Fww6/YQkKN9F71LNyYLvFiAwP/4szIw== X-Received: by 10.80.165.23 with SMTP id y23mr32541882edb.155.1507196965498; Thu, 05 Oct 2017 02:49:25 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id j6sm10648903edj.58.2017.10.05.02.49.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Oct 2017 02:49:24 -0700 (PDT) From: Adrien Mazarguil To: Ferruh Yigit , Gaetan Rivet Cc: dev@dpdk.org Date: Thu, 5 Oct 2017 11:49:05 +0200 Message-Id: <6023ff5fcfe867b53cad1d0ffeedcf2dacdb5d26.1507193186.git.adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v1 4/7] app/testpmd: rely on flow API conversion function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Oct 2017 09:49:26 -0000 This commit replaces all local information about pattern items and actions as well as flow rule duplication code with calls to rte_flow_conv(). Signed-off-by: Adrien Mazarguil --- app/test-pmd/config.c | 293 ++++++++++---------------------------------- app/test-pmd/testpmd.h | 7 +- 2 files changed, 66 insertions(+), 234 deletions(-) diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 60a8d07..11b9a0f 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -918,213 +918,36 @@ 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(PORT, sizeof(struct rte_flow_item_port)), - MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), /* +pattern[] */ - 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)), -}; - -/** Compute storage space needed by item specification. */ -static void -flow_item_spec_size(const struct rte_flow_item *item, - size_t *size, size_t *pad) -{ - if (!item->spec) { - *size = 0; - goto empty; - } - switch (item->type) { - union { - const struct rte_flow_item_raw *raw; - } spec; - - case RTE_FLOW_ITEM_TYPE_RAW: - spec.raw = item->spec; - *size = offsetof(struct rte_flow_item_raw, pattern) + - spec.raw->length * sizeof(*spec.raw->pattern); - break; - default: - *size = flow_item[item->type].size; - break; - } -empty: - *pad = RTE_ALIGN_CEIL(*size, sizeof(double)) - *size; -} - -/** 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, 0), - MK_FLOW_ACTION(DUP, sizeof(struct rte_flow_action_dup)), - MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */ - MK_FLOW_ACTION(PF, 0), - MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)), -}; - -/** Compute storage space needed by action configuration. */ -static void -flow_action_conf_size(const struct rte_flow_action *action, - size_t *size, size_t *pad) -{ - if (!action->conf) { - *size = 0; - goto empty; - } - switch (action->type) { - union { - const struct rte_flow_action_rss *rss; - } conf; - - case RTE_FLOW_ACTION_TYPE_RSS: - conf.rss = action->conf; - *size = offsetof(struct rte_flow_action_rss, queue) + - conf.rss->num * sizeof(*conf.rss->queue); - break; - default: - *size = flow_action[action->type].size; - break; - } -empty: - *pad = RTE_ALIGN_CEIL(*size, sizeof(double)) - *size; -} - /** 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_action *actions, + struct rte_flow_error *error) { - const struct rte_flow_item *item; - const struct rte_flow_action *action; + const struct rte_flow_conv_rule rule = { + { attr }, { pattern }, { actions }, + }; struct port_flow *pf = NULL; - size_t tmp; - size_t pad; - 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); - flow_item_spec_size(item, &tmp, &pad); - if (item->spec) { - if (pf) - dst->spec = memcpy(pf->data + off2, - item->spec, tmp); - off2 += tmp + pad; - } - if (item->last) { - if (pf) - dst->last = memcpy(pf->data + off2, - item->last, tmp); - off2 += tmp + pad; - } - if (item->mask) { - if (pf) - dst->mask = memcpy(pf->data + off2, - item->mask, tmp); - off2 += tmp + pad; - } - 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); - flow_action_conf_size(action, &tmp, &pad); - if (action->conf) { - if (pf) - dst->conf = memcpy(pf->data + off2, - action->conf, tmp); - off2 += tmp + pad; - } - off2 = RTE_ALIGN_CEIL(off2, sizeof(double)); - } while ((action++)->type != RTE_FLOW_ACTION_TYPE_END); - if (pf != NULL) - 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; - return NULL; + int ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, + &pf->rule, 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; + } + ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, + &pf->rule, ret, &rule, error); + if (ret < 0) { + free(pf); + return NULL; + } + return pf; } /** Print a message out of a flow error. */ @@ -1208,13 +1031,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; @@ -1306,6 +1126,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) @@ -1318,11 +1139,10 @@ 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) - name = "unknown"; - else - name = flow_action[action].name; + ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR, + &name, sizeof(name), (void *)action, &error); + if (ret < 0) + return port_flow_complain(&error); switch (action) { case RTE_FLOW_ACTION_TYPE_COUNT: break; @@ -1374,47 +1194,62 @@ 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\t", pf->id, - pf->attr.group, - pf->attr.priority, - pf->attr.ingress ? 'i' : '-', - pf->attr.egress ? 'e' : '-'); + pf->rule.attr->group, + pf->rule.attr->priority, + pf->rule.attr->ingress ? 'i' : '-', + pf->rule.attr->egress ? 'e' : '-'); 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"); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 1d1ee75..c8bc493 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -151,15 +151,12 @@ struct fwd_stream { /** Descriptor for a single flow. */ struct port_flow { - size_t size; /**< Allocated space including data[]. */ struct port_flow *next; /**< Next flow in list. */ struct port_flow *tmp; /**< Temporary linking. */ uint32_t id; /**< Flow rule ID. */ struct rte_flow *flow; /**< Opaque flow object returned by PMD. */ - struct rte_flow_attr attr; /**< Attributes. */ - struct rte_flow_item *pattern; /**< Pattern. */ - struct rte_flow_action *actions; /**< Actions. */ - uint8_t data[]; /**< Storage for pattern/actions. */ + struct rte_flow_conv_rule rule; /* Saved flow rule description. */ + uint8_t data[]; /**< Storage for flow rule description */ }; /** -- 2.1.4