13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
23998e2a0SBruce Richardson * Copyright(c) 2010-2015 Intel Corporation
3cc7e8ae8SMichal Jastrzebski */
4cc7e8ae8SMichal Jastrzebski
5cc7e8ae8SMichal Jastrzebski #include <stdint.h>
6cc7e8ae8SMichal Jastrzebski #include <sys/queue.h>
756faae82SDaniel Mrzyglod #include <sys/socket.h>
8cc7e8ae8SMichal Jastrzebski #include <stdlib.h>
9cc7e8ae8SMichal Jastrzebski #include <string.h>
10cc7e8ae8SMichal Jastrzebski #include <stdio.h>
11cc7e8ae8SMichal Jastrzebski #include <assert.h>
12cc7e8ae8SMichal Jastrzebski #include <errno.h>
13cc7e8ae8SMichal Jastrzebski #include <signal.h>
14cc7e8ae8SMichal Jastrzebski #include <stdarg.h>
15cc7e8ae8SMichal Jastrzebski #include <inttypes.h>
16cc7e8ae8SMichal Jastrzebski #include <getopt.h>
17cc7e8ae8SMichal Jastrzebski #include <termios.h>
18cc7e8ae8SMichal Jastrzebski #include <unistd.h>
19cc7e8ae8SMichal Jastrzebski #include <pthread.h>
20cc7e8ae8SMichal Jastrzebski
21cc7e8ae8SMichal Jastrzebski #include <rte_common.h>
22cc7e8ae8SMichal Jastrzebski #include <rte_log.h>
23cc7e8ae8SMichal Jastrzebski #include <rte_memory.h>
24cc7e8ae8SMichal Jastrzebski #include <rte_memcpy.h>
25cc7e8ae8SMichal Jastrzebski #include <rte_eal.h>
26cc7e8ae8SMichal Jastrzebski #include <rte_launch.h>
27cc7e8ae8SMichal Jastrzebski #include <rte_cycles.h>
28cc7e8ae8SMichal Jastrzebski #include <rte_prefetch.h>
29cc7e8ae8SMichal Jastrzebski #include <rte_lcore.h>
30cc7e8ae8SMichal Jastrzebski #include <rte_per_lcore.h>
31cc7e8ae8SMichal Jastrzebski #include <rte_branch_prediction.h>
32cc7e8ae8SMichal Jastrzebski #include <rte_interrupts.h>
33cc7e8ae8SMichal Jastrzebski #include <rte_random.h>
34cc7e8ae8SMichal Jastrzebski #include <rte_debug.h>
35cc7e8ae8SMichal Jastrzebski #include <rte_ether.h>
36cc7e8ae8SMichal Jastrzebski #include <rte_ethdev.h>
37cc7e8ae8SMichal Jastrzebski #include <rte_mempool.h>
38cc7e8ae8SMichal Jastrzebski #include <rte_mbuf.h>
39cc7e8ae8SMichal Jastrzebski #include <rte_ip.h>
40cc7e8ae8SMichal Jastrzebski #include <rte_tcp.h>
41cc7e8ae8SMichal Jastrzebski #include <rte_arp.h>
42cc7e8ae8SMichal Jastrzebski #include <rte_spinlock.h>
437b0de673SThomas Monjalon #include <rte_devargs.h>
447b0de673SThomas Monjalon #include <rte_byteorder.h>
457b0de673SThomas Monjalon #include <rte_cpuflags.h>
467b0de673SThomas Monjalon #include <rte_eth_bond.h>
47cc7e8ae8SMichal Jastrzebski
48cc7e8ae8SMichal Jastrzebski #include <cmdline_socket.h>
49cfc3bc5dSBruce Richardson #include "commands.h"
50cc7e8ae8SMichal Jastrzebski
51cc7e8ae8SMichal Jastrzebski #define RTE_LOGTYPE_DCB RTE_LOGTYPE_USER1
52cc7e8ae8SMichal Jastrzebski
53cc7e8ae8SMichal Jastrzebski #define NB_MBUF (1024*8)
54cc7e8ae8SMichal Jastrzebski
55cc7e8ae8SMichal Jastrzebski #define MAX_PKT_BURST 32
56cc7e8ae8SMichal Jastrzebski #define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
57cc7e8ae8SMichal Jastrzebski #define BURST_RX_INTERVAL_NS (10) /* RX poll interval ~100ns */
58cc7e8ae8SMichal Jastrzebski
59cc7e8ae8SMichal Jastrzebski /*
60cc7e8ae8SMichal Jastrzebski * RX and TX Prefetch, Host, and Write-back threshold values should be
61cc7e8ae8SMichal Jastrzebski * carefully set for optimal performance. Consult the network
62cc7e8ae8SMichal Jastrzebski * controller's datasheet and supporting DPDK documentation for guidance
63cc7e8ae8SMichal Jastrzebski * on how these parameters should be set.
64cc7e8ae8SMichal Jastrzebski */
65cc7e8ae8SMichal Jastrzebski #define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */
66cc7e8ae8SMichal Jastrzebski #define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */
67cc7e8ae8SMichal Jastrzebski #define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */
68cc7e8ae8SMichal Jastrzebski #define RX_FTHRESH (MAX_PKT_BURST * 2)/**< Default values of RX free threshold reg. */
69cc7e8ae8SMichal Jastrzebski
70cc7e8ae8SMichal Jastrzebski /*
71cc7e8ae8SMichal Jastrzebski * These default values are optimized for use with the Intel(R) 82599 10 GbE
72cc7e8ae8SMichal Jastrzebski * Controller and the DPDK ixgbe PMD. Consider using other values for other
73cc7e8ae8SMichal Jastrzebski * network controllers and/or network drivers.
74cc7e8ae8SMichal Jastrzebski */
75cc7e8ae8SMichal Jastrzebski #define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */
76cc7e8ae8SMichal Jastrzebski #define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */
77cc7e8ae8SMichal Jastrzebski #define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */
78cc7e8ae8SMichal Jastrzebski
79cc7e8ae8SMichal Jastrzebski /*
80cc7e8ae8SMichal Jastrzebski * Configurable number of RX/TX ring descriptors
81cc7e8ae8SMichal Jastrzebski */
82867a6c66SKevin Laatz #define RTE_RX_DESC_DEFAULT 1024
83867a6c66SKevin Laatz #define RTE_TX_DESC_DEFAULT 1024
84cc7e8ae8SMichal Jastrzebski
85cc7e8ae8SMichal Jastrzebski #define BOND_IP_1 7
86cc7e8ae8SMichal Jastrzebski #define BOND_IP_2 0
87cc7e8ae8SMichal Jastrzebski #define BOND_IP_3 0
88cc7e8ae8SMichal Jastrzebski #define BOND_IP_4 10
89cc7e8ae8SMichal Jastrzebski
90cc7e8ae8SMichal Jastrzebski /* not defined under linux */
91cc7e8ae8SMichal Jastrzebski #ifndef NIPQUAD
92cc7e8ae8SMichal Jastrzebski #define NIPQUAD_FMT "%u.%u.%u.%u"
93cc7e8ae8SMichal Jastrzebski #endif
94cc7e8ae8SMichal Jastrzebski
95cc7e8ae8SMichal Jastrzebski #define MAX_PORTS 4
96cc7e8ae8SMichal Jastrzebski #define PRINT_MAC(addr) printf("%02"PRIx8":%02"PRIx8":%02"PRIx8 \
97cc7e8ae8SMichal Jastrzebski ":%02"PRIx8":%02"PRIx8":%02"PRIx8, \
98a7db3afcSAman Deep Singh RTE_ETHER_ADDR_BYTES(&addr))
99cc7e8ae8SMichal Jastrzebski
10015e34522SLong Wu uint16_t members[RTE_MAX_ETHPORTS];
10115e34522SLong Wu uint16_t members_count;
102cc7e8ae8SMichal Jastrzebski
103f8244c63SZhiyong Yang static uint16_t BOND_PORT = 0xffff;
104cc7e8ae8SMichal Jastrzebski
105cc7e8ae8SMichal Jastrzebski static struct rte_mempool *mbuf_pool;
106cc7e8ae8SMichal Jastrzebski
107cc7e8ae8SMichal Jastrzebski static struct rte_eth_conf port_conf = {
108cc7e8ae8SMichal Jastrzebski .rxmode = {
109295968d1SFerruh Yigit .mq_mode = RTE_ETH_MQ_RX_NONE,
110cc7e8ae8SMichal Jastrzebski },
111cc7e8ae8SMichal Jastrzebski .rx_adv_conf = {
112cc7e8ae8SMichal Jastrzebski .rss_conf = {
113cc7e8ae8SMichal Jastrzebski .rss_key = NULL,
114295968d1SFerruh Yigit .rss_hf = RTE_ETH_RSS_IP,
115cc7e8ae8SMichal Jastrzebski },
116cc7e8ae8SMichal Jastrzebski },
117cc7e8ae8SMichal Jastrzebski .txmode = {
118295968d1SFerruh Yigit .mq_mode = RTE_ETH_MQ_TX_NONE,
119cc7e8ae8SMichal Jastrzebski },
120cc7e8ae8SMichal Jastrzebski };
121cc7e8ae8SMichal Jastrzebski
122cc7e8ae8SMichal Jastrzebski static void
member_port_init(uint16_t portid,struct rte_mempool * mbuf_pool)12315e34522SLong Wu member_port_init(uint16_t portid, struct rte_mempool *mbuf_pool)
124cc7e8ae8SMichal Jastrzebski {
125cc7e8ae8SMichal Jastrzebski int retval;
12660efb44fSRoman Zhukov uint16_t nb_rxd = RTE_RX_DESC_DEFAULT;
12760efb44fSRoman Zhukov uint16_t nb_txd = RTE_TX_DESC_DEFAULT;
128c1b77788SShahaf Shuler struct rte_eth_dev_info dev_info;
129c1b77788SShahaf Shuler struct rte_eth_rxconf rxq_conf;
130c1b77788SShahaf Shuler struct rte_eth_txconf txq_conf;
131c1b77788SShahaf Shuler struct rte_eth_conf local_port_conf = port_conf;
132cc7e8ae8SMichal Jastrzebski
133a9dbe180SThomas Monjalon if (!rte_eth_dev_is_valid_port(portid))
134cc7e8ae8SMichal Jastrzebski rte_exit(EXIT_FAILURE, "Invalid port\n");
135cc7e8ae8SMichal Jastrzebski
136089e5ed7SIvan Ilchenko retval = rte_eth_dev_info_get(portid, &dev_info);
137089e5ed7SIvan Ilchenko if (retval != 0)
138089e5ed7SIvan Ilchenko rte_exit(EXIT_FAILURE,
139089e5ed7SIvan Ilchenko "Error during getting device (port %u) info: %s\n",
140089e5ed7SIvan Ilchenko portid, strerror(-retval));
141089e5ed7SIvan Ilchenko
142295968d1SFerruh Yigit if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
143c1b77788SShahaf Shuler local_port_conf.txmode.offloads |=
144295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
1454f5701f2SFerruh Yigit
1464f5701f2SFerruh Yigit local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
1474f5701f2SFerruh Yigit dev_info.flow_type_rss_offloads;
1484f5701f2SFerruh Yigit if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
1494f5701f2SFerruh Yigit port_conf.rx_adv_conf.rss_conf.rss_hf) {
1504f5701f2SFerruh Yigit printf("Port %u modified RSS hash function based on hardware support,"
1514f5701f2SFerruh Yigit "requested:%#"PRIx64" configured:%#"PRIx64"\n",
1524f5701f2SFerruh Yigit portid,
1534f5701f2SFerruh Yigit port_conf.rx_adv_conf.rss_conf.rss_hf,
1544f5701f2SFerruh Yigit local_port_conf.rx_adv_conf.rss_conf.rss_hf);
1554f5701f2SFerruh Yigit }
1564f5701f2SFerruh Yigit
157c1b77788SShahaf Shuler retval = rte_eth_dev_configure(portid, 1, 1, &local_port_conf);
158cc7e8ae8SMichal Jastrzebski if (retval != 0)
159cc7e8ae8SMichal Jastrzebski rte_exit(EXIT_FAILURE, "port %u: configuration failed (res=%d)\n",
160cc7e8ae8SMichal Jastrzebski portid, retval);
161cc7e8ae8SMichal Jastrzebski
16260efb44fSRoman Zhukov retval = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, &nb_txd);
16360efb44fSRoman Zhukov if (retval != 0)
16460efb44fSRoman Zhukov rte_exit(EXIT_FAILURE, "port %u: rte_eth_dev_adjust_nb_rx_tx_desc "
16560efb44fSRoman Zhukov "failed (res=%d)\n", portid, retval);
16660efb44fSRoman Zhukov
167cc7e8ae8SMichal Jastrzebski /* RX setup */
168c1b77788SShahaf Shuler rxq_conf = dev_info.default_rxconf;
169c1b77788SShahaf Shuler rxq_conf.offloads = local_port_conf.rxmode.offloads;
17060efb44fSRoman Zhukov retval = rte_eth_rx_queue_setup(portid, 0, nb_rxd,
171c1b77788SShahaf Shuler rte_eth_dev_socket_id(portid),
172c1b77788SShahaf Shuler &rxq_conf,
173cc7e8ae8SMichal Jastrzebski mbuf_pool);
174cc7e8ae8SMichal Jastrzebski if (retval < 0)
175cc7e8ae8SMichal Jastrzebski rte_exit(retval, " port %u: RX queue 0 setup failed (res=%d)",
176cc7e8ae8SMichal Jastrzebski portid, retval);
177cc7e8ae8SMichal Jastrzebski
178cc7e8ae8SMichal Jastrzebski /* TX setup */
179c1b77788SShahaf Shuler txq_conf = dev_info.default_txconf;
180c1b77788SShahaf Shuler txq_conf.offloads = local_port_conf.txmode.offloads;
18160efb44fSRoman Zhukov retval = rte_eth_tx_queue_setup(portid, 0, nb_txd,
182c1b77788SShahaf Shuler rte_eth_dev_socket_id(portid), &txq_conf);
183cc7e8ae8SMichal Jastrzebski
184cc7e8ae8SMichal Jastrzebski if (retval < 0)
185cc7e8ae8SMichal Jastrzebski rte_exit(retval, "port %u: TX queue 0 setup failed (res=%d)",
186cc7e8ae8SMichal Jastrzebski portid, retval);
187cc7e8ae8SMichal Jastrzebski
188cc7e8ae8SMichal Jastrzebski retval = rte_eth_dev_start(portid);
189cc7e8ae8SMichal Jastrzebski if (retval < 0)
190cc7e8ae8SMichal Jastrzebski rte_exit(retval,
191cc7e8ae8SMichal Jastrzebski "Start port %d failed (res=%d)",
192cc7e8ae8SMichal Jastrzebski portid, retval);
193cc7e8ae8SMichal Jastrzebski
1946d13ea8eSOlivier Matz struct rte_ether_addr addr;
195cc7e8ae8SMichal Jastrzebski
19670febdcfSIgor Romanov retval = rte_eth_macaddr_get(portid, &addr);
19770febdcfSIgor Romanov if (retval != 0)
19870febdcfSIgor Romanov rte_exit(retval,
19970febdcfSIgor Romanov "Mac address get port %d failed (res=%d)",
20070febdcfSIgor Romanov portid, retval);
20170febdcfSIgor Romanov
202f8244c63SZhiyong Yang printf("Port %u MAC: ", portid);
203cc7e8ae8SMichal Jastrzebski PRINT_MAC(addr);
204cc7e8ae8SMichal Jastrzebski printf("\n");
205cc7e8ae8SMichal Jastrzebski }
206cc7e8ae8SMichal Jastrzebski
207cc7e8ae8SMichal Jastrzebski static void
bond_port_init(struct rte_mempool * mbuf_pool)208cc7e8ae8SMichal Jastrzebski bond_port_init(struct rte_mempool *mbuf_pool)
209cc7e8ae8SMichal Jastrzebski {
210cc7e8ae8SMichal Jastrzebski int retval;
211cc7e8ae8SMichal Jastrzebski uint8_t i;
21260efb44fSRoman Zhukov uint16_t nb_rxd = RTE_RX_DESC_DEFAULT;
21360efb44fSRoman Zhukov uint16_t nb_txd = RTE_TX_DESC_DEFAULT;
214c1b77788SShahaf Shuler struct rte_eth_dev_info dev_info;
215c1b77788SShahaf Shuler struct rte_eth_rxconf rxq_conf;
216c1b77788SShahaf Shuler struct rte_eth_txconf txq_conf;
217c1b77788SShahaf Shuler struct rte_eth_conf local_port_conf = port_conf;
218292fdb76SRadu Nicolau uint16_t wait_counter = 20;
219cc7e8ae8SMichal Jastrzebski
220e6509c6cSRadu Nicolau retval = rte_eth_bond_create("net_bonding0", BONDING_MODE_ALB,
221cc7e8ae8SMichal Jastrzebski 0 /*SOCKET_ID_ANY*/);
222cc7e8ae8SMichal Jastrzebski if (retval < 0)
223cc7e8ae8SMichal Jastrzebski rte_exit(EXIT_FAILURE,
2247be78d02SJosh Soref "Failed to create bond port\n");
225cc7e8ae8SMichal Jastrzebski
226f8244c63SZhiyong Yang BOND_PORT = retval;
227cc7e8ae8SMichal Jastrzebski
228089e5ed7SIvan Ilchenko retval = rte_eth_dev_info_get(BOND_PORT, &dev_info);
229089e5ed7SIvan Ilchenko if (retval != 0)
230089e5ed7SIvan Ilchenko rte_exit(EXIT_FAILURE,
231089e5ed7SIvan Ilchenko "Error during getting device (port %u) info: %s\n",
232089e5ed7SIvan Ilchenko BOND_PORT, strerror(-retval));
233089e5ed7SIvan Ilchenko
234295968d1SFerruh Yigit if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
235c1b77788SShahaf Shuler local_port_conf.txmode.offloads |=
236295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
237c1b77788SShahaf Shuler retval = rte_eth_dev_configure(BOND_PORT, 1, 1, &local_port_conf);
238cc7e8ae8SMichal Jastrzebski if (retval != 0)
239cc7e8ae8SMichal Jastrzebski rte_exit(EXIT_FAILURE, "port %u: configuration failed (res=%d)\n",
240cc7e8ae8SMichal Jastrzebski BOND_PORT, retval);
241cc7e8ae8SMichal Jastrzebski
24260efb44fSRoman Zhukov retval = rte_eth_dev_adjust_nb_rx_tx_desc(BOND_PORT, &nb_rxd, &nb_txd);
24360efb44fSRoman Zhukov if (retval != 0)
24460efb44fSRoman Zhukov rte_exit(EXIT_FAILURE, "port %u: rte_eth_dev_adjust_nb_rx_tx_desc "
24560efb44fSRoman Zhukov "failed (res=%d)\n", BOND_PORT, retval);
24660efb44fSRoman Zhukov
24715e34522SLong Wu for (i = 0; i < members_count; i++) {
24815e34522SLong Wu if (rte_eth_bond_member_add(BOND_PORT, members[i]) == -1)
24915e34522SLong Wu rte_exit(-1, "Oooops! adding member (%u) to bond (%u) failed!\n",
25015e34522SLong Wu members[i], BOND_PORT);
2512eee509cSRadu Nicolau
2522eee509cSRadu Nicolau }
2532eee509cSRadu Nicolau
254cc7e8ae8SMichal Jastrzebski /* RX setup */
255c1b77788SShahaf Shuler rxq_conf = dev_info.default_rxconf;
256c1b77788SShahaf Shuler rxq_conf.offloads = local_port_conf.rxmode.offloads;
25760efb44fSRoman Zhukov retval = rte_eth_rx_queue_setup(BOND_PORT, 0, nb_rxd,
258c1b77788SShahaf Shuler rte_eth_dev_socket_id(BOND_PORT),
259c1b77788SShahaf Shuler &rxq_conf, mbuf_pool);
260cc7e8ae8SMichal Jastrzebski if (retval < 0)
261cc7e8ae8SMichal Jastrzebski rte_exit(retval, " port %u: RX queue 0 setup failed (res=%d)",
262cc7e8ae8SMichal Jastrzebski BOND_PORT, retval);
263cc7e8ae8SMichal Jastrzebski
264cc7e8ae8SMichal Jastrzebski /* TX setup */
265c1b77788SShahaf Shuler txq_conf = dev_info.default_txconf;
266c1b77788SShahaf Shuler txq_conf.offloads = local_port_conf.txmode.offloads;
26760efb44fSRoman Zhukov retval = rte_eth_tx_queue_setup(BOND_PORT, 0, nb_txd,
268c1b77788SShahaf Shuler rte_eth_dev_socket_id(BOND_PORT), &txq_conf);
269cc7e8ae8SMichal Jastrzebski
270cc7e8ae8SMichal Jastrzebski if (retval < 0)
271cc7e8ae8SMichal Jastrzebski rte_exit(retval, "port %u: TX queue 0 setup failed (res=%d)",
272cc7e8ae8SMichal Jastrzebski BOND_PORT, retval);
273cc7e8ae8SMichal Jastrzebski
274cc7e8ae8SMichal Jastrzebski retval = rte_eth_dev_start(BOND_PORT);
275cc7e8ae8SMichal Jastrzebski if (retval < 0)
276cc7e8ae8SMichal Jastrzebski rte_exit(retval, "Start port %d failed (res=%d)", BOND_PORT, retval);
277cc7e8ae8SMichal Jastrzebski
27815e34522SLong Wu printf("Waiting for members to become active...");
279292fdb76SRadu Nicolau while (wait_counter) {
28015e34522SLong Wu uint16_t act_members[16] = {0};
28115e34522SLong Wu if (rte_eth_bond_active_members_get(BOND_PORT, act_members, 16) ==
28215e34522SLong Wu members_count) {
283292fdb76SRadu Nicolau printf("\n");
284292fdb76SRadu Nicolau break;
285292fdb76SRadu Nicolau }
286292fdb76SRadu Nicolau sleep(1);
287292fdb76SRadu Nicolau printf("...");
288292fdb76SRadu Nicolau if (--wait_counter == 0)
28915e34522SLong Wu rte_exit(-1, "\nFailed to activate members\n");
290292fdb76SRadu Nicolau }
291292fdb76SRadu Nicolau
292f430bbceSIvan Ilchenko retval = rte_eth_promiscuous_enable(BOND_PORT);
293f430bbceSIvan Ilchenko if (retval != 0) {
294f430bbceSIvan Ilchenko rte_exit(EXIT_FAILURE,
295f430bbceSIvan Ilchenko "port %u: promiscuous mode enable failed: %s\n",
296f430bbceSIvan Ilchenko BOND_PORT, rte_strerror(-retval));
297f430bbceSIvan Ilchenko return;
298f430bbceSIvan Ilchenko }
299cc7e8ae8SMichal Jastrzebski
3006d13ea8eSOlivier Matz struct rte_ether_addr addr;
301cc7e8ae8SMichal Jastrzebski
30270febdcfSIgor Romanov retval = rte_eth_macaddr_get(BOND_PORT, &addr);
30370febdcfSIgor Romanov if (retval != 0)
30470febdcfSIgor Romanov rte_exit(retval, "port %u: Mac address get failed (res=%d)",
30570febdcfSIgor Romanov BOND_PORT, retval);
30670febdcfSIgor Romanov
307cc7e8ae8SMichal Jastrzebski printf("Port %u MAC: ", (unsigned)BOND_PORT);
308cc7e8ae8SMichal Jastrzebski PRINT_MAC(addr);
309cc7e8ae8SMichal Jastrzebski printf("\n");
310cc7e8ae8SMichal Jastrzebski }
311cc7e8ae8SMichal Jastrzebski
312cc7e8ae8SMichal Jastrzebski static inline size_t
get_vlan_offset(struct rte_ether_hdr * eth_hdr,uint16_t * proto)3136d13ea8eSOlivier Matz get_vlan_offset(struct rte_ether_hdr *eth_hdr, uint16_t *proto)
314cc7e8ae8SMichal Jastrzebski {
315cc7e8ae8SMichal Jastrzebski size_t vlan_offset = 0;
316cc7e8ae8SMichal Jastrzebski
31735b2d13fSOlivier Matz if (rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) == *proto) {
3186d13ea8eSOlivier Matz struct rte_vlan_hdr *vlan_hdr =
3196d13ea8eSOlivier Matz (struct rte_vlan_hdr *)(eth_hdr + 1);
320cc7e8ae8SMichal Jastrzebski
3216d13ea8eSOlivier Matz vlan_offset = sizeof(struct rte_vlan_hdr);
322cc7e8ae8SMichal Jastrzebski *proto = vlan_hdr->eth_proto;
323cc7e8ae8SMichal Jastrzebski
32435b2d13fSOlivier Matz if (rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) == *proto) {
325cc7e8ae8SMichal Jastrzebski vlan_hdr = vlan_hdr + 1;
326cc7e8ae8SMichal Jastrzebski
327cc7e8ae8SMichal Jastrzebski *proto = vlan_hdr->eth_proto;
3286d13ea8eSOlivier Matz vlan_offset += sizeof(struct rte_vlan_hdr);
329cc7e8ae8SMichal Jastrzebski }
330cc7e8ae8SMichal Jastrzebski }
331cc7e8ae8SMichal Jastrzebski return vlan_offset;
332cc7e8ae8SMichal Jastrzebski }
333cc7e8ae8SMichal Jastrzebski
334cc7e8ae8SMichal Jastrzebski struct global_flag_stru_t {
335cc7e8ae8SMichal Jastrzebski int LcoreMainIsRunning;
336cc7e8ae8SMichal Jastrzebski int LcoreMainCore;
337cc7e8ae8SMichal Jastrzebski uint32_t port_packets[4];
338cc7e8ae8SMichal Jastrzebski rte_spinlock_t lock;
339cc7e8ae8SMichal Jastrzebski };
340cc7e8ae8SMichal Jastrzebski struct global_flag_stru_t global_flag_stru;
341cc7e8ae8SMichal Jastrzebski struct global_flag_stru_t *global_flag_stru_p = &global_flag_stru;
342cc7e8ae8SMichal Jastrzebski
343cc7e8ae8SMichal Jastrzebski /*
344cc7e8ae8SMichal Jastrzebski * Main thread that does the work, reading from INPUT_PORT
345cc7e8ae8SMichal Jastrzebski * and writing to OUTPUT_PORT
346cc7e8ae8SMichal Jastrzebski */
lcore_main(__rte_unused void * arg1)347f2fc83b4SThomas Monjalon static int lcore_main(__rte_unused void *arg1)
348cc7e8ae8SMichal Jastrzebski {
349*7e06c0deSTyler Retzlaff alignas(RTE_CACHE_LINE_SIZE) struct rte_mbuf *pkts[MAX_PKT_BURST];
35004d43857SDmitry Kozlyuk struct rte_ether_addr dst_addr;
351cc7e8ae8SMichal Jastrzebski
35270febdcfSIgor Romanov struct rte_ether_addr bond_mac_addr;
3536d13ea8eSOlivier Matz struct rte_ether_hdr *eth_hdr;
354f2745bfeSOlivier Matz struct rte_arp_hdr *arp_hdr;
355a7c528e5SOlivier Matz struct rte_ipv4_hdr *ipv4_hdr;
356cc7e8ae8SMichal Jastrzebski uint16_t ether_type, offset;
357cc7e8ae8SMichal Jastrzebski
358cc7e8ae8SMichal Jastrzebski uint16_t rx_cnt;
359cc7e8ae8SMichal Jastrzebski uint32_t bond_ip;
360cc7e8ae8SMichal Jastrzebski int i = 0;
361cc7e8ae8SMichal Jastrzebski uint8_t is_free;
36270febdcfSIgor Romanov int ret;
363cc7e8ae8SMichal Jastrzebski
364cc7e8ae8SMichal Jastrzebski bond_ip = BOND_IP_1 | (BOND_IP_2 << 8) |
365cc7e8ae8SMichal Jastrzebski (BOND_IP_3 << 16) | (BOND_IP_4 << 24);
366cc7e8ae8SMichal Jastrzebski
36703382cf4SMattias Rönnblom rte_spinlock_lock(&global_flag_stru_p->lock);
368cc7e8ae8SMichal Jastrzebski
369cc7e8ae8SMichal Jastrzebski while (global_flag_stru_p->LcoreMainIsRunning) {
370cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
371cc7e8ae8SMichal Jastrzebski rx_cnt = rte_eth_rx_burst(BOND_PORT, 0, pkts, MAX_PKT_BURST);
372cc7e8ae8SMichal Jastrzebski is_free = 0;
373cc7e8ae8SMichal Jastrzebski
374cc7e8ae8SMichal Jastrzebski /* If didn't receive any packets, wait and go to next iteration */
375cc7e8ae8SMichal Jastrzebski if (rx_cnt == 0) {
376cc7e8ae8SMichal Jastrzebski rte_delay_us(50);
377cc7e8ae8SMichal Jastrzebski continue;
378cc7e8ae8SMichal Jastrzebski }
379cc7e8ae8SMichal Jastrzebski
38070febdcfSIgor Romanov ret = rte_eth_macaddr_get(BOND_PORT, &bond_mac_addr);
38170febdcfSIgor Romanov if (ret != 0) {
38270febdcfSIgor Romanov printf("Bond (port %u) MAC address get failed: %s.\n"
38370febdcfSIgor Romanov "%u packets dropped", BOND_PORT, strerror(-ret),
38470febdcfSIgor Romanov rx_cnt);
38570febdcfSIgor Romanov rte_pktmbuf_free(pkts[i]);
38670febdcfSIgor Romanov continue;
38770febdcfSIgor Romanov }
38870febdcfSIgor Romanov
389cc7e8ae8SMichal Jastrzebski /* Search incoming data for ARP packets and prepare response */
390cc7e8ae8SMichal Jastrzebski for (i = 0; i < rx_cnt; i++) {
391cc7e8ae8SMichal Jastrzebski if (rte_spinlock_trylock(&global_flag_stru_p->lock) == 1) {
392cc7e8ae8SMichal Jastrzebski global_flag_stru_p->port_packets[0]++;
393cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
394cc7e8ae8SMichal Jastrzebski }
3956d13ea8eSOlivier Matz eth_hdr = rte_pktmbuf_mtod(pkts[i],
3966d13ea8eSOlivier Matz struct rte_ether_hdr *);
397cc7e8ae8SMichal Jastrzebski ether_type = eth_hdr->ether_type;
39835b2d13fSOlivier Matz if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN))
3997be78d02SJosh Soref printf("VLAN tagged frame, offset:");
400cc7e8ae8SMichal Jastrzebski offset = get_vlan_offset(eth_hdr, ðer_type);
401cc7e8ae8SMichal Jastrzebski if (offset > 0)
402cc7e8ae8SMichal Jastrzebski printf("%d\n", offset);
40335b2d13fSOlivier Matz if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP)) {
404cc7e8ae8SMichal Jastrzebski if (rte_spinlock_trylock(&global_flag_stru_p->lock) == 1) {
405cc7e8ae8SMichal Jastrzebski global_flag_stru_p->port_packets[1]++;
406cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
407cc7e8ae8SMichal Jastrzebski }
408f2745bfeSOlivier Matz arp_hdr = (struct rte_arp_hdr *)(
409f2745bfeSOlivier Matz (char *)(eth_hdr + 1) + offset);
410cc7e8ae8SMichal Jastrzebski if (arp_hdr->arp_data.arp_tip == bond_ip) {
411e482e0faSOlivier Matz if (arp_hdr->arp_opcode == rte_cpu_to_be_16(RTE_ARP_OP_REQUEST)) {
412e482e0faSOlivier Matz arp_hdr->arp_opcode = rte_cpu_to_be_16(RTE_ARP_OP_REPLY);
413cc7e8ae8SMichal Jastrzebski /* Switch src and dst data and set bonding MAC */
41404d43857SDmitry Kozlyuk rte_ether_addr_copy(ð_hdr->src_addr, ð_hdr->dst_addr);
41504d43857SDmitry Kozlyuk rte_ether_addr_copy(&bond_mac_addr, ð_hdr->src_addr);
416538da7a1SOlivier Matz rte_ether_addr_copy(&arp_hdr->arp_data.arp_sha,
417538da7a1SOlivier Matz &arp_hdr->arp_data.arp_tha);
418cc7e8ae8SMichal Jastrzebski arp_hdr->arp_data.arp_tip = arp_hdr->arp_data.arp_sip;
41904d43857SDmitry Kozlyuk rte_ether_addr_copy(&bond_mac_addr, &dst_addr);
42004d43857SDmitry Kozlyuk rte_ether_addr_copy(&dst_addr, &arp_hdr->arp_data.arp_sha);
421cc7e8ae8SMichal Jastrzebski arp_hdr->arp_data.arp_sip = bond_ip;
422cc7e8ae8SMichal Jastrzebski rte_eth_tx_burst(BOND_PORT, 0, &pkts[i], 1);
423cc7e8ae8SMichal Jastrzebski is_free = 1;
424cc7e8ae8SMichal Jastrzebski } else {
425cc7e8ae8SMichal Jastrzebski rte_eth_tx_burst(BOND_PORT, 0, NULL, 0);
426cc7e8ae8SMichal Jastrzebski }
427cc7e8ae8SMichal Jastrzebski }
4280c9da755SDavid Marchand } else if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
429cc7e8ae8SMichal Jastrzebski if (rte_spinlock_trylock(&global_flag_stru_p->lock) == 1) {
430cc7e8ae8SMichal Jastrzebski global_flag_stru_p->port_packets[2]++;
431cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
432cc7e8ae8SMichal Jastrzebski }
433a7c528e5SOlivier Matz ipv4_hdr = (struct rte_ipv4_hdr *)((char *)(eth_hdr + 1) + offset);
434cc7e8ae8SMichal Jastrzebski if (ipv4_hdr->dst_addr == bond_ip) {
43504d43857SDmitry Kozlyuk rte_ether_addr_copy(ð_hdr->src_addr,
43604d43857SDmitry Kozlyuk ð_hdr->dst_addr);
43704d43857SDmitry Kozlyuk rte_ether_addr_copy(&bond_mac_addr,
43804d43857SDmitry Kozlyuk ð_hdr->src_addr);
439cc7e8ae8SMichal Jastrzebski ipv4_hdr->dst_addr = ipv4_hdr->src_addr;
440cc7e8ae8SMichal Jastrzebski ipv4_hdr->src_addr = bond_ip;
441cc7e8ae8SMichal Jastrzebski rte_eth_tx_burst(BOND_PORT, 0, &pkts[i], 1);
442cc7e8ae8SMichal Jastrzebski }
443cc7e8ae8SMichal Jastrzebski
444cc7e8ae8SMichal Jastrzebski }
445cc7e8ae8SMichal Jastrzebski
446cc7e8ae8SMichal Jastrzebski /* Free processed packets */
447cc7e8ae8SMichal Jastrzebski if (is_free == 0)
448cc7e8ae8SMichal Jastrzebski rte_pktmbuf_free(pkts[i]);
449cc7e8ae8SMichal Jastrzebski }
45003382cf4SMattias Rönnblom rte_spinlock_lock(&global_flag_stru_p->lock);
451cc7e8ae8SMichal Jastrzebski }
452cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
453cc7e8ae8SMichal Jastrzebski printf("BYE lcore_main\n");
454cc7e8ae8SMichal Jastrzebski return 0;
455cc7e8ae8SMichal Jastrzebski }
456cc7e8ae8SMichal Jastrzebski
get_string(struct cmd_send_result * res,char * buf,uint8_t size)457cfc3bc5dSBruce Richardson static inline void get_string(struct cmd_send_result *res, char *buf, uint8_t size)
458cc7e8ae8SMichal Jastrzebski {
459cc7e8ae8SMichal Jastrzebski snprintf(buf, size, NIPQUAD_FMT,
460cc7e8ae8SMichal Jastrzebski ((unsigned)((unsigned char *)&(res->ip.addr.ipv4))[0]),
461cc7e8ae8SMichal Jastrzebski ((unsigned)((unsigned char *)&(res->ip.addr.ipv4))[1]),
462cc7e8ae8SMichal Jastrzebski ((unsigned)((unsigned char *)&(res->ip.addr.ipv4))[2]),
463cc7e8ae8SMichal Jastrzebski ((unsigned)((unsigned char *)&(res->ip.addr.ipv4))[3])
464cc7e8ae8SMichal Jastrzebski );
465cc7e8ae8SMichal Jastrzebski }
466cfc3bc5dSBruce Richardson void
cmd_send_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)467cfc3bc5dSBruce Richardson cmd_send_parsed(void *parsed_result, __rte_unused struct cmdline *cl, __rte_unused void *data)
468cc7e8ae8SMichal Jastrzebski {
469cc7e8ae8SMichal Jastrzebski
470cfc3bc5dSBruce Richardson struct cmd_send_result *res = parsed_result;
471cc7e8ae8SMichal Jastrzebski char ip_str[INET6_ADDRSTRLEN];
472cc7e8ae8SMichal Jastrzebski
47370febdcfSIgor Romanov struct rte_ether_addr bond_mac_addr;
474cc7e8ae8SMichal Jastrzebski struct rte_mbuf *created_pkt;
4756d13ea8eSOlivier Matz struct rte_ether_hdr *eth_hdr;
476f2745bfeSOlivier Matz struct rte_arp_hdr *arp_hdr;
477cc7e8ae8SMichal Jastrzebski
478cc7e8ae8SMichal Jastrzebski uint32_t bond_ip;
479cc7e8ae8SMichal Jastrzebski size_t pkt_size;
48070febdcfSIgor Romanov int ret;
481cc7e8ae8SMichal Jastrzebski
482cc7e8ae8SMichal Jastrzebski if (res->ip.family == AF_INET)
483cc7e8ae8SMichal Jastrzebski get_string(res, ip_str, INET_ADDRSTRLEN);
484cc7e8ae8SMichal Jastrzebski else
485cc7e8ae8SMichal Jastrzebski cmdline_printf(cl, "Wrong IP format. Only IPv4 is supported\n");
486cc7e8ae8SMichal Jastrzebski
487cc7e8ae8SMichal Jastrzebski bond_ip = BOND_IP_1 | (BOND_IP_2 << 8) |
488cc7e8ae8SMichal Jastrzebski (BOND_IP_3 << 16) | (BOND_IP_4 << 24);
489cc7e8ae8SMichal Jastrzebski
49070febdcfSIgor Romanov ret = rte_eth_macaddr_get(BOND_PORT, &bond_mac_addr);
49170febdcfSIgor Romanov if (ret != 0) {
49270febdcfSIgor Romanov cmdline_printf(cl,
49370febdcfSIgor Romanov "Failed to get bond (port %u) MAC address: %s\n",
49470febdcfSIgor Romanov BOND_PORT, strerror(-ret));
49570febdcfSIgor Romanov }
49670febdcfSIgor Romanov
497cc7e8ae8SMichal Jastrzebski created_pkt = rte_pktmbuf_alloc(mbuf_pool);
4980bb76fc9SRadu Nicolau if (created_pkt == NULL) {
4990bb76fc9SRadu Nicolau cmdline_printf(cl, "Failed to allocate mbuf\n");
5000bb76fc9SRadu Nicolau return;
5010bb76fc9SRadu Nicolau }
5020bb76fc9SRadu Nicolau
5036d13ea8eSOlivier Matz pkt_size = sizeof(struct rte_ether_hdr) + sizeof(struct rte_arp_hdr);
504cc7e8ae8SMichal Jastrzebski created_pkt->data_len = pkt_size;
505cc7e8ae8SMichal Jastrzebski created_pkt->pkt_len = pkt_size;
506cc7e8ae8SMichal Jastrzebski
5076d13ea8eSOlivier Matz eth_hdr = rte_pktmbuf_mtod(created_pkt, struct rte_ether_hdr *);
50804d43857SDmitry Kozlyuk rte_ether_addr_copy(&bond_mac_addr, ð_hdr->src_addr);
50904d43857SDmitry Kozlyuk memset(ð_hdr->dst_addr, 0xFF, RTE_ETHER_ADDR_LEN);
51035b2d13fSOlivier Matz eth_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);
511cc7e8ae8SMichal Jastrzebski
512f2745bfeSOlivier Matz arp_hdr = (struct rte_arp_hdr *)(
5136d13ea8eSOlivier Matz (char *)eth_hdr + sizeof(struct rte_ether_hdr));
514e482e0faSOlivier Matz arp_hdr->arp_hardware = rte_cpu_to_be_16(RTE_ARP_HRD_ETHER);
5150c9da755SDavid Marchand arp_hdr->arp_protocol = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
51635b2d13fSOlivier Matz arp_hdr->arp_hlen = RTE_ETHER_ADDR_LEN;
517f2745bfeSOlivier Matz arp_hdr->arp_plen = sizeof(uint32_t);
518e482e0faSOlivier Matz arp_hdr->arp_opcode = rte_cpu_to_be_16(RTE_ARP_OP_REQUEST);
519cc7e8ae8SMichal Jastrzebski
52070febdcfSIgor Romanov rte_ether_addr_copy(&bond_mac_addr, &arp_hdr->arp_data.arp_sha);
521cc7e8ae8SMichal Jastrzebski arp_hdr->arp_data.arp_sip = bond_ip;
52235b2d13fSOlivier Matz memset(&arp_hdr->arp_data.arp_tha, 0, RTE_ETHER_ADDR_LEN);
523cc7e8ae8SMichal Jastrzebski arp_hdr->arp_data.arp_tip =
524cc7e8ae8SMichal Jastrzebski ((unsigned char *)&res->ip.addr.ipv4)[0] |
525cc7e8ae8SMichal Jastrzebski (((unsigned char *)&res->ip.addr.ipv4)[1] << 8) |
526cc7e8ae8SMichal Jastrzebski (((unsigned char *)&res->ip.addr.ipv4)[2] << 16) |
527cc7e8ae8SMichal Jastrzebski (((unsigned char *)&res->ip.addr.ipv4)[3] << 24);
528cc7e8ae8SMichal Jastrzebski rte_eth_tx_burst(BOND_PORT, 0, &created_pkt, 1);
529cc7e8ae8SMichal Jastrzebski
530cc7e8ae8SMichal Jastrzebski rte_delay_ms(100);
531cc7e8ae8SMichal Jastrzebski cmdline_printf(cl, "\n");
532cc7e8ae8SMichal Jastrzebski }
533cc7e8ae8SMichal Jastrzebski
534cfc3bc5dSBruce Richardson void
cmd_start_parsed(__rte_unused void * parsed_result,struct cmdline * cl,__rte_unused void * data)535cfc3bc5dSBruce Richardson cmd_start_parsed(__rte_unused void *parsed_result, struct cmdline *cl, __rte_unused void *data)
536cc7e8ae8SMichal Jastrzebski {
537cb056611SStephen Hemminger int worker_core_id = rte_lcore_id();
538cc7e8ae8SMichal Jastrzebski
53903382cf4SMattias Rönnblom rte_spinlock_lock(&global_flag_stru_p->lock);
540cc7e8ae8SMichal Jastrzebski if (global_flag_stru_p->LcoreMainIsRunning == 0) {
5412b7a03c5SStephen Hemminger if (rte_eal_get_lcore_state(global_flag_stru_p->LcoreMainCore)
5422b7a03c5SStephen Hemminger != WAIT) {
543cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
544cc7e8ae8SMichal Jastrzebski return;
545cc7e8ae8SMichal Jastrzebski }
546cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
547cc7e8ae8SMichal Jastrzebski } else {
548cc7e8ae8SMichal Jastrzebski cmdline_printf(cl, "lcore_main already running on core:%d\n",
549cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainCore);
550cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
551cc7e8ae8SMichal Jastrzebski return;
552cc7e8ae8SMichal Jastrzebski }
553cc7e8ae8SMichal Jastrzebski
554cb056611SStephen Hemminger /* start lcore main on core != main_core - ARP response thread */
555cb056611SStephen Hemminger worker_core_id = rte_get_next_lcore(rte_lcore_id(), 1, 0);
556cb056611SStephen Hemminger if ((worker_core_id >= RTE_MAX_LCORE) || (worker_core_id == 0))
557cc7e8ae8SMichal Jastrzebski return;
558cc7e8ae8SMichal Jastrzebski
55903382cf4SMattias Rönnblom rte_spinlock_lock(&global_flag_stru_p->lock);
560cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainIsRunning = 1;
561cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
562cc7e8ae8SMichal Jastrzebski cmdline_printf(cl,
563cc7e8ae8SMichal Jastrzebski "Starting lcore_main on core %d:%d "
564cc7e8ae8SMichal Jastrzebski "Our IP:%d.%d.%d.%d\n",
565cb056611SStephen Hemminger worker_core_id,
566cb056611SStephen Hemminger rte_eal_remote_launch(lcore_main, NULL, worker_core_id),
567cc7e8ae8SMichal Jastrzebski BOND_IP_1,
568cc7e8ae8SMichal Jastrzebski BOND_IP_2,
569cc7e8ae8SMichal Jastrzebski BOND_IP_3,
570cc7e8ae8SMichal Jastrzebski BOND_IP_4
571cc7e8ae8SMichal Jastrzebski );
572cc7e8ae8SMichal Jastrzebski }
573cc7e8ae8SMichal Jastrzebski
574cfc3bc5dSBruce Richardson void
cmd_help_parsed(__rte_unused void * parsed_result,struct cmdline * cl,__rte_unused void * data)575cfc3bc5dSBruce Richardson cmd_help_parsed(__rte_unused void *parsed_result, struct cmdline *cl, __rte_unused void *data)
576cc7e8ae8SMichal Jastrzebski {
577cc7e8ae8SMichal Jastrzebski cmdline_printf(cl,
578cc7e8ae8SMichal Jastrzebski "ALB - link bonding mode 6 example\n"
57998a7ea33SJerin Jacob "send IP - sends one ARPrequest through bonding for IP.\n"
580cc7e8ae8SMichal Jastrzebski "start - starts listening ARPs.\n"
581cc7e8ae8SMichal Jastrzebski "stop - stops lcore_main.\n"
58215e34522SLong Wu "show - shows some bond info: ex. active members etc.\n"
583cc7e8ae8SMichal Jastrzebski "help - prints help.\n"
584cc7e8ae8SMichal Jastrzebski "quit - terminate all threads and quit.\n"
585cc7e8ae8SMichal Jastrzebski );
586cc7e8ae8SMichal Jastrzebski }
587cc7e8ae8SMichal Jastrzebski
588cfc3bc5dSBruce Richardson void
cmd_stop_parsed(__rte_unused void * parsed_result,struct cmdline * cl,__rte_unused void * data)589cfc3bc5dSBruce Richardson cmd_stop_parsed(__rte_unused void *parsed_result, struct cmdline *cl, __rte_unused void *data)
590cc7e8ae8SMichal Jastrzebski {
59103382cf4SMattias Rönnblom rte_spinlock_lock(&global_flag_stru_p->lock);
592cc7e8ae8SMichal Jastrzebski if (global_flag_stru_p->LcoreMainIsRunning == 0) {
593cc7e8ae8SMichal Jastrzebski cmdline_printf(cl,
594cc7e8ae8SMichal Jastrzebski "lcore_main not running on core:%d\n",
595cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainCore);
596cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
597cc7e8ae8SMichal Jastrzebski return;
598cc7e8ae8SMichal Jastrzebski }
599cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainIsRunning = 0;
6003ca530edSPiotr Azarewicz if (rte_eal_wait_lcore(global_flag_stru_p->LcoreMainCore) < 0)
6013ca530edSPiotr Azarewicz cmdline_printf(cl,
6023ca530edSPiotr Azarewicz "error: lcore_main can not stop on core:%d\n",
6033ca530edSPiotr Azarewicz global_flag_stru_p->LcoreMainCore);
6043ca530edSPiotr Azarewicz else
605cc7e8ae8SMichal Jastrzebski cmdline_printf(cl,
606cc7e8ae8SMichal Jastrzebski "lcore_main stopped on core:%d\n",
607cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainCore);
608cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
609cc7e8ae8SMichal Jastrzebski }
610cc7e8ae8SMichal Jastrzebski
611cfc3bc5dSBruce Richardson void
cmd_quit_parsed(__rte_unused void * parsed_result,struct cmdline * cl,__rte_unused void * data)612cfc3bc5dSBruce Richardson cmd_quit_parsed(__rte_unused void *parsed_result, struct cmdline *cl, __rte_unused void *data)
613cc7e8ae8SMichal Jastrzebski {
61403382cf4SMattias Rönnblom rte_spinlock_lock(&global_flag_stru_p->lock);
615cc7e8ae8SMichal Jastrzebski if (global_flag_stru_p->LcoreMainIsRunning == 0) {
616cc7e8ae8SMichal Jastrzebski cmdline_printf(cl,
617cc7e8ae8SMichal Jastrzebski "lcore_main not running on core:%d\n",
618cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainCore);
619cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
620cc7e8ae8SMichal Jastrzebski cmdline_quit(cl);
621cc7e8ae8SMichal Jastrzebski return;
622cc7e8ae8SMichal Jastrzebski }
623cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainIsRunning = 0;
6243ca530edSPiotr Azarewicz if (rte_eal_wait_lcore(global_flag_stru_p->LcoreMainCore) < 0)
6253ca530edSPiotr Azarewicz cmdline_printf(cl,
6263ca530edSPiotr Azarewicz "error: lcore_main can not stop on core:%d\n",
6273ca530edSPiotr Azarewicz global_flag_stru_p->LcoreMainCore);
6283ca530edSPiotr Azarewicz else
629cc7e8ae8SMichal Jastrzebski cmdline_printf(cl,
630cc7e8ae8SMichal Jastrzebski "lcore_main stopped on core:%d\n",
631cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainCore);
632cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
633cc7e8ae8SMichal Jastrzebski cmdline_quit(cl);
634cc7e8ae8SMichal Jastrzebski }
635cc7e8ae8SMichal Jastrzebski
636cfc3bc5dSBruce Richardson void
cmd_show_parsed(__rte_unused void * parsed_result,struct cmdline * cl,__rte_unused void * data)637cfc3bc5dSBruce Richardson cmd_show_parsed(__rte_unused void *parsed_result, struct cmdline *cl, __rte_unused void *data)
638cc7e8ae8SMichal Jastrzebski {
63915e34522SLong Wu uint16_t members[16] = {0};
640cc7e8ae8SMichal Jastrzebski uint8_t len = 16;
6416d13ea8eSOlivier Matz struct rte_ether_addr addr;
64270febdcfSIgor Romanov uint16_t i;
64370febdcfSIgor Romanov int ret;
644cc7e8ae8SMichal Jastrzebski
64515e34522SLong Wu for (i = 0; i < members_count; i++) {
64670febdcfSIgor Romanov ret = rte_eth_macaddr_get(i, &addr);
64770febdcfSIgor Romanov if (ret != 0) {
64870febdcfSIgor Romanov cmdline_printf(cl,
64970febdcfSIgor Romanov "Failed to get port %u MAC address: %s\n",
65070febdcfSIgor Romanov i, strerror(-ret));
65170febdcfSIgor Romanov continue;
65270febdcfSIgor Romanov }
65370febdcfSIgor Romanov
654cc7e8ae8SMichal Jastrzebski PRINT_MAC(addr);
655cc7e8ae8SMichal Jastrzebski printf("\n");
656cc7e8ae8SMichal Jastrzebski }
657cc7e8ae8SMichal Jastrzebski
65803382cf4SMattias Rönnblom rte_spinlock_lock(&global_flag_stru_p->lock);
659cc7e8ae8SMichal Jastrzebski cmdline_printf(cl,
66015e34522SLong Wu "Active_members:%d "
661cc7e8ae8SMichal Jastrzebski "packets received:Tot:%d Arp:%d IPv4:%d\n",
66215e34522SLong Wu rte_eth_bond_active_members_get(BOND_PORT, members, len),
663cc7e8ae8SMichal Jastrzebski global_flag_stru_p->port_packets[0],
664cc7e8ae8SMichal Jastrzebski global_flag_stru_p->port_packets[1],
665cc7e8ae8SMichal Jastrzebski global_flag_stru_p->port_packets[2]);
666cc7e8ae8SMichal Jastrzebski rte_spinlock_unlock(&global_flag_stru_p->lock);
667cc7e8ae8SMichal Jastrzebski }
668cc7e8ae8SMichal Jastrzebski
669cb056611SStephen Hemminger /* prompt function, called from main on MAIN lcore */
prompt(__rte_unused void * arg1)670f2fc83b4SThomas Monjalon static void prompt(__rte_unused void *arg1)
671cc7e8ae8SMichal Jastrzebski {
672cc7e8ae8SMichal Jastrzebski struct cmdline *cl;
673cc7e8ae8SMichal Jastrzebski
674cc7e8ae8SMichal Jastrzebski cl = cmdline_stdin_new(main_ctx, "bond6>");
675cc7e8ae8SMichal Jastrzebski if (cl != NULL) {
676cc7e8ae8SMichal Jastrzebski cmdline_interact(cl);
677cc7e8ae8SMichal Jastrzebski cmdline_stdin_exit(cl);
678cc7e8ae8SMichal Jastrzebski }
679cc7e8ae8SMichal Jastrzebski }
680cc7e8ae8SMichal Jastrzebski
681cc7e8ae8SMichal Jastrzebski /* Main function, does initialisation and calls the per-lcore functions */
682cc7e8ae8SMichal Jastrzebski int
main(int argc,char * argv[])683cc7e8ae8SMichal Jastrzebski main(int argc, char *argv[])
684cc7e8ae8SMichal Jastrzebski {
685cb056611SStephen Hemminger int ret, worker_core_id;
6868728ccf3SThomas Monjalon uint16_t nb_ports, i;
687cc7e8ae8SMichal Jastrzebski
688cc7e8ae8SMichal Jastrzebski /* init EAL */
689cc7e8ae8SMichal Jastrzebski ret = rte_eal_init(argc, argv);
690b65ecf19SGaetan Rivet rte_devargs_dump(stdout);
691cc7e8ae8SMichal Jastrzebski if (ret < 0)
692cc7e8ae8SMichal Jastrzebski rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
693cc7e8ae8SMichal Jastrzebski argc -= ret;
694cc7e8ae8SMichal Jastrzebski argv += ret;
695cc7e8ae8SMichal Jastrzebski
696d9a42a69SThomas Monjalon nb_ports = rte_eth_dev_count_avail();
697cc7e8ae8SMichal Jastrzebski if (nb_ports == 0)
698cc7e8ae8SMichal Jastrzebski rte_exit(EXIT_FAILURE, "Give at least one port\n");
699cc7e8ae8SMichal Jastrzebski else if (nb_ports > MAX_PORTS)
700cc7e8ae8SMichal Jastrzebski rte_exit(EXIT_FAILURE, "You can have max 4 ports\n");
701cc7e8ae8SMichal Jastrzebski
702ea0c20eaSOlivier Matz mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NB_MBUF, 32,
703824cb29cSKonstantin Ananyev 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
704cc7e8ae8SMichal Jastrzebski if (mbuf_pool == NULL)
705cc7e8ae8SMichal Jastrzebski rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
706cc7e8ae8SMichal Jastrzebski
707cc7e8ae8SMichal Jastrzebski /* initialize all ports */
70815e34522SLong Wu members_count = nb_ports;
7098728ccf3SThomas Monjalon RTE_ETH_FOREACH_DEV(i) {
71015e34522SLong Wu member_port_init(i, mbuf_pool);
71115e34522SLong Wu members[i] = i;
712cc7e8ae8SMichal Jastrzebski }
713cc7e8ae8SMichal Jastrzebski
714cc7e8ae8SMichal Jastrzebski bond_port_init(mbuf_pool);
715cc7e8ae8SMichal Jastrzebski
716cc7e8ae8SMichal Jastrzebski rte_spinlock_init(&global_flag_stru_p->lock);
717cc7e8ae8SMichal Jastrzebski
718cc7e8ae8SMichal Jastrzebski /* check state of lcores */
719cb056611SStephen Hemminger RTE_LCORE_FOREACH_WORKER(worker_core_id) {
720cb056611SStephen Hemminger if (rte_eal_get_lcore_state(worker_core_id) != WAIT)
721cc7e8ae8SMichal Jastrzebski return -EBUSY;
722cc7e8ae8SMichal Jastrzebski }
7232b7a03c5SStephen Hemminger
724cb056611SStephen Hemminger /* start lcore main on core != main_core - ARP response thread */
725cb056611SStephen Hemminger worker_core_id = rte_get_next_lcore(rte_lcore_id(), 1, 0);
726cb056611SStephen Hemminger if ((worker_core_id >= RTE_MAX_LCORE) || (worker_core_id == 0))
727cc7e8ae8SMichal Jastrzebski return -EPERM;
728cc7e8ae8SMichal Jastrzebski
729cc7e8ae8SMichal Jastrzebski global_flag_stru_p->LcoreMainIsRunning = 1;
730cb056611SStephen Hemminger global_flag_stru_p->LcoreMainCore = worker_core_id;
731cc7e8ae8SMichal Jastrzebski printf("Starting lcore_main on core %d:%d Our IP:%d.%d.%d.%d\n",
732cb056611SStephen Hemminger worker_core_id,
733cc7e8ae8SMichal Jastrzebski rte_eal_remote_launch((lcore_function_t *)lcore_main,
734cc7e8ae8SMichal Jastrzebski NULL,
735cb056611SStephen Hemminger worker_core_id),
736cc7e8ae8SMichal Jastrzebski BOND_IP_1,
737cc7e8ae8SMichal Jastrzebski BOND_IP_2,
738cc7e8ae8SMichal Jastrzebski BOND_IP_3,
739cc7e8ae8SMichal Jastrzebski BOND_IP_4
740cc7e8ae8SMichal Jastrzebski );
741cc7e8ae8SMichal Jastrzebski
742cc7e8ae8SMichal Jastrzebski /* Start prompt for user interact */
743cc7e8ae8SMichal Jastrzebski prompt(NULL);
744cc7e8ae8SMichal Jastrzebski
745cc7e8ae8SMichal Jastrzebski rte_delay_ms(100);
74610aa3757SChengchang Tang
74710aa3757SChengchang Tang /* clean up the EAL */
74810aa3757SChengchang Tang rte_eal_cleanup();
74910aa3757SChengchang Tang
750cc7e8ae8SMichal Jastrzebski return 0;
751cc7e8ae8SMichal Jastrzebski }
752