1474572d2SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2474572d2SBruce Richardson * Copyright(c) 2010-2016 Intel Corporation 3474572d2SBruce Richardson */ 4474572d2SBruce Richardson 5474572d2SBruce Richardson #include <stdio.h> 6474572d2SBruce Richardson #include <stdlib.h> 7474572d2SBruce Richardson #include <stdint.h> 8474572d2SBruce Richardson 9474572d2SBruce Richardson #include <rte_log.h> 10474572d2SBruce Richardson #include <rte_ethdev.h> 11474572d2SBruce Richardson #include <rte_ether.h> 12474572d2SBruce Richardson #include <rte_ip.h> 13474572d2SBruce Richardson #include <rte_byteorder.h> 14474572d2SBruce Richardson 15474572d2SBruce Richardson #include <rte_port_ring.h> 16474572d2SBruce Richardson #include <rte_table_lpm_ipv6.h> 17474572d2SBruce Richardson #include <rte_pipeline.h> 18474572d2SBruce Richardson 19474572d2SBruce Richardson #include "main.h" 20474572d2SBruce Richardson 21474572d2SBruce Richardson void 22474572d2SBruce Richardson app_main_loop_worker_pipeline_lpm_ipv6(void) { 23474572d2SBruce Richardson struct rte_pipeline_params pipeline_params = { 24474572d2SBruce Richardson .name = "pipeline", 25474572d2SBruce Richardson .socket_id = rte_socket_id(), 26474572d2SBruce Richardson }; 27474572d2SBruce Richardson 28474572d2SBruce Richardson struct rte_pipeline *p; 29474572d2SBruce Richardson uint32_t port_in_id[APP_MAX_PORTS]; 30474572d2SBruce Richardson uint32_t port_out_id[APP_MAX_PORTS]; 31474572d2SBruce Richardson uint32_t table_id; 32474572d2SBruce Richardson uint32_t i; 33474572d2SBruce Richardson 34474572d2SBruce Richardson RTE_LOG(INFO, USER1, 35474572d2SBruce Richardson "Core %u is doing work (pipeline with IPv6 LPM table)\n", 36474572d2SBruce Richardson rte_lcore_id()); 37474572d2SBruce Richardson 38474572d2SBruce Richardson /* Pipeline configuration */ 39474572d2SBruce Richardson p = rte_pipeline_create(&pipeline_params); 40474572d2SBruce Richardson if (p == NULL) 41474572d2SBruce Richardson rte_panic("Unable to configure the pipeline\n"); 42474572d2SBruce Richardson 43474572d2SBruce Richardson /* Input port configuration */ 44474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) { 45474572d2SBruce Richardson struct rte_port_ring_reader_params port_ring_params = { 46474572d2SBruce Richardson .ring = app.rings_rx[i], 47474572d2SBruce Richardson }; 48474572d2SBruce Richardson 49474572d2SBruce Richardson struct rte_pipeline_port_in_params port_params = { 50474572d2SBruce Richardson .ops = &rte_port_ring_reader_ops, 51474572d2SBruce Richardson .arg_create = (void *) &port_ring_params, 52474572d2SBruce Richardson .f_action = NULL, 53474572d2SBruce Richardson .arg_ah = NULL, 54474572d2SBruce Richardson .burst_size = app.burst_size_worker_read, 55474572d2SBruce Richardson }; 56474572d2SBruce Richardson 57474572d2SBruce Richardson if (rte_pipeline_port_in_create(p, &port_params, 58474572d2SBruce Richardson &port_in_id[i])) 59474572d2SBruce Richardson rte_panic("Unable to configure input port for " 60474572d2SBruce Richardson "ring %d\n", i); 61474572d2SBruce Richardson } 62474572d2SBruce Richardson 63474572d2SBruce Richardson /* Output port configuration */ 64474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) { 65474572d2SBruce Richardson struct rte_port_ring_writer_params port_ring_params = { 66474572d2SBruce Richardson .ring = app.rings_tx[i], 67474572d2SBruce Richardson .tx_burst_sz = app.burst_size_worker_write, 68474572d2SBruce Richardson }; 69474572d2SBruce Richardson 70474572d2SBruce Richardson struct rte_pipeline_port_out_params port_params = { 71474572d2SBruce Richardson .ops = &rte_port_ring_writer_ops, 72474572d2SBruce Richardson .arg_create = (void *) &port_ring_params, 73474572d2SBruce Richardson .f_action = NULL, 74474572d2SBruce Richardson .arg_ah = NULL, 75474572d2SBruce Richardson }; 76474572d2SBruce Richardson 77474572d2SBruce Richardson if (rte_pipeline_port_out_create(p, &port_params, 78474572d2SBruce Richardson &port_out_id[i])) 79474572d2SBruce Richardson rte_panic("Unable to configure output port for " 80474572d2SBruce Richardson "ring %d\n", i); 81474572d2SBruce Richardson } 82474572d2SBruce Richardson 83474572d2SBruce Richardson /* Table configuration */ 84474572d2SBruce Richardson { 85474572d2SBruce Richardson struct rte_table_lpm_ipv6_params table_lpm_ipv6_params = { 86474572d2SBruce Richardson .name = "LPM", 87474572d2SBruce Richardson .n_rules = 1 << 24, 88474572d2SBruce Richardson .number_tbl8s = 1 << 21, 89474572d2SBruce Richardson .entry_unique_size = 90474572d2SBruce Richardson sizeof(struct rte_pipeline_table_entry), 91474572d2SBruce Richardson .offset = APP_METADATA_OFFSET(32), 92474572d2SBruce Richardson }; 93474572d2SBruce Richardson 94474572d2SBruce Richardson struct rte_pipeline_table_params table_params = { 95474572d2SBruce Richardson .ops = &rte_table_lpm_ipv6_ops, 96474572d2SBruce Richardson .arg_create = &table_lpm_ipv6_params, 97474572d2SBruce Richardson .f_action_hit = NULL, 98474572d2SBruce Richardson .f_action_miss = NULL, 99474572d2SBruce Richardson .arg_ah = NULL, 100474572d2SBruce Richardson .action_data_size = 0, 101474572d2SBruce Richardson }; 102474572d2SBruce Richardson 103474572d2SBruce Richardson if (rte_pipeline_table_create(p, &table_params, &table_id)) 104474572d2SBruce Richardson rte_panic("Unable to configure the IPv6 LPM table\n"); 105474572d2SBruce Richardson } 106474572d2SBruce Richardson 107474572d2SBruce Richardson /* Interconnecting ports and tables */ 108474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) 109474572d2SBruce Richardson if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], 110474572d2SBruce Richardson table_id)) 111474572d2SBruce Richardson rte_panic("Unable to connect input port %u to " 112474572d2SBruce Richardson "table %u\n", port_in_id[i], table_id); 113474572d2SBruce Richardson 114474572d2SBruce Richardson /* Add entries to tables */ 115474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) { 116474572d2SBruce Richardson struct rte_pipeline_table_entry entry = { 117474572d2SBruce Richardson .action = RTE_PIPELINE_ACTION_PORT, 118474572d2SBruce Richardson {.port_id = port_out_id[i & (app.n_ports - 1)]}, 119474572d2SBruce Richardson }; 120474572d2SBruce Richardson 121474572d2SBruce Richardson struct rte_table_lpm_ipv6_key key; 122474572d2SBruce Richardson struct rte_pipeline_table_entry *entry_ptr; 123474572d2SBruce Richardson uint32_t ip; 124474572d2SBruce Richardson int key_found, status; 125474572d2SBruce Richardson 1263d4e27fdSDavid Marchand key.depth = 8 + rte_popcount32(app.n_ports - 1); 127474572d2SBruce Richardson 128474572d2SBruce Richardson ip = rte_bswap32(i << (24 - 1293d4e27fdSDavid Marchand rte_popcount32(app.n_ports - 1))); 130*e1a06e39SRobin Jarry memcpy(&key.ip, &ip, sizeof(uint32_t)); 131474572d2SBruce Richardson 132474572d2SBruce Richardson printf("Adding rule to IPv6 LPM table (IPv6 destination = " 133*e1a06e39SRobin Jarry RTE_IPV6_ADDR_FMT "/%u => port out = %u)\n", 134*e1a06e39SRobin Jarry RTE_IPV6_ADDR_SPLIT(&key.ip), 135474572d2SBruce Richardson key.depth, i); 136474572d2SBruce Richardson 137474572d2SBruce Richardson status = rte_pipeline_table_entry_add(p, table_id, &key, &entry, 138474572d2SBruce Richardson &key_found, &entry_ptr); 139474572d2SBruce Richardson if (status < 0) 140474572d2SBruce Richardson rte_panic("Unable to add entry to table %u (%d)\n", 141474572d2SBruce Richardson table_id, status); 142474572d2SBruce Richardson } 143474572d2SBruce Richardson 144474572d2SBruce Richardson /* Enable input ports */ 145474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) 146474572d2SBruce Richardson if (rte_pipeline_port_in_enable(p, port_in_id[i])) 147474572d2SBruce Richardson rte_panic("Unable to enable input port %u\n", 148474572d2SBruce Richardson port_in_id[i]); 149474572d2SBruce Richardson 150474572d2SBruce Richardson /* Check pipeline consistency */ 151474572d2SBruce Richardson if (rte_pipeline_check(p) < 0) 152474572d2SBruce Richardson rte_panic("Pipeline consistency check failed\n"); 153474572d2SBruce Richardson 154474572d2SBruce Richardson /* Run-time */ 155474572d2SBruce Richardson #if APP_FLUSH == 0 156f6897b23SFeifei Wang while (!force_quit) 157474572d2SBruce Richardson rte_pipeline_run(p); 158474572d2SBruce Richardson #else 159f6897b23SFeifei Wang i = 0; 160f6897b23SFeifei Wang while (!force_quit) { 161474572d2SBruce Richardson rte_pipeline_run(p); 162474572d2SBruce Richardson 163474572d2SBruce Richardson if ((i & APP_FLUSH) == 0) 164474572d2SBruce Richardson rte_pipeline_flush(p); 165f6897b23SFeifei Wang i++; 166474572d2SBruce Richardson } 167474572d2SBruce Richardson #endif 168474572d2SBruce Richardson } 169