@@ -182,14 +182,14 @@ add_count(struct rte_flow_action *actions,
}
void
-fill_actions(struct rte_flow_action *actions, uint64_t flow_actions,
+fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
uint32_t counter, uint16_t next_table, uint16_t hairpinq)
{
struct additional_para additional_para_data;
uint8_t actions_counter = 0;
uint16_t hairpin_queues[hairpinq];
uint16_t queues[RXQ_NUM];
- uint16_t i;
+ uint16_t i, j;
for (i = 0; i < RXQ_NUM; i++)
queues[i] = i;
@@ -217,7 +217,7 @@ fill_actions(struct rte_flow_action *actions, uint64_t flow_actions,
uint8_t actions_counter,
struct additional_para para
);
- } flows_actions[] = {
+ } actions_list[] = {
{
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
.funct = add_mark,
@@ -264,13 +264,19 @@ fill_actions(struct rte_flow_action *actions, uint64_t flow_actions,
},
};
- for (i = 0; i < RTE_DIM(flows_actions); i++) {
- if ((flow_actions & flows_actions[i].mask) == 0)
- continue;
- flows_actions[i].funct(
- actions, actions_counter++,
- additional_para_data
- );
+ for (j = 0; j < MAX_ACTIONS_NUM; j++) {
+ if (flow_actions[j] == 0)
+ break;
+ for (i = 0; i < RTE_DIM(actions_list); i++) {
+ if ((flow_actions[j] &
+ actions_list[i].mask) == 0)
+ continue;
+ actions_list[i].funct(
+ actions, actions_counter++,
+ additional_para_data
+ );
+ break;
+ }
}
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_END;
}
@@ -12,7 +12,7 @@
#include "config.h"
-void fill_actions(struct rte_flow_action *actions, uint64_t actions_selector,
+void fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
uint32_t counter, uint16_t next_table, uint16_t hairpinq);
#endif /* FLOW_PERF_ACTION_GEN */
@@ -29,3 +29,4 @@
/* Flow items/acctions max size */
#define MAX_ITEMS_NUM 32
#define MAX_ACTIONS_NUM 32
+#define MAX_ATTRS_NUM 16
@@ -18,23 +18,28 @@
static void
fill_attributes(struct rte_flow_attr *attr,
- uint64_t flow_attrs, uint16_t group)
+ uint64_t *flow_attrs, uint16_t group)
{
- if (flow_attrs & INGRESS)
- attr->ingress = 1;
- if (flow_attrs & EGRESS)
- attr->egress = 1;
- if (flow_attrs & TRANSFER)
- attr->transfer = 1;
+ uint8_t i;
+ for (i = 0; i < MAX_ATTRS_NUM; i++) {
+ if (flow_attrs[i] == 0)
+ break;
+ if (flow_attrs[i] & INGRESS)
+ attr->ingress = 1;
+ else if (flow_attrs[i] & EGRESS)
+ attr->egress = 1;
+ else if (flow_attrs[i] & TRANSFER)
+ attr->transfer = 1;
+ }
attr->group = group;
}
struct rte_flow *
generate_flow(uint16_t port_id,
uint16_t group,
- uint64_t flow_attrs,
- uint64_t flow_items,
- uint64_t flow_actions,
+ uint64_t *flow_attrs,
+ uint64_t *flow_items,
+ uint64_t *flow_actions,
uint16_t next_table,
uint32_t outer_ip_src,
uint16_t hairpinq,
@@ -26,9 +26,9 @@
struct rte_flow *
generate_flow(uint16_t port_id,
uint16_t group,
- uint64_t flow_attrs,
- uint64_t flow_items,
- uint64_t flow_actions,
+ uint64_t *flow_attrs,
+ uint64_t *flow_items,
+ uint64_t *flow_actions,
uint16_t next_table,
uint32_t outer_ip_src,
uint16_t hairpinq,
@@ -312,10 +312,10 @@ add_meta_tag(struct rte_flow_item *items,
void
fill_items(struct rte_flow_item *items,
- uint64_t flow_items, uint32_t outer_ip_src)
+ uint64_t *flow_items, uint32_t outer_ip_src)
{
uint8_t items_counter = 0;
- uint8_t i;
+ uint8_t i, j;
struct additional_para additional_para_data = {
.src_ip = outer_ip_src,
};
@@ -328,7 +328,7 @@ fill_items(struct rte_flow_item *items,
uint8_t items_counter,
struct additional_para para
);
- } flows_items[] = {
+ } items_list[] = {
{
.mask = RTE_FLOW_ITEM_TYPE_META,
.funct = add_meta_data,
@@ -384,13 +384,19 @@ fill_items(struct rte_flow_item *items,
};
- for (i = 0; i < RTE_DIM(flows_items); i++) {
- if ((flow_items & FLOW_ITEM_MASK(flows_items[i].mask)) == 0)
- continue;
- flows_items[i].funct(
- items, items_counter++,
- additional_para_data
- );
+ for (j = 0; j < MAX_ITEMS_NUM; j++) {
+ if (flow_items[j] == 0)
+ break;
+ for (i = 0; i < RTE_DIM(items_list); i++) {
+ if ((flow_items[j] &
+ FLOW_ITEM_MASK(items_list[i].mask)) == 0)
+ continue;
+ items_list[i].funct(
+ items, items_counter++,
+ additional_para_data
+ );
+ break;
+ }
}
items[items_counter].type = RTE_FLOW_ITEM_TYPE_END;
@@ -12,7 +12,7 @@
#include "config.h"
-void fill_items(struct rte_flow_item *items, uint64_t flow_items,
+void fill_items(struct rte_flow_item *items, uint64_t *flow_items,
uint32_t outer_ip_src);
#endif /* FLOW_PERF_ITEMS_GEN */
@@ -45,9 +45,10 @@
struct rte_flow *flow;
static uint8_t flow_group;
-static uint64_t flow_items;
-static uint64_t flow_actions;
-static uint64_t flow_attrs;
+static uint64_t flow_items[MAX_ITEMS_NUM];
+static uint64_t flow_actions[MAX_ACTIONS_NUM];
+static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint8_t items_idx, actions_idx, attrs_idx;
static volatile bool force_quit;
static bool dump_iterations;
@@ -150,132 +151,159 @@ args_parse(int argc, char **argv)
static const struct option_dict {
const char *str;
const uint64_t mask;
- uint64_t *bitmap;
+ uint64_t *map;
+ uint8_t *map_idx;
+
} flow_options[] = {
{
.str = "ether",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "ipv4",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "ipv6",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "vlan",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "tcp",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "udp",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "vxlan",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "vxlan-gpe",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "gre",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "geneve",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "gtp",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "meta",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "tag",
.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
- .bitmap = &flow_items
+ .map = &flow_items[0],
+ .map_idx = &items_idx
},
{
.str = "ingress",
.mask = INGRESS,
- .bitmap = &flow_attrs
+ .map = &flow_attrs[0],
+ .map_idx = &attrs_idx
},
{
.str = "egress",
.mask = EGRESS,
- .bitmap = &flow_attrs
+ .map = &flow_attrs[0],
+ .map_idx = &attrs_idx
},
{
.str = "transfer",
.mask = TRANSFER,
- .bitmap = &flow_attrs
+ .map = &flow_attrs[0],
+ .map_idx = &attrs_idx
},
{
.str = "port-id",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
},
{
.str = "rss",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
},
{
.str = "queue",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
},
{
.str = "jump",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
},
{
.str = "mark",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
},
{
.str = "count",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
},
{
.str = "set-meta",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
},
{
.str = "set-tag",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
},
{
.str = "drop",
.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
- .bitmap = &flow_actions
+ .map = &flow_actions[0],
+ .map_idx = &actions_idx
}
};
@@ -320,9 +348,6 @@ args_parse(int argc, char **argv)
{ "hairpin-rss", 1, 0, 0 },
};
- flow_items = 0;
- flow_actions = 0;
- flow_attrs = 0;
hairpin_queues_num = 0;
argvopt = argv;
@@ -349,7 +374,8 @@ args_parse(int argc, char **argv)
for (i = 0; i < RTE_DIM(flow_options); i++)
if (strcmp(lgopts[opt_idx].name,
flow_options[i].str) == 0) {
- *flow_options[i].bitmap |=
+ flow_options[i].map[
+ (*flow_options[i].map_idx)++] =
flow_options[i].mask;
printf("%s / ", flow_options[i].str);
}
@@ -363,7 +389,8 @@ args_parse(int argc, char **argv)
rte_exit(EXIT_SUCCESS,
"Hairpin queues should be > 0\n");
- flow_actions |= HAIRPIN_RSS_ACTION;
+ flow_actions[actions_idx++] =
+ HAIRPIN_RSS_ACTION;
printf("hairpin-rss / ");
}
if (strcmp(lgopts[opt_idx].name,
@@ -375,7 +402,8 @@ args_parse(int argc, char **argv)
rte_exit(EXIT_SUCCESS,
"Hairpin queues should be > 0\n");
- flow_actions |= HAIRPIN_QUEUE_ACTION;
+ flow_actions[actions_idx++] =
+ HAIRPIN_QUEUE_ACTION;
printf("hairpin-queue / ");
}
@@ -558,6 +586,11 @@ flows_handler(void)
int port_id;
int iter_id;
uint32_t flow_index;
+ uint64_t global_items[MAX_ITEMS_NUM] = { 0 };
+ uint64_t global_actions[MAX_ACTIONS_NUM] = { 0 };
+
+ global_items[0] = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH);
+ global_actions[0] = FLOW_ITEM_MASK(RTE_FLOW_ACTION_TYPE_JUMP);
nr_ports = rte_eth_dev_count_avail();
@@ -587,8 +620,7 @@ flows_handler(void)
*
*/
flow = generate_flow(port_id, 0, flow_attrs,
- FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
- FLOW_ITEM_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
+ global_items, global_actions,
flow_group, 0, 0, &error);
if (flow == NULL) {
@@ -272,6 +272,14 @@ New Features
of ingress packets to specific NIC queues.
See the :doc:`../sample_app_ug/ipsec_secgw` for more details.
+* **Add more support for flow-perf application.**
+
+ * Start supporting user order instead of bit mask:
+ Now the user can create any structure of rte_flow
+ using flow performance application with any order,
+ moreover the app also now starts to support inner
+ items matching as well.
+
Removed Items
-------------
@@ -16,20 +16,18 @@ After that the application will start producing rules with same pattern
but increasing the outer IP source address by 1 each time, thus it will
give different flow each time, and all other items will have open masks.
+The application also provide the ability to measure rte flow deletion rate,
+in addition to memory consumption before and after the flows creation.
+
+The app supports single and multi core performance measurements.
+
Known Limitations
-----------------
The current version has limitations which can be removed in future:
-* Support outer items up to tunnel layer only.
* Single core insertion only.
-* Only one instance of same action can be added in one rule.
-
-The application also provide the ability to measure rte flow deletion rate,
-in addition to memory consumption before and after the flows creation.
-
-The app supports single and multi core performance measurements.
Compiling the Application