1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2016 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <stdint.h> 8 9 #include <rte_log.h> 10 #include <rte_ethdev.h> 11 #include <rte_ether.h> 12 #include <rte_ip.h> 13 #include <rte_byteorder.h> 14 15 #include <rte_port_ring.h> 16 #include <rte_table_lpm.h> 17 #include <rte_pipeline.h> 18 19 #include "main.h" 20 21 #ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s 22 #define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256 23 #endif 24 25 void 26 app_main_loop_worker_pipeline_lpm(void) { 27 struct rte_pipeline_params pipeline_params = { 28 .name = "pipeline", 29 .socket_id = rte_socket_id(), 30 }; 31 32 struct rte_pipeline *p; 33 uint32_t port_in_id[APP_MAX_PORTS]; 34 uint32_t port_out_id[APP_MAX_PORTS]; 35 uint32_t table_id; 36 uint32_t i; 37 38 RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with " 39 "LPM table)\n", rte_lcore_id()); 40 41 /* Pipeline configuration */ 42 p = rte_pipeline_create(&pipeline_params); 43 if (p == NULL) 44 rte_panic("Unable to configure the pipeline\n"); 45 46 /* Input port configuration */ 47 for (i = 0; i < app.n_ports; i++) { 48 struct rte_port_ring_reader_params port_ring_params = { 49 .ring = app.rings_rx[i], 50 }; 51 52 struct rte_pipeline_port_in_params port_params = { 53 .ops = &rte_port_ring_reader_ops, 54 .arg_create = (void *) &port_ring_params, 55 .f_action = NULL, 56 .arg_ah = NULL, 57 .burst_size = app.burst_size_worker_read, 58 }; 59 60 if (rte_pipeline_port_in_create(p, &port_params, 61 &port_in_id[i])) 62 rte_panic("Unable to configure input port for " 63 "ring %d\n", i); 64 } 65 66 /* Output port configuration */ 67 for (i = 0; i < app.n_ports; i++) { 68 struct rte_port_ring_writer_params port_ring_params = { 69 .ring = app.rings_tx[i], 70 .tx_burst_sz = app.burst_size_worker_write, 71 }; 72 73 struct rte_pipeline_port_out_params port_params = { 74 .ops = &rte_port_ring_writer_ops, 75 .arg_create = (void *) &port_ring_params, 76 .f_action = NULL, 77 .arg_ah = NULL, 78 }; 79 80 if (rte_pipeline_port_out_create(p, &port_params, 81 &port_out_id[i])) 82 rte_panic("Unable to configure output port for " 83 "ring %d\n", i); 84 } 85 86 /* Table configuration */ 87 { 88 struct rte_table_lpm_params table_lpm_params = { 89 .name = "LPM", 90 .n_rules = 1 << 24, 91 .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s, 92 .flags = 0, 93 .entry_unique_size = 94 sizeof(struct rte_pipeline_table_entry), 95 .offset = APP_METADATA_OFFSET(32), 96 }; 97 98 struct rte_pipeline_table_params table_params = { 99 .ops = &rte_table_lpm_ops, 100 .arg_create = &table_lpm_params, 101 .f_action_hit = NULL, 102 .f_action_miss = NULL, 103 .arg_ah = NULL, 104 .action_data_size = 0, 105 }; 106 107 if (rte_pipeline_table_create(p, &table_params, &table_id)) 108 rte_panic("Unable to configure the LPM table\n"); 109 } 110 111 /* Interconnecting ports and tables */ 112 for (i = 0; i < app.n_ports; i++) 113 if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], 114 table_id)) 115 rte_panic("Unable to connect input port %u to " 116 "table %u\n", port_in_id[i], table_id); 117 118 /* Add entries to tables */ 119 for (i = 0; i < app.n_ports; i++) { 120 struct rte_pipeline_table_entry entry = { 121 .action = RTE_PIPELINE_ACTION_PORT, 122 {.port_id = port_out_id[i & (app.n_ports - 1)]}, 123 }; 124 125 struct rte_table_lpm_key key = { 126 .ip = i << (24 - __builtin_popcount(app.n_ports - 1)), 127 .depth = 8 + __builtin_popcount(app.n_ports - 1), 128 }; 129 130 struct rte_pipeline_table_entry *entry_ptr; 131 132 int key_found, status; 133 134 printf("Adding rule to LPM table (IPv4 destination = %" 135 PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8 136 " => port out = %" PRIu32 ")\n", 137 (key.ip & 0xFF000000) >> 24, 138 (key.ip & 0x00FF0000) >> 16, 139 (key.ip & 0x0000FF00) >> 8, 140 key.ip & 0x000000FF, 141 key.depth, 142 i); 143 144 status = rte_pipeline_table_entry_add(p, table_id, &key, &entry, 145 &key_found, &entry_ptr); 146 if (status < 0) 147 rte_panic("Unable to add entry to table %u (%d)\n", 148 table_id, status); 149 } 150 151 /* Enable input ports */ 152 for (i = 0; i < app.n_ports; i++) 153 if (rte_pipeline_port_in_enable(p, port_in_id[i])) 154 rte_panic("Unable to enable input port %u\n", 155 port_in_id[i]); 156 157 /* Check pipeline consistency */ 158 if (rte_pipeline_check(p) < 0) 159 rte_panic("Pipeline consistency check failed\n"); 160 161 /* Run-time */ 162 #if APP_FLUSH == 0 163 for ( ; ; ) 164 rte_pipeline_run(p); 165 #else 166 for (i = 0; ; i++) { 167 rte_pipeline_run(p); 168 169 if ((i & APP_FLUSH) == 0) 170 rte_pipeline_flush(p); 171 } 172 #endif 173 } 174