diff options
-rw-r--r-- | src/plugins/dpdk/device/flow.c | 23 | ||||
-rw-r--r-- | src/vnet/flow/flow.h | 4 | ||||
-rw-r--r-- | src/vnet/flow/flow_cli.c | 19 |
3 files changed, 45 insertions, 1 deletions
diff --git a/src/plugins/dpdk/device/flow.c b/src/plugins/dpdk/device/flow.c index 91541f40163..9f765a6f845 100644 --- a/src/plugins/dpdk/device/flow.c +++ b/src/plugins/dpdk/device/flow.c @@ -103,6 +103,25 @@ dpdk_flow_convert_rss_types (u64 type, u64 * dpdk_rss_type) return; } +/** Maximum number of queue indices in struct rte_flow_action_rss. */ +#define ACTION_RSS_QUEUE_NUM 128 + +static inline void +dpdk_flow_convert_rss_queues (u32 queue_index, u32 queue_num, + struct rte_flow_action_rss *rss) +{ + u16 *queues = clib_mem_alloc (sizeof (*queues) * ACTION_RSS_QUEUE_NUM); + int i; + + for (i = 0; i < queue_num; i++) + queues[i] = queue_index++; + + rss->queue_num = queue_num; + rss->queue = queues; + + return; +} + static inline enum rte_eth_hash_function dpdk_flow_convert_rss_func (vnet_rss_function_t func) { @@ -505,6 +524,10 @@ pattern_end: /* convert types to DPDK rss bitmask */ dpdk_flow_convert_rss_types (f->rss_types, &rss_type); + if (f->queue_num) + /* convert rss queues to array */ + dpdk_flow_convert_rss_queues (f->queue_index, f->queue_num, &rss); + rss.types = rss_type; if ((rss.func = dpdk_flow_convert_rss_func (f->rss_fun)) == RTE_ETH_HASH_FUNCTION_MAX) diff --git a/src/vnet/flow/flow.h b/src/vnet/flow/flow.h index 313e85c45f9..194579b88d8 100644 --- a/src/vnet/flow/flow.h +++ b/src/vnet/flow/flow.h @@ -252,6 +252,10 @@ typedef struct /* queue for VNET_FLOW_ACTION_REDIRECT_TO_QUEUE */ u32 redirect_queue; + /* start queue index and queue numbers for RSS queue group */ + u32 queue_index; + u32 queue_num; + /* buffer offset for VNET_FLOW_ACTION_BUFFER_ADVANCE */ i32 buffer_advance; diff --git a/src/vnet/flow/flow_cli.c b/src/vnet/flow/flow_cli.c index f3e6c3912bd..5f44a099f57 100644 --- a/src/vnet/flow/flow_cli.c +++ b/src/vnet/flow/flow_cli.c @@ -364,6 +364,7 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, int rv; u32 teid = 0, session_id = 0, spi = 0; u32 vni = 0; + u32 queue_start = 0, queue_end = 0; vnet_flow_type_t type = VNET_FLOW_TYPE_UNKNOWN; ip4_address_and_mask_t ip4s = { }; ip4_address_and_mask_t ip4d = { }; @@ -522,6 +523,21 @@ test_flow (vlib_main_t * vm, unformat_input_t * input, #undef _ flow.actions |= VNET_FLOW_ACTION_RSS; } + else if (unformat (line_input, "rss queues")) + { + if (unformat (line_input, "%d to %d", &queue_start, &queue_end)) + ; + else + { + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + } + + flow.queue_index = queue_start; + flow.queue_num = queue_end - queue_start + 1; + + flow.actions |= VNET_FLOW_ACTION_RSS; + } else if (unformat (line_input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index)) ; @@ -728,7 +744,8 @@ VLIB_CLI_COMMAND (test_flow_command, static) = { "[spec <spec string>] [mask <mask string>]" "[next-node <node>] [mark <id>] [buffer-advance <len>] " "[redirect-to-queue <queue>] [drop] " - "[rss function <name>] [rss types <flow type>]", + "[rss function <name>] [rss types <flow type>]" + "[rss queues <queue_start> to <queue_end>]", .function = test_flow, }; /* *INDENT-ON* */ |