2 // Copyright (c) 2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #ifndef __INCLUDE_MAIN__
18 #define __INCLUDE_MAIN_H__
24 #include <sys/types.h>
26 #include <sys/queue.h>
33 #include <rte_common.h>
35 #include <rte_byteorder.h>
37 #include <rte_memory.h>
38 #include <rte_memcpy.h>
39 #include <rte_memzone.h>
41 #include <rte_per_lcore.h>
42 #include <rte_launch.h>
43 #include <rte_atomic.h>
44 #include <rte_cycles.h>
45 #include <rte_prefetch.h>
46 #include <rte_lcore.h>
47 #include <rte_per_lcore.h>
48 #include <rte_branch_prediction.h>
49 #include <rte_interrupts.h>
51 #include <rte_random.h>
52 #include <rte_debug.h>
53 #include <rte_ether.h>
54 #include <rte_ethdev.h>
56 #include <rte_mempool.h>
61 #include <rte_string_fns.h>
62 #include <rte_cpuflags.h>
63 #include <rte_timer.h>
66 #include "interface.h"
67 #include "l3fwd_common.h"
68 #include "l3fwd_lpm4.h"
69 #include "l3fwd_lpm6.h"
70 #define TIMER_RESOLUTION_CYCLES 20000000ULL /* around 10ms at 2 Ghz */
71 unsigned lcore_id = 1;
72 void convert_ipstr_to_numeric(void);
73 struct sockaddr_in ipaddr1, ipaddr2, ipaddr3, ipaddr4;
74 uint8_t ipv6_addr0[16] = {
75 0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0, 0xc0, 0x10, 0x28, 0x15
78 uint8_t ipv6_addr1[16] = {
79 0x12, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0, 0xc0, 0x10, 0x28, 0x15
82 /*{port_id, nrx_queue, ntx_queue, adminstate, promisc}*/
83 port_config_t portconf[5] = {
91 .buffer_size = 2048 + sizeof(struct rte_mbuf) +
93 .pool_size = 32 * 1024,
100 .mq_mode = ETH_MQ_RX_NONE,
101 .header_split = 0, /* Header split */
102 .hw_ip_checksum = 0, /* IP checksum offload */
103 .hw_vlan_filter = 0, /* VLAN filtering */
104 .hw_vlan_strip = 0, /* VLAN strip */
105 .hw_vlan_extend = 0, /* Extended VLAN */
106 .jumbo_frame = 0, /* Jumbo frame support */
107 .hw_strip_crc = 0, /* CRC strip by HW */
108 .enable_scatter = 0, /* Scattered packets RX handler */
109 .max_rx_pkt_len = 9000, /* Jumbo frame max packet len */
110 .split_hdr_size = 0, /* Header split buffer size */
120 .mq_mode = ETH_MQ_TX_NONE,},
124 /**< lsc interrupt feature enabled */
133 .rx_free_thresh = 64,
135 .rx_deferred_start = 0,
145 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS,
146 .tx_deferred_start = 0,
156 .buffer_size = 2048 + sizeof(struct rte_mbuf) +
157 RTE_PKTMBUF_HEADROOM,
158 .pool_size = 32 * 1024,
165 .mq_mode = ETH_MQ_RX_NONE,
166 .header_split = 0, /* Header split */
167 .hw_ip_checksum = 0, /* IP checksum offload */
168 .hw_vlan_filter = 0, /* VLAN filtering */
169 .hw_vlan_strip = 0, /* VLAN strip */
170 .hw_vlan_extend = 0, /* Extended VLAN */
171 .jumbo_frame = 0, /* Jumbo frame support */
172 .hw_strip_crc = 0, /* CRC strip by HW */
173 .enable_scatter = 0, /* Scattered packets RX handler */
174 .max_rx_pkt_len = 9000, /* Jumbo frame max packet len */
175 .split_hdr_size = 0, /* Header split buffer size */
185 .mq_mode = ETH_MQ_TX_NONE,},
189 /**< lsc interrupt feature enabled */
198 .rx_free_thresh = 64,
200 .rx_deferred_start = 0,
210 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOOFFLOADS,
211 .tx_deferred_start = 0,
216 static __attribute__ ((noreturn))
217 int lcore_mainloop (__attribute__ ((unused))
220 l2_phy_interface_t *port;
222 struct rte_mbuf *pkts_burst[IFM_BURST_SIZE];
223 uint32_t nb_tx, nb_rx;
224 const uint64_t drain_tsc =
225 (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
226 uint64_t prev_tsc = 0, cur_tsc, diff_tsc;
228 port = ifm_get_first_port();
229 while (port != NULL) {
231 portid = port->pmdid;
232 cur_tsc = rte_rdtsc();
233 diff_tsc = cur_tsc - prev_tsc;
235 /* call rx function ptr from port, with port.arpq, */
236 if (unlikely(diff_tsc > drain_tsc)) {
237 if (port->tx_buf_len > 0) {
240 //nb_tx = port->transmit_bulk_pkts(port, port->tx_buf, port->tx_buf_len);
241 port->tx_buf_len = 0;
245 nb_rx = port->retrieve_bulk_pkts(portid, 0, pkts_burst);
246 port->n_rxpkts += nb_rx;
247 protocol_handler_recv(pkts_burst, nb_rx, port);
248 port = ifm_get_next_port(portid);
255 void convert_ipstr_to_numeric(void)
257 memset(&ipaddr1, '\0', sizeof(struct sockaddr_in));
258 ipaddr1.sin_addr.s_addr = inet_addr("30.0.0.10");
259 memset(&ipaddr2, '\0', sizeof(struct sockaddr_in));
260 ipaddr2.sin_addr.s_addr = inet_addr("120.0.0.10");
263 int main(int argc, char **argv)
267 ret = rte_eal_init(argc, argv);
269 rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n");
273 ifm_configure_ports(portconf);
275 //convert_ipstr_to_numeric();
276 //ifm_add_ipv4_port(0, ipaddr1.sin_addr.s_addr, 24);
277 //ifm_add_ipv4_port(1, ipaddr2.sin_addr.s_addr, 24);
278 ifm_add_ipv6_port(0, ipv6_addr0, 96);
279 ifm_add_ipv6_port(1, ipv6_addr1, 96);
280 print_interface_details();
286 populate_lpm_routes();
287 /*call the main loop */
288 /* launch per-lcore init on every lcore */
290 for (ii = 0; ii < 16; ii += 2) {
291 printf("%02X%02X ", ipv6_addr0[ii], ipv6_addr0[ii + 1]);
294 for (ii = 0; ii < 16; ii += 2) {
295 printf("%02X%02X ", ipv6_addr1[ii], ipv6_addr1[ii + 1]);
297 printf("REMOTE LAUNCH STARTED........\n");
298 rte_eal_remote_launch(lcore_mainloop, NULL, lcore_id);
299 printf("REMOTE LAUNCH DONE.......\n");
300 if (rte_eal_wait_lcore(lcore_id) < 0) {