39 #define I40E_RSS_HKEY_LEN 52
41 #if RTE_VER_YEAR <= 19
42 static int i40eDeviceEnableSymHash(
43 int port_id,
const char *port_name, uint32_t ftype,
enum rte_eth_hash_function
function)
45 struct rte_eth_hash_filter_info info;
49 memset(&info, 0,
sizeof(info));
51 #pragma GCC diagnostic push
52 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
53 retval = rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_HASH);
54 #pragma GCC diagnostic pop
56 SCLogError(
"RTE_ETH_FILTER_HASH not supported on port: %s", port_name);
60 info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
61 info.info.global_conf.hash_func =
function;
63 idx = ftype / UINT64_BIT;
64 offset = ftype % UINT64_BIT;
65 info.info.global_conf.valid_bit_mask[idx] |= (1ULL <<
offset);
66 info.info.global_conf.sym_hash_enable_mask[idx] |= (1ULL <<
offset);
68 #pragma GCC diagnostic push
69 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
70 retval = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_HASH, RTE_ETH_FILTER_SET, &info);
71 #pragma GCC diagnostic pop
74 SCLogError(
"Cannot set global hash configurations on port %s", port_name);
81 static int i40eDeviceSetSymHash(
int port_id,
const char *port_name,
int enable)
84 struct rte_eth_hash_filter_info info;
86 memset(&info, 0,
sizeof(info));
88 #pragma GCC diagnostic push
89 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
90 ret = rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_HASH);
91 #pragma GCC diagnostic pop
94 SCLogError(
"RTE_ETH_FILTER_HASH not supported on port: %s", port_name);
98 info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
99 info.info.enable = enable;
100 #pragma GCC diagnostic push
101 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
102 ret = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_HASH, RTE_ETH_FILTER_SET, &info);
103 #pragma GCC diagnostic pop
106 SCLogError(
"Cannot set symmetric hash enable per port on port %s", port_name);
113 static int i40eDeviceSetRSSWithFilter(
int port_id,
const char *port_name)
119 retval |= i40eDeviceEnableSymHash(
120 port_id, port_name, RTE_ETH_FLOW_FRAG_IPV4, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
121 retval |= i40eDeviceEnableSymHash(
122 port_id, port_name, RTE_ETH_FLOW_NONFRAG_IPV4_TCP, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
123 retval |= i40eDeviceEnableSymHash(
124 port_id, port_name, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
125 retval |= i40eDeviceEnableSymHash(
126 port_id, port_name, RTE_ETH_FLOW_NONFRAG_IPV4_SCTP, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
127 retval |= i40eDeviceEnableSymHash(
128 port_id, port_name, RTE_ETH_FLOW_NONFRAG_IPV4_OTHER, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
130 retval |= i40eDeviceEnableSymHash(
131 port_id, port_name, RTE_ETH_FLOW_FRAG_IPV6, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
132 retval |= i40eDeviceEnableSymHash(
133 port_id, port_name, RTE_ETH_FLOW_NONFRAG_IPV6_TCP, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
134 retval |= i40eDeviceEnableSymHash(
135 port_id, port_name, RTE_ETH_FLOW_NONFRAG_IPV6_UDP, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
136 retval |= i40eDeviceEnableSymHash(
137 port_id, port_name, RTE_ETH_FLOW_NONFRAG_IPV6_SCTP, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
138 retval |= i40eDeviceEnableSymHash(
139 port_id, port_name, RTE_ETH_FLOW_NONFRAG_IPV6_OTHER, RTE_ETH_HASH_FUNCTION_TOEPLITZ);
141 retval |= i40eDeviceSetSymHash(port_id, port_name, 1);
147 static int i40eDeviceSetRSSFlowQueues(
148 int port_id,
const char *port_name,
struct rte_eth_rss_conf rss_conf,
int nb_rx_queues)
150 struct rte_flow_action_rss rss_action_conf = { 0 };
151 struct rte_flow_attr attr = { 0 };
152 struct rte_flow_item pattern[] = { { 0 }, { 0 }, { 0 }, { 0 } };
153 struct rte_flow_action action[] = { { 0 }, { 0 } };
154 struct rte_flow *flow;
155 struct rte_flow_error flow_error = { 0 };
156 uint16_t queues[RTE_MAX_QUEUES_PER_PORT];
158 for (
int i = 0; i < nb_rx_queues; ++i)
161 rss_action_conf.func = RTE_ETH_HASH_FUNCTION_DEFAULT;
162 rss_action_conf.level = 0;
163 rss_action_conf.types = 0;
164 rss_action_conf.key_len = 0;
165 rss_action_conf.key = NULL;
167 if (nb_rx_queues < 1) {
168 FatalError(
"The number of queues for RSS configuration must be "
169 "configured with a positive number");
172 rss_action_conf.queue_num = nb_rx_queues;
173 rss_action_conf.queue = queues;
176 pattern[0].type = RTE_FLOW_ITEM_TYPE_END;
177 action[0].type = RTE_FLOW_ACTION_TYPE_RSS;
178 action[0].conf = &rss_action_conf;
179 action[1].type = RTE_FLOW_ACTION_TYPE_END;
181 flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error);
183 SCLogError(
"Error when creating rte_flow rule on %s: %s", port_name, flow_error.message);
184 int ret = rte_flow_validate(port_id, &attr, pattern, action, &flow_error);
185 SCLogError(
"Error on rte_flow validation for port %s: %s errmsg: %s", port_name,
186 rte_strerror(-ret), flow_error.message);
189 SCLogInfo(
"RTE_FLOW queue region created for port %s", port_name);
194 static int i40eDeviceCreateRSSFlow(
int port_id,
const char *port_name,
195 struct rte_eth_rss_conf rss_conf, uint64_t rss_type,
struct rte_flow_item *pattern)
197 struct rte_flow_action_rss rss_action_conf = { 0 };
198 struct rte_flow_attr attr = { 0 };
199 struct rte_flow_action action[] = { { 0 }, { 0 } };
200 struct rte_flow *flow;
201 struct rte_flow_error flow_error = { 0 };
203 rss_action_conf.func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ;
204 rss_action_conf.level = 0;
205 rss_action_conf.types = rss_type;
206 rss_action_conf.key_len = rss_conf.rss_key_len;
207 rss_action_conf.key = rss_conf.rss_key;
208 rss_action_conf.queue_num = 0;
209 rss_action_conf.queue = NULL;
212 action[0].type = RTE_FLOW_ACTION_TYPE_RSS;
213 action[0].conf = &rss_action_conf;
214 action[1].type = RTE_FLOW_ACTION_TYPE_END;
216 flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error);
218 SCLogError(
"Error when creating rte_flow rule on %s: %s", port_name, flow_error.message);
219 int ret = rte_flow_validate(port_id, &attr, pattern, action, &flow_error);
220 SCLogError(
"Error on rte_flow validation for port %s: %s errmsg: %s", port_name,
221 rte_strerror(-ret), flow_error.message);
224 SCLogInfo(
"RTE_FLOW flow rule created for port %s", port_name);
230 static int i40eDeviceSetRSSFlowIPv4(
231 int port_id,
const char *port_name,
struct rte_eth_rss_conf rss_conf)
234 struct rte_flow_item pattern[] = { { 0 }, { 0 }, { 0 }, { 0 } };
236 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
237 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
238 pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
239 ret |= i40eDeviceCreateRSSFlow(
240 port_id, port_name, rss_conf, RTE_ETH_RSS_NONFRAG_IPV4_OTHER, pattern);
241 memset(pattern, 0,
sizeof(pattern));
243 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
244 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
245 pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP;
246 pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
247 ret |= i40eDeviceCreateRSSFlow(
248 port_id, port_name, rss_conf, RTE_ETH_RSS_NONFRAG_IPV4_UDP, pattern);
249 memset(pattern, 0,
sizeof(pattern));
251 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
252 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
253 pattern[2].type = RTE_FLOW_ITEM_TYPE_TCP;
254 pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
255 ret |= i40eDeviceCreateRSSFlow(
256 port_id, port_name, rss_conf, RTE_ETH_RSS_NONFRAG_IPV4_TCP, pattern);
257 memset(pattern, 0,
sizeof(pattern));
259 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
260 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
261 pattern[2].type = RTE_FLOW_ITEM_TYPE_SCTP;
262 pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
263 ret |= i40eDeviceCreateRSSFlow(
264 port_id, port_name, rss_conf, RTE_ETH_RSS_NONFRAG_IPV4_SCTP, pattern);
265 memset(pattern, 0,
sizeof(pattern));
267 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
268 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
269 pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
270 ret |= i40eDeviceCreateRSSFlow(port_id, port_name, rss_conf, RTE_ETH_RSS_FRAG_IPV4, pattern);
275 static int i40eDeviceSetRSSFlowIPv6(
276 int port_id,
const char *port_name,
struct rte_eth_rss_conf rss_conf)
279 struct rte_flow_item pattern[] = { { 0 }, { 0 }, { 0 }, { 0 } };
281 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
282 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV6;
283 pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
284 ret |= i40eDeviceCreateRSSFlow(
285 port_id, port_name, rss_conf, RTE_ETH_RSS_NONFRAG_IPV6_OTHER, pattern);
286 memset(pattern, 0,
sizeof(pattern));
288 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
289 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV6;
290 pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP;
291 pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
292 ret |= i40eDeviceCreateRSSFlow(
293 port_id, port_name, rss_conf, RTE_ETH_RSS_NONFRAG_IPV6_UDP, pattern);
294 memset(pattern, 0,
sizeof(pattern));
296 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
297 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV6;
298 pattern[2].type = RTE_FLOW_ITEM_TYPE_TCP;
299 pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
300 ret |= i40eDeviceCreateRSSFlow(
301 port_id, port_name, rss_conf, RTE_ETH_RSS_NONFRAG_IPV6_TCP, pattern);
302 memset(pattern, 0,
sizeof(pattern));
304 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
305 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV6;
306 pattern[2].type = RTE_FLOW_ITEM_TYPE_SCTP;
307 pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
308 ret |= i40eDeviceCreateRSSFlow(
309 port_id, port_name, rss_conf, RTE_ETH_RSS_NONFRAG_IPV6_SCTP, pattern);
310 memset(pattern, 0,
sizeof(pattern));
312 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
313 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV6;
314 pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
315 ret |= i40eDeviceCreateRSSFlow(port_id, port_name, rss_conf, RTE_ETH_RSS_FRAG_IPV6, pattern);
320 static int i40eDeviceSetRSSWithFlows(
int port_id,
const char *port_name,
int nb_rx_queues)
323 uint8_t rss_key[I40E_RSS_HKEY_LEN];
324 struct rte_flow_error flush_error = { 0 };
325 struct rte_eth_rss_conf rss_conf = {
327 .rss_key_len = I40E_RSS_HKEY_LEN,
330 retval = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
332 SCLogError(
"Unable to get RSS hash configuration of port %s", port_name);
337 retval |= i40eDeviceSetRSSFlowQueues(port_id, port_name, rss_conf, nb_rx_queues);
338 retval |= i40eDeviceSetRSSFlowIPv4(port_id, port_name, rss_conf);
339 retval |= i40eDeviceSetRSSFlowIPv6(port_id, port_name, rss_conf);
341 retval = rte_flow_flush(port_id, &flush_error);
343 SCLogError(
"Unable to flush rte_flow rules of %s: %s Flush error msg: %s", port_name,
344 rte_strerror(-retval), flush_error.message);
354 int i40eDeviceSetRSS(
int port_id,
int nb_rx_queues)
358 char port_name[RTE_ETH_NAME_MAX_LEN];
360 retval = rte_eth_dev_get_name_by_port(port_id, port_name);
362 SCLogError(
"Failed to convert port id %d to the interface name: %s", port_id,
367 #if RTE_VER_YEAR <= 19
368 i40eDeviceSetRSSWithFilter(port_id, port_name);
370 i40eDeviceSetRSSWithFlows(port_id, port_name, nb_rx_queues);
375 void i40eDeviceSetRSSHashFunction(uint64_t *rss_hf)
377 if (RTE_VER_YEAR <= 19)
378 *rss_hf = RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_TCP |
379 RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
380 RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_FRAG_IPV6 |
381 RTE_ETH_RSS_NONFRAG_IPV6_TCP | RTE_ETH_RSS_NONFRAG_IPV6_UDP |
382 RTE_ETH_RSS_NONFRAG_IPV6_SCTP | RTE_ETH_RSS_NONFRAG_IPV6_OTHER | RTE_ETH_RSS_SCTP;
384 *rss_hf = RTE_ETH_RSS_FRAG_IPV4 | RTE_ETH_RSS_NONFRAG_IPV4_OTHER | RTE_ETH_RSS_FRAG_IPV6 |
385 RTE_ETH_RSS_NONFRAG_IPV6_OTHER;