1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2016 Intel Corporation
10 #include <rte_ethdev.h>
11 #include <rte_ether.h>
13 #include <rte_byteorder.h>
15 #include <rte_port_ring.h>
16 #include <rte_table_hash.h>
18 #include <rte_pipeline.h>
23 translate_options(uint32_t *special, uint32_t *ext, uint32_t *key_size)
25 switch (app.pipeline_type) {
26 case e_APP_PIPELINE_HASH_KEY8_EXT:
27 *special = 0; *ext = 1; *key_size = 8; return;
28 case e_APP_PIPELINE_HASH_KEY8_LRU:
29 *special = 0; *ext = 0; *key_size = 8; return;
30 case e_APP_PIPELINE_HASH_KEY16_EXT:
31 *special = 0; *ext = 1; *key_size = 16; return;
32 case e_APP_PIPELINE_HASH_KEY16_LRU:
33 *special = 0; *ext = 0; *key_size = 16; return;
34 case e_APP_PIPELINE_HASH_KEY32_EXT:
35 *special = 0; *ext = 1; *key_size = 32; return;
36 case e_APP_PIPELINE_HASH_KEY32_LRU:
37 *special = 0; *ext = 0; *key_size = 32; return;
39 case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
40 *special = 1; *ext = 1; *key_size = 8; return;
41 case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
42 *special = 1; *ext = 0; *key_size = 8; return;
43 case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
44 *special = 1; *ext = 1; *key_size = 16; return;
45 case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
46 *special = 1; *ext = 0; *key_size = 16; return;
47 case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
48 *special = 1; *ext = 1; *key_size = 32; return;
49 case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
50 *special = 1; *ext = 0; *key_size = 32; return;
52 case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
53 *special = 0; *ext = 0; *key_size = 8; return;
54 case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
55 *special = 0; *ext = 0; *key_size = 16; return;
56 case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
57 *special = 0; *ext = 0; *key_size = 32; return;
58 case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
59 *special = 0; *ext = 0; *key_size = 48; return;
60 case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
61 *special = 0; *ext = 0; *key_size = 64; return;
62 case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
63 *special = 0; *ext = 0; *key_size = 80; return;
64 case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
65 *special = 0; *ext = 0; *key_size = 96; return;
66 case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
67 *special = 0; *ext = 0; *key_size = 112; return;
68 case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
69 *special = 0; *ext = 0; *key_size = 128; return;
72 rte_panic("Invalid hash table type or key size\n");
76 app_main_loop_worker_pipeline_hash(void) {
77 struct rte_pipeline_params pipeline_params = {
79 .socket_id = rte_socket_id(),
82 struct rte_pipeline *p;
83 uint32_t port_in_id[APP_MAX_PORTS];
84 uint32_t port_out_id[APP_MAX_PORTS];
87 uint32_t special, ext, key_size;
89 translate_options(&special, &ext, &key_size);
91 RTE_LOG(INFO, USER1, "Core %u is doing work "
92 "(pipeline with hash table, %s, %s, %d-byte key)\n",
94 special ? "specialized" : "non-specialized",
95 ext ? "extendible bucket" : "LRU",
98 /* Pipeline configuration */
99 p = rte_pipeline_create(&pipeline_params);
101 rte_panic("Unable to configure the pipeline\n");
103 /* Input port configuration */
104 for (i = 0; i < app.n_ports; i++) {
105 struct rte_port_ring_reader_params port_ring_params = {
106 .ring = app.rings_rx[i],
109 struct rte_pipeline_port_in_params port_params = {
110 .ops = &rte_port_ring_reader_ops,
111 .arg_create = (void *) &port_ring_params,
114 .burst_size = app.burst_size_worker_read,
117 if (rte_pipeline_port_in_create(p, &port_params,
119 rte_panic("Unable to configure input port for "
123 /* Output port configuration */
124 for (i = 0; i < app.n_ports; i++) {
125 struct rte_port_ring_writer_params port_ring_params = {
126 .ring = app.rings_tx[i],
127 .tx_burst_sz = app.burst_size_worker_write,
130 struct rte_pipeline_port_out_params port_params = {
131 .ops = &rte_port_ring_writer_ops,
132 .arg_create = (void *) &port_ring_params,
137 if (rte_pipeline_port_out_create(p, &port_params,
139 rte_panic("Unable to configure output port for "
143 struct rte_table_hash_params table_hash_params = {
145 .key_size = key_size,
146 .key_offset = APP_METADATA_OFFSET(32),
149 .n_buckets = 1 << 22,
154 /* Table configuration */
155 switch (app.pipeline_type) {
156 case e_APP_PIPELINE_HASH_KEY8_EXT:
157 case e_APP_PIPELINE_HASH_KEY16_EXT:
158 case e_APP_PIPELINE_HASH_KEY32_EXT:
160 struct rte_pipeline_table_params table_params = {
161 .ops = &rte_table_hash_ext_ops,
162 .arg_create = &table_hash_params,
163 .f_action_hit = NULL,
164 .f_action_miss = NULL,
166 .action_data_size = 0,
169 if (rte_pipeline_table_create(p, &table_params, &table_id))
170 rte_panic("Unable to configure the hash table\n");
174 case e_APP_PIPELINE_HASH_KEY8_LRU:
175 case e_APP_PIPELINE_HASH_KEY16_LRU:
176 case e_APP_PIPELINE_HASH_KEY32_LRU:
178 struct rte_pipeline_table_params table_params = {
179 .ops = &rte_table_hash_lru_ops,
180 .arg_create = &table_hash_params,
181 .f_action_hit = NULL,
182 .f_action_miss = NULL,
184 .action_data_size = 0,
187 if (rte_pipeline_table_create(p, &table_params, &table_id))
188 rte_panic("Unable to configure the hash table\n");
192 case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
194 struct rte_pipeline_table_params table_params = {
195 .ops = &rte_table_hash_key8_ext_ops,
196 .arg_create = &table_hash_params,
197 .f_action_hit = NULL,
198 .f_action_miss = NULL,
200 .action_data_size = 0,
203 if (rte_pipeline_table_create(p, &table_params, &table_id))
204 rte_panic("Unable to configure the hash table\n");
208 case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
210 struct rte_pipeline_table_params table_params = {
211 .ops = &rte_table_hash_key8_lru_ops,
212 .arg_create = &table_hash_params,
213 .f_action_hit = NULL,
214 .f_action_miss = NULL,
216 .action_data_size = 0,
219 if (rte_pipeline_table_create(p, &table_params, &table_id))
220 rte_panic("Unable to configure the hash table\n");
224 case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
226 struct rte_pipeline_table_params table_params = {
227 .ops = &rte_table_hash_key16_ext_ops,
228 .arg_create = &table_hash_params,
229 .f_action_hit = NULL,
230 .f_action_miss = NULL,
232 .action_data_size = 0,
235 if (rte_pipeline_table_create(p, &table_params, &table_id))
236 rte_panic("Unable to configure the hash table)\n");
240 case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
242 struct rte_pipeline_table_params table_params = {
243 .ops = &rte_table_hash_key16_lru_ops,
244 .arg_create = &table_hash_params,
245 .f_action_hit = NULL,
246 .f_action_miss = NULL,
248 .action_data_size = 0,
251 if (rte_pipeline_table_create(p, &table_params, &table_id))
252 rte_panic("Unable to configure the hash table\n");
256 case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
258 struct rte_pipeline_table_params table_params = {
259 .ops = &rte_table_hash_key32_ext_ops,
260 .arg_create = &table_hash_params,
261 .f_action_hit = NULL,
262 .f_action_miss = NULL,
264 .action_data_size = 0,
267 if (rte_pipeline_table_create(p, &table_params, &table_id))
268 rte_panic("Unable to configure the hash table\n");
273 case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
275 struct rte_pipeline_table_params table_params = {
276 .ops = &rte_table_hash_key32_lru_ops,
277 .arg_create = &table_hash_params,
278 .f_action_hit = NULL,
279 .f_action_miss = NULL,
281 .action_data_size = 0,
284 if (rte_pipeline_table_create(p, &table_params, &table_id))
285 rte_panic("Unable to configure the hash table\n");
289 case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
290 case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
291 case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
292 case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
293 case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
294 case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
295 case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
296 case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
297 case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
299 struct rte_pipeline_table_params table_params = {
300 .ops = &rte_table_hash_cuckoo_ops,
301 .arg_create = &table_hash_params,
302 .f_action_hit = NULL,
303 .f_action_miss = NULL,
305 .action_data_size = 0,
308 if (rte_pipeline_table_create(p, &table_params, &table_id))
309 rte_panic("Unable to configure the hash table\n");
314 rte_panic("Invalid hash table type or key size\n");
317 /* Interconnecting ports and tables */
318 for (i = 0; i < app.n_ports; i++)
319 if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
321 rte_panic("Unable to connect input port %u to "
322 "table %u\n", port_in_id[i], table_id);
324 /* Add entries to tables */
325 for (i = 0; i < (1 << 24); i++) {
326 struct rte_pipeline_table_entry entry = {
327 .action = RTE_PIPELINE_ACTION_PORT,
328 {.port_id = port_out_id[i & (app.n_ports - 1)]},
330 struct rte_pipeline_table_entry *entry_ptr;
332 uint32_t *k32 = (uint32_t *) key;
333 int key_found, status;
335 memset(key, 0, sizeof(key));
336 k32[0] = rte_be_to_cpu_32(i);
338 status = rte_pipeline_table_entry_add(p, table_id, key, &entry,
339 &key_found, &entry_ptr);
341 rte_panic("Unable to add entry to table %u (%d)\n",
345 /* Enable input ports */
346 for (i = 0; i < app.n_ports; i++)
347 if (rte_pipeline_port_in_enable(p, port_in_id[i]))
348 rte_panic("Unable to enable input port %u\n",
351 /* Check pipeline consistency */
352 if (rte_pipeline_check(p) < 0)
353 rte_panic("Pipeline consistency check failed\n");
363 if ((i & APP_FLUSH) == 0)
364 rte_pipeline_flush(p);
371 __attribute__((unused)) void *key_mask,
372 __attribute__((unused)) uint32_t key_size,
373 __attribute__((unused)) uint64_t seed)
376 uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
377 uint64_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
383 app_main_loop_rx_metadata(void) {
387 RTE_LOG(INFO, USER1, "Core %u is doing RX (with meta-data)\n",
390 for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) {
393 n_mbufs = rte_eth_rx_burst(
397 app.burst_size_rx_read);
402 for (j = 0; j < n_mbufs; j++) {
404 uint8_t *m_data, *key;
405 struct ipv4_hdr *ip_hdr;
406 struct ipv6_hdr *ipv6_hdr;
409 uint32_t *signature, *k32;
411 m = app.mbuf_rx.array[j];
412 m_data = rte_pktmbuf_mtod(m, uint8_t *);
413 signature = RTE_MBUF_METADATA_UINT32_PTR(m,
414 APP_METADATA_OFFSET(0));
415 key = RTE_MBUF_METADATA_UINT8_PTR(m,
416 APP_METADATA_OFFSET(32));
418 if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
419 ip_hdr = (struct ipv4_hdr *)
420 &m_data[sizeof(struct ether_hdr)];
421 ip_dst = ip_hdr->dst_addr;
423 k32 = (uint32_t *) key;
424 k32[0] = ip_dst & 0xFFFFFF00;
425 } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
426 ipv6_hdr = (struct ipv6_hdr *)
427 &m_data[sizeof(struct ether_hdr)];
428 ipv6_dst = ipv6_hdr->dst_addr;
430 memcpy(key, ipv6_dst, 16);
434 *signature = test_hash(key, NULL, 0, 0);
438 ret = rte_ring_sp_enqueue_bulk(
440 (void **) app.mbuf_rx.array,